Pagination

All list endpoints support offset-based pagination. The SDK also provides an async generator for iterating through all pages.

How pagination works

KalimaLab uses offset-based pagination via the offset-based pagination via the pagelimit query parameters. The response envelope includes pagination metadata in the

ParameterTypeDefaultMaxDescription
pageinteger1Page number, starting at 1.
limitinteger20100 (Free: 20)Results per page.

Free plan page size limit

Free plan accounts are limited to a maximum of 20 results per page. Paid plans support up to 100.

Pagination metadata in responses

Every paginated response includes these fields in the meta object:

paginated-response.json
{  "data": [ ...20 words... ],  "error": null,  "meta": {    "requestId": "req_01j9...",    "responseTimeMs": 14,    "page": 1,    "limit": 20,    "total": 47432,    "totalPages": 2372  }}
FieldDescription
meta.pageCurrent page number.
meta.limitNumber of results per page as requested.
meta.totalTotal number of matching records across all pages.
meta.totalPagesTotal number of pages. Equals Math.ceil(total / limit).

Fetching pages manually

Fetch a specific page by passing the

bash
GET /v1/words?letters=5&page=2&limit=20Authorization: Bearer klmt_live_your_key
typescript
import { KalimaLab } from '@kalimalab/sdk'const client = new KalimaLab({ apiKey: process.env.KALIMALAB_API_KEY! })// Fetch page 2 of 5-letter wordsconst page2 = await client.words.search({ letters: 5, page: 2, limit: 20 })console.log(`Page ${page2.meta.page} of ${page2.meta.totalPages}`)console.log(`Total results: ${page2.meta.total}`)

Fetching multiple pages manually

typescript
async function fetchAllFiveLetterWords() {  const allWords = []  let page = 1  while (true) {    const result = await client.words.search({ letters: 5, page, limit: 100 })    allWords.push(...result.data)    if (page >= result.meta.totalPages) break    page++  }  return allWords}

SDK async generator (recommended)

The SDK provides a paginate() method that returns an async generator. This is the most convenient way to iterate through large result sets:

paginate.ts
import { KalimaLab } from '@kalimalab/sdk'const client = new KalimaLab({ apiKey: process.env.KALIMALAB_API_KEY! })// Iterate through every page of 5-letter wordsfor await (const page of client.words.paginate({ letters: 5, limit: 100 })) {  console.log(`Processing page ${page.meta.page}/${page.meta.totalPages}`)  for (const word of page.data) {    console.log(word.arabic)  }}// You can break earlyfor await (const page of client.words.paginate({ pos: 'verb' })) {  processPage(page.data)  if (page.meta.page >= 5) break // Stop after 5 pages}

Collecting all results at once

typescript
// Convenience: collect all pages into a flat arrayasync function collectAll<T>(  generator: AsyncGenerator<{ data: T[]; meta: { totalPages: number; page: number } }>): Promise<T[]> {  const all: T[] = []  for await (const page of generator) {    all.push(...page.data)  }  return all}const allVerbs = await collectAll(client.words.paginate({ pos: 'verb' }))

Paginated endpoints

The following endpoints support the page and limit parameters:

GET /v1/wordsBrowse and search words.
GET /v1/rootsBrowse Arabic roots.
GET /v1/patternsBrowse morphological patterns.
GET /v1/lettersBrowse letters with frequency data.
GET /v1/proverbsBrowse Arabic proverbs.
GET /v1/grammar/prepositionsBrowse prepositions.
GET /v1/grammar/conjunctionsBrowse conjunctions.

Performance tip

When fetching large datasets, use the maximum limit value (100 for paid plans) to minimize the number of HTTP round trips. Each request adds latency, so fewer pages means faster completion.