API Keys
Every request tohttps://api.beltic.com/v1 must include an API key in the X-Api-Key header:
Environments
Beltic has two environments, each with its own API key prefix:| Environment | Key prefix | Base URL |
|---|---|---|
| Production | sk_production_... | https://api.beltic.com/v1 |
| Staging | sk_staging_... | https://api.beltic.com/v1 |
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| Scope | Required for |
|---|---|
workflows:read | GET /v1/workflows, GET /v1/workflows/{id} (metadata; full definition requires workflows:editor:read) |
workflows:editor:read | Viewing a workflow’s full definition in GET /v1/workflows/{id} (the editor / preview). Implied by workflows:write |
workflows:write | POST /v1/workflows, PATCH /v1/workflows/{id}, PUT /v1/workflows/{id}/state, POST /v1/workflows/{id}/deploy, DELETE /v1/workflows/{id} |
workflows:execute | POST /v1/workflows/execute |
workflows:executions:read | GET /v1/workflows/executions, GET /v1/workflows/{id}/executions, GET /v1/workflows/status/{executionId} |
| Scope | Required for |
|---|---|
credentials:write | POST /v1/credentials, POST /v1/credentials/batch-issue |
credentials:read | GET /v1/credentials, GET /v1/credentials/{id} |
credentials:verify | POST /v1/credentials/verify |
credentials:revoke | POST /v1/credentials/{id}/revoke |
credentials:delete | DELETE /v1/credentials/{id} |
audit:read | GET /v1/audit/events |
audit:write | POST /v1/audit/events |
audit:streams | POST /v1/audit/streams, GET /v1/audit/streams, DELETE /v1/audit/streams/{id} |
| Scope | Required for |
|---|---|
documents:write | POST /v1/documents |
documents:read | GET /v1/documents, GET /v1/documents/{id} |
document_templates:write | POST /v1/document-templates, PATCH /v1/document-templates/{id} |
document_templates:read | GET /v1/document-templates, GET /v1/document-templates/{id} |
| Scope | Required for |
|---|---|
businesses:write | POST /v1/businesses |
businesses:read | GET /v1/businesses, GET /v1/businesses/{id} |
screenings:write | POST /v1/screenings |
screenings:read | GET /v1/screenings, GET /v1/screenings/{id} |
website_checks:write | POST /v1/website-checks |
| Scope | Required for |
|---|---|
webhooks:write | POST /v1/webhooks, PATCH /v1/webhooks/{id}, DELETE /v1/webhooks/{id}, POST /v1/webhooks/{id}/resend |
webhooks:read | GET /v1/webhooks, GET /v1/webhooks/{id} |
403 Forbidden.
Error Responses
Authentication errors return standard HTTP codes with a JSON body:| HTTP | Code | Cause |
|---|---|---|
401 | unauthorized | Key missing, malformed, or revoked |
403 | forbidden | Key valid but lacks required scope |
429 | rate_limited | Too many requests — see below |
Rate Limits
Rate limits are applied per API key:| Tier | Requests / minute | Burst |
|---|---|---|
| Default | 300 | 500 |
| Workflow execution | 60 | 100 |
| Batch issue | 10 | 10 |
429 Too Many Requests with a Retry-After header indicating how many seconds to wait:
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-Afteron429responses — don’t backoff shorter than what the header specifies
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:
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:| Endpoint | Purpose |
|---|---|
GET /.well-known/jwks.json | Issuer’s public signing keys |
GET /.well-known/did.json | Issuer DID document |
GET /.well-known/status-lists/v1 | Revocation bitstring |
POST /v1/credentials/_public/verify | Verify a credential JWT without an API key |