اتنقل للمحتوى
طبلةالمطوّرين

مرجع الـ API

كل عمليات Tabla API 1.2.0، متولّدة وقت البناء من نفس العقد اللي الـ API شغّال بيه.

وصف العمليات والخانات جاي من العقد، وهو بالإنجليزي.

Tabla, the multi-tenant notification engine: send messages by template over push, SMS, e-mail, WhatsApp and an in-app inbox; manage recipients, devices and templates; read statuses and usage. Server to server only, with OAuth 2.0 client credentials. Status webhooks (message.sent, message.delivered, message.failed, message.expired) carry Tabla-Signature: t=<unix>,v1=<hex HMAC-SHA256 of "t.body" with the webhook secret>.

الدخول

post/oauth/token

Client credentials: a 10-minute access token for the tenant API

الـ Scope
مفيش: دي اللي بتاخد بيها التوكن
operationId
token

الـ Parameters

الـ parameters بتاعة token
الاسممكانهاالنوعإجباريالوصف
Authorizationheaderstringلأ

جسم الطلب

نوع المحتوى: application/x-www-form-urlencoded

خانات token
الاسمالنوعإجباريالوصف
client_idstringلأ
client_secretstringلأ
grant_typestringلأ
scopestringلأ
مثال
client_id=tc_your_client_id&client_secret=ts_your_client_secret&grant_type=client_credentials&scope=messages%3Asend%20messages%3Aread

الردود

200 OK · */* · object

مثال
{}

الرسايل والاستهلاك

webhooks الحالة (message.sent، message.delivered، message.failed، message.expired) طبلة هي اللي بتبعتها على العنوان اللي بتحطه في لوحة التحكم. صفحة ابدأ من هنا بتوريك شكلها وإزاي تتأكد من توقيعها.

post/v1/messages

Accepts a message for delivery (202); idempotent per key

الـ Scope
messages:send
operationId
sendMessage

محتاجة هيدر Idempotency-Key

الـ Parameters

الـ parameters بتاعة sendMessage
الاسممكانهاالنوعإجباريالوصف
Idempotency-Keyheaderstringلأ
1 to 100 printable characters; the same key and body answer the same message

جسم الطلب

نوع المحتوى: application/json · SendRequest

مثال
{
  "data": {},
  "options": {
    "appId": "app.example.android",
    "channels": [
      "PUSH"
    ],
    "fallback": [
      "PUSH"
    ],
    "link": "app://bookings/42",
    "priority": "HIGH",
    "pushData": {},
    "ttlSeconds": 30
  },
  "recipient": {
    "email": "mona@example.com",
    "id": "user-42",
    "locale": "ar",
    "phone": "+201001234567"
  },
  "template": "booking.confirmed"
}

الردود

200 OK · */* · AcceptedResponse

مثال
{
  "id": "3f6c1a52-8d4e-4b7a-9c2f-5e1d0a9b7c31",
  "status": "ACCEPTED"
}

الأخطاء

Problem details (application/problem+json) ومعاها code ثابت. الأكواد المشهورة متشرحة في الأخطاء، بالعربي والإنجليزي.

أخطاء sendMessage
الحالةالوصفنوع المحتوى
401
Missing, expired or revoked access token
application/problem+jsonProblem
402
Billing refused it: BILLING_CAP_REACHED (the month's spending cap; OTP and transactional get a grace of 10% of it), CREDIT_EXHAUSTED (prepaid credit or the credit limit), or PLAN_VOLUME_EXHAUSTED (a plan without overage)
application/problem+jsonProblem
403
The token lacks the operation's scope
application/problem+jsonProblem
429
The tenant's request budget or quota is spent; see Retry-After
application/problem+jsonProblem
503
BILLING_UNAVAILABLE: bulk can't be checked right now; OTP and transactional still go. Retry shortly
application/problem+jsonProblem

post/v1/messages/batch

Accepts up to 500 messages, all or none (202)

الـ Scope
messages:send
operationId
sendMessages

محتاجة هيدر Idempotency-Key

الـ Parameters

الـ parameters بتاعة sendMessages
الاسممكانهاالنوعإجباريالوصف
Idempotency-Keyheaderstringلأ
For the whole batch; each message takes <key>#<index>

جسم الطلب

نوع المحتوى: application/json · BatchRequest

مثال
{
  "messages": [
    {
      "data": {},
      "options": {
        "appId": "app.example.android",
        "channels": [
          "PUSH"
        ],
        "fallback": [
          "PUSH"
        ],
        "link": "app://bookings/42",
        "priority": "HIGH",
        "pushData": {},
        "ttlSeconds": 30
      },
      "recipient": {
        "email": "mona@example.com",
        "id": "user-42",
        "locale": "ar",
        "phone": "+201001234567"
      },
      "template": "booking.confirmed"
    }
  ]
}

الردود

200 OK · */* · BatchResponse

مثال
{
  "messages": [
    {
      "id": "3f6c1a52-8d4e-4b7a-9c2f-5e1d0a9b7c31",
      "status": "ACCEPTED"
    }
  ]
}

الأخطاء

Problem details (application/problem+json) ومعاها code ثابت. الأكواد المشهورة متشرحة في الأخطاء، بالعربي والإنجليزي.

أخطاء sendMessages
الحالةالوصفنوع المحتوى
401
Missing, expired or revoked access token
application/problem+jsonProblem
402
Billing refused it: BILLING_CAP_REACHED (the month's spending cap; OTP and transactional get a grace of 10% of it), CREDIT_EXHAUSTED (prepaid credit or the credit limit), or PLAN_VOLUME_EXHAUSTED (a plan without overage)
application/problem+jsonProblem
403
The token lacks the operation's scope
application/problem+jsonProblem
429
The tenant's request budget or quota is spent; see Retry-After
application/problem+jsonProblem
503
BILLING_UNAVAILABLE: bulk can't be checked right now; OTP and transactional still go. Retry shortly
application/problem+jsonProblem

get/v1/messages/{messageId}

A message's status, per channel and attempt

الـ Scope
messages:read
operationId
getMessage

الـ Parameters

الـ parameters بتاعة getMessage
الاسممكانهاالنوعإجباريالوصف
messageIdpathstring (uuid)أيوه
Message id

الردود

200 OK · */* · MessageResponse

مثال
{
  "category": "OTP",
  "channels": [
    {
      "channel": "PUSH",
      "leg": 1,
      "status": "string"
    }
  ],
  "createdAt": "2026-10-10T17:00:00Z",
  "expiresAt": "2026-10-10T17:00:00Z",
  "finishedAt": "2026-10-10T17:00:00Z",
  "id": "3f6c1a52-8d4e-4b7a-9c2f-5e1d0a9b7c31",
  "lane": "OTP",
  "legs": [
    {
      "attempts": [
        {
          "address": "string",
          "at": "2026-10-10T17:00:00Z",
          "attempt": 1,
          "channel": "string",
          "error": "string",
          "provider": "string",
          "status": "string",
          "willRetry": true
        }
      ],
      "channels": [
        "PUSH"
      ],
      "current": "PUSH",
      "leg": 1,
      "status": "PENDING"
    }
  ],
  "priority": "HIGH",
  "recipientId": "user-42",
  "status": "ACCEPTED",
  "template": "booking.confirmed"
}

الأخطاء

Problem details (application/problem+json) ومعاها code ثابت. الأكواد المشهورة متشرحة في الأخطاء، بالعربي والإنجليزي.

أخطاء getMessage
الحالةالوصفنوع المحتوى
401
Missing, expired or revoked access token
application/problem+jsonProblem
403
The token lacks the operation's scope
application/problem+jsonProblem
429
The tenant's request budget or quota is spent; see Retry-After
application/problem+jsonProblem

get/v1/usage

Messages providers accepted, per Cairo day and channel (92 days at most)

الـ Scope
messages:read
operationId
getUsage

الـ Parameters

الـ parameters بتاعة getUsage
الاسممكانهاالنوعإجباريالوصف
fromquerystring (date)أيوه
First day, yyyy-MM-dd
toquerystring (date)أيوه
Last day, yyyy-MM-dd

الردود

200 OK · */* · UsageResponse

مثال
{
  "days": [
    {
      "channel": "string",
      "day": "string",
      "sent": 1
    }
  ],
  "from": "string",
  "to": "string"
}

الأخطاء

Problem details (application/problem+json) ومعاها code ثابت. الأكواد المشهورة متشرحة في الأخطاء، بالعربي والإنجليزي.

أخطاء getUsage
الحالةالوصفنوع المحتوى
401
Missing, expired or revoked access token
application/problem+jsonProblem
403
The token lacks the operation's scope
application/problem+jsonProblem
429
The tenant's request budget or quota is spent; see Retry-After
application/problem+jsonProblem

المستلمين وأجهزتهم

get/v1/recipients/{recipientId}

الـ Scope
recipients:read
operationId
getRecipient

الـ Parameters

الـ parameters بتاعة getRecipient
الاسممكانهاالنوعإجباريالوصف
recipientIdpathstringأيوه
The tenant's own user id

الردود

200 OK · */* · RecipientResponse

مثال
{
  "activeDevices": 1,
  "createdAt": "2026-10-10T17:00:00Z",
  "email": "mona@example.com",
  "id": "user-42",
  "locale": "ar",
  "phone": "+201001234567",
  "phoneVerified": true,
  "preferences": {},
  "quietHours": {
    "end": "string",
    "start": "string"
  },
  "timeZone": "string",
  "updatedAt": "2026-10-10T17:00:00Z"
}

الأخطاء

Problem details (application/problem+json) ومعاها code ثابت. الأكواد المشهورة متشرحة في الأخطاء، بالعربي والإنجليزي.

أخطاء getRecipient
الحالةالوصفنوع المحتوى
401
Missing, expired or revoked access token
application/problem+jsonProblem
403
The token lacks the operation's scope
application/problem+jsonProblem
429
The tenant's request budget or quota is spent; see Retry-After
application/problem+jsonProblem

put/v1/recipients/{recipientId}

Creates or replaces a recipient

الـ Scope
recipients:write
operationId
putRecipient

الـ Parameters

الـ parameters بتاعة putRecipient
الاسممكانهاالنوعإجباريالوصف
recipientIdpathstringأيوه
The tenant's own user id

جسم الطلب

نوع المحتوى: application/json · RecipientRequest

مثال
{
  "email": "mona@example.com",
  "locale": "ar",
  "phone": "+201001234567",
  "phoneVerified": true,
  "preferences": {},
  "quietHours": {
    "end": "string",
    "start": "string"
  },
  "timeZone": "string"
}

الردود

200 OK · */* · RecipientResponse

مثال
{
  "activeDevices": 1,
  "createdAt": "2026-10-10T17:00:00Z",
  "email": "mona@example.com",
  "id": "user-42",
  "locale": "ar",
  "phone": "+201001234567",
  "phoneVerified": true,
  "preferences": {},
  "quietHours": {
    "end": "string",
    "start": "string"
  },
  "timeZone": "string",
  "updatedAt": "2026-10-10T17:00:00Z"
}

الأخطاء

Problem details (application/problem+json) ومعاها code ثابت. الأكواد المشهورة متشرحة في الأخطاء، بالعربي والإنجليزي.

أخطاء putRecipient
الحالةالوصفنوع المحتوى
401
Missing, expired or revoked access token
application/problem+jsonProblem
403
The token lacks the operation's scope
application/problem+jsonProblem
429
The tenant's request budget or quota is spent; see Retry-After
application/problem+jsonProblem

post/v1/recipients/{recipientId}/devices

Registers a push token; a token already known for the app moves to this recipient

الـ Scope
recipients:write
operationId
registerDevice

الـ Parameters

الـ parameters بتاعة registerDevice
الاسممكانهاالنوعإجباريالوصف
recipientIdpathstringأيوه
The tenant's own user id

جسم الطلب

نوع المحتوى: application/json · DeviceRequest

مثال
{
  "appId": "app.example.android",
  "platform": "string",
  "token": "fcm-device-token…"
}

الردود

201 Created · */* · DeviceResponse

مثال
{
  "id": "3f6c1a52-8d4e-4b7a-9c2f-5e1d0a9b7c31"
}

الأخطاء

Problem details (application/problem+json) ومعاها code ثابت. الأكواد المشهورة متشرحة في الأخطاء، بالعربي والإنجليزي.

أخطاء registerDevice
الحالةالوصفنوع المحتوى
401
Missing, expired or revoked access token
application/problem+jsonProblem
403
The token lacks the operation's scope
application/problem+jsonProblem
429
The tenant's request budget or quota is spent; see Retry-After
application/problem+jsonProblem

post/v1/recipients/{recipientId}/devices/unregister

Forgets a push token; 204 whether or not it was known

الـ Scope
recipients:write
operationId
unregisterDevice

الـ Parameters

الـ parameters بتاعة unregisterDevice
الاسممكانهاالنوعإجباريالوصف
recipientIdpathstringأيوه
The tenant's own user id

جسم الطلب

نوع المحتوى: application/json · DeviceRemovalRequest

مثال
{
  "appId": "app.example.android",
  "token": "fcm-device-token…"
}

الردود

204 No Content

الأخطاء

Problem details (application/problem+json) ومعاها code ثابت. الأكواد المشهورة متشرحة في الأخطاء، بالعربي والإنجليزي.

أخطاء unregisterDevice
الحالةالوصفنوع المحتوى
401
Missing, expired or revoked access token
application/problem+jsonProblem
403
The token lacks the operation's scope
application/problem+jsonProblem
429
The tenant's request budget or quota is spent; see Retry-After
application/problem+jsonProblem

post/v1/recipients/{recipientId}/erasure

Deletes the recipient, devices and inbox now and redacts their messages (ADR 0008)

الـ Scope
erasure:write
operationId
eraseRecipient

الـ Parameters

الـ parameters بتاعة eraseRecipient
الاسممكانهاالنوعإجباريالوصف
recipientIdpathstringأيوه
The tenant's own user id

الردود

202 Accepted · */* · ErasureResponse

مثال
{
  "erasedAt": "2026-10-10T17:00:00Z",
  "id": "user-42"
}

الأخطاء

Problem details (application/problem+json) ومعاها code ثابت. الأكواد المشهورة متشرحة في الأخطاء، بالعربي والإنجليزي.

أخطاء eraseRecipient
الحالةالوصفنوع المحتوى
401
Missing, expired or revoked access token
application/problem+jsonProblem
403
The token lacks the operation's scope
application/problem+jsonProblem
429
The tenant's request budget or quota is spent; see Retry-After
application/problem+jsonProblem

صندوق الرسايل

get/v1/recipients/{recipientId}/inbox

Newest first, keyset-paged

Items are ordered by createdAt, then id, both descending. Page on with the opaque cursor (the previous page's next), or instead with before and beforeId set to the last item's createdAt and id: the next page is the items after it in that order. before alone gives the items strictly older than that instant. A cursor with before, or beforeId without before, is CURSOR_INVALID.

الـ Scope
inbox:read
operationId
listInbox

الـ Parameters

الـ parameters بتاعة listInbox
الاسممكانهاالنوعإجباريالوصف
recipientIdpathstringأيوه
The tenant's own user id
cursorquerystringلأ
From the previous page's nextmaxLength 200
beforequerystring (date-time)لأ
Instead of cursor: the last item's createdAt (ISO 8601, e.g. 2026-10-05T10:00:00.123Z)
beforeIdquerystring (uuid)لأ
With before: the last item's id
limitqueryinteger (int32)لأ
Page size, 1 to 100min 1 · max 100 · default 20
unreadOnlyquerybooleanلأ
Only unread itemsdefault false

الردود

200 OK · */* · InboxPage

مثال
{
  "items": [
    {
      "body": "See you at 6 PM, Mona.",
      "category": "OTP",
      "createdAt": "2026-10-10T17:00:00Z",
      "id": "3f6c1a52-8d4e-4b7a-9c2f-5e1d0a9b7c31",
      "link": "app://bookings/42",
      "messageId": "3f6c1a52-8d4e-4b7a-9c2f-5e1d0a9b7c31",
      "readAt": "2026-10-10T17:00:00Z",
      "template": "booking.confirmed",
      "title": "Booking confirmed"
    }
  ],
  "next": "string"
}

الأخطاء

Problem details (application/problem+json) ومعاها code ثابت. الأكواد المشهورة متشرحة في الأخطاء، بالعربي والإنجليزي.

أخطاء listInbox
الحالةالوصفنوع المحتوى
401
Missing, expired or revoked access token
application/problem+jsonProblem
403
The token lacks the operation's scope
application/problem+jsonProblem
429
The tenant's request budget or quota is spent; see Retry-After
application/problem+jsonProblem

post/v1/recipients/{recipientId}/inbox/by-message/{messageId}/read

Marks read the item a message made

For a tapped push, which carries the messageId but not the item id. Idempotent: an item already read keeps its readAt. 404 INBOX_ITEM_NOT_FOUND when the recipient has no inbox item for that message.

الـ Scope
inbox:write
operationId
markInboxItemReadByMessage

الـ Parameters

الـ parameters بتاعة markInboxItemReadByMessage
الاسممكانهاالنوعإجباريالوصف
recipientIdpathstringأيوه
The tenant's own user id
messageIdpathstring (uuid)أيوه
Message id, as in the push's messageId

الردود

204 No Content

الأخطاء

Problem details (application/problem+json) ومعاها code ثابت. الأكواد المشهورة متشرحة في الأخطاء، بالعربي والإنجليزي.

أخطاء markInboxItemReadByMessage
الحالةالوصفنوع المحتوى
401
Missing, expired or revoked access token
application/problem+jsonProblem
403
The token lacks the operation's scope
application/problem+jsonProblem
429
The tenant's request budget or quota is spent; see Retry-After
application/problem+jsonProblem

post/v1/recipients/{recipientId}/inbox/read-all

Marks every unread item read

الـ Scope
inbox:write
operationId
markInboxRead

الـ Parameters

الـ parameters بتاعة markInboxRead
الاسممكانهاالنوعإجباريالوصف
recipientIdpathstringأيوه
The tenant's own user id

الردود

200 OK · */* · MarkedRead

مثال
{
  "marked": 1
}

الأخطاء

Problem details (application/problem+json) ومعاها code ثابت. الأكواد المشهورة متشرحة في الأخطاء، بالعربي والإنجليزي.

أخطاء markInboxRead
الحالةالوصفنوع المحتوى
401
Missing, expired or revoked access token
application/problem+jsonProblem
403
The token lacks the operation's scope
application/problem+jsonProblem
429
The tenant's request budget or quota is spent; see Retry-After
application/problem+jsonProblem

get/v1/recipients/{recipientId}/inbox/unread-count

الـ Scope
inbox:read
operationId
countUnreadInbox

الـ Parameters

الـ parameters بتاعة countUnreadInbox
الاسممكانهاالنوعإجباريالوصف
recipientIdpathstringأيوه
The tenant's own user id

الردود

200 OK · */* · UnreadCount

مثال
{
  "unread": 1
}

الأخطاء

Problem details (application/problem+json) ومعاها code ثابت. الأكواد المشهورة متشرحة في الأخطاء، بالعربي والإنجليزي.

أخطاء countUnreadInbox
الحالةالوصفنوع المحتوى
401
Missing, expired or revoked access token
application/problem+jsonProblem
403
The token lacks the operation's scope
application/problem+jsonProblem
429
The tenant's request budget or quota is spent; see Retry-After
application/problem+jsonProblem

post/v1/recipients/{recipientId}/inbox/{itemId}/read

الـ Scope
inbox:write
operationId
markInboxItemRead

الـ Parameters

الـ parameters بتاعة markInboxItemRead
الاسممكانهاالنوعإجباريالوصف
recipientIdpathstringأيوه
The tenant's own user id
itemIdpathstring (uuid)أيوه
Inbox item id

الردود

204 No Content

الأخطاء

Problem details (application/problem+json) ومعاها code ثابت. الأكواد المشهورة متشرحة في الأخطاء، بالعربي والإنجليزي.

أخطاء markInboxItemRead
الحالةالوصفنوع المحتوى
401
Missing, expired or revoked access token
application/problem+jsonProblem
403
The token lacks the operation's scope
application/problem+jsonProblem
429
The tenant's request budget or quota is spent; see Retry-After
application/problem+jsonProblem

القوالب

get/v1/templates

Templates by key, 50 a page by default

الـ Scope
templates:read
operationId
listTemplates

الـ Parameters

الـ parameters بتاعة listTemplates
الاسممكانهاالنوعإجباريالوصف
afterquerystringلأ
The last key of the previous pagemaxLength 100
limitqueryinteger (int32)لأ
Page size, 1 to 200min 1 · max 200 · default 50

الردود

200 OK · */* · TemplatePage

مثال
{
  "items": [
    {
      "category": "OTP",
      "currentVersion": 1,
      "key": "booking.confirmed",
      "updatedAt": "2026-10-10T17:00:00Z"
    }
  ],
  "next": "string"
}

الأخطاء

Problem details (application/problem+json) ومعاها code ثابت. الأكواد المشهورة متشرحة في الأخطاء، بالعربي والإنجليزي.

أخطاء listTemplates
الحالةالوصفنوع المحتوى
401
Missing, expired or revoked access token
application/problem+jsonProblem
403
The token lacks the operation's scope
application/problem+jsonProblem
429
The tenant's request budget or quota is spent; see Retry-After
application/problem+jsonProblem

get/v1/templates/{key}

The current version

الـ Scope
templates:read
operationId
getTemplate

الـ Parameters

الـ parameters بتاعة getTemplate
الاسممكانهاالنوعإجباريالوصف
keypathstringأيوه
Template key

الردود

200 OK · */* · TemplateResponse

مثال
{
  "category": "OTP",
  "content": {},
  "createdAt": "2026-10-10T17:00:00Z",
  "currentVersion": 1,
  "key": "booking.confirmed",
  "variables": [
    "string"
  ],
  "version": 1
}

الأخطاء

Problem details (application/problem+json) ومعاها code ثابت. الأكواد المشهورة متشرحة في الأخطاء، بالعربي والإنجليزي.

أخطاء getTemplate
الحالةالوصفنوع المحتوى
401
Missing, expired or revoked access token
application/problem+jsonProblem
403
The token lacks the operation's scope
application/problem+jsonProblem
429
The tenant's request budget or quota is spent; see Retry-After
application/problem+jsonProblem

put/v1/templates/{key}

Creates the template (201) or, when the content changed, its next version (200)

الـ Scope
templates:write
operationId
putTemplate

الـ Parameters

الـ parameters بتاعة putTemplate
الاسممكانهاالنوعإجباريالوصف
keypathstringأيوه
e.g. booking.confirmed

جسم الطلب

نوع المحتوى: application/json · TemplateRequest

مثال
{
  "category": "OTP",
  "email": {
    "ar": {
      "html": "string",
      "subject": "Your booking is confirmed",
      "text": "Your code is 123456"
    },
    "en": {
      "html": "string",
      "subject": "Your booking is confirmed",
      "text": "Your code is 123456"
    }
  },
  "inbox": {
    "ar": {
      "body": "See you at 6 PM, Mona.",
      "title": "Booking confirmed"
    },
    "en": {
      "body": "See you at 6 PM, Mona.",
      "title": "Booking confirmed"
    }
  },
  "push": {
    "ar": {
      "body": "See you at 6 PM, Mona.",
      "title": "Booking confirmed"
    },
    "en": {
      "body": "See you at 6 PM, Mona.",
      "title": "Booking confirmed"
    }
  },
  "sms": {
    "ar": {
      "text": "Your code is 123456"
    },
    "en": {
      "text": "Your code is 123456"
    }
  },
  "whatsapp": {
    "ar": {
      "language": "ar",
      "name": "booking_confirmed",
      "params": [
        "string"
      ]
    },
    "en": {
      "language": "ar",
      "name": "booking_confirmed",
      "params": [
        "string"
      ]
    }
  }
}

الردود

200 OK · */* · TemplateResponse

مثال
{
  "category": "OTP",
  "content": {},
  "createdAt": "2026-10-10T17:00:00Z",
  "currentVersion": 1,
  "key": "booking.confirmed",
  "variables": [
    "string"
  ],
  "version": 1
}

الأخطاء

Problem details (application/problem+json) ومعاها code ثابت. الأكواد المشهورة متشرحة في الأخطاء، بالعربي والإنجليزي.

أخطاء putTemplate
الحالةالوصفنوع المحتوى
401
Missing, expired or revoked access token
application/problem+jsonProblem
403
The token lacks the operation's scope
application/problem+jsonProblem
429
The tenant's request budget or quota is spent; see Retry-After
application/problem+jsonProblem

get/v1/templates/{key}/versions/{version}

الـ Scope
templates:read
operationId
getTemplateVersion

الـ Parameters

الـ parameters بتاعة getTemplateVersion
الاسممكانهاالنوعإجباريالوصف
keypathstringأيوه
Template key
versionpathinteger (int32)أيوه
Version number

الردود

200 OK · */* · TemplateResponse

مثال
{
  "category": "OTP",
  "content": {},
  "createdAt": "2026-10-10T17:00:00Z",
  "currentVersion": 1,
  "key": "booking.confirmed",
  "variables": [
    "string"
  ],
  "version": 1
}

الأخطاء

Problem details (application/problem+json) ومعاها code ثابت. الأكواد المشهورة متشرحة في الأخطاء، بالعربي والإنجليزي.

أخطاء getTemplateVersion
الحالةالوصفنوع المحتوى
401
Missing, expired or revoked access token
application/problem+jsonProblem
403
The token lacks the operation's scope
application/problem+jsonProblem
429
The tenant's request budget or quota is spent; see Retry-After
application/problem+jsonProblem

الـ Schemas

AcceptedResponse

An accepted message

خانات AcceptedResponse
الاسمالنوعإجباريالوصف
idstring (uuid)لأ
Message id
status"ACCEPTED" | "QUEUED" | "SENT" | "DELIVERED" | "FAILED" | "EXPIRED"لأ
ACCEPTED, or its current status when replayed

AttemptResponse

One attempt on one channel

خانات AttemptResponse
الاسمالنوعإجباريالوصف
addressstringلأ
Masked address
atstring (date-time)لأ
Last change
attemptinteger (int32)لأ
Attempt number on that channel
channelstringلأ
Channel
errorstringلأ
Why it failed or was skipped
providerstringلأ
Provider
statusstringلأ
SENDING, SENT, DELIVERED, FAILED, SKIPPED or EXPIRED
willRetrybooleanلأ
Whether a retry is scheduled

BatchRequest

Up to 500 messages, accepted all or none

خانات BatchRequest
الاسمالنوعإجباريالوصف
messagesarray of SendRequestأيوه
The messagesminItems 1 · maxItems 500

BatchResponse

The accepted messages, in request order

خانات BatchResponse
الاسمالنوعإجباريالوصف
messagesarray of AcceptedResponseلأ
One per message

ChannelState

One channel of one leg

خانات ChannelState
الاسمالنوعإجباريالوصف
channel"PUSH" | "SMS" | "EMAIL" | "WHATSAPP" | "INBOX"لأ
Channel
leginteger (int32)لأ
Leg
statusstringلأ
QUEUED, SENT, DELIVERED, FAILED, SKIPPED or EXPIRED

DeviceRemovalRequest

A push token to forget, e.g. on sign-out

خانات DeviceRemovalRequest
الاسمالنوعإجباريالوصف
appIdstringأيوه
The tenant app's idmaxLength 150
tokenstringأيوه
The FCM registration tokenmaxLength 512

DeviceRequest

A push token the tenant's app reported for this user

خانات DeviceRequest
الاسمالنوعإجباريالوصف
appIdstringأيوه
The tenant app's id, as registered with Tabla for pushmaxLength 150
platformstringأيوه
ANDROID, IOS or WEBminLength 1
tokenstringأيوه
The FCM registration tokenmaxLength 512

DeviceResponse

The registered device

خانات DeviceResponse
الاسمالنوعإجباريالوصف
idstring (uuid)لأ
Tabla's device id

EmailBody

An e-mail: a subject, and HTML, plain text or both

خانات EmailBody
الاسمالنوعإجباريالوصف
htmlstringلأ
HTML partmaxLength 12000
subjectstringأيوه
SubjectmaxLength 200
textstringلأ
Plain-text partmaxLength 12000

EmailLocales

Arabic and English; at least one

خانات EmailLocales
الاسمالنوعإجباريالوصف
arEmailBodyلأ
Egyptian Arabic
enEmailBodyلأ
English

ErasureResponse

The recipient is gone; their messages are redacted shortly after

خانات ErasureResponse
الاسمالنوعإجباريالوصف
erasedAtstring (date-time)لأ
When it was erased
idstringلأ
The tenant's id

InboxItemResponse

An inbox item, rendered in the recipient's language when it arrived

خانات InboxItemResponse
الاسمالنوعإجباريالوصف
bodystringلأ
Body
category"OTP" | "TRANSACTIONAL" | "MARKETING"لأ
Category
createdAtstring (date-time)لأ
When it arrived
idstring (uuid)لأ
Item id
linkstringلأ
What it opens in the app, as the tenant sent it
messageIdstring (uuid)لأ
The message it came from; its push carries the same messageId
readAtstring (date-time)لأ
When it was read; null while unread
templatestringلأ
Template key
titlestringلأ
Title

InboxPage

A page of inbox items, newest first

خانات InboxPage
الاسمالنوعإجباريالوصف
itemsarray of InboxItemResponseلأ
Items
nextstringلأ
Cursor of the next page; null on the last

LegResponse

A fallback chain and what happened on it

خانات LegResponse
الاسمالنوعإجباريالوصف
attemptsarray of AttemptResponseلأ
Every attempt
channelsarray of "PUSH" | "SMS" | "EMAIL" | "WHATSAPP" | "INBOX"لأ
The chain
current"PUSH" | "SMS" | "EMAIL" | "WHATSAPP" | "INBOX"لأ
Where the chain stands
leginteger (int32)لأ
Leg
status"PENDING" | "SENT" | "DELIVERED" | "FAILED" | "SKIPPED" | "EXPIRED"لأ
PENDING, SENT, DELIVERED, FAILED, SKIPPED or EXPIRED

MarkedRead

How many items were marked read

خانات MarkedRead
الاسمالنوعإجباريالوصف
markedinteger (int32)لأ
Items marked read

MessageResponse

A message's status, per channel and per attempt

خانات MessageResponse
الاسمالنوعإجباريالوصف
category"OTP" | "TRANSACTIONAL" | "MARKETING"لأ
Category
channelsarray of ChannelStateلأ
Each channel's state
createdAtstring (date-time)لأ
Accepted at
expiresAtstring (date-time)لأ
Goes out until
finishedAtstring (date-time)لأ
Every leg final at; null until then
idstring (uuid)لأ
Message id
lane"OTP" | "TRANSACTIONAL" | "BULK"لأ
Lane
legsarray of LegResponseلأ
Each leg with its attempts
priority"HIGH" | "NORMAL" | "LOW"لأ
Priority
recipientIdstringلأ
The tenant's recipient id; null for an inline OTP or an erased recipient
status"ACCEPTED" | "QUEUED" | "SENT" | "DELIVERED" | "FAILED" | "EXPIRED"لأ
ACCEPTED, QUEUED, SENT, DELIVERED, FAILED or EXPIRED
templatestringلأ
Template key

Problem

RFC 9457 problem details with a stable code

خانات Problem
الاسمالنوعإجباريالوصف
codeobjectلأ
Stable error code
detailobjectلأ
Localized explanation
statusobjectلأ
HTTP status
titleobjectلأ
Short summary
typeobjectلأ
urn:tabla:problem:<code>

QuietHoursBody

A wall-clock window, may cross midnight, e.g. 22:00 to 08:00

خانات QuietHoursBody
الاسمالنوعإجباريالوصف
endstringأيوه
HH:mmminLength 1
startstringأيوه
HH:mmminLength 1

RecipientRef

A registered recipient by the tenant's id, or for OTP templates only an inline phone or e-mail

خانات RecipientRef
الاسمالنوعإجباريالوصف
emailstringلأ
OTP only: an e-mail addressmaxLength 254
idstringلأ
The tenant's own user idmaxLength 128
localestringلأ
OTP only: ar or en; the tenant's default when absent
phonestringلأ
OTP only: a mobile numbermaxLength 32

RecipientRequest

Everything Tabla keeps about one of the tenant's users; a PUT replaces every field

خانات RecipientRequest
الاسمالنوعإجباريالوصف
emailstringلأ
E-mail addressmaxLength 254
localestringأيوه
ar or en
phonestringلأ
Mobile number; read as Egyptian without a country codemaxLength 32
phoneVerifiedbooleanلأ
Whether the tenant verified the phone; non-OTP SMS and WhatsApp need it
preferencesobjectلأ
Overrides per category (TRANSACTIONAL, MARKETING) and channel
quietHoursQuietHoursBodyلأ
Daily quiet window; none when absent
timeZonestringلأ
IANA zone of the recipient's clock; Africa/Cairo when absentmaxLength 40

RecipientResponse

A recipient; contact data is masked

خانات RecipientResponse
الاسمالنوعإجباريالوصف
activeDevicesinteger (int32)لأ
Push devices still active
createdAtstring (date-time)لأ
First stored
emailstringلأ
Masked e-mail
idstringلأ
The tenant's own id
localestringلأ
ar or en
phonestringلأ
Masked phone
phoneVerifiedbooleanلأ
Whether the tenant verified the phone
preferencesobjectلأ
Effective preferences, defaults included
quietHoursQuietHoursBodyلأ
Quiet window
timeZonestringلأ
IANA zone
updatedAtstring (date-time)لأ
Last replaced

SendOptions

How to deliver. Neither channels nor fallback: auto (inbox plus push, e-mail, WhatsApp, SMS as a fallback chain, over the channels the template has content for)

خانات SendOptions
الاسمالنوعإجباريالوصف
appIdstringلأ
Limit push to one of the tenant's appsmaxLength 150
channelsarray of "PUSH" | "SMS" | "EMAIL" | "WHATSAPP" | "INBOX"لأ
Channels each delivered on its ownminItems 0 · maxItems 5
fallbackarray of "PUSH" | "SMS" | "EMAIL" | "WHATSAPP" | "INBOX"لأ
One fallback chain, tried in order until one takes itminItems 0 · maxItems 5
linkstringلأ
What the push and inbox item open in the appmaxLength 500
priority"HIGH" | "NORMAL" | "LOW"لأ
HIGH, NORMAL (default) or LOW; LOW transactional goes to the bulk lane
pushDataobjectلأ
The tenant's own keys for its app, sent in the push's data payload beside Tabla's messageId, template and link. Flat strings: at most 20 keys matching [a-zA-Z][a-zA-Z0-9_]{0,39}, values up to 256 characters, 2048 bytes (UTF-8) of keys and values in all. Reserved, in any case: messageId, template, link, from, collapse_key, message_type, notification, aps, and keys starting tabla, google or gcm (MESSAGE_PUSH_DATA_RESERVED). Kept with the message, so retries carry it, and redacted with the body after 30 days. Push only: ids and routing keys, never personal data, as it passes through Google and Apple
ttlSecondsinteger (int32)لأ
Seconds the message may still go out; OTP 30 to 1800, others 30 to 604800min 30 · max 604800

SendRequest

One message: who, which template, which data, and how

خانات SendRequest
الاسمالنوعإجباريالوصف
dataobjectلأ
Template variables: strings, numbers (Arabic-Indic digits in Arabic) and booleans
optionsSendOptionsلأ
Channels, fallback, priority, TTL; all optional
recipientRecipientRefأيوه
The recipient
templatestringأيوه
Template key, e.g. booking.confirmedmaxLength 100

SmsBody

An SMS text

خانات SmsBody
الاسمالنوعإجباريالوصف
textstringأيوه
TextmaxLength 1600

SmsLocales

Arabic and English; at least one

خانات SmsLocales
الاسمالنوعإجباريالوصف
arSmsBodyلأ
Egyptian Arabic
enSmsBodyلأ
English

TemplatePage

A page of templates by key

خانات TemplatePage
الاسمالنوعإجباريالوصف
itemsarray of TemplateSummaryلأ
Templates
nextstringلأ
Pass as `after` for the next page; null on the last

TemplateRequest

A template's content: per channel, per locale. Text may use {{variable}} placeholders only

خانات TemplateRequest
الاسمالنوعإجباريالوصف
category"OTP" | "TRANSACTIONAL" | "MARKETING"أيوه
OTP, TRANSACTIONAL or MARKETING; fixed after the first version
emailEmailLocalesلأ
E-mail; html is HTML-escaped per value
inboxTitleBodyLocalesلأ
In-app inbox item
pushTitleBodyLocalesلأ
Push notification
smsSmsLocalesلأ
SMS
whatsappWhatsAppLocalesلأ
A WhatsApp template approved by Meta

TemplateResponse

One version of a template

خانات TemplateResponse
الاسمالنوعإجباريالوصف
category"OTP" | "TRANSACTIONAL" | "MARKETING"لأ
Category
contentobjectلأ
Content per channel and locale
createdAtstring (date-time)لأ
When this version was written
currentVersioninteger (int32)لأ
The template's current version
keystringلأ
Key
variablesarray of stringلأ
Variables a message must supply
versioninteger (int32)لأ
This version's number

TemplateSummary

A template in a list

خانات TemplateSummary
الاسمالنوعإجباريالوصف
category"OTP" | "TRANSACTIONAL" | "MARKETING"لأ
Category
currentVersioninteger (int32)لأ
Current version
keystringلأ
Key
updatedAtstring (date-time)لأ
When the current version was written

TitleBody

A title and a body

خانات TitleBody
الاسمالنوعإجباريالوصف
bodystringأيوه
BodymaxLength 2000
titlestringأيوه
TitlemaxLength 200

TitleBodyLocales

Arabic and English; at least one

خانات TitleBodyLocales
الاسمالنوعإجباريالوصف
arTitleBodyلأ
Egyptian Arabic
enTitleBodyلأ
English

UnreadCount

Unread items

خانات UnreadCount
الاسمالنوعإجباريالوصف
unreadinteger (int64)لأ
How many items are unread

UsageDay

One day and channel

خانات UsageDay
الاسمالنوعإجباريالوصف
channelstringلأ
Channel
daystringلأ
Cairo day
sentinteger (int64)لأ
Accepted by the provider

UsageResponse

Messages providers accepted, per Cairo day and channel

خانات UsageResponse
الاسمالنوعإجباريالوصف
daysarray of UsageDayلأ
Rows
fromstringلأ
First day
tostringلأ
Last day

WhatsAppBody

A Meta-approved template: name, language, and the variables for its body parameters in order

خانات WhatsAppBody
الاسمالنوعإجباريالوصف
languagestringأيوه
Language code at Meta, e.g. ar or en_USmaxLength 10
namestringأيوه
Template name at MetamaxLength 512
paramsarray of stringلأ
Variable names, in parameter orderminItems 0 · maxItems 20

WhatsAppLocales

Arabic and English; at least one

خانات WhatsAppLocales
الاسمالنوعإجباريالوصف
arWhatsAppBodyلأ
Arabic template
enWhatsAppBodyلأ
English template