API Authentication
Assumetr supports machine-to-machine API access through API clients — secure service accounts that exchange credentials for short-lived bearer tokens.
Overview
API clients allow your CI/CD pipelines, SIEM integrations, and automation tools to access Assumetr programmatically without borrowing a user session.
Key properties:
- API clients are created per organization and bound to specific sites
- Access is governed by scopes (what the client can do) and site bindings (which sites it can access)
- Tokens are short-lived (15 minutes by default) and cannot be refreshed — exchange credentials again to get a new token
Creating an API Client
Required role: Organization Owner or Admin (manage:settings permission).
Create an API client via the Assumetr API:
curl -X POST https://api.example.com/v1/org/api-clients \
-H "Authorization: Bearer <SESSION_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"name": "CI Pipeline",
"scopes": ["evidence:read", "sites:read"],
"site_ids": ["<SITE_ID>"]
}'Response:
{
"id": "7f83b162-...",
"name": "CI Pipeline",
"client_secret": "asc_...",
"scopes": ["evidence:read", "sites:read"],
"site_ids": ["<SITE_ID>"],
"created_at": "2026-03-24T14:00:00Z"
}Important: The
client_secretis shown once on creation. Store it securely — it cannot be retrieved later.
Exchanging Credentials for a Token
Use the client credentials flow to obtain an access token:
TOKEN=$(curl -s -X POST https://api.example.com/v1/auth/token \
-u "<CLIENT_ID>:<CLIENT_SECRET>" \
-d "grant_type=client_credentials" | jq -r '.access_token')Response:
{
"access_token": "eyJ...",
"token_type": "bearer",
"expires_in": 900,
"scope": "evidence:read sites:read"
}Using the Token
Include the token as a Bearer in the Authorization header:
curl -H "Authorization: Bearer $TOKEN" \
https://api.example.com/v1/sites/<SITE_ID>/statusAvailable Scopes
| Scope | Description |
|---|---|
evidence:read | Read evidence export runs, verify signatures, download packets |
evidence:write | Trigger evidence exports, manage export jobs |
sites:read | Read site status, traffic, and session data |
sites:write | Manage site settings and privacy controls |
org:read | Read organization usage, plan, and posture data |
org:admin | Manage users, invites, and workspace settings |
Scopes are assigned at creation time and cannot be expanded beyond the creating user's permissions.
Bearer-Enabled Routes
The following routes accept API client bearer tokens:
| Method | Path | Required Scope |
|---|---|---|
GET | /v1/sites/:siteID/status | sites:read |
GET | /v1/sites/:siteID/evidence-export-runs | evidence:read |
GET | /v1/sites/:siteID/evidence-export-runs/:runID | evidence:read |
GET | /v1/sites/:siteID/evidence-export-runs/:runID/verify | evidence:read |
GET | /v1/sites/:siteID/evidence-export-runs/:runID/download | evidence:read |
All other routes require session authentication via the web UI.
Error Responses
| Status | Code | Description |
|---|---|---|
401 | invalid_client | Invalid credentials, revoked client, or expired client |
403 | insufficient_scope | Token lacks the required scope for this route |
403 | access_denied | Client is not bound to the requested site |
429 | rate_limited | Too many token exchange attempts. Retry after the Retry-After header value |
Client Lifecycle
Listing Clients
curl -H "Authorization: Bearer <SESSION_TOKEN>" \
https://api.example.com/v1/org/api-clientsRevoking a Client
curl -X DELETE \
-H "Authorization: Bearer <SESSION_TOKEN>" \
https://api.example.com/v1/org/api-clients/<CLIENT_ID>Revocation is immediate. In-flight tokens expire within 15 minutes.
Rotating a Client Secret
curl -X POST \
-H "Authorization: Bearer <SESSION_TOKEN>" \
https://api.example.com/v1/org/api-clients/<CLIENT_ID>/rotateDuring rotation, both old and new secrets are valid for a grace period (default: 24 hours). After the grace period, only the new secret works.
Rate Limits
Token exchange has per-client and per-IP rate limits:
- Per client: 5 requests per minute
- Per IP: 20 requests per minute
After 3 consecutive failures, exponential backoff applies (30s → 60s → 120s cap). The Retry-After header indicates when to retry.
Best Practices
- Store secrets securely — use a secrets manager, not source control
- Use minimum scopes — request only the scopes your integration needs
- Bind to specific sites — avoid broad access when site-specific is sufficient
- Handle token expiry — re-exchange credentials when the token expires (no refresh mechanism)
- Monitor for failures — 401 responses may indicate credential issues that need rotation