Read a clinic's patients, appointments and invoices, book and cancel appointments, and receive signed webhooks (appointment.*, invoice.*, claim.*, patient.erased). Money is always integer halalas (1 SAR = 100); ids of clinical rows are ULIDs; times are ISO-8601 in the branch's zone. Errors are JSON {error, message, details}; the message follows Accept-Language (ar or en). Lists answer {data, meta} and page with ?page and ?per_page (at most 100). No diagnoses, clinical notes or photos ever travel through this API.
التنزيلات
الثلاثة مولَّدة من ملف OpenAPI نفسه الذي تُبنى منه هذه الصفحة، فهي تطابق الواجهة الحية دائماً. لا يلزم تسجيل دخول.
استوردها في Postman، وضع رمز عميلك في المتغيّر {{token}} ثم نفّذ أي طلب. «الاشتراك» يحفظ {{webhook_id}} و{{webhook_secret}}؛ ومجلد «توقيع الإشعار» يوقّع إشعاراً تجريبياً ويرسله إلى {{receiver_url}} لتختبر مستقبِلك قبل أي حدث حقيقي.
المصادقة
ينشئ مالك الحساب عميل واجهة من المكتب ← المطوّرون ويختار صلاحياته. يُعرض الرمز مرة واحدة. أرسله مع كل طلب:
يمكن إرسال الرمز أيضاً في الترويسة X-Api-Key. يجيب GET /ping بالعميل وصلاحياته والعيادة؛ استخدمه كطلب «اختبار الاتصال».
الصلاحيات
تحتاج كل نقطة إلى صلاحية واحدة؛ الطلب بدونها يجيب 403 insufficient_ability مع details.required_ability. صلاحية webhooks تدير الاشتراكات فقط: لاستقبال حدث أو استعراض عناصره الأخيرة يحتاج العميل أيضاً إلى الصلاحية التي تقرأ تلك البيانات.
الصلاحية
النقاط
any
GET /ping · GET /meta
patients:read
GET /patients · GET /patients/{id}
appointments:read
GET /appointments · GET /appointments/{id}
appointments:write
POST /appointments · POST /appointments/{id}/cancel
invoices:read
GET /invoices · GET /invoices/{id}
webhooks
GET /webhooks · POST /webhooks · GET /webhooks/events · GET /webhooks/events/{event}/recent · GET /webhooks/{id} · PUT /webhooks/{id} · DELETE /webhooks/{id} · POST /webhooks/{id}/rotate · POST /webhooks/{id}/test
حدّ الطلبات
120 طلباً في الدقيقة لكل عميل واجهة. يحمل الجواب 429 الترويسة Retry-After، ويحمل كل جواب X-RateLimit-Limit وX-RateLimit-Remaining.
الطلبات التي لا يطابق رمزها عميلاً نشطاً تتقاسم حدّاً واحداً لكل عنوان: 30 في الدقيقة. الخطة التي لا تشمل واجهة الشركاء تجيب 403 not_entitled.
الأخطاء
كل خطأ JSON بالشكل {error, message, details}؛ الرسالة بحسب Accept-Language (ar أو en). المبالغ دائماً هللات صحيحة (1 ريال = 100).
رمز الواجهة مفقود. أرسله في الترويسة "Authorization: Bearer bmc_…".
token_invalid
401
رمز الواجهة غير صالح أو أُلغي.
tenant_inactive
403
حساب هذه العيادة موقوف أو مغلق.
not_entitled
403
خطة هذا الحساب لا تشمل واجهة الشركاء.
insufficient_ability
403
عميل الواجهة لا يملك الصلاحية التي يحتاجها هذا الطلب.
forbidden
403
إدارة عملاء الواجهة والإشعارات لمالك الحساب فقط.
not_found
404
غير موجود.
client_revoked
409
أُلغي عميل الواجهة هذا.
webhook_disabled
409
هذا الاشتراك متوقف.
delivery_sent
409
وصل هذا الإشعار بنجاح من قبل.
payload_redacted
409
حُذف محتوى هذا الإرسال (مدة الاحتفاظ أو محو بيانات مريض)، ولا يمكن إرساله مجدداً.
validation_failed
422
بعض الحقول غير صحيحة.
event_unknown
422
حدث غير معروف.
url_not_allowed
422
هذا الرابط لا يقبل الإشعارات (HTTPS على عنوان عام فقط).
webhook_limit
422
عدد الاشتراكات كبير.
rate_limited
429
طلبات كثيرة. حاول بعد قليل.
not_implemented
501
هذه النقطة موثّقة ولم تُتَح بعد؛ ستجيب عند صدور حزمتها.
قريباً
النقاط الموسومة «قريباً» موثّقة بالكامل هنا وتُفرض صلاحياتها، لكنها تجيب 501 not_implemented حتى تصدر حزمتها (المرضى، المواعيد، الفواتير). ابنِ تكاملك على هذا الملف؛ الأشكال ثابتة.
حجز الموعد POST /appointments متكرر-آمن عبر external_ref لكل عميل واجهة: إرسال الحجز نفسه ثانيةً يجيب 200 بالموعد نفسه، لا حجزاً ثانياً. إلغاء موعد مرتين لا يغيّر شيئاً. عند انتهاء المهلة اقرأ قبل أن تعيد المحاولة. قد يصل الإشعار الواحد أكثر من مرة: تجاهل المكرر عبر X-Basmtak-Event-Id (الحقل id في الجسم).
الإشعارات (REST hooks)
اشترك عبر POST /webhooks {target_url, event} وألغِ الاشتراك عبر DELETE /webhooks/{id} — نمط REST hook في Zapier وMake. كل إرسال هو POST بالجسم {id, event, tenant_id, occurred_at, api_version, data}، يُعاد بتراجع أُسّي؛ 20 إخفاقاً متتالياً (أو جواب 410) يوقف الاشتراك. لا تحمل الإشعارات تشخيصاً ولا ملاحظات سريرية ولا صوراً أبداً.
شكل الإرسال
طلب POST بالترويسة Content-Type: application/json والجسم {id, event, tenant_id, occurred_at, api_version, data}؛ لـ data الشكل نفسه الذي تعيده الواجهة لذلك الكائن. الترويسات: X-Basmtak-Event وX-Basmtak-Event-Id وX-Basmtak-Delivery وX-Basmtak-Timestamp وX-Basmtak-Signature.
بهذه المدخلات يجب أن ينتج كودك هذا التوقيع بالضبط (محسوب حيّاً بالكود نفسه الذي يوقّع الإرسالات الحقيقية). استخدم السر كما استلمته بما فيه whsec_، وبايتات الجسم الخام قبل أي تحليل JSON.
أي جواب 2xx خلال 10 ثانية نجاح. غير ذلك (حالة أخرى، مهلة، عنوان مرفوض) يُعاد بعد 60 ثانية مضاعفةً كل مرة حتى 6 ساعات؛ بعد 10 محاولة يُترك الإرسال. 20 محاولة فاشلة متتالية توقف الاشتراك، وجواب 410 Gone يوقفه فوراً (طريقة REST hook لإلغاء الاشتراك). يُحفظ رمز الحالة فقط، ولا يُحفظ جسم جوابك أبداً.
يجب أن يكون رابط الإشعار HTTPS على عنوان عام (hooks.zapier.com وhook.*.make.com كذلك). السيناريو الذي يحتاج إجراءات فقط (حجز موعد، إلغاؤه) أو بحثاً (مريض بالرقم أو الهاتف، فاتورة) يستدعي النقاط أدناه مباشرة.
النقاط
meta Connectivity and what this server offers
GET/pingCheck the token and see the client's abilitiesالصلاحية: any
الأجوبة
200
The client, its abilities and the clinic
401
{error, message, details}
Error
GET/metaAbilities, the event catalogue, rate limits and the spec versionالصلاحية: any
POST/appointmentsBook an appointmentالصلاحية: appointments:write
Books a free slot (GET the clinic's slots through the portal rules the SCHEDULING package publishes). external_ref makes the call idempotent per API client: the same external_ref answers 200 with the same appointment, never a second booking. The patient is named by id or by phone (a new patient file is opened when the phone is unknown).
The answer carries the subscription id and its signing secret. The secret is shown only here. The client must hold the ability that reads each event's data (appointments:read, invoices:read, patients:read).
GET/webhooks/eventsThe events, each with the ability it needs and sample dataالصلاحية: webhooks
الأجوبة
200
{data: [{event, ability, sample}]}
GET/webhooks/events/{event}/recentRecent real objects of one event (REST hook perform list)الصلاحية: webhooks
The newest real objects of one event, each wrapped in the envelope a delivery carries {id, event, tenant_id, occurred_at, api_version, data}, newest first. Zapier calls this as the REST Hook trigger's perform list when a user tests a Zap; Make uses it to fetch sample data. id is event:object-id (stable, for de-duplication), not the uuid of a live delivery. Besides webhooks the client needs the ability that receives the event. meta.sample is the static sample, for a clinic with no data yet; data is empty until the event's package publishes its recent objects.