#Authentication

5 min read

Except for public status endpoints, AiDial API requests require authentication. Partner integrations should use server-side API keys. AiDial Portal sessions use an AiDial-issued access token. Do not embed partner API keys in browser code, mobile applications, or other client-side surfaces.

Production API: https://api.aidial.ai

This page omits environment-specific host names, internal topology, and deployment details.

#API Key Authentication

You authenticate by including your API key in the X-API-Key header of every request.

Header: X-API-Key Generated key format: sk_live_<64_hexadecimal_characters> (72 characters total) Example: sk_live_YOUR_API_KEY_HERE

#Key Lifecycle

Generated API keys are stored as salted SHA-256 hashes, not as plaintext. A key must have active status and must not be past its expires_at timestamp to authenticate.

StateDescription
activeValid and usable for API requests
revokedPermanently disabled; cannot be reactivated
expiredPast the expiry date set at provisioning

Requests made with a revoked or expired key receive a 401 Unauthorized response.

The API-key inventory available through AiDial Portal and partner-authenticated API surfaces returns metadata only: id, client, scope, environment, description, status, created time, expiry, nullable last_used_at, and nullable revoke time. Plaintext keys are returned only once at creation or rotation, and stored hashes are never response fields.

#Security: Server-Side Only

Your API key is a secret credential. Follow these rules:

  • Never embed your API key in client-side JavaScript, mobile applications, or browser code
  • Never commit your API key to version control
  • Store your API key in environment variables or a secrets manager
  • If your key is compromised, rotate or revoke it immediately through the AiDial Portal

#Bearer Authentication

Bearer authentication is for AiDial Portal sessions and other first-party portal flows. It is not the recommended mode for partner server-to-server integrations unless AiDial explicitly provisions that integration path.

Header: Authorization Format: Bearer <jwt>

#Authentication Precedence

Protected API routes that use the shared authentication dependency resolve credentials in this order:

  1. X-API-Key
  2. Authorization: Bearer <jwt>

If both X-API-Key and Authorization: Bearer headers are present in the same request, the API key is used and the bearer token is ignored.

Some endpoints impose stricter requirements after authentication. For example, portal-only endpoints may require bearer authentication and gateway-only routes may require a dedicated API-key scope. Report schedules, report sample dispatch, report delivery history, notification preferences, and data-deletion requests require a customer bearer principal; an API key is denied even if its stored scope text is client_admin. Check each endpoint page for route-specific scope requirements.

#Tenant IP Allowlist

If a tenant enables an IP allowlist, requests are checked against it after credentials resolve, in both authentication modes. Tenants with no allowlist enabled are unaffected.

  • A request from an address outside the tenant allowlist returns 403 Forbidden with the body {"code": "ip_allowlist_restricted", "message": "Access restricted."}.
  • A partner caller is checked against the target tenant's allowlist: the tenant named in the request, or the partner's own tenant when none is named. A blocked partner request is hidden with 404 Not Found rather than 403.
  • If the allowlist cannot be evaluated, the request returns 503 Service Unavailable with code ip_allowlist_unavailable.

#Data Scoping

Both authentication modes resolve to an AuthContext containing the authenticated client_id, data_env, scope, auth_type, and principal metadata. Bearer contexts may also include safe email/display-name metadata and project ids resolved from the database. All API responses are scoped to that context. You only see resources belonging to your organisation; cross-client data is never returned. Accessing resources outside your scope returns 404 Not Found (not 403 Forbidden) to prevent information disclosure.

Metadata, authentication, portal assignment, project configuration, and routing data come from the local API metadata store on the API host. Analytics and call data are routed by the strict (client_id, data_env) mapping in the tenant routing map; there is no cross-tenant fallback route. A missing route is an API configuration error and returns 500 Internal Server Error. If the routed data host, tunnel, or database is unavailable, the API returns 503 Service Unavailable.

PII-sensitive responses also respect the client-level PII flags in aidial_clients. Phone and transcript decryption goes through server-side decryption pathways before any permitted plaintext is returned. When PII permissions are missing, lookup fails, or decryption fails, the API fails closed by redacting or omitting PII. Raw encrypted fields such as ciphertext, wrapped keys, and *_encrypted database fields are not partner response fields.

#Public Health Endpoints

GET / and GET /v1/health do not require authentication. /v1/health includes API database readiness details, including database.db_writable, for deployment and HA monitoring.

#Error Semantics

ConditionStatus
Missing authentication401 Unauthorized
Invalid, revoked, or expired API key401 Unauthorized
Expired or invalid bearer token401 Unauthorized
Valid authentication but out-of-scope resource or assignment404 Not Found
Partner request for a tenant whose IP allowlist blocks the source address404 Not Found
Non-partner caller blocked by its own tenant's IP allowlist403 Forbidden
Missing bearer auth configuration500 Internal Server Error
Missing (client_id, data_env) data route500 Internal Server Error
Bearer portal-assignment lookup, IP allowlist evaluation, or routed data dependency unavailable503 Service Unavailable

#Example

#Successful API Key Authentication

Request:

Bash
curl -X GET "https://api.aidial.ai/v1/partner/me" \
  -H "X-API-Key: sk_live_YOUR_API_KEY_HERE"

Response (200 OK):

JSON
{
  "client_id": "client_example_001",
  "scope": "partner_admin",
  "data_env": "prod",
  "auth_type": "api_key",
  "api_key_id": 42,
  "api_key_description": "Primary integration",
  "expires_at": null
}

#Authentication Failure

Request (missing credentials):

Bash
curl -X GET "https://api.aidial.ai/v1/partner/me"

Response (401 Unauthorized):

JSON
{
  "error": "Missing authentication. Provide X-API-Key or Authorization: Bearer token.",
  "status_code": 401
}