المطوّرون
مخططك يدخل، والناس يتكلّمون، و JSON مُتحقَّق منه يخرج.
عرّف البيانات التي تحتاجها، وأرسل ما قاله الناس، واستلمه بالشكل نفسه — دون أن تبني بنفسك التعرّف على الكلام وفهم اللغة والتحقق. ويبقى منطق العمل في نظامك الخلفي.
تعمل الواجهة البرمجية اليوم كخدمة محلية، ونقطة الوصول المستضافة مخطّط لها. تستخدم الأمثلة العنوان المؤقت https://api.example.com.
curl -X POST https://api.example.com/api/v1/voice/parse \
-H "Authorization: Bearer $API_KEY" \
-F "audio=@voice.webm" \
-F "schema=restaurant_order"مخططك
١٨ نوع حقل، وقوائم وكائنات متداخلة، مع إصدارات. والاستجابة تتبع شكله.
حقول مُتحقَّق منها
كل قيمة تُفحص في الكود، مع حالة ودرجة ثقة و requiresConfirmation.
الجلسات
اجمع سجلًا واحدًا عبر عدة مدخلات، واسأل فقط عمّا ينقص.
أي لغة، تلقائيًا
الإنجليزية، والعربية الشامية والخليجية، والكلام المختلط — تُكتشف ولا تُضبط.
المراجع التقنية أدناه (رموز الأخطاء والحدود ونقاط الوصول) بالإنجليزية، كما في التوثيق.
المصادقة
أرسل مفتاحك في أيٍّ من الترويستين. تُفحص المفاتيح عندما يُعدّ الخادم بالمتغيّر API_KEYS، والتطوير المحلي يعمل دونها.
Authorization: Bearer YOUR_API_KEYأبقِ المفاتيح على الخادم. على تطبيقات المتصفح استدعاء واجهة الصوت عبر نظامها الخلفي. إدارة المفاتيح ذاتيًا على خريطة الطريق — ولوحة التحكم تعرض الواجهة المخطّط لها.
المخططات
المخطط هو العقد: الحقول التي تريدها وأنواعها. احفظه عبر POST /api/v1/schemas (أو في المحرّر)، ثم سمِّه في الطلبات. الإصدارات لا يتغيّر معناها أبدًا.
{
"name": "restaurant_order",
"version": "1.0",
"description": "Restaurant delivery order",
"locale": "ar-JO",
"fields": {
"customerName": { "type": "person", "label": "Customer name", "required": true },
"phone": {
"type": "phone",
"required": true,
"validation": { "country": "JO" },
"normalization": { "format": "international" }
},
"items": {
"type": "array",
"required": true,
"items": {
"type": "object",
"fields": {
"name": { "type": "string", "required": true },
"quantity": { "type": "integer", "required": true, "min": 1, "default": 1 }
}
}
},
"address": { "type": "address", "required": true },
"notes": { "type": "text" }
}
}الطلب
POST /api/v1/voice/parse بصيغة multipart/form-data (أو POST /api/v1/text/parse بصيغة JSON):
| الحقل | إلزامي | الوصف |
|---|---|---|
audio | نعم | التسجيل: webm, ogg, opus, mp4 / m4a, aac, mp3, wav, flac, aiff |
schema | لا | اسم، أو name@version، أو تعريف مضمّن. الافتراضي delivery_order. |
schemaVersion | لا | يثبّت إصدارًا. |
locale, dialect | لا | تجاوزات اختيارية. الافتراضي auto: تُكتشف اللغة واللهجة من المُدخل. |
sessionId | لا | يضيف المُدخل إلى جلسة. |
context | لا | JSON: referenceTime (للتواريخ النسبية)، والمفردات، ومنطقة الهاتف، والعملة، والحقول الإلزامية. |
الاستجابة
يعود كل حقل بحالة، ودرجة ثقة تحسبها الخدمة، و requiresConfirmation. ويحمل data القيم فقط، بينما يخبر missingFields و fieldsRequiringConfirmation واجهتك بالضبط ماذا تسأل.
الحالات: extracted, uncertain, invalid, rejected, missing, defaulted, confirmed.
{
"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" }
}رقم الهاتف الذي سُمع ناقصًا رقمًا لا يُملأ أبدًا — بل يعود بما سُمع بالضبط:
"phone": {
"value": null,
"type": "phone",
"status": "invalid",
"heard": "078824021",
"confidence": 0.3,
"requiresConfirmation": true,
"reason": "invalid_number_heard"
}الجلسات
ابدأ جلسة، وأرسل كل إجابة مع sessionId الخاص بها، فيُحدَّث السجل بقواعد ثابتة: القيم الجديدة تحلّ محلّ القديمة، والسكوت لا يمحو شيئًا، و missingFields يخبرك بما تسأل عنه بعد ذلك.
# 1. Start a session (pins appointment_booking@1.0)
curl -X POST https://api.example.com/api/v1/sessions -H 'Content-Type: application/json' \
-d '{"schema": "appointment_booking", "context": {"referenceTime": "2026-09-24T10:00:00+03:00"}}'
→ { "sessionId": "ses_Xy…", "missingFields": ["customerName", "phone", "date", "time"], … }
# 2. «بدي أحجز موعد مع الدكتور أحمد»
curl -X POST https://api.example.com/api/v1/voice/parse -F audio=@turn1.webm -F sessionId=ses_Xy…
→ data.doctor = "أحمد", missingFields = ["customerName", "phone", "date", "time"]
# 3. Your app asks «متى الموعد؟» — «بكرا الساعة خمسة المسا»
curl -X POST https://api.example.com/api/v1/voice/parse -F audio=@turn2.webm -F sessionId=ses_Xy…
→ data.doctor = "أحمد" (kept), data.date = "2026-09-25", data.time = "17:00",
changedFields = ["date", "time"], missingFields = ["customerName", "phone"]
# 4. The user confirms or corrects in your UI
curl -X POST https://api.example.com/api/v1/sessions/ses_Xy…/review -H 'Content-Type: application/json' \
-d '{"confirm": ["time"], "set": {"customerName": "سارة", "phone": "0781234567"}}'
→ { "complete": true, "data": { … } }البث المتتابع
أضف ?stream=true لتستلم أحداث NDJSON مع اكتمال كل مرحلة. السطر الأخير هو result أو error.
curl -N -X POST "https://api.example.com/api/v1/voice/parse?stream=true" \
-H "Authorization: Bearer $API_KEY" -F "audio=@voice.webm" -F "schema=restaurant_order"
{"event": "received", "audioSeconds": 6.2}
{"event": "transcribing"}
{"event": "transcribed", "transcription": {"text": "…", "language": "ar", "confidence": 0.9}}
{"event": "extracting"}
{"event": "result", "result": { … }}الأخطاء
غلاف واحد لكل الأخطاء: {"error": {"code", "message", "details"}}.
| الحالة | الرمز | المعنى |
|---|---|---|
| 400 | invalid_context | `context` is not valid JSON, or names unknown fields. |
| 400 | unsupported_locale | An override (`locale` / `dialect`) the service does not know. Leave both out for auto. |
| 401 | unauthorized | Missing or wrong API key (when the server requires one). |
| 403 | read_only_schema | Built-in schemas cannot be overwritten or deleted. |
| 404 | unknown_schema / unknown_session | No such schema or version (details list what exists), or the session expired. |
| 409 | version_exists | That schema version is saved with different content. Save a new version. |
| 409 | session_conflict / session_schema_mismatch / session_turn_limit | Two inputs at once, a different schema than the session's, or too many inputs. |
| 413 | audio_too_large / audio_too_long / text_too_long | Over the size or duration limit. |
| 415 | unsupported_media_type | Not an accepted audio type. |
| 422 | invalid_schema | The schema (saved or inline) is not valid. `details.errors` lists each problem with its path. |
| 422 | invalid_audio / no_speech / invalid_request / invalid_review | Unreadable audio, silence, a malformed request, or a review value of the wrong shape. |
| 429 | rate_limited | Too many requests this minute. |
| 503 | extraction_unavailable | The language model is unavailable. `details.transcription` still carries what was heard. |
| 504 | timeout | Processing exceeded the request timeout. |
الحدود
الإعدادات الافتراضية الحالية للخدمة المستضافة ذاتيًا — وكلها قابلة للتعديل. حدود الخطط المستضافة في صفحة الأسعار.
| الحد | الافتراضي | الإعداد |
|---|---|---|
| Audio size | 25 MB | MAX_AUDIO_SIZE_MB |
| Audio duration | 120 s | MAX_AUDIO_SECONDS — probed before transcription |
| Text input | 4,000 characters | MAX_TEXT_CHARS |
| Request timeout | 180 s | REQUEST_TIMEOUT_SECONDS |
| Concurrency | 1 job at a time (queued) | MAX_CONCURRENT_JOBS — CPU speech recognition |
| Schema size | 60 fields, 3 levels deep | Checked when a schema is saved or sent inline |
| Sessions | 30 min idle, 20 inputs | SESSION_TTL_MINUTES, MAX_SESSION_TURNS — in memory |
| Rate limit | Off by default | RATE_LIMIT_PER_MINUTE per key or IP |
اللغات والمخططات
autoAuto (default)
Language (English, Arabic, mixed) and Arabic dialect detected per input. Nothing to configure.
en · en-US · en-GBEnglish
First-class. en-US / en-GB add US / UK phone formats and currency.
arArabic, dialect detected
Forces Arabic; the dialect is still detected.
ar-JO · ar-PS · ar-LB · ar-SYLevantine: Jordan, Palestine, Lebanon, Syria
Forces the dialect: its phone format is enforced, its currency reported.
ar-SA · ar-AE · ar-KW · ar-QA · ar-BH · ar-OMGulf: Saudi Arabia, UAE, Kuwait, Qatar, Bahrain, Oman
Same, for the Gulf.
ar-IQ · ar-EG · ar-YEExperimental: Iraq, Egypt, Yemen
Registered with phone rules and basic dialect notes; not benchmarked yet.
نقاط الوصول
- POST/api/v1/voice/parseAudio → transcript → your schema, validated. ?stream=true for NDJSON progress. Optional sessionId.
- POST/api/v1/text/parseThe same extraction and validation from text. Optional sessionId.
- GET/api/v1/schemasAll schemas (latest version of each), built-in and saved.
- POST/api/v1/schemasSave a schema version. A saved version never changes (409 on conflicting content).
- POST/api/v1/schemas/validateCheck a schema without saving it; every error with its path.
- GET/api/v1/schemas/{name}One definition (latest, or ?version=).
- GET/api/v1/schemas/{name}/versionsThe versions of a schema.
- DELETE/api/v1/schemas/{name}Delete a saved schema (one ?version=, or all). Built-ins are read-only.
- GET/api/v1/field-typesThe field types and their options.
- POST/api/v1/sessionsStart a session; pins one schema version.
- GET/api/v1/sessions/{id}The session's current record and history.
- POST/api/v1/sessions/{id}/reviewConfirm, reject or set field values.
- DELETE/api/v1/sessions/{id}Forget a session, transcripts included.
- GET/api/v1/localesSupported locales.
- GET/healthLiveness.
- GET/readyReadiness — speech model loaded, language model reachable.
جاهز للبناء؟
يأخذك التوثيق من أول طلب إلى التعامل مع كل حالة حقل في واجهتك.
