Every REST response uses snake_case fields on the public API surface. Organization and application scoping is derived from the API key.
Authentication
Create an application-scoped API key in the panel. Send it as a Bearer token on every API request. API keys carry scopes, an application_id, and an organization_id.
curl https://api.hora.to/v1/usage \
-H "Authorization: Bearer $HORATO_API_KEY"Provider connection flow
Start an OAuth authorization for a provider, redirect the user, then let Horato store the connection and provider tokens. Use capability endpoints before attempting provider-specific operations.
curl -X POST https://api.hora.to/v1/auth/connectors/google/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"}'Read and mutate resources
Prefer canonical IDs for stored resources and preserve provider IDs for reconciliation. Mutating calls should include etags when the resource surface exposes conflict control.
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"}'Pagination and idempotency
List endpoints return `next_cursor` when more results exist. Write endpoints should send an `Idempotency-Key` header for retry-safe creation when the client may retry after network failures.