Quickstart

Make your first request to the Arabic Words API in under 5 minutes.

1Create a KalimaLab account and get your API key
2Install the TypeScript SDK
3Make your first request
4Explore the response
5Next steps

1. Create an account and get your API key

Head to the KalimaLab dashboard and create a free account. Once signed in, navigate to Dashboard → API Keys and click "Create API Key".

Copy your key immediately

Your API key is shown only once. Store it in a password manager or .env file right away.

Your key will look like this: klmt_live_••••••••••••••••••••

2. Install the SDK

Install the official kalimalab package. Works in Node.js, Deno, Bun, and any modern JavaScript runtime.

npm install kalimalab
pnpm add kalimalab
yarn add kalimalab
bun add kalimalab

The SDK requires Node.js 18+ or any runtime with native fetch support.

3. Make your first request

Add your API key to environment variables, then write your first script:

KALIMALAB_API_KEY=klmt_live_your_key_here
import { KalimaLab } from 'kalimalab'const client = new KalimaLab({ apiKey: process.env.KALIMALAB_API_KEY! })// Get today's word of the day (0 DP if cached)const word = await client.words.daily()console.log(word.lemma)        // كَتَبَconsole.log(word.primaryGloss) // "to write"console.log(word.primaryPos)   // "verb"console.log(word.pattern)      // "فَعَلَ"// Search for 5-letter nounsconst results = await client.words.search({ letters: 5, pos: 'noun', limit: 10 })console.log(`Found ${results.meta.total} lemmas`)results.data.forEach((w) => console.log(w.lemma))

Using the REST API directly?

You can also call the API without the SDK using any HTTP client. See the Authentication guide for header examples with cURL, Python, and more.

4. Explore the response

Here is what a typical word response looks like. Every word object includes linguistic metadata:

{  "data": {    "lemma": "كَتَبَ",    "primaryPos": "verb",    "primaryGloss": "to write",    "root": "كتب",    "pattern": "فَعَلَ",    "transliteration": "kataba",    "frequencyRank": 143  },  "error": null,  "meta": {    "requestId": "req_01j9xyz...",    "responseTimeMs": 8  }}
lemmaThe word with full diacritics.
primaryPosPart of speech: verb, noun, adjective, or particle.
rootThe Arabic root — trilateral or quadrilateral base.
patternThe morphological pattern (وزن) in verb form.
transliterationALA-LC transliteration.
frequencyRankUsage frequency rank (1 = most frequent).

Filtered search response

When filtering words — for example by letter count or root — the API returns a paginated list. This is the full shape of a GET /v1/words?letters=3&root=كتب response:

{  "data": [    {      "lemma": "كَتَبَ",      "primaryPos": "verb",      "primaryGloss": "to write",      "root": "كتب",      "pattern": "فَعَلَ",      "transliteration": "kataba",      "frequencyRank": 47    }  ],  "error": null,  "meta": {    "requestId": "req_abc123",    "responseTimeMs": 12,    "page": 1,    "limit": 20,    "total": 47,    "totalPages": 3  }}
meta.pageCurrent page number (starts at 1).
meta.limitNumber of results per page (up to 100).
meta.totalTotal number of matching words across all pages.
meta.totalPagesTotal pages available for this query.
meta.responseTimeMsServer-side processing time in milliseconds.

Error handling

Always check that the response succeeded before using data. The two most common errors are 401 Unauthorized (wrong or missing key) and 429 Too Many Requests (rate limit exceeded).

import { KalimaLab, AuthError, RateLimitError } from 'kalimalab'const client = new KalimaLab({ apiKey: process.env.KALIMALAB_API_KEY! })async function safeSearch(letters: number, root: string) {  try {    const results = await client.words.search({ letters, root, limit: 20 })    return results.data  } catch (err) {    if (err instanceof AuthError) {      // 401 — key is missing, invalid, or revoked      console.error('Check your KALIMALAB_API_KEY environment variable.')      throw err    }    if (err instanceof RateLimitError) {      // 429 — too many requests; wait until the limit resets      const waitMs = err.resetAt.getTime() - Date.now()      console.warn(`Rate limited. Retrying in ${Math.ceil(waitMs / 1000)}s.`)      await new Promise((r) => setTimeout(r, waitMs))      return safeSearch(letters, root) // retry once    }    throw err // unexpected error — let it bubble up  }}const words = await safeSearch(3, 'كتب')console.log(words)

Full error reference

For a complete list of error codes, HTTP status codes, and retry guidance, see the Error handling page.

5. Next steps

You're all set! If you run into any issues, contact support.