Skip to content
Menu
Guide

Authentication

One optional header. Send your key in X-API-Key; a Bearer token works too. Without a key, every metered endpoint answers 401 with a stable code.

The X-API-Key header

The OpenAPI document declares one security scheme, ApiKeyHeader: an API key in a header named X-API-Key. Its own description is the shortest way to say it — “Your Ozituma API key. Create one free at /developers.”

curl "https://ozituma.com/api/v1/words?q=mmiri&limit=2" \
  -H "X-API-Key: $OZITUMA_API_KEY"

The header is optional at the HTTP level and required at the route level: an endpoint either needs a key or it does not. This table is that split, read from the route wrappers.

Which endpoints take a key.
EndpointKey
GET /api/v1/wordsRequired
GET /api/v1/words/{id}Required
GET /api/v1/word-of-the-dayRequired
GET /api/v1/languagesRequired
GET /api/v1/statsRequired
POST /api/v1/developersNot required
GET /api/v1/openapi.jsonNot required

The Bearer alternative

Many HTTP clients and generated SDKs default to an Authorization header, so the pipeline accepts one. It reads X-API-Key first; only if that is absent or empty does it look at Authorization, and then only when the value starts with Bearer . Either header carries the same key and reaches the same key record.

curl "https://ozituma.com/api/v1/stats" \
  -H "Authorization: Bearer $OZITUMA_API_KEY"

Without a key

A request to a metered endpoint with no key is refused before the handler runs, with HTTP 401 and the code missing_api_key. The message is fixed:

{
  "error": {
    "code": "missing_api_key",
    "message": "No API key supplied. Send your key in the X-API-Key header. Get a free key at /developers."
  }
}

A key that is unknown, revoked, expired, or attached to a suspended developer is refused the same way, with invalid_api_key:

{
  "error": {
    "code": "invalid_api_key",
    "message": "That API key is not valid, has been revoked, or has expired."
  }
}

Revocation is deliberately reported through invalid_api_key rather than through revoked_api_key: the shared code table defines the latter, but authenticateApiKey returns null for every unusable credential and the caller cannot tell them apart. Errors records that in full.

What a key looks like, and how it is stored

Keys are prefixed ozt_live_ and then carry 40 hexadecimal characters of randomness. Only a SHA-256 hash of the whole key is stored, plus the first 17 characters — the prefix and eight more — kept in the clear so a dashboard can show which key is which. The plaintext is returned once, at creation, and is not recoverable.

A key is created with the scope read. Keys do not expire on their own: they stay valid until they are revoked, so a leaked key is a one-call fix rather than a rotation project.

Getting a key

The landing page has the form and the 60-second quickstart. In one call it is POST /api/v1/developers, which needs no key of its own — you need a key to get a key — and is therefore throttled per IP instead.

Get a free key POST /developers