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.
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
- 1Log in to the Audital dashboard
- 2Navigate to Settings → API
- 3Click "Create new key"
- 4Give the key a descriptive name (e.g. "Production — Credit Scorer")
- 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:
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:
# 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
| Scope | Description |
|---|---|
audit:read | Read audit events and chain status |
audit:write | Write new audit events |
evidence:read | Read evidence packages |
evidence:generate | Generate new evidence bundles |
models:read | List and read model metadata |
models:write | Register and update models |
shadow-ai:read | Read Shadow AI detection results |
admin | Full access — all scopes (restricted) |
Step 1: Redirect to authorization
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_hereStep 2: Exchange code for tokens
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"{
"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.
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.
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
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_01HZABCDEF1234567890ABCDIdempotency
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:
{
"error": "unauthorized",
"message": "Invalid or expired API key. Check the Authorization header.",
"code": 401,
"docs": "https://audital.ai/docs/authentication"
}| Code | HTTP | Cause |
|---|---|---|
unauthorized | 401 | Missing or invalid Authorization header |
api_key_expired | 401 | API key was rotated or expired |
api_key_revoked | 401 | API key was manually revoked |
insufficient_scope | 403 | OAuth token lacks the required scope |
token_expired | 401 | OAuth access token has expired — refresh it |