Authentication
Every authenticated route on the Not AI Public REST API is gated by a aik_v1_* API key. The only unauthenticated routes are /health, /openapi/v3.json, and /swagger.
Key format
API keys are opaque strings that start with the literal prefix aik_v1_. The full key is exactly 47 characters: the 7-character prefix plus a 40-character base64url body. Do not parse the body; treat the whole string as a secret credential.
aik_v1_<40-char base64url body>
Keys are minted in the Not AI dashboard at dash.isnotai.com and are bound to:
- One integration. The integration the key resolves to is what
/v1/integrationreturns, and is the implicit scope of every list endpoint. - One region. Keys do not cross regions. See Region binding below.
The dashboard displays the full key once at creation time. After that, only a masked form is shown (the exact mask is set by the dashboard; the apiKeyMasked field on GET /v1/integration returns the same masked value the dashboard renders).
Presenting the key
The API accepts the key in either of two headers. Pick one per request.
Authorization: Bearer aik_v1_<your-key>
x-api-key: aik_v1_<your-key>
Authorization: Bearer is the modern preference and the one shown in every example in these docs. x-api-key exists for environments where Authorization is reserved or stripped (some corporate load balancers, some serverless gateways, some on-prem proxies will strip or rewrite Authorization before it reaches the application). If both headers are present, Authorization wins.
# Bearer form (preferred)
curl https://stg-api.isnotai.com/v1/integration \
-H "Authorization: Bearer $ISNOTAI_API_KEY"
# x-api-key form (use when Authorization is unavailable)
curl https://stg-api.isnotai.com/v1/integration \
-H "x-api-key: $ISNOTAI_API_KEY"
Failure modes
Authentication failures return a 401 with the error envelope. The middleware distinguishes between “no credential was presented” and “the credential was presented but is invalid”:
{
"error": {
"code": "MISSING_API_KEY",
"message": "Provide your API key via 'Authorization: Bearer aik_v1_...' or the 'x-api-key' header."
}
}
{
"error": {
"code": "INVALID_API_KEY",
"message": "The supplied API key is not valid."
}
}
MISSING_API_KEY is emitted when neither Authorization: Bearer nor x-api-key is present on the request. INVALID_API_KEY is emitted in every other failure case — wrong prefix, right shape but unknown, valid shape but wrong region, revoked. The validator is timing-safe and the four INVALID_API_KEY reasons collapse to one envelope; rotating keys does not leak which keys are valid.
The response may also carry WWW-Authenticate: Bearer (set on early rejection when the request omits the header or presents a malformed value) so HTTP clients can react to the challenge in the standard way.
Region binding
Not AI runs two fully isolated Staging stacks, US and EU. A key minted under the US dashboard cannot be used against the EU stack and vice versa.
The practical consequences:
| Key minted in | Authenticates against |
|---|---|
| US dashboard | https://stg-api.isnotai.com only |
| EU dashboard | https://stg-api-eu.isnotai.com only |
Presenting a US key to https://stg-api-eu.isnotai.com returns 401 INVALID_API_KEY, the same envelope you would get for a typo or revoked key. There is no cross-region routing and no fallback. If you operate in both regions, mint one key per region from the appropriate dashboard.
Rotation and revocation
If a key may be compromised, rotate it immediately:
- Sign in to
dash.isnotai.com. - Open the integration the key belongs to.
- Create a new key.
- Update your application’s secret store with the new value.
- Revoke the old key from the same panel.
Revocation is effective on the next request. Once revoked, the old key returns 401 INVALID_API_KEY like any other unknown credential.
Operational hygiene
- Store the key in an environment variable or secret manager. Never commit it to source control, never embed it in a browser bundle, and never paste it into a public ticket.
- Consider a separate key per environment (development, staging, production) so rotating one does not disturb the others.
- Consider a separate key per consuming application or agent so revoking one does not cascade.
What the key authorizes
A valid aik_v1_* key authorizes both read and write access on the data the underlying integration already owns. Concretely:
Read access to scored sessions and their details, events, and labels (GET /v1/sessions*); users and their session history (GET /v1/users and GET /v1/users/{id}/sessions); courses (GET /v1/courses); analytics and stats (GET /v1/analytics, GET /v1/stats); your own API consumption (GET /v1/usage); the resolved integration record (GET /v1/integration); your outbound webhook subscriptions (GET /v1/webhooks*); the integration’s risk-classification cutpoints (GET /v1/settings/risk-thresholds).
Write access for closing the loop on findings:
- Label a scored session as bot or human (
POST /v1/sessions/{id}/label). - Mark a
(userId, fingerprint)pair as a legitimate device for the user (POST /v1/users/{id}/devices/{fingerprint}/confirm) — suppresses future shared-device and device-switch anomalies on that pair. - Replace the integration’s risk-classification cutpoints (
PUT /v1/settings/risk-thresholds). - Manage your outbound webhook subscriptions — register (
POST /v1/webhooks), update (PATCH /v1/webhooks/{id}), delete (DELETE /v1/webhooks/{id}), rotate the signing secret (POST /v1/webhooks/{id}/rotate-secret), and fire a synthetic test event (POST /v1/webhooks/{id}/test).
The key does not authorize:
- Account management, key rotation, billing changes, notification-preference editing, or onboarding new integrations. Those flows live in the dashboard at
dash.isnotai.com. - Access to data belonging to other integrations or other tenants.
For anything outside the documented surface, use the dashboard.