Field formats
A model that guesses a field name gets either a 400 or, worse, a confident answer about a different chart. Here is the exact contract.
A chart-shaped body
Section titled “A chart-shaped 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, defaults to 0 (UTC) |
timezone | IANA zone name such as Europe/Kyiv, or auto | no, and when sent it replaces timezoneOffset |
latitude | decimal degrees, north positive | yes |
longitude | decimal degrees, east positive | yes |
houseSystem | a single letter, P by default | no |
city | string, a label only | no |
zodiacType | tropical or sidereal | no |
Short spellings are refused
Section titled “Short spellings are refused”lat, lon, lng, long, tz, tzOffset, utcOffset, gmtOffset, timeZone and time_zone return 400 INVALID_FIELD naming the right field:
{ "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 separators carry no meaning: TZ_Offset and tzoffset are refused the same way. Every offending field is reported at once rather than the first one, so one round trip is enough to fix them all.
The strictness has a reason. Before this check, a field the API did not read silently meant an offset of 0, and the answer was a confident chart for UTC. Three hours of offset is roughly 45° of ascendant, so a different rising sign, with no warning at all.
timezone: a zone name instead of an offset
Section titled “timezone: a zone name instead of an offset”The offset has to be the one the clocks kept on that date, and it is easy to get wrong by hand: Kyiv in May 1990 kept Moscow summer time, UTC+4, not +3. Send timezone and the server works it out from the tz database, summer time included.
{ "date": "1990-05-15", "time": "14:30:00", "timezone": "Europe/Kyiv", "latitude": 50.45, "longitude": 30.52 }autolooks the zone up fromlatitudeandlongitude. A name is more precise near a border.- When
timezoneandtimezoneOffsetarrive together,timezonewins.input.timezoneOffsetin the response shows the value that was used. - A clock time that happened twice, when clocks went back, takes the first occurrence. A time that never happened, when clocks went forward, takes the offset from before the change.
- Without a
time(a date alone, ortimeUnknown: true) the zone is read at local noon. - Refused with
400 INVALID_FIELD: an empty value, abbreviations such asESTorPST, offsets written as text such as+03:00, names the database does not know, andautowithout coordinates.UTCandGMTare accepted. - Each object resolves on its own, so
chart1andchart2can sit in different zones.
houseSystem: a letter, not a name
Section titled “houseSystem: a letter, not a 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 Makransky, i by Treindl. A system name ("Placidus", "Koch") returns 400. It used to work by accident, because the engine reads only the first letter of the string, and by the same accident "Zodiac" quietly produced Placidus.
Unknown birth time
Section titled “Unknown birth time”Instead of inventing noon, send timeUnknown: true and omit time. Then houses, houseAspects, chartSect and siderealTime come back null rather than invented. Details: API conventions.
Unknown keys are not refused
Section titled “Unknown keys are not refused”The body accepts extra fields silently: an unrecognised key is simply ignored. So a typo in a field name that is not on the refusal list above will not announce itself. Check against the specification: /v1/openapi.json.