Skip to content

API Authentication & API Keys

How to authenticate against the AstraPBX API (https://devpbx.astradial.com/api/v1). There are three credential types for normal org access plus a separate admin path. Picking the wrong one is the most common source of Invalid credentials / Authentication failed errors — this page maps each to its exact use.

TL;DR — for an integration/partner, use an ak_ API key

Create an ak_… API key in the dashboard (API & Webhooks → API Keys → + Create API Key) and send it as X-API-Key: ak_…. It doesn't expire, has granular permissions, and needs no login step. Don't use the JWT /auth/login flow for ak_ keys — they are a different system.


The three credential types

Method Credential Sent as Expires? Best for
1. API key (ak_) ak_… key (from UI) X-API-Key: ak_… No (until revoked) Integrations, CRM, partners (recommended)
2. Org key (org_) org_… key X-API-Key: org_… No Org-level programmatic access
3. JWT (Bearer) org_… key + api_secret → token Authorization: Bearer <jwt> Yes — 24h Short-lived org-scoped sessions

All three resolve to the same org scope. The middleware (authenticateOrg) checks them in order: X-API-Key starting ak_ → org API key; else X-API-Key → org key; else Authorization: Bearer → JWT.


A per-org key with granular permissions, created and managed in the dashboard.

Create it (UI): dashboard → API & Webhooks → API Keys → + Create API Key → name it, pick permissions, Create Key.

  • You get api_key (ak_…) and api_secret (as_…) shown once — save them. (See the note on the secret below.)
  • Permissions are granular: calls.read/write/click_to_call/originate_ai/recording/live/transfer/hangup/hold and crm.read/write/delete/assign/customize.
  • Manage/revoke from the same page. Revoked keys stop working immediately.

Use it:

curl https://devpbx.astradial.com/api/v1/calls/count \
  -H "X-API-Key: ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
# -> 200 {"total":23,"active":0,...}

No login, no JWT. The key alone authenticates and the call is scoped to that key's permissions.

The as_ secret is not checked

The API only validates the ak_ key — the as_ secret is stored (hashed) but not currently verified on requests. So the ak_ key alone is the full credential: if it leaks, revoke it immediately and issue a new one. Never paste a live key into chat, tickets, or screenshots.


Method 2 — Org key (org_) directly

Every org has a master org_… key. It can be sent directly as X-API-Key (no JWT step) for full org access:

curl https://devpbx.astradial.com/api/v1/calls/count \
  -H "X-API-Key: org_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

This is full-org scope (no granular permissions), so prefer a scoped ak_ key for integrations. The org must be active — an inactive/suspended org returns 401 "Invalid authentication or organization not active".


Method 3 — JWT Bearer token

For short-lived org-scoped tokens, exchange the org_ key + plaintext api_secret for a JWT:

curl -X POST https://devpbx.astradial.com/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"api_key":"org_xxxx","api_secret":"<org api secret>"}'
# -> { "token": "eyJhbGci..." }

Then:

curl https://devpbx.astradial.com/api/v1/users \
  -H "Authorization: Bearer eyJhbGci..."
  • The token expires after 24 hours — re-call /auth/login to refresh. Reusing an old token returns 401 "Authentication failed".
  • The api_secret here is the org secret (returned once when the org was created via POST /api/v1/organizations; unrecoverable afterward, no rotate endpoint). It is not an ak_/as_ key.

Admin authentication (platform management)

Endpoints under /api/v1/admin/* (create/suspend orgs, etc.) require admin auth, not org auth:

  • POST /api/v1/admin/auth with the server's admin username/password → admin JWT (24h), used only for /admin/*.
  • Server-to-server callers may use the X-Internal-Key header (INTERNAL_API_KEY). With it, POST /api/v1/auth/admin-token ({org_id}) or POST /api/v1/admin/impersonate/:orgId mints an org token without that org's secret.

Don't use admin tokens for regular API operations.


Common errors → cause

Response Cause Fix
400 "API key and secret are required" Called /auth/login without both fields Send api_key + api_secret
401 "Invalid credentials" (on /auth/login) Put an ak_ key into /auth/login — wrong system, or wrong org secret Use the ak_ key via X-API-Key instead; or use the correct org_ key + org api_secret
401 "Authentication failed" Expired or malformed JWT Re-login for a fresh token (JWTs last 24h)
401 "Invalid authentication or organization not active" Unknown key, or the org is not active Use a valid key for an active org
401 "Authentication required" No X-API-Key and no Authorization header Add one of them
403 (permission) ak_ key lacks the required permission Re-issue the key with the needed calls.*/crm.* permission

  1. In the org's dashboard, create an ak_ API key with only the permissions the integration needs.
  2. Store the ak_ key in the integration's secret store.
  3. Call endpoints with X-API-Key: ak_… — no login, no token refresh.
  4. Rotate by creating a new key and revoking the old one (keys don't expire on their own).
  5. Reserve the org_+JWT flow for cases that specifically need a short-lived bearer token; reserve /admin/* for org provisioning only.
  • API Reference
  • Live Swagger: https://devpbx.astradial.com/api-docs