Skip to main content

API Keys

Every request to https://api.beltic.com/v1 must include an API key in the X-Api-Key header:
X-Api-Key: sk_production_...
API keys are created and managed in the Beltic Console under Settings → API Keys. The raw key value is shown exactly once at creation — copy it immediately and store it in a secrets manager. It cannot be recovered after you leave the page.

Environments

Beltic has two environments, each with its own API key prefix:
EnvironmentKey prefixBase URL
Productionsk_production_...https://api.beltic.com/v1
Stagingsk_staging_...https://api.beltic.com/v1
The base URL is the same for both environments — the key prefix determines which environment your requests target. Never use a production key in development or test code. Staging credentials are isolated from production data and can be freely reset.
# Staging
export BELTIC_API_KEY=sk_staging_...

# Production
export BELTIC_API_KEY=sk_production_...

Key Scopes

Keys carry a fixed permission set. Request only the scopes your service actually needs — a key used only to verify credentials shouldn’t also be able to revoke them. Workflow API
ScopeRequired for
workflows:readGET /v1/workflows, GET /v1/workflows/{id} (metadata; full definition requires workflows:editor:read)
workflows:editor:readViewing a workflow’s full definition in GET /v1/workflows/{id} (the editor / preview). Implied by workflows:write
workflows:writePOST /v1/workflows, PATCH /v1/workflows/{id}, PUT /v1/workflows/{id}/state, POST /v1/workflows/{id}/deploy, DELETE /v1/workflows/{id}
workflows:executePOST /v1/workflows/execute
workflows:executions:readGET /v1/workflows/executions, GET /v1/workflows/{id}/executions, GET /v1/workflows/status/{executionId}
Credentials API
ScopeRequired for
credentials:writePOST /v1/credentials, POST /v1/credentials/batch-issue
credentials:readGET /v1/credentials, GET /v1/credentials/{id}
credentials:verifyPOST /v1/credentials/verify
credentials:revokePOST /v1/credentials/{id}/revoke
credentials:deleteDELETE /v1/credentials/{id}
audit:readGET /v1/audit/events
audit:writePOST /v1/audit/events
audit:streamsPOST /v1/audit/streams, GET /v1/audit/streams, DELETE /v1/audit/streams/{id}
Document API
ScopeRequired for
documents:writePOST /v1/documents
documents:readGET /v1/documents, GET /v1/documents/{id}
document_templates:writePOST /v1/document-templates, PATCH /v1/document-templates/{id}
document_templates:readGET /v1/document-templates, GET /v1/document-templates/{id}
Business & Screening APIs
ScopeRequired for
businesses:writePOST /v1/businesses
businesses:readGET /v1/businesses, GET /v1/businesses/{id}
screenings:writePOST /v1/screenings
screenings:readGET /v1/screenings, GET /v1/screenings/{id}
website_checks:writePOST /v1/website-checks
Webhooks
ScopeRequired for
webhooks:writePOST /v1/webhooks, PATCH /v1/webhooks/{id}, DELETE /v1/webhooks/{id}, POST /v1/webhooks/{id}/resend
webhooks:readGET /v1/webhooks, GET /v1/webhooks/{id}
Requests with a valid key but missing scope return 403 Forbidden.

Error Responses

Authentication errors return standard HTTP codes with a JSON body:
{
  "error": "unauthorized",
  "message": "API key is invalid or has been revoked"
}
HTTPCodeCause
401unauthorizedKey missing, malformed, or revoked
403forbiddenKey valid but lacks required scope
429rate_limitedToo many requests — see below

Rate Limits

Rate limits are applied per API key:
TierRequests / minuteBurst
Default300500
Workflow execution60100
Batch issue1010
When a limit is exceeded, the API returns 429 Too Many Requests with a Retry-After header indicating how many seconds to wait:
HTTP/1.1 429 Too Many Requests
Retry-After: 3
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1716292800

Retries

The Beltic API is safe to retry on transient errors. Follow these conventions:
  • Retry on: 429, 500, 502, 503, 504
  • Do not retry on: 400, 401, 403, 404, 422 — these are deterministic failures that won’t resolve on retry
  • Use exponential backoff with jitter, starting at 1 second, capping at 30 seconds
  • Honour Retry-After on 429 responses — don’t backoff shorter than what the header specifies
For mutation requests (POST, DELETE), use idempotency keys to ensure retries don’t produce duplicate side effects.

Idempotency

Mutation endpoints (POST /v1/credentials, POST /v1/workflows/execute) accept an Idempotency-Key header. Submitting the same key twice within 24 hours returns the original response without re-executing:
curl -X POST https://api.beltic.com/v1/credentials \
  -H "X-Api-Key: $BELTIC_API_KEY" \
  -H "Idempotency-Key: your-unique-request-id" \
  -H "Content-Type: application/json" \
  -d @payload.json
Concurrent requests with the same key return 409 Conflict. Use a UUID or a hash of the request payload as the key.

Public Endpoints (No Auth)

The following endpoints do not require authentication — they are used by third-party verifiers who don’t have a Beltic account:
EndpointPurpose
GET /.well-known/jwks.jsonIssuer’s public signing keys
GET /.well-known/did.jsonIssuer DID document
GET /.well-known/status-lists/v1Revocation bitstring
POST /v1/credentials/_public/verifyVerify a credential JWT without an API key
See Public Endpoints for details.