Astrocal
Guides

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

The easiest way to create your first API key is from the dashboard. Go to Settings → API Keys and click Create Key.

Once you have a key, you can also create additional keys via the API:

curl -X POST https://api.astrocal.dev/v1/api-keys \
  -H "Authorization: Bearer ac_live_..." \
  -H "Content-Type: application/json" \
  -d '{"name": "My Integration", "mode": "live"}'
const response = await fetch("https://api.astrocal.dev/v1/api-keys", {
  method: "POST",
  headers: {
    Authorization: "Bearer ac_live_...",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ name: "My Integration", mode: "live" }),
});
const data = await response.json();

Try it in the API playground →

The full key is returned only once in the response. 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

EndpointMethodDescription
POST /v1/api-keysPOSTCreate a new API key
GET /v1/api-keysGETList all API keys
DELETE /v1/api-keys/{id}DELETERevoke an API key

Revoked keys immediately fail authentication. Revocation is idempotent.

Public Endpoints

Some endpoints don't require authentication:

  • GET /health: Health check
  • POST /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 slots
  • GET /v1/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 types
  • PUT/GET /v1/event-types/{id}/availability: Manage availability rules
  • POST/GET/DELETE /v1/event-types/{id}/hosts: Manage round-robin hosts
  • GET /v1/bookings: List bookings
  • GET /v1/bookings/{id}: Get booking details
  • GET/DELETE /v1/calendars: Calendar connections
  • GET/POST/PATCH/DELETE /v1/webhooks: Webhook management
  • GET /v1/webhooks/{id}/deliveries: Webhook delivery history
  • POST /v1/webhooks/{id}/deliveries/{delivery_id}/retry: Retry a delivery
  • GET/POST/DELETE /v1/api-keys: API key management
  • GET /v1/usage: Usage and rate limits
  • GET /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: org_uuid_here" \
  -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": "org_uuid_here",
    "X-Astrocal-Mode": "live",
  },
});
const data = await response.json();
HeaderRequiredDescription
Authorization: Bearer <service_key>YesThe service key from ASTROCAL_SERVICE_KEY
X-Org-IdYesThe organization UUID to act on behalf of
X-Astrocal-ModeNolive (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.

On this page