Authentication
How to authenticate with the Astrocal API using API keys.
Astrocal uses API key authentication. Every request to an authenticated endpoint must include a Bearer token in the Authorization header.
API Keys
API keys are scoped to an organization and come in two modes:
- Live keys (
ac_live_...): Affect real data, create real bookings and calendar events. - Test keys (
ac_test_...): Isolated sandbox data. See Sandbox Mode.
Creating an API Key
Create API keys from the dashboard. Go to Settings → API Keys and click Create Key.
Key creation is dashboard-only by design: a request to POST /v1/api-keys
authenticated with an API key is rejected with 403 forbidden, so a leaked
key cannot be used to mint further keys.
The full key is shown only once, at creation. Store it securely.
Using an API Key
Include it as a Bearer token:
curl https://api.astrocal.dev/v1/event-types \
-H "Authorization: Bearer ac_live_..."const response = await fetch("https://api.astrocal.dev/v1/event-types", {
headers: {
Authorization: "Bearer ac_live_...",
},
});
const data = await response.json();Try it in the API playground →
Key Management
| Endpoint | Method | Description |
|---|---|---|
POST /v1/api-keys | POST | Create a new API key (dashboard only) |
GET /v1/api-keys | GET | List all API keys |
DELETE /v1/api-keys/{id} | DELETE | Revoke an API key |
Revoked keys immediately fail authentication. Revocation is idempotent.
Public Endpoints
Some endpoints don't require authentication:
GET /health: Health checkPOST /v1/bookings: Create a booking (public booking page)POST /v1/bookings/{id}/cancel: Cancel with?token=(invitee self-service)POST /v1/bookings/{id}/reschedule: Reschedule with?token=(invitee self-service)GET /v1/availability: Check available slotsGET /v1/public/event-types/{id}: Public event type detail (active, non-test only)GET /v1/openapi.json: OpenAPI specification
Authenticated Endpoints
All other endpoints require an API key:
GET/POST/PATCH/DELETE /v1/event-types: Manage event typesGET /v1/event-types/{id}: Event type detail, scoped to your organization (includes test mode)PUT/GET /v1/event-types/{id}/availability: Manage availability rulesPOST/GET/DELETE /v1/event-types/{id}/hosts: Manage round-robin hostsGET /v1/bookings: List bookingsGET /v1/bookings/{id}: Get booking detailsGET/DELETE /v1/calendars: Calendar connectionsGET/POST/PATCH/DELETE /v1/webhooks: Webhook managementGET /v1/webhooks/{id}/deliveries: Webhook delivery historyPOST /v1/webhooks/{id}/deliveries/{delivery_id}/retry: Retry a deliveryGET/DELETE /v1/api-keys: API key management (POSTis dashboard-only — see Key Management above)GET /v1/usage: Usage and rate limitsGET /v1/activity: Activity log
Service Key Auth (BFF Pattern)
Internal use only. This section documents the dashboard's server-to-server authentication. If you're integrating via API keys, you can skip this.
If you're building a backend-for-frontend that talks to the Astrocal API on behalf of users, you can authenticate with a service key instead of an API key. This bypasses API key lookup and lets you act on behalf of any organization.
curl https://api.astrocal.dev/v1/event-types \
-H "Authorization: Bearer $ASTROCAL_SERVICE_KEY" \
-H "X-Org-Id: 550e8400-e29b-41d4-a716-446655440000" \
-H "X-Astrocal-Mode: live"const response = await fetch("https://api.astrocal.dev/v1/event-types", {
headers: {
Authorization: "Bearer $ASTROCAL_SERVICE_KEY",
"X-Org-Id": "550e8400-e29b-41d4-a716-446655440000",
"X-Astrocal-Mode": "live",
},
});
const data = await response.json();| Header | Required | Description |
|---|---|---|
Authorization: Bearer <service_key> | Yes | The service key from ASTROCAL_SERVICE_KEY |
X-Org-Id | Yes | The organization UUID to act on behalf of |
X-Astrocal-Mode | No | live (default) or test - controls sandbox isolation |
Service keys are for server-to-server use only. Never expose them to the browser.
Error Responses
Missing or invalid authentication returns a 401 error:
{
"error": {
"code": "unauthorized",
"message": "Missing or invalid Authorization header"
}
}Rate Limits
API keys are subject to rate limits based on your subscription plan. See Rate Limits for details.