Pagination
One endpoint paginates. page and limit select a slice; the body reports where the slice sits in the whole result, and a header carries the total.
Which endpoints paginate
GET /api/v1/words—pageandlimit.
The other endpoints return a whole collection in one response — a single entry, every language, the totals object — and take no page or limit.
The two parameters
| Parameter | Type | Default | Range |
|---|---|---|---|
page | integer | 1 | Minimum 1. The implementation rejects a value above 10,000 with invalid_parameter. |
limit | integer | 20 | 1–100. The document caps it at 100 and the route enforces the same maximum. |
The maximum of 10,000 on page is not in the document; it is the bound the route passes to its integer parser. The document declares only the minimum and the default.
The envelope
A paginated response is the PaginatedWords schema: the slice in data, the whole match count in total, and the position and whether another page exists.
{ "data": [ { "id": 5192, "language": "igbo", "headword": "mmiri", "exactForm": "mmiri", "slug": "mmiri", "pronunciation": null, "isCommon": true, "isVerified": true, "frequencyRank": null, "glosses": ["liquid"], "partOfSpeech": "Noun", "matchType": "headword", "score": 1185 } ], "total": 93, "page": 2, "perPage": 20, "hasMore": true }
Illustrative values. The envelope keys are the schema’s; each element of data is a full WordSummary, as on the search page.
totalis the number of matches across every page, not the length ofdata.perPageis thelimitthe response was produced with.hasMoreis whether a further page exists.diagnosticsis an optional object the document types without describing. When it is present, read the keys that are there; the document does not say what they are.
Content-Range carries the total
The same convention the Igbo API uses, so a client migrating from it keeps working: the response carries a Content-Range header in the form items 0-19/93, meaning items 0 to 19 of 93.
Content-Range: items 0-19/93
The range is computed from the page and the length of the returned slice, so an empty page reports items 0-0/0. Note that the header and the body can disagree about off-by-one: the header counts items from zero, while page counts from one.
Caching
Paginated responses are identical for every caller and change slowly, so they are cached:
Cache-Control: public, s-maxage=300, stale-while-revalidate=600
A shared cache may serve the response for up to five minutes after it is fresh and may serve a stale copy for ten minutes while it revalidates. The word-of-the-day and single entry responses carry longer windows of their own; those are declared on their pages.
Paging through a search
curl "https://ozituma.com/api/v1/words?q=mmiri&page=1&limit=20" \ -H "X-API-Key: $OZITUMA_API_KEY" curl "https://ozituma.com/api/v1/words?q=mmiri&page=2&limit=20" \ -H "X-API-Key: $OZITUMA_API_KEY"
Keep the same q and filters on every page, as above, or page 2 will be a slice of a different result set. Stop when hasMore is false rather than when a page comes back short: the last page is short precisely because it is the last, and an empty page in the middle would mean something else went wrong.