View as Markdown

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/integration returns, 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:

  1. Sign in to dash.isnotai.com.
  2. Open the integration the key belongs to.
  3. Create a new key.
  4. Update your application’s secret store with the new value.
  5. 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.