Las respuestas usan campos de recurso en camelCase; las claves de paginación/envoltura como next_cursor siguen en snake_case. Los cuerpos de request aceptan camelCase (y snake_case también se tolera). El alcance de organización y aplicación viene de la API key.
Autenticación
Crea una API key con alcance de aplicación en el panel. Envíala como Bearer token en cada request API, o como header `X-Api-Key` si el Bearer no es cómodo. Las API keys contienen scopes, application_id y organization_id, así que el alcance de organización y aplicación de cada llamada viene de la key: nunca los pasas explícitamente.
Las keys se muestran una sola vez al crearlas. Guárdalas solo del lado servidor y rótalas desde la misma aplicación que atiende producción.
curl https://api.hora.to/v1/usage \
-H "Authorization: Bearer $HORATO_API_KEY"
# Equivalent, using the header form:
curl https://api.hora.to/v1/usage \
-H "X-Api-Key: $HORATO_API_KEY"Flujo de autorización de conectores
Inicia la autorización OAuth, redirige al usuario y deja que Horato guarde las credenciales de conexión. Consulta los endpoints de capacidades antes de intentar acciones que dependan de la cuenta conectada.
curl -X POST https://api.hora.to/v1/auth/connectors/{provider}/authorize \
-H "Authorization: Bearer $HORATO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"scopes":["email.read","calendar.write"],"redirect_uri":"https://app.example.com/oauth/callback"}'Leer y mutar recursos
Prefiere IDs canónicos para recursos almacenados y conserva IDs externos para reconciliación. Las mutaciones deben incluir etags cuando la superficie del recurso expone control de conflictos.
curl "https://api.hora.to/v1/email/messages?connection_id=conn_123&limit=25" \
-H "Authorization: Bearer $HORATO_API_KEY"curl -X POST https://api.hora.to/v1/calendars/cal_primary/events \
-H "Authorization: Bearer $HORATO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"connection_id":"conn_123","title":"Intro call","start":"2026-06-10T16:00:00Z","end":"2026-06-10T16:30:00Z"}'Paginación e idempotencia
Los endpoints de lista aceptan los parámetros `limit` y `cursor` y devuelven `next_cursor` cuando existen más resultados. Pagina reenviando el `next_cursor` anterior como `cursor`; un `next_cursor` nulo significa que llegaste al final.
Los endpoints de escritura aceptan el header `Idempotency-Key` para crear recursos de forma segura. Reusar la misma key con el mismo request devuelve el resultado original en lugar de duplicar, así el cliente puede reintentar tras un fallo de red.
curl "https://api.hora.to/v1/email/messages?connection_id=conn_123&limit=50&cursor=$NEXT_CURSOR" \
-H "Authorization: Bearer $HORATO_API_KEY"curl -X POST https://api.hora.to/v1/scheduling/bookings \
-H "Authorization: Bearer $HORATO_API_KEY" \
-H "Idempotency-Key: booking-2026-06-10-abc" \
-H "Content-Type: application/json" \
-d '{"eventTypeId":"evt_123","start":"2026-06-10T16:00:00Z","inviteeEmail":"dana@example.com"}'Límites de tasa
La API se limita por API key. Cada respuesta incluye el presupuesto actual para que ajustes el ritmo sin adivinar.
El presupuesto por defecto es 1.000 requests por minuto por key. Al excederlo, la API devuelve `429` con el código `rate_limited` y un header `Retry-After` (segundos). El limitador falla abierto ante errores de su propia infraestructura, así que una caída del limitador nunca bloquea tu tráfico: solo un exceso confirmado se rechaza.
- `x-ratelimit-limit`: el tope por minuto de la key.
- `x-ratelimit-remaining`: requests restantes en la ventana actual.
- En `429`, espera `Retry-After` segundos y reintenta con backoff.
HTTP/1.1 200 OK
x-ratelimit-limit: 1000
x-ratelimit-remaining: 984
x-request-id: req_1a2b3cSeguridad de API keys
Endurece una key restringiendo dónde puede usarse. Una key puede llevar una lista blanca de dominios (comparada con el Origin/Referer del request) y una lista blanca de direcciones IP o rangos CIDR. Un request fuera de la lista se rechaza con `forbidden` antes de ejecutar cualquier trabajo.
Combina las listas blancas con scopes de privilegio mínimo: emite una key estrecha y bloqueada por dominio para uso cercano al navegador, y una key de servidor separada para workers de backend.
- Lista de dominios: hosts exactos, p. ej. `app.example.com`.
- Lista de IPs: direcciones individuales o rangos CIDR, p. ej. `203.0.113.10` o `203.0.113.0/24`.
- Una lista vacía significa sin restricción en esa dimensión.