Skip to content · تخطَّ إلى المحتوى
نبرة Nabra

Schema-driven voice AI · English + Arabic dialects · early access

Define your data. Let people speak. Get structured JSON.

Nabra turns natural speech into validated structured data your software can use. You describe the fields you need; people talk the way they normally do; every value comes back checked against what was actually said.

Developer? Read the API docs
Any schema
Orders, bookings, forms — yours
Any dialect
Levantine, Gulf, English, mixed
Never invents
Every value checked in code
Runs locally
No cloud AI calls

Your schema · appointment_booking

customerName · personphone · phonedoctor · persondate · datetime · timenotes · text
Someone speaks · detected: Arabic, Levantine0:05

بدي أحجز عند الدكتور أحمد بكرا الساعة خمسة، اسمي سارة ورقمي 0781234567.

Validated JSON

time: confirm am/pm
{
"customerName": "سارة",
"phone": "0781234567",
"doctor": "أحمد",
"date": "2026-09-25",
"time": "17:00"
}

In 45 seconds

From what your users say to the data your app needs.

Speech in, validated JSON out — and when something is missing, Nabra asks for it.

Schema-driven

The schema changes. The engine stays the same.

You describe what you need. The same pipeline — speech recognition, understanding, normalization, validation — fills any schema, and never invents what wasn't said.

Restaurant

restaurant_order

1 · Schema (abridged)

"items": {
  "type": "array",
  "items": {
    "type": "object",
    "fields": {
      "name": { "type": "string" },
      "quantity": {
        "type": "integer",
        "default": 1 }
    }
  }
},
"address": { "type": "address" }

2 · Someone says

«بدي ٢ شاورما ووجبة زنجر والتوصيل لخلدا»

Two shawarma and a Zinger meal, delivered to Khalda.

3 · Your app receives

{
  "items": [
    { "name": "شاورما",
      "quantity": 2 },
    { "name": "وجبة زنجر",
      "quantity": 1 }
  ],
  "address": "خلدا"
}

No number was said for the Zinger meal, so its quantity comes from the schema default (1). A quantity nobody said is never invented.

Appointment

appointment_booking

1 · Schema (abridged)

"doctor": { "type": "person" },
"date": {
  "type": "date",
  "required": true },
"time": {
  "type": "time",
  "required": true }

2 · Someone says

«بدي أحجز عند الدكتور أحمد بكرا الساعة خمسة»

I'd like to book with Dr. Ahmad tomorrow at five.

3 · Your app receives

{
  "doctor": "أحمد",
  "date": "2026-09-25",
  "time": "17:00"
}

«بكرا» is resolved in code from the request's referenceTime. «خمسة» without morning/evening is flagged for confirmation.

HR leave

hr_leave_request

1 · Schema (abridged)

"leaveType": {
  "type": "enum",
  "values": ["annual", "sick",
    "unpaid", "emergency"] },
"startDate": { "type": "date" },
"endDate": {
  "type": "date",
  "validation": {
    "notBefore": "startDate" } },
"reason": { "type": "text" }

2 · Someone says

«بدي إجازة من الأحد للخميس بسبب سفر»

I need leave from Sunday to Thursday — I'm travelling.

3 · Your app receives

{
  // uncertain · mapped_by_model
  "leaveType": "annual",
  "startDate": "2026-09-27",
  "endDate": "2026-10-01",
  "reason": "سفر"
}

No leave type was said. The model guessed “annual” from «سفر», so validation marks it uncertain and asks for confirmation instead of passing it off as fact. The end date lands after the start date by rule.

Live demo

Speak. Watch it become data.

This is the real pipeline — not a recording. Pick a schema, speak, and your voice is transcribed, mapped to that schema, validated, and returned as JSON.

  • Choose what to collect — a delivery, a restaurant order, an appointment, a leave request — and say it in English, Arabic, or both.
  • Every value is checked against what you said. Nothing is invented.
  • Each stage is shown as it happens; a short request takes a few seconds.

Running locally: start the Voice API (see Quick start). The demo shows its connection status in the top corner.

Try it yourself

Pick what to collect, then speak naturally — Arabic (any dialect), English, or both.

Checking Voice API…

schema = "delivery_order"

Start recording
  1. Upload
  2. Speech → text
  3. Understand
  4. Validate

Tap the microphone and speak. Nothing is stored — audio is deleted after processing.

No microphone? Try a sample (sent as text)

Speaks the way your customers do

English, Levantine and Gulf Arabic, and mixed speech — detected automatically, with no language setting.

See every dialect

Not just speech-to-text

A transcript is text. Your software needs data.

Speech-to-text stops at words. Nabra goes on: it maps them to the schema you defined, normalizes them, and checks every value in code before it reaches you.

Speech-to-text gives you

«مرحبا، بدي أبعث طلب من مطعم حمادة بالجبيهة للشميساني، المستلم أحمد ورقمه صفر سبعة تسعة واحد اثنين ثلاثة أربعة خمسة ستة سبعة»

A string. You still have to find the places, the name and the number — and notice the number was spoken as words.

Nabra gives you

{
"pickup": "مطعم حمادة - الجبيهة",
"dropoff": "الشميساني",
"receiverName": "أحمد",
"receiverPhone": "0791234567"
}

Fields, in your schema, each with a status and confidence. The phone number was spoken digit by digit and normalised deterministically — not guessed.

How it works

From a schema and a sentence to a record

One API call. The pipeline behind it is replaceable piece by piece — the contract stays the same.

  1. 01

    Define

    Describe the data you need: fields, types, what is required. In the builder or as JSON.

    "doctor": { "type": "person" },
    "date":   { "type": "date" }
  2. 02

    Speak

    People talk the way they normally do — any dialect, filler words, numbers as words.

    «بدي أحجز عند الدكتور أحمد بكرا…»

  3. 03

    Understand & validate

    The model maps what was said to your fields; code normalizes and checks every value.

    {
      "doctor": "أحمد",
      "date": "2026-09-25"
    }
  4. 04

    Integrate

    Your application receives JSON — with what's missing and what to confirm — and decides.

    your booking APIyour backend

Validation

Designed to never invent a value

Language models are good at reading dialect — and bad at admitting they didn't hear something. So every value they propose passes a deterministic check against the transcript before it reaches you.

  • Phone number not said

    Model proposes 0799999999

    Rejected — only numbers actually spoken can fill a phone field

  • Digit lost in transcription

    Heard 078824021 (9 digits)

    Returned as incomplete with what was heard, so the user fixes one digit

  • Name that wasn't mentioned

    Model adds «محمود»

    Rejected — every word of a name must appear in the transcript

  • Invented instruction

    «قبل الساعة 7» when 5 was said

    Rejected — no new numbers or instructions

  • Money

    «مبلغ التحصيل ستاشر دينار»

    Kept as 16 JOD, and always flagged for a person to confirm

  • Hedged or two numbers

    “maybe five” · «خمسة أو ستة»

    Marked uncertain, or returned with both options and a question — never picked silently

  • Relative date

    «بكرا» with no current date sent

    Returned as invalid with what was heard — a date is never guessed

  • Order item not said

    Model adds «بيبسي» to the list

    Rejected — the entry is dropped and reported in issues

Integration

You keep your business logic. We turn voice into data.

The Voice API never creates orders, charges money or calls your systems. It returns structured data; your application decides what to do with it.

Your app

Records the user (web, mobile, IVR)

Nabra Voice API

Transcribes, understands, validates

Structured JSON

Fields + status + confidence

Your backend

Creates the order, ticket, booking — your business logic

For developers

Your schema in. Validated JSON back.

Name a schema and send audio (or text) from any client. Get every field with a status, a confidence and a “needs confirmation” flag, plus the missing fields — so your UI knows exactly what to ask next.

Request
curl -X POST https://api.example.com/api/v1/voice/parse \
  -H "Authorization: Bearer $API_KEY" \
  -F "audio=@voice.webm" \
  -F "schema=restaurant_order"
Response (abridged)
{
  "requestId": "req_3f9c2a1b7d10",
  "schema": "restaurant_order",
  "schemaVersion": "1.0",
  "locale": "ar-JO",
  "sessionId": null,
  "transcription": {
    "text": "بدي ٢ شاورما ووجبة زنجر والتوصيل لخلدا، اسمي محمد ورقمي 0791234567",
    "language": "ar", "confidence": 0.9, "audioSeconds": 7.4
  },
  "fields": {
    "customerName": { "value": "محمد", "type": "person", "status": "extracted", "confidence": 0.86, "requiresConfirmation": false },
    "phone":        { "value": "0791234567", "type": "phone", "status": "extracted", "confidence": 0.93, "requiresConfirmation": false },
    "items": {
      "value": [ { "name": "شاورما", "quantity": 2 }, { "name": "وجبة زنجر", "quantity": 1 } ],
      "type": "array", "status": "extracted", "confidence": 0.86, "requiresConfirmation": false, "issues": []
    },
    "address":      { "value": "خلدا", "type": "address", "status": "extracted", "confidence": 0.86, "requiresConfirmation": false },
    "notes":        { "value": null, "type": "text", "status": "missing", "confidence": 0, "requiresConfirmation": false }
  },
  "data": {
    "customerName": "محمد", "phone": "0791234567",
    "items": [ { "name": "شاورما", "quantity": 2 }, { "name": "وجبة زنجر", "quantity": 1 } ],
    "address": "خلدا", "notes": null
  },
  "missingFields": [],
  "fieldsRequiringConfirmation": [],
  "complete": true,
  "language": {
    "requested": "auto", "detected": "ar", "locale": "ar-JO", "dialect": "jordanian", "dialectGroup": "levantine",
    "direction": "rtl", "mixedLanguage": false, "secondaryLanguages": [], "source": "detected",
    "evidence": ["بدي", "خلدا"]
  },
  "clarification": null,
  "warnings": [],
  "timings": { "uploadMs": 0.4, "transcriptionMs": 3120, "extractionMs": 3410, "validationMs": 1.1, "totalMs": 6533 },
  "models": { "speechToText": "faster-whisper:large-v3-turbo", "extraction": "ollama:qwen2.5:7b" }
}

Privacy

Built to support private voice processing

Voice is personal data. The architecture keeps it short-lived: audio is processed, turned into structured data, and deleted. Recordings are not stored unless you explicitly turn on debugging.

Works today

Local processing

Speech recognition and extraction run on your own machine — how the prototype runs today.

Planned

Self-hosted

The same service in your data centre or private cloud, with your own models.

Planned

Managed cloud

A hosted API for teams that don't want to run infrastructure.

No certifications are claimed at this stage. Read how data is handled

Honest roadmap

What works today — and what's next

Available now

  • Custom schemas: 18 field types, a visual builder and JSON, versioned
  • Deterministic validation for every type — phones, names, amounts, dates, lists
  • Sessions: build one record over several voice or text inputs
  • Example schemas: delivery, restaurant, appointment, field service, HR leave
  • English, Levantine and Gulf Arabic, and mixed speech — detected automatically, clarified in the user's language
  • Voice API prototype with OpenAPI docs, streaming progress, and this playground

Coming later

  • Production cloud deployment and uptime commitments
  • Accounts, teams and billing
  • API key management backend
  • Usage analytics from real traffic
  • Webhooks (request.completed, session.updated…)
  • SDKs for JavaScript, Python, React Native and Flutter

Define your data. Let people speak.

Try the live demo, or build a schema and test it with your own voice in a few minutes.