# Alan Formatları

Model, which guesses the field name, gets either a `400` or, worse, a confident response for a different chart. Below is the exact contract.

## Card Request Body

| Field | Type and format | Required |
|---|---|---|
| `date` | `YYYY-MM-DD`, and it must be a real calendar day | yes |
| `time` | `HH:mm:ss` | yes, or `timeUnknown: true` |
| `timezoneOffset` | number, hours from UTC, e.g. `5.75` | no, default `0` (UTC) |
| `timezone` | IANA zone name, e.g. `Europe/Kyiv`, or `auto` | no, and when sent, it replaces `timezoneOffset` |
| `latitude` | decimal degrees, north positive | yes |
| `longitude` | decimal degrees, east positive | yes |
| `houseSystem` | one letter, default `P` | no |
| `city` | string, for signature only | no |
| `zodiacType` | `tropical` or `sidereal` | no |

<Aside type="caution">
`city` does not geocode anything. This field is for a signature in your interface, and it **never** replaces coordinates.
</Aside>

## Short forms are rejected

`lat`, `lon`, `lng`, `long`, `tz`, `tzOffset`, `utcOffset`, `gmtOffset`, `timeZone`, `time_zone` return `400 INVALID_FIELD` with the name of the correct field:

```json
{ "error": { "code": "INVALID_FIELD",
  "message": "Unsupported field \"tz\". Rename it to \"timezoneOffset\" (numeric hours from UTC, e.g. 5.75; a zone name goes in timezone)." } }
```

Case and value separators don't matter: `TZ_Offset` and `tzoffset` are rejected the same way. **All** found fields are reported at once, not just the first, so you can fix everything in one go.

The reason is strict: before this check, the field that the API didn't read silently gave an offset of `0`, and the response was a confident chart for UTC. Three hours of offset is about 45° of ascendant, meaning a different rising sign, and no warning.

## `timezone`: Zone name instead of offset

The offset must be the one the clocks kept **on that exact date**, and it's easy to manually specify it wrong: Kyiv in May 1990 lived on Moscow daylight time, UTC+4, not +3. Send `timezone`, and the server will take the offset from the time zone database, along with daylight time.

```json
{ "date": "1990-05-15", "time": "14:30:00", "timezone": "Europe/Kyiv",
  "latitude": 50.45, "longitude": 30.52 }
```

- `auto` determines the zone by `latitude` and `longitude`. Near the border, the name is more precise.
- If `timezone` and `timezoneOffset` come together, `timezone` takes effect. `input.timezoneOffset` in the response shows the offset that was used.
- Time that was twice (when clocks were set back) is taken as the first occurrence. Time that didn't exist (when set forward) gets the offset that was in effect before the change.
- Without `time` (only date or `timeUnknown: true`) the zone is read at local noon.
- Rejected with `400 INVALID_FIELD`: empty value, abbreviations like `EST` or `PST`, offset written as text like `+03:00`, names not in the database, and `auto` without coordinates. `UTC` and `GMT` are accepted.
- Each object is parsed separately, so `chart1` and `chart2` can be in different zones.

<Aside type="note">
Before 1970, the time zone database is not reliable for every place: Amsterdam in June 1930 returns as +1, although clocks showed +0:20. If the local time of that birth is known, send `timezoneOffset`.
</Aside>

## `houseSystem`: Letter, not name

Exactly these 25 Swiss Ephemeris codes are accepted:

`P` `K` `R` `C` `E` `W` `B` `M` `O` `A` `T` `V` `D` `F` `G` `H` `I` `i` `L` `N` `Q` `S` `U` `X` `Y`

Case matters: `I` is Sunshine by Makranski, `i` by Traingle. The system name (`"Placidus"`, `"Koch"`) returns `400`. It worked accidentally before because the engine reads only the first letter from the string, and for the same reason `"Zodiac"` silently gave Placidus.

## Unknown birth time

Instead of a made-up noon, send `timeUnknown: true` and don't send `time`. Then `houses`, `houseAspects`, `chartSect` and `siderealTime` come as `null`, not made-up. Details: [API Conventions](/api-conventions/#unknown-birth-time)

## Unknown keys are not rejected

The body silently accepts extra fields: an unknown key is simply ignored. So an error in a field name not in the rejection list above won't make itself known. Check against the specification: [`/v1/openapi.json`](https://api.astroway.info/v1/openapi.json)

## Next

- [Common Mistakes](/agent-setup/mistakes/)
- [Gotchas](/agent-setup/gotchas/)
