# Formatos de campos

El modelo que adivina el nombre del campo recibe o `400`, o, peor aún, una respuesta segura sobre otro mapa. A continuación el contrato exacto.

## Cuerpo de la solicitud de carta

| Campo | Tipo y formato | Obligatorio |
|---|---|---|
| `date` | `YYYY-MM-DD`, y debe ser un día real del calendario | sí |
| `time` | `HH:mm:ss` | sí, o `timeUnknown: true` |
| `timezoneOffset` | número, horas desde UTC, p. ej. `5.75` | no, por defecto `0` (UTC) |
| `timezone` | nombre de zona IANA, p. ej. `Europe/Kyiv`, o `auto` | no, y si se envía, reemplaza a `timezoneOffset` |
| `latitude` | grados decimales, norte positivo | sí |
| `longitude` | grados decimales, este positivo | sí |
| `houseSystem` | una letra, por defecto `P` | no |
| `city` | cadena, solo la firma | no |
| `zodiacType` | `tropical` o `sidereal` | no |

<Aside type="caution">
`city` no geocodifica nada. Este campo es para la firma en tu interfaz, y **nunca** reemplaza a las coordenadas.
</Aside>

## Se rechazan abreviaturas

`lat`, `lon`, `lng`, `long`, `tz`, `tzOffset`, `utcOffset`, `gmtOffset`, `timeZone`, `time_zone` devuelven `400 INVALID_FIELD` con el nombre del campo correcto:

```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)." } }
```

No se permiten mayúsculas ni separadores en el valor: `TZ_Offset` y `tzoffset` se rechazan de la misma forma. Se informan **todos** los campos encontrados de una vez, no solo el primero, para que puedas corregirlos en un solo paso.

La razón es estricta: antes de esta validación, un campo que la API no leía silenciosamente daba un desplazamiento `0`, y la respuesta era una carta segura para UTC. Tres horas de desplazamiento son aproximadamente 45° de ascendente, es decir, otro signo ascendente, sin ninguna advertencia.

## `timezone`: nombre de zona en lugar de desplazamiento

El desplazamiento debe ser el que tenían los relojes **exactamente en esa fecha**, y es fácil indicarlo manualmente de forma incorrecta: Kiev en mayo de 1990 seguía el horario de verano de Moscú, UTC+4, no +3. Envía `timezone`, y el servidor tomará el desplazamiento de la base de datos de zonas horarias, incluido el horario de verano.

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

- `auto` determina la zona a partir de `latitude` y `longitude`. Cerca de la frontera el nombre es más preciso.
- Si `timezone` y `timezoneOffset` llegan juntos, se usa `timezone`. `input.timezoneOffset` en la respuesta muestra el desplazamiento que se utilizó.
- El tiempo que se repitió (cuando los relojes se atrasaron) se toma la primera vez. El tiempo que no existió (cuando se adelantaron) recibe el desplazamiento que estaba en vigor antes del cambio.
- Sin `time` (solo fecha o `timeUnknown: true`) la zona se lee al mediodía local.
- Se rechazan con `400 INVALID_FIELD`: valor vacío, abreviaturas como `EST` o `PST`, desplazamiento escrito como texto, como `+03:00`, nombres que no existen en la base, y `auto` sin coordenadas. `UTC` y `GMT` se aceptan.
- Cada objeto se procesa por separado, por lo que `chart1` y `chart2` pueden estar en zonas diferentes.

<Aside type="note">
Hasta 1970 la base de datos de zonas horarias no es fiable para todos los lugares: Ámsterdam en junio de 1930 aparece como +1, aunque los relojes mostraban +0:20. Si conoces la hora local de ese nacimiento, envía `timezoneOffset`.
</Aside>

## `houseSystem`: letra, no nombre

Se aceptan exactamente estos 25 códigos de Swiss Ephemeris:

`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`

La mayúscula es significativa: `I` es Sunshine según McRansky, `i` según Trundle. El nombre del sistema (`"Placidus"`, `"Koch"`) devuelve `400`. Antes funcionaba por casualidad, porque el motor lee solo la primera letra de la cadena, y por la misma razón `"Zodiac"` devolvía silenciosamente Placidus.

## Tiempo de nacimiento desconocido

En lugar de un mediodía inventado, envía `timeUnknown: true` y no envíes `time`. Entonces `houses`, `houseAspects`, `chartSect` y `siderealTime` llegan como `null`, no como valores inventados. Detalles: [Convenciones API](/api-conventions/#невідомий-час-народження).

## Las claves desconocidas no se rechazan

El cuerpo acepta campos adicionales silenciosamente: la clave desconocida simplemente se ignora. Por lo tanto, un error en el nombre de un campo que no está en la lista de rechazos anterior no se notificará. Consulta la especificación: [`/v1/openapi.json`](https://api.astroway.info/v1/openapi.json).

## Más

- [Errores típicos](/agent-setup/mistakes/)
- [Trampas](/agent-setup/gotchas/)
