Authentication
The Strata HTTP API authenticates every request with a Bearer token. Keys are issued per organization, scoped to specific capabilities and models, and carry their own rate and token-budget limits. There are no cookies and no session state — every key is a long-lived server-to-server credential bound to one organization.
Examples use <API_BASE_URL> in place of the host — substitute https://app.strata.kronisys.com or your org's deployment.
Bearer tokens
Pass your key in the Authorization header on every request except GET /v1/openapi.json.
Authorization: Bearer sk_strata_live_4f2a8e9c0b3d1e5a...
Production keys are prefixed sk_strata_live_; keys issued in a non-production deployment use sk_strata_test_ so a leaked key is visually distinguishable from a real one. The prefix is followed by a hex secret. The full token is a single opaque string — do not split it, URL-encode it, or wrap it in quotes.
curl <API_BASE_URL>/v1/health \
-H "Authorization: Bearer sk_strata_live_4f2a8e9c0b3d1e5a..."
The token is only ever read from the Authorization header — never from a query string or request body. A missing or malformed header returns 401. A revoked, expired, or unknown key also returns 401. All errors are returned as RFC 7807 application/problem+json (see Error responses).
Where keys come from
An admin creates keys in Admin → API Keys in the Strata web app. Minting, rotating, and revoking keys all require the canManageApiKeys permission.
WarningKeys cannot be minted while your organization is on a self-serve trial, and existing keys stop authenticating if the organization is on one — the check runs at request time, not just at mint time. Add a payment plan to enable programmatic access.
When you create a key, the admin UI shows you the secret exactly once. After you close the dialog, the secret is gone — Strata stores only a SHA-256 hash plus the public prefix.
WarningThe full key value is shown only at creation time. Copy it into your secrets manager before dismissing the dialog. If you lose it, the only recovery is to mint a new key (or rotate the existing one) and revoke the old one.
The prefix is the leading portion of the token — the sk_strata_live_ (or sk_strata_test_) tag plus the first 16 characters of the secret. It is safe to log and is how you identify keys in the admin UI and audit log. The full key ID (a UUID) is returned in the X-Strata-Api-Key-Id response header on every authenticated request.
Scopes
Each key carries an explicit list of allowed scopes. Nothing defaults on — an admin opts into each scope at mint time. A request to an endpoint outside the key's scopes returns 403 with a type of insufficient_scope.
| Scope | Endpoints |
|---|---|
chat | POST /v1/chat, POST /v1/query, GET /v1/conversations, GET /v1/conversations/:id, DELETE /v1/conversations/:id |
files | POST /v1/files, GET /v1/files/:id |
excel | POST /v1/excel |
pdf | POST /v1/pdf |
pptx | POST /v1/pptx |
docx | POST /v1/docx |
audit:read | GET /v1/audit — read-only audit-trail export for SIEM ingestion |
Grant only the scopes a key actually needs. A reporting service that produces PDFs from a saved conversation needs chat and pdf — nothing else.
Extension scopes
Ten further scopes — outlook.read, outlook.send, onedrive.read, onedrive.write, sql.read, sql.write, jira.read, jira.write, confluence.read, and confluence.write — let a key read/send mail, work with OneDrive, run SQL, or reach Jira and Confluence while answering a chat prompt (they augment chat; they add no new endpoints). jira.read covers searching, counting, and reading issues and Jira Service Management queues; jira.write covers creating an issue and posting a comment. confluence.read covers searching and reading pages and listing spaces; confluence.write covers creating a page and commenting on one. The four Atlassian scopes are independent — a read scope never implies its write scope, and a Jira scope never implies a Confluence one. Unlike the scopes above, an extension scope only works when the key's actor — a user or a connection bot — has already connected that extension; otherwise the key can't be minted with it. Atlassian satisfies that check either way: the actor connected their own Atlassian account, or the organization runs an Atlassian service account the key rides. See Extension access for the full model, including connection bots and the security guardrails.
jira.write and confluence.write are each necessary but not sufficient. Your organization's write posture for that product is re-checked at request time — if writes are off org-wide, the write tools are never offered and the key behaves as read-only there no matter what it was minted with. The two products resolve independently, so a key can write to Jira and not Confluence, or the reverse. Where both gates pass, the write goes through: in the web app a person is shown an approval prompt before each Atlassian write, but an API-key run is unattended and has nobody to ask. Every Atlassian write is recorded in the audit log. See Atlassian extensions.
Allowed models
Every key also carries an allowed_models list — the subset of your organization's enabled models this key may invoke. Strata runs a DB-driven Model Catalog that Kronisys curates centrally and your organization enables a subset of; a key can only ever use models from that org-enabled set. An admin picks which of those models this specific key may call when minting it.
Two gates apply, and the request must pass both:
- Key gate — the requested
modelmust be in the key'sallowed_models. A model outside it returns403with atypeofmodel_not_allowed. - Org policy gate — at request time, the model is re-checked against the organization's current enabled models. If an admin disables a model in the catalog after the key was minted, calls to that model start returning
model_not_allowedeven though the key's snapshot still lists it. The org's allow-list is always authoritative.
If you omit model on a chat request, Strata uses the first model in the key's allowed_models. Voice, transcription, and embedding models cannot be used with the /v1 chat surface — a key must include at least one chat model.
NoteIf your organization pins a required conversation mode, the
/v1chat endpoints force that mode regardless of themodeyou send.
Per-key configuration
Every key carries the following fields, all editable by an admin after creation except the secret itself.
| Field | Type | Purpose |
|---|---|---|
name | string | Human label shown in the admin UI and audit log. |
prefix | string | The sk_strata_live_/sk_strata_test_ tag plus the first 16 characters of the secret. Safe to log; used to identify the key. |
allowed_scopes | array | Allowed scopes (see above). |
allowed_models | array | Models this key may invoke (see above). |
rate_limit_per_hour | integer | Hourly request cap. Default 1000. See rate limits. |
monthly_token_budget | integer | Monthly token cap. AI calls deduct from this; null means unlimited. Default 5000000. |
include_in_org_pool | boolean | Whether this key's spend counts toward the organization's shared monthly token pool. Default true. |
expires_at | string | Optional ISO-8601 timestamp. After this moment the key returns 401. Capped at 5 years out. |
revoked_at | string | Set when an admin revokes the key. Non-null means the key is dead. |
Read the current state of your own key at any time with GET /v1/health (requires the key in the Authorization header).
{
"status": "ok",
"key": {
"id": "8f3b1c2d-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
"prefix": "sk_strata_live_4f2a8e9c0b3d1e5a",
"name": "Reporting service",
"allowed_scopes": ["chat", "pdf"],
"allowed_models": ["gpt-5.4", "claude-sonnet"],
"rate_limit_per_hour": 1000,
"monthly_token_budget": 5000000,
"expires_at": null
},
"budget": {
"used": 128400,
"limit": 5000000,
"remaining": 4871600,
"cycle_started_at": "2026-06-01T00:00:00.000Z"
},
"timestamp": "2026-06-24T14:00:00.000Z"
}
Rate-limit and identity headers
Every authenticated response carries headers you can poll for limits and to trace traffic back to a specific key:
| Header | Meaning |
|---|---|
X-Strata-Api-Key-Id | The key's UUID. Use this to correlate requests in your logs. |
X-RateLimit-Limit | The key's rate_limit_per_hour. |
X-RateLimit-Remaining | Requests left in the current window. |
X-RateLimit-Reset | Unix epoch second when the window clears. |
X-Strata-Budget-Used | Tokens spent this cycle (present when the key has a token budget). |
X-Strata-Budget-Limit | The key's monthly_token_budget (present when set). |
When a limit is hit, Strata returns 429 with a Retry-After header (seconds). A coarse per-IP guardrail also throttles bursts before the key is even resolved. See Rate limits and budgets for the full model.
Error responses
Auth failures use RFC 7807 application/problem+json and never leak internal details. The type field is a stable, machine-readable identifier.
| Status | type | When |
|---|---|---|
401 | missing_token | No Authorization: Bearer header. |
401 | invalid_token | Malformed, unknown, expired, or revoked key. |
402 | subscription_required | The key's organization has no active subscription. |
403 | insufficient_scope | The key lacks the scope the endpoint requires. |
403 | model_not_allowed | The requested model isn't allowed by the key or org policy. |
403 | org_suspended | The key's organization is suspended. |
403 | trial_no_api_access | The key's organization is on a self-serve trial. The API is not available during a trial. |
403 | key_actor_revoked | The user or connection bot the key acts as is no longer active. |
429 | rate_limit_exceeded | The key exceeded its hourly request cap. |
429 | budget_exhausted | The key exceeded its monthly token budget. |
{
"type": "https://api.strata.kronisys.com/errors/insufficient_scope",
"title": "This API key was not granted the \"pdf\" scope...",
"status": 403,
"required_scope": "pdf",
"granted_scopes": ["chat"]
}
See Errors for the full reference.
Security best practices
Treat a Strata API key like a database password.
Store keys in a secrets manager
Keep keys in AWS Secrets Manager, Azure Key Vault, HashiCorp Vault, or your platform's equivalent. Inject them at runtime as environment variables. Do not commit keys to source control, paste them into tickets, or embed them in client-side code.
Use least privilege
Create one key per service with only the scopes and models that service needs. A nightly Excel export job does not need chat or pdf — give it excel alone, and restrict allowed_models to the single model it actually calls. Cap its rate_limit_per_hour to a few multiples of its real traffic so a runaway loop fails fast.
Set a token budget
For any key that calls POST /v1/chat, set monthly_token_budget. A misconfigured agent loop can burn through millions of tokens in minutes. The budget is a hard stop at the AI-call layer, enforced even under concurrent bursts.
Pin keys to one environment
Production keys belong only in production. Issue separate keys for staging and development with smaller budgets and tighter rate limits — non-production deployments mint sk_strata_test_ keys so they're easy to tell apart.
TipThe
prefixandX-Strata-Api-Key-Idheader are the right identifiers to surface in your service logs. They let you trace requests to a specific key without ever exposing the secret.
Rotation
An admin can rotate a key from Admin → API Keys. Rotation mints a new key with the same name, scopes, models, and limits, then revokes the old one with a grace period (24 hours by default). During the grace window both keys verify, so you can deploy the new secret and confirm traffic before the old one stops working.
The recommended rotation flow:
- Rotate the key. Copy the new secret immediately (shown once).
- Deploy the new secret to your service.
- Confirm traffic is flowing on the new key (its
X-Strata-Api-Key-Idappears in your logs). - Wait out — or shorten — the grace window; the old key auto-revokes when it ends.
A 90-day rotation cadence is a reasonable default; rotate immediately on any suspected exposure.
Revocation
An admin revokes a key from Admin → API Keys by clicking Revoke on the row. Revocation is immediate and irreversible:
- The next request returns
401once the grace window (if any) closes. - The key is preserved in the admin UI and the audit log so usage history remains attributable.
- If you have webhook subscriptions, a
key.revokedevent fires once.
Strata never reactivates a revoked key. To restore access, mint a new one or rotate before revoking. Keys that hit expires_at are rejected automatically with the same invalid_token behavior.