Getting Started

Authentication

The Audital API supports two authentication methods: API keys for server-to-server integrations and OAuth 2.0 for user-facing applications. All requests must be made over HTTPS.

Last updated: 2 March 2026

API Keys

API keys are the simplest authentication method for server-side integrations. They are long-lived credentials — treat them like passwords and never expose them in client-side code, version control, or log files.

Creating an API key

  1. 1Log in to the Audital dashboard
  2. 2Navigate to Settings → API
  3. 3Click "Create new key"
  4. 4Give the key a descriptive name (e.g. "Production — Credit Scorer")
  5. 5Copy the key immediately — it will only be shown once

Using an API key

Pass the key as a Bearer token in the Authorization header:

bash
curl https://api.audital.ai/v1/audit \
  -H "Authorization: Bearer ak_live_xxxxxxxxxxxxxxxxxxxx"

As a last resort, you may pass the key as a query parameter, but this is discouraged because URLs are often logged by intermediaries:

bash
# Query parameter — use only for server-to-server calls where headers aren't possible
curl "https://api.audital.ai/v1/audit?api_key=ak_live_xxxxxxxxxxxxxxxxxxxx"

Key prefixes

ak_live_ — Production key. Events are written to your live chain.

ak_test_ — Sandbox key. Events are stored in an isolated test chain, not counted against rate limits.

OAuth 2.0

OAuth 2.0 is recommended when your application acts on behalf of a user. Audital implements the Authorization Code flow with PKCE for public clients.

Available scopes

ScopeDescription
audit:readRead audit events and chain status
audit:writeWrite new audit events
evidence:readRead evidence packages
evidence:generateGenerate new evidence bundles
models:readList and read model metadata
models:writeRegister and update models
shadow-ai:readRead Shadow AI detection results
adminFull access — all scopes (restricted)

Step 1: Redirect to authorization

http
GET https://audital.ai/oauth/authorize
  ?client_id=oa_client_xxxxxxxxxxxx
  &redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback
  &response_type=code
  &scope=audit%3Aread%20audit%3Awrite%20evidence%3Aread
  &state=random_csrf_token_here

Step 2: Exchange code for tokens

bash
curl -X POST https://audital.ai/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "code=AUTH_CODE_FROM_REDIRECT" \
  -d "client_id=oa_client_xxxxxxxxxxxx" \
  -d "client_secret=oa_secret_xxxxxxxxxxxx" \
  -d "redirect_uri=https://app.example.com/callback"
json
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "rt_xxxxxxxxxxxxxxxxxxxx",
  "scope": "audit:read audit:write evidence:read"
}

Step 3: Refresh an access token

Access tokens expire after 3600 seconds. Use the refresh token to obtain a new pair without requiring user interaction.

bash
curl -X POST https://audital.ai/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=refresh_token" \
  -d "refresh_token=rt_xxxxxxxxxxxxxxxxxxxx" \
  -d "client_id=oa_client_xxxxxxxxxxxx" \
  -d "client_secret=oa_secret_xxxxxxxxxxxx"

Request Signing (HMAC-SHA256)

For the highest assurance level — required by Founding Partner accounts — requests can be additionally signed with HMAC-SHA256. Signed requests prove the request body has not been tampered with in transit.

sign_request.py·python
import hmac
import hashlib
import time
import json

def sign_request(secret_key: str, method: str, path: str, body: dict) -> dict:
    """Generate HMAC-SHA256 signed headers for an Audital API request."""
    timestamp = str(int(time.time()))
    body_str = json.dumps(body, separators=(',', ':'), sort_keys=True)
    body_hash = hashlib.sha256(body_str.encode()).hexdigest()

    # Canonical string: METHOD\nPATH\nTIMESTAMP\nBODY_HASH
    canonical = f"{method.upper()}\n{path}\n{timestamp}\n{body_hash}"

    signature = hmac.new(
        secret_key.encode(),
        canonical.encode(),
        hashlib.sha256
    ).hexdigest()

    return {
        "X-Audital-Timestamp": timestamp,
        "X-Audital-Signature": f"hmac-sha256={signature}",
        "X-Audital-Body-Hash": body_hash,
    }

headers = sign_request(
    secret_key="sk_live_xxxxxxxxxxxxxxxxxxxx",
    method="POST",
    path="/v1/audit",
    body={"modelId": "mdl_abc123", "eventType": "INFERENCE"},
)

Full signed request headers

http
POST /v1/audit HTTP/1.1
Host: api.audital.ai
Authorization: Bearer ak_live_xxxxxxxxxxxxxxxxxxxx
Content-Type: application/json
X-Audital-Timestamp: 1741000000
X-Audital-Signature: hmac-sha256=7c4a8d09ca3762af61e59520943dc26...
X-Audital-Version: 2024-04-10
Idempotency-Key: ide_01HZABCDEF1234567890ABCD

Idempotency

Include an Idempotency-Key header (a UUID v4 or similar unique ID) to safely retry failed requests. The same key submitted within 24 hours returns the original response without creating a duplicate event.

Authentication Errors

All authentication errors return HTTP 401 with a JSON body:

json
{
  "error": "unauthorized",
  "message": "Invalid or expired API key. Check the Authorization header.",
  "code": 401,
  "docs": "https://audital.ai/docs/authentication"
}
CodeHTTPCause
unauthorized401Missing or invalid Authorization header
api_key_expired401API key was rotated or expired
api_key_revoked401API key was manually revoked
insufficient_scope403OAuth token lacks the required scope
token_expired401OAuth access token has expired — refresh it