Authentication & API keys
Every request to the OKIAS API is authenticated with a secret API key sent as a bearer token. Keys come in two modes — test and live — and are managed entirely from your dashboard.
Authenticate by placing your secret key in an Authorization: Bearer header on every request. There are no other credentials to manage.
The Authorization header
Send your key as a bearer token:
Authorization: Bearer ok_live_4f8a2c9e1b7d...curl https://api.okias.io/v1/verifications \
-H "Authorization: Bearer $OKIAS_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "level": ["FULL_KYC"], "country": "pk" }'401 with error code INVALID_API_KEY.{
"error": {
"code": "INVALID_API_KEY"
}
}Key modes: test vs live
Each key carries its environment in its prefix, so you can tell at a glance which one you are holding. The mode is fixed when the key is created.
| Prefix | Mode | Behaviour |
|---|---|---|
| ok_test_ | Sandbox | Runs against the deterministic sandbox. Outcomes are simulated, no real checks run, and no credit is charged. Use it for every branch of your integration. |
| ok_live_ | Live | Runs real document, liveness, face-match and sanctions checks. Bills one credit per approved full KYC at $0.15 — declined, review and errored checks are free. |
APPROVED, REVIEW, DECLINED and ERROR before spending a credit. See Verifications.Key scopes (checks)
When you create a key you choose which checks it may run, from the three in the catalog — FULL_KYC, ID_DOCUMENT and AML_SCREENING (see levels & checks). A create call that omits level runs the key's configured checks. This keeps each integration least-privilege: a key scoped only to what it needs limits the blast radius if it ever leaks.
Keys are stored only as a SHA-256 hash. The plaintext secret exists exactly once, in the response that created it — OKIAS cannot show it to you again or recover it for you.
Creating, rotating & revoking keys
Manage keys from Dashboard → API keys. Behind the dashboard, these map to authenticated endpoints:
/v1/api-keys/v1/api-keys/v1/api-keys/:id/v1/api-keys/:idCreate a key
web-prod), pick the mode (test or live), and select the checks it may run..env. Afterwards only a masked preview is displayed.Rotate a key
Rotation means: create a new key, deploy it, then revoke the old one. Because you can run both keys during the overlap, rotation is zero-downtime. Rotate on a schedule and whenever a key may have been exposed.
Revoke a key
Revoking a key takes effect immediately — the next request using it returns 401. A leaked key can be killed instantly without affecting other keys.
Network controls: IP allowlist & rate limit
A key is a bearer credential, so the strongest protection is to keep it server-side and revoke it the moment it leaks. For defence in depth you can additionally pin a key to the networks it is allowed to call from, and cap how fast it may be used. Both are optional and off by default, so existing keys are unaffected until you set them.
| Field | Meaning |
|---|---|
| ip_allowlist | A list of IPv4/IPv6 addresses or CIDR ranges (e.g. 203.0.113.7, 198.51.100.0/24, 2001:db8::/32). When non-empty, a request from any other source IP is rejected with 403 IP_NOT_ALLOWED. An empty list means every source IP is allowed. |
| rate_limit_per_min | Maximum requests per minute for this key, counted across all source IPs. Requests over the limit get 429 RATE_LIMITED with a Retry-After header. null (the default) means no per-key cap. This is separate from, and stricter than, the account-wide limits in Errors & rate limits. |
Set them at creation, or update them on an existing key at any time:
# Restrict an existing key to your servers and cap it at 600 req/min
curl -X PATCH https://api.okias.io/v1/api-keys/$KEY_ID \
-H "Authorization: Bearer $DASHBOARD_JWT" \
-H "Content-Type: application/json" \
-d '{
"ip_allowlist": ["198.51.100.0/24", "203.0.113.7"],
"rate_limit_per_min": 600
}'PATCH endpoint is what the console calls, authenticated with your dashboard session. To remove a control, send an empty ip_allowlist or a null rate_limit_per_min.Security best practices
- Keep keys server-side. Never ship a secret key to a browser, mobile app or public repo. All verification calls should originate from your backend.
- Use environment variables. Read the key from
process.env/ the environment — never hardcode it. - One key per environment / service. Separate keys make rotation and revocation surgical and give you clean per-service attribution.
- Least privilege. Scope each key to only the checks it needs.
- TLS only. The API is HTTPS-only; requests over plain HTTP are rejected. Never send a key over an unencrypted channel.
- Rotate regularly and immediately on any suspected exposure. If you accidentally commit a key, revoke it — do not just delete the commit.