Documentation

Lahja API

Lahja (لهجة, “dialect”) serves Arabic dialect phrases written and recorded by native-speaking teachers. Nothing is AI-generated: AI is only ever used to match phrases by meaning.

Each phrase has its dialect text with vowel marks, a transliteration, a literal English gloss, a meaning (what the phrase actually does), structured nuance such as register and addressee, and one or more recordings. Recordings note the speaker's gender, age band, and where they grew up and live.

The API is REST over JSON, described by an OpenAPI 3.1 spec. Generate a typed client in any language from it.

BASEhttps://api.lahjaapi.com/v1

Authentication

Every request except GET /health needs an API key, sent as a bearer token. Keys look like lahja_live_… and are shown once when issued. Keep them on your server, never in a shipped app or web page.

Authorization: Bearer lahja_live_XXXXXXXXXXXXXXXX
Lahja is in early access. Keys are issued by hand for now; request one here. Self-serve sign-up is on the way.

Quickstart

1. Check your balance

curl https://api.lahjaapi.com/v1/account \
  -H "Authorization: Bearer $LAHJA_KEY"
{ "id": "3b7d…", "name": "Acme Learning", "balance": 10 }

2. Ask for what you need

A prompt request is something you want said, in the dialects you want, under your own key. Requests are shared: if another customer already asked for the same meaning, addressee and register, yours joins theirs and anything already recorded is ready.

curl -X PUT https://api.lahjaapi.com/v1/requests \
  -H "Authorization: Bearer $LAHJA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"requests":[{
        "key": "game.jump",
        "english": "jump",
        "meaning": "telling one boy to jump, as a game command",
        "addressee": "masculine",
        "register": "casual",
        "dialects": ["egyptian", "levantine"]
      }]}'

3. Check what's published

GET /requests returns each of your requests with the published phrase IDs per dialect.

4. Unlock

curl -X POST https://api.lahjaapi.com/v1/phrases/b41e…/unlock \
  -H "Authorization: Bearer $LAHJA_KEY"
{ "phraseId": "b41e…", "charged": true, "creditsCharged": 1, "balance": 9 }

Credits & billing

Errors

Errors return a JSON body with a machine-readable error and a human-readable message.

{ "error": "insufficient_credits", "message": "This phrase costs 1 credit; your balance is 0." }
StatusMeaning
400A field is invalid. Nothing was saved.
401Missing, unknown or revoked API key.
402Not enough credits to unlock.
404No published phrase with this ID.

API reference

All paths are relative to https://api.lahjaapi.com/v1. The OpenAPI spec is the source of truth.

Health

GET/health

No key needed. Returns { "status": "ok" } when the service is up.

Account

GET/account

Your account and credit balance. balance can be negative after a refund or chargeback, which blocks unlocking.

FieldTypeDescription
iduuidYour customer ID.
namestringAccount name.
balanceintegerCredits available.

Ledger

GET/account/ledger?limit=50

Credit movements, most recent first. limit is 1–200 (default 50).

FieldTypeDescription
idint64Entry ID.
deltaintegerCredits added (positive) or spent (negative).
reasonenumsignup_grant, purchase, unlock, refund, chargeback, adjustment
phraseIduuid?Set for unlocks.
createdAtdate-timeWhen it happened.

Prompt requests

PUT/requests

Creates or updates up to 500 requests at once. Re-submitting a key replaces its meaning and dialects. If any request is invalid, nothing is saved.

FieldTypeDescription
keystringYour own identifier, unique in your account (≤200), e.g. simon_says_verb.jump.
englishstringShort label shown to teachers (≤100), e.g. “jump”.
meaningstringThe full request as a sentence (≤500). With addressee and register, decides whether you join an existing prompt.
addresseeenumWho it's said to. See enums.
registerenum?How formal. See enums.
dialectsarrayOne or more dialects you want.
fushaTextstring?Optional Modern Standard Arabic form, to help teachers (≤200).
guidancestring?Optional notes for teachers (≤1000).
GET/requests

All your requests by key. Each has the shared promptId and a published list of { dialect, phraseIds } for your requested dialects that have recordings. Unlock those IDs to get the content.

Unlock a phrase

POST/phrases/{phraseId}/unlock

Charges the phrase's credit cost the first time. Repeat calls are free and return charged: false. Returns 402 if your balance is too low.

FieldTypeDescription
phraseIduuidThe phrase.
chargedbooleanFalse when you already owned it.
creditsChargedintegerCredits taken by this call.
balanceintegerYour balance afterwards.

Dialects & enums

EnumValues
Dialectfusha, egyptian, levantine, gulf, iraqi, maghrebi, sudanese
Addresseemasculine, feminine, plural, any (when the form doesn't matter)
Registerintimate, casual, polite, formal

Coming soon

For teachers

Lahja's content comes from native-speaking teachers. Teachers sign in with their ArabicCompanion teacher account, are approved for their dialects, and record phrases from a shared queue. Every phrase is confirmed by a second teacher of the same dialect before it's published, and teachers are paid for approved contributions.