Authentication
The Apertur API uses API keys for authentication. Keys are scoped to a project.
API key format
API keys follow the format:
aptr_{env}_{random}| Part | Value | Description |
|---|---|---|
| aptr | Fixed prefix | Identifies an Apertur key |
| random | 32 hex chars | Cryptographically random secret |
Example:
aptr_live_z9y8x7w6v5u4t3s2r1q0p9o8n7m6l5k4
Sending the API key
Include your API key in the Authorization header of every request using the Bearer scheme:
Authorization: Bearer aptr_live_xxxx
API keys must be kept secret. Never expose them in client-side JavaScript or commit them to version control. Use environment variables on your server.
curl https://api.apertur.ca/v1/upload-sessions \ -H "Authorization: Bearer aptr_live_xxxx"
Request signing
For extra protection against tampering and replay, enable HMAC request signing on an API key from its settings in the dashboard. Once enabled, every request must also carry a valid signature — signing is an additional factor, so the Bearer key is still required on every request.
Send the signature and timestamp in the X-Aptr-Signature and X-Aptr-Timestamp headers, computed with HMAC-SHA256 over the timestamp, method, path, and body hash:
X-Aptr-Signature: sha256=<hex> X-Aptr-Timestamp: <unix seconds>
Sign the full request path exactly as sent, including the /api/v1 prefix and any query string — for example /api/v1/upload-sessions. The method is uppercase, the timestamp is Unix seconds, and the body hash is the lowercase hex SHA-256 digest of the exact request body bytes (the digest of an empty string when there is no body).
HMAC_SHA256(signingSecret, `${timestamp}.${method}.${path}.${sha256hex(body)}`)Requests older than 5 minutes are rejected.
Signing secret
Enable, rotate, or disable signing for a key from its settings in the dashboard. Enabling or rotating returns the signing secret once — copy it now, as it cannot be retrieved again.
SIGNING_SECRET=your-signing-secret # shown once when you enable signing
TS=$(date +%s)
BODY='{"destination_ids":["dst_xxxx"]}'
BODY_HASH=$(printf '%s' "$BODY" | openssl dgst -sha256 | sed 's/^.* //')
SIG=$(printf '%s' "$TS.POST./api/v1/upload-sessions.$BODY_HASH" | openssl dgst -sha256 -hmac "$SIGNING_SECRET" | sed 's/^.* //')
curl https://api.aptr.ca/api/v1/upload-sessions \
-H "Authorization: Bearer aptr_live_xxxxxxxx" \
-H "X-Aptr-Timestamp: $TS" \
-H "X-Aptr-Signature: sha256=$SIG" \
-H "Content-Type: application/json" \
-d "$BODY"Rate limits
The API applies rate limits per API key. Limits are returned in response headers:
X-RateLimit-Limit: 100 X-RateLimit-Remaining: 97 X-RateLimit-Reset: 1711627200
| Endpoint | Limit | Window |
|---|---|---|
| POST /api/v1/sessions | 100 requests | per minute |
| GET /api/v1/sessions | 300 requests | per minute |
| All other endpoints | 200 requests | per minute |
When a rate limit is exceeded, the API returns 429 Too Many Requests. See the Errors page for details.