{
  "openapi": "3.1.0",
  "info": {
    "title": "Mursilat Public API",
    "description": "Send every message type a linked number can send — text, image, video (GIF / round video note), audio, voice note, document, sticker, location, contact cards, poll, event (experimental), reply buttons, lists and link buttons — with one endpoint (POST /whatsapp/public/messages), react to / edit / delete messages, and receive replies, poll votes and receipts by webhook. Authenticate with the x-api-key of the number. Every send needs an Idempotency-Key header. message/send, media/send and interactive/send are legacy (still supported, unchanged). Buttons on linked-device numbers may show as plain text on some phones; the numbered fallback means the customer can always answer, and replies arrive as interactive.reply either way. Docs: https://mursilat.com/developers",
    "version": "2026-10",
    "contact": {}
  },
  "servers": [
    {
      "url": "https://mursilat.com"
    }
  ],
  "tags": [
    {
      "name": "Public API",
      "description": "x-api-key endpoints"
    }
  ],
  "paths": {
    "/api/v1/whatsapp/public/messages": {
      "post": {
        "description": "One endpoint for every type a linked number can send: text, image, video (GIF / round video note), audio, voice note, document, sticker, location, contact cards, poll, event (experimental), reply buttons, list, link button. JSON, or multipart/form-data with a `file` for media types. Types that a linked device cannot send (live location, payments, catalog/orders, status, calls, templates) return 400 MESSAGE_TYPE_NOT_SUPPORTED with the reason.",
        "operationId": "PublicMessagesController_send",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Unique key for safe retries (same key + same body returns the same response)",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-api-key",
            "in": "header",
            "description": "Number API key (scope `send`; media types also `media`)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UnifiedSendRequest"
              },
              "examples": {
                "text": {
                  "summary": "Text (with link preview)",
                  "value": {
                    "to": "201001234567",
                    "type": "text",
                    "text": "طلبك اتشحن 🚚 *شكرًا*\nتتبع: https://example.com/t/1042",
                    "reference": "order-1042"
                  }
                },
                "image_url": {
                  "summary": "Image by URL",
                  "value": {
                    "to": "201001234567",
                    "type": "image",
                    "media": {
                      "url": "https://example.com/catalog.jpg"
                    },
                    "caption": "الكتالوج الجديد"
                  }
                },
                "video_note": {
                  "summary": "Round video note (uploaded media id)",
                  "value": {
                    "to": "201001234567",
                    "type": "video",
                    "media": {
                      "id": "med_8f2c1d9a7b3e4f56a1b2c3d4"
                    },
                    "videoNote": true
                  }
                },
                "voice": {
                  "summary": "Voice note",
                  "value": {
                    "to": "201001234567",
                    "type": "voice",
                    "media": {
                      "id": "med_0a1b2c3d4e5f60718293a4b5"
                    }
                  }
                },
                "document": {
                  "summary": "Document by URL",
                  "value": {
                    "to": "201001234567",
                    "type": "document",
                    "media": {
                      "url": "https://example.com/invoice-1042.pdf"
                    },
                    "fileName": "فاتورة 1042.pdf",
                    "caption": "فاتورتك"
                  }
                },
                "sticker": {
                  "summary": "Sticker (PNG converted to WebP)",
                  "value": {
                    "to": "201001234567",
                    "type": "sticker",
                    "media": {
                      "url": "https://example.com/thanks.png"
                    }
                  }
                },
                "location": {
                  "summary": "Location pin",
                  "value": {
                    "to": "201001234567",
                    "type": "location",
                    "latitude": 30.0444,
                    "longitude": 31.2357,
                    "name": "فرع وسط البلد",
                    "address": "12 شارع طلعت حرب، القاهرة"
                  }
                },
                "contact": {
                  "summary": "Contact card",
                  "value": {
                    "to": "201001234567",
                    "type": "contact",
                    "contacts": [
                      {
                        "name": "خدمة العملاء",
                        "phones": [
                          "+201001234567"
                        ],
                        "email": "support@example.com",
                        "organization": "متجر النور"
                      }
                    ]
                  }
                },
                "poll": {
                  "summary": "Poll (votes → poll.vote webhook)",
                  "value": {
                    "to": "201001234567",
                    "type": "poll",
                    "name": "أنسب يوم للتوصيل؟",
                    "options": [
                      "الأحد",
                      "الاثنين",
                      "الثلاثاء"
                    ],
                    "selectableCount": 1,
                    "reference": "survey-7"
                  }
                },
                "event": {
                  "summary": "Event (experimental, often group-only)",
                  "value": {
                    "to": "201001234567",
                    "type": "event",
                    "name": "افتتاح الفرع",
                    "startAt": "2026-11-01T17:00:00.000Z",
                    "endAt": "2026-11-01T20:00:00.000Z",
                    "locationName": "فرع وسط البلد"
                  }
                },
                "buttons": {
                  "summary": "Reply buttons (numbered fallback)",
                  "value": {
                    "to": "201001234567",
                    "type": "buttons",
                    "body": {
                      "text": "هل تؤكد طلبك؟"
                    },
                    "footer": {
                      "text": "متجر النور"
                    },
                    "buttons": [
                      {
                        "id": "confirm",
                        "title": "تأكيد"
                      },
                      {
                        "id": "cancel_order",
                        "title": "إلغاء الطلب"
                      }
                    ],
                    "fallback": "numbered",
                    "reference": "order-1042"
                  }
                },
                "list": {
                  "summary": "List",
                  "value": {
                    "to": "201001234567",
                    "type": "list",
                    "body": {
                      "text": "اختار الخدمة"
                    },
                    "list": {
                      "buttonText": "اختار",
                      "sections": [
                        {
                          "title": "الخدمات",
                          "rows": [
                            {
                              "id": "prices",
                              "title": "الأسعار",
                              "description": "اعرف أسعارنا"
                            }
                          ]
                        }
                      ]
                    }
                  }
                },
                "cta_url": {
                  "summary": "Link button",
                  "value": {
                    "to": "201001234567",
                    "type": "cta_url",
                    "body": {
                      "text": "شحنتك في الطريق"
                    },
                    "cta": {
                      "title": "تتبع الشحنة",
                      "url": "https://example.com/track/1042"
                    }
                  }
                }
              }
            },
            "multipart/form-data": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/UnifiedSendRequest"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "file": {
                        "type": "string",
                        "format": "binary",
                        "description": "Media types only, instead of `media`. Objects / arrays (contacts, options, body, buttons, list, cta…) as JSON strings; booleans / numbers as strings."
                      }
                    }
                  }
                ]
              },
              "example": {
                "to": "201001234567",
                "type": "document",
                "caption": "فاتورتك",
                "file": "(binary) invoice-1042.pdf"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnifiedSendResponse"
                }
              }
            }
          },
          "400": {
            "description": "MESSAGE_* / INTERACTIVE_* validation codes, INVALID_RECIPIENT, SESSION_NOT_CONNECTED"
          },
          "401": {
            "description": "API_KEY_REQUIRED / API_KEY_INVALID"
          },
          "403": {
            "description": "API_ACCESS_NOT_IN_PLAN / API_SCOPE_DISABLED / quota / SAFETY_*"
          },
          "404": {
            "description": "MESSAGE_MEDIA_NOT_FOUND / MESSAGE_REPLY_TARGET_NOT_FOUND"
          },
          "409": {
            "description": "IDEMPOTENCY_*"
          },
          "413": {
            "description": "MESSAGE_MEDIA_TOO_LARGE"
          },
          "415": {
            "description": "MESSAGE_MEDIA_TYPE_NOT_ALLOWED"
          },
          "422": {
            "description": "MESSAGE_MEDIA_FETCH_FAILED / MESSAGE_STICKER_INVALID / SAFETY_CONTENT_BLOCKED"
          },
          "429": {
            "description": "Rate limit / API_TEMPORARY_BAN / SAFETY_* caps"
          }
        },
        "security": [
          {
            "x-api-key": []
          }
        ],
        "summary": "Send any message type (unified endpoint)",
        "tags": [
          "Public API"
        ]
      }
    },
    "/api/v1/whatsapp/public/media/upload": {
      "post": {
        "description": "Stores a file privately for 24 hours and returns a `mediaId` to use as `media: { \"id\": … }` in POST /whatsapp/public/messages (scope `media`). Idempotency-Key is optional here.",
        "operationId": "PublicMessagesController_uploadMedia",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Unique key for safe retries (same key + same body returns the same response)",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-api-key",
            "in": "header",
            "description": "Number API key (scope `media`)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MediaUploadResponse"
                }
              }
            }
          },
          "413": {
            "description": "MESSAGE_MEDIA_TOO_LARGE (100 MB)"
          }
        },
        "security": [
          {
            "x-api-key": []
          }
        ],
        "summary": "Upload media for a later send",
        "tags": [
          "Public API"
        ]
      }
    },
    "/api/v1/whatsapp/public/messages/{messageId}/react": {
      "post": {
        "operationId": "PublicMessagesController_react",
        "parameters": [
          {
            "name": "messageId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Unique key for safe retries (same key + same body returns the same response)",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-api-key",
            "in": "header",
            "description": "Number API key (scope `send`; media types also `media`)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReactRequest"
              },
              "example": {
                "emoji": "👍"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageActionResponse"
                }
              }
            }
          },
          "400": {
            "description": "MESSAGE_REACTION_INVALID"
          },
          "404": {
            "description": "MESSAGE_NOT_FOUND"
          },
          "409": {
            "description": "MESSAGE_NOT_EDITABLE (deleted / unsent) / SESSION_NOT_CONNECTED"
          }
        },
        "security": [
          {
            "x-api-key": []
          }
        ],
        "summary": "React to a message (emoji, \"\" removes)",
        "tags": [
          "Public API"
        ]
      }
    },
    "/api/v1/whatsapp/public/messages/{messageId}/edit": {
      "post": {
        "operationId": "PublicMessagesController_edit",
        "parameters": [
          {
            "name": "messageId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Unique key for safe retries (same key + same body returns the same response)",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-api-key",
            "in": "header",
            "description": "Number API key (scope `send`; media types also `media`)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EditRequest"
              },
              "example": {
                "text": "الموعد اتغير لـ 5 مساءً"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageActionResponse"
                }
              }
            }
          },
          "403": {
            "description": "MESSAGE_NOT_EDITABLE (campaign / auto-reply / AI / OTP messages)"
          },
          "404": {
            "description": "MESSAGE_NOT_FOUND"
          },
          "409": {
            "description": "MESSAGE_NOT_EDITABLE / MESSAGE_EDIT_WINDOW_PASSED / SESSION_NOT_CONNECTED"
          }
        },
        "security": [
          {
            "x-api-key": []
          }
        ],
        "summary": "Edit a sent text message (within 15 minutes)",
        "tags": [
          "Public API"
        ]
      }
    },
    "/api/v1/whatsapp/public/messages/{messageId}/delete": {
      "post": {
        "operationId": "PublicMessagesController_remove",
        "parameters": [
          {
            "name": "messageId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Unique key for safe retries (same key + same body returns the same response)",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-api-key",
            "in": "header",
            "description": "Number API key (scope `send`; media types also `media`)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeleteRequest"
              },
              "example": {
                "forEveryone": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageActionResponse"
                }
              }
            }
          },
          "404": {
            "description": "MESSAGE_NOT_FOUND"
          },
          "409": {
            "description": "MESSAGE_NOT_DELETABLE / MESSAGE_DELETE_WINDOW_PASSED / SESSION_NOT_CONNECTED"
          }
        },
        "security": [
          {
            "x-api-key": []
          }
        ],
        "summary": "Delete a message (for everyone ≤48 h, or for me)",
        "tags": [
          "Public API"
        ]
      }
    },
    "/api/v1/whatsapp/public/interactions/{interactionId}": {
      "get": {
        "description": "Poll alternative to the interactive.reply webhook.",
        "operationId": "InteractivePublicController_get",
        "parameters": [
          {
            "name": "interactionId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-api-key",
            "in": "header",
            "description": "Number API key (scope `send`)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InteractionResponse"
                }
              }
            }
          },
          "404": {
            "description": "INTERACTION_NOT_FOUND"
          }
        },
        "security": [
          {
            "x-api-key": []
          }
        ],
        "summary": "Interaction status and answer",
        "tags": [
          "Public API"
        ]
      }
    },
    "/api/v1/whatsapp/public/media/{mediaId}": {
      "get": {
        "description": "Use the signed `media.url` from a webhook (valid 24 hours) as is, or call with the media id and your x-api-key (scope `media`).",
        "operationId": "PublicMediaController_download",
        "parameters": [
          {
            "name": "mediaId",
            "required": true,
            "in": "path",
            "description": "`data.media.id` from message.received",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-api-key",
            "in": "header",
            "description": "Alternative to exp/sig",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sig",
            "required": false,
            "in": "query",
            "description": "Signed link signature",
            "schema": {}
          },
          {
            "name": "exp",
            "required": false,
            "in": "query",
            "description": "Signed link expiry (unix seconds)",
            "schema": {}
          }
        ],
        "responses": {
          "200": {
            "description": "The file (Content-Type of the media)"
          },
          "401": {
            "description": "MEDIA_LINK_INVALID / missing key"
          },
          "404": {
            "description": "MEDIA_NOT_FOUND / INBOX_MEDIA_UNAVAILABLE"
          },
          "410": {
            "description": "MEDIA_LINK_EXPIRED"
          }
        },
        "security": [
          {
            "x-api-key": []
          }
        ],
        "summary": "Download inbound media",
        "tags": [
          "Public API"
        ]
      }
    },
    "/api/v1/whatsapp/public/message/send": {
      "post": {
        "description": "Legacy — still supported, unchanged. New integrations: POST /whatsapp/public/messages. Sends a text message using the session linked to x-api-key. Message usage is deducted from the session package quota (or allowed for unlimited packages).",
        "operationId": "WhatsAppPublicController_sendMessage",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Unique key for safe retries. Same key + same payload returns the same response.",
            "required": true,
            "schema": {
              "type": "string",
              "example": "send-20260208-001"
            }
          },
          {
            "name": "x-api-key",
            "in": "header",
            "description": "Session API key (from WhatsApp session details)",
            "required": true,
            "schema": {
              "type": "string",
              "example": "wa_live_1234567890abcdef"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendMessageDto"
              },
              "example": {
                "phoneNumber": "201001234567",
                "content": "طلبك اتشحن 🚚",
                "reference": "order-1042-shipped"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Message sent successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SendMessageResponseDto"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid x-api-key header"
          },
          "403": {
            "description": "No active package or message quota exceeded"
          },
          "409": {
            "description": "Idempotency conflict (reused key with different payload or request still in progress)"
          },
          "429": {
            "description": "Public API key/session rate limit exceeded"
          }
        },
        "security": [
          {
            "x-api-key": []
          }
        ],
        "summary": "Send a text message (legacy)",
        "tags": [
          "Public API"
        ]
      }
    },
    "/api/v1/whatsapp/public/media/send": {
      "post": {
        "description": "Legacy — still supported, unchanged. New integrations: POST /whatsapp/public/messages. Sends media using the session linked to x-api-key. Supports multipart file upload or mediaUrl.",
        "operationId": "WhatsAppPublicController_sendMedia",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Unique key for safe retries. Same key + same payload returns the same response.",
            "required": true,
            "schema": {
              "type": "string",
              "example": "media-20260208-001"
            }
          },
          {
            "name": "x-api-key",
            "in": "header",
            "description": "Session API key (from WhatsApp session details)",
            "required": true,
            "schema": {
              "type": "string",
              "example": "wa_live_1234567890abcdef"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "phoneNumber": {
                    "type": "string",
                    "example": "201234567890"
                  },
                  "mediaType": {
                    "type": "string",
                    "enum": [
                      "image",
                      "video",
                      "document",
                      "audio"
                    ],
                    "example": "image"
                  },
                  "mediaUrl": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uri",
                    "example": "https://example.com/image.jpg"
                  },
                  "file": {
                    "type": "string",
                    "format": "binary"
                  },
                  "caption": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "filename": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "voiceNote": {
                    "type": [
                      "boolean",
                      "null"
                    ]
                  },
                  "reference": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 128,
                    "description": "Your own id, echoed in message.status webhooks"
                  }
                },
                "required": [
                  "phoneNumber",
                  "mediaType"
                ]
              },
              "example": {
                "phoneNumber": "201001234567",
                "mediaType": "image",
                "mediaUrl": "https://example.com/invoice.jpg",
                "caption": "فاتورتك",
                "reference": "invoice-77"
              }
            },
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "phoneNumber": {
                    "type": "string",
                    "example": "201234567890"
                  },
                  "mediaType": {
                    "type": "string",
                    "enum": [
                      "image",
                      "video",
                      "document",
                      "audio"
                    ],
                    "example": "image"
                  },
                  "mediaUrl": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uri",
                    "example": "https://example.com/image.jpg"
                  },
                  "file": {
                    "type": "string",
                    "format": "binary"
                  },
                  "caption": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "filename": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "voiceNote": {
                    "type": [
                      "boolean",
                      "null"
                    ]
                  },
                  "reference": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 128,
                    "description": "Your own id, echoed in message.status webhooks"
                  }
                },
                "required": [
                  "phoneNumber",
                  "mediaType"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Media sent successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SendMediaResponseDto"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid x-api-key header"
          },
          "403": {
            "description": "No active package or message quota exceeded"
          },
          "409": {
            "description": "Idempotency conflict (reused key with different payload or request still in progress)"
          },
          "429": {
            "description": "Public API key/session rate limit exceeded"
          }
        },
        "security": [
          {
            "x-api-key": []
          }
        ],
        "summary": "Send media (image, video, document, audio) (legacy)",
        "tags": [
          "Public API"
        ]
      }
    },
    "/api/v1/whatsapp/public/interactive/send": {
      "post": {
        "description": "Legacy — still supported, unchanged. New integrations: POST /whatsapp/public/messages. Linked-device numbers: buttons may show as plain text on some phones. With `fallback: \"numbered\"` (default) the options are also listed as numbered text, so the customer can always answer by tapping, typing the number or the title. Replies arrive as `interactive.reply` webhooks.",
        "operationId": "InteractivePublicController_send",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Unique key for safe retries (same key + same body returns the same response)",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-api-key",
            "in": "header",
            "description": "Number API key (scope `send`)",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InteractiveSendRequest"
              },
              "example": {
                "to": "201001234567",
                "type": "buttons",
                "header": {
                  "text": "طلبك #1042"
                },
                "body": {
                  "text": "هل تؤكد طلبك؟"
                },
                "footer": {
                  "text": "متجر النور"
                },
                "buttons": [
                  {
                    "id": "confirm",
                    "title": "تأكيد"
                  },
                  {
                    "id": "cancel_order",
                    "title": "إلغاء الطلب"
                  }
                ],
                "reference": "order-1042"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InteractiveSendResponse"
                }
              }
            }
          },
          "400": {
            "description": "INTERACTIVE_* validation codes, INVALID_RECIPIENT"
          },
          "401": {
            "description": "API_KEY_REQUIRED / API_KEY_INVALID"
          },
          "403": {
            "description": "API_ACCESS_NOT_IN_PLAN / API_SCOPE_DISABLED / quota / SAFETY_*"
          },
          "409": {
            "description": "IDEMPOTENCY_* / SESSION_NOT_CONNECTED"
          },
          "429": {
            "description": "Rate limit / API_TEMPORARY_BAN / SAFETY_* caps"
          }
        },
        "security": [
          {
            "x-api-key": []
          }
        ],
        "summary": "Send an interactive message (buttons, list or link button) (legacy)",
        "tags": [
          "Public API"
        ]
      }
    }
  },
  "webhooks": {
    "message.received": {
      "post": {
        "summary": "message.received event",
        "description": "Sent to your webhook URL (v2). Answer 2xx within 10 s. 410 disables the webhook; other failures are retried after 10s, 1m, 5m, 15m and 30m.",
        "parameters": [
          {
            "in": "header",
            "required": true,
            "name": "X-Wasla-Signature",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256(secret, \"<t>.<raw body>\")>"
          },
          {
            "in": "header",
            "required": true,
            "name": "X-Wasla-Event",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "required": true,
            "name": "X-Wasla-Delivery",
            "schema": {
              "type": "string"
            },
            "description": "Same for every retry of one delivery"
          },
          {
            "in": "header",
            "required": true,
            "name": "X-Wasla-Webhook-Version",
            "schema": {
              "type": "string",
              "const": "2"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "id",
                  "type",
                  "apiVersion",
                  "createdAt",
                  "sessionId",
                  "number",
                  "data"
                ],
                "properties": {
                  "id": {
                    "type": "string",
                    "example": "evt_5f0c2b7d9e1a4c3b8a6f2d10",
                    "description": "Unique event id — dedupe on it"
                  },
                  "type": {
                    "type": "string",
                    "const": "message.received"
                  },
                  "apiVersion": {
                    "type": "string",
                    "const": "2026-10"
                  },
                  "createdAt": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "sessionId": {
                    "type": "string"
                  },
                  "number": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Your WhatsApp number (digits)"
                  },
                  "data": {
                    "type": "object",
                    "properties": {
                      "messageId": {
                        "type": "string"
                      },
                      "from": {
                        "type": "object",
                        "properties": {
                          "phone": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "example": "201099887766"
                          },
                          "lid": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "WhatsApp privacy id when the phone is hidden"
                          },
                          "name": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "example": "منى"
                          }
                        }
                      },
                      "chat": {
                        "type": "object",
                        "properties": {
                          "type": {
                            "enum": [
                              "direct",
                              "group"
                            ]
                          },
                          "groupId": {
                            "type": "string"
                          },
                          "groupName": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        }
                      },
                      "type": {
                        "enum": [
                          "text",
                          "image",
                          "video",
                          "audio",
                          "voice",
                          "document",
                          "sticker",
                          "location",
                          "contact",
                          "reaction",
                          "interactive_reply",
                          "unsupported"
                        ]
                      },
                      "text": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "caption": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "media": {
                        "type": [
                          "object",
                          "null"
                        ],
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "mimeType": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "size": {
                            "type": [
                              "integer",
                              "null"
                            ]
                          },
                          "fileName": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "url": {
                            "type": "string",
                            "description": "Signed download link, valid 24 hours"
                          }
                        }
                      },
                      "location": {
                        "type": [
                          "object",
                          "null"
                        ],
                        "properties": {
                          "lat": {
                            "type": "number"
                          },
                          "lng": {
                            "type": "number"
                          },
                          "name": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "address": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        }
                      },
                      "replyTo": {
                        "type": [
                          "object",
                          "null"
                        ],
                        "properties": {
                          "messageId": {
                            "type": "string"
                          }
                        }
                      },
                      "timestamp": {
                        "type": "string",
                        "format": "date-time"
                      }
                    }
                  }
                },
                "example": {
                  "id": "evt_5f0c2b7d9e1a4c3b8a6f2d10",
                  "type": "message.received",
                  "apiVersion": "2026-10",
                  "createdAt": "2026-10-10T12:00:03.000Z",
                  "sessionId": "cm1abcd2345efgh6789ijkl",
                  "number": "201100302759",
                  "data": {
                    "messageId": "3EB0C1D2E3F4A5B6C7D8",
                    "from": {
                      "phone": "201099887766",
                      "lid": null,
                      "name": "منى"
                    },
                    "chat": {
                      "type": "direct"
                    },
                    "type": "image",
                    "text": null,
                    "caption": "صورة الفاتورة",
                    "media": {
                      "id": "cm2media0001",
                      "mimeType": "image/jpeg",
                      "size": 48213,
                      "url": "https://mursilat.com/api/v1/whatsapp/public/media/cm2media0001?exp=1760184000&sig=…"
                    },
                    "location": null,
                    "replyTo": null,
                    "timestamp": "2026-10-10T12:00:02.000Z"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Received"
          },
          "410": {
            "description": "Stop sending (webhook disabled)"
          }
        }
      }
    },
    "message.status": {
      "post": {
        "summary": "message.status event",
        "description": "Sent to your webhook URL (v2). Answer 2xx within 10 s. 410 disables the webhook; other failures are retried after 10s, 1m, 5m, 15m and 30m.",
        "parameters": [
          {
            "in": "header",
            "required": true,
            "name": "X-Wasla-Signature",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256(secret, \"<t>.<raw body>\")>"
          },
          {
            "in": "header",
            "required": true,
            "name": "X-Wasla-Event",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "required": true,
            "name": "X-Wasla-Delivery",
            "schema": {
              "type": "string"
            },
            "description": "Same for every retry of one delivery"
          },
          {
            "in": "header",
            "required": true,
            "name": "X-Wasla-Webhook-Version",
            "schema": {
              "type": "string",
              "const": "2"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "id",
                  "type",
                  "apiVersion",
                  "createdAt",
                  "sessionId",
                  "number",
                  "data"
                ],
                "properties": {
                  "id": {
                    "type": "string",
                    "example": "evt_5f0c2b7d9e1a4c3b8a6f2d10",
                    "description": "Unique event id — dedupe on it"
                  },
                  "type": {
                    "type": "string",
                    "const": "message.status"
                  },
                  "apiVersion": {
                    "type": "string",
                    "const": "2026-10"
                  },
                  "createdAt": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "sessionId": {
                    "type": "string"
                  },
                  "number": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Your WhatsApp number (digits)"
                  },
                  "data": {
                    "type": "object",
                    "properties": {
                      "messageId": {
                        "type": "string"
                      },
                      "reference": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "to": {
                        "type": "string",
                        "description": "Phone digits, or lid:<digits>"
                      },
                      "status": {
                        "enum": [
                          "sent",
                          "delivered",
                          "read",
                          "failed"
                        ]
                      },
                      "error": {
                        "type": [
                          "object",
                          "null"
                        ],
                        "properties": {
                          "code": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      },
                      "timestamp": {
                        "type": "string",
                        "format": "date-time"
                      }
                    }
                  }
                },
                "example": {
                  "id": "evt_5f0c2b7d9e1a4c3b8a6f2d10",
                  "type": "message.status",
                  "apiVersion": "2026-10",
                  "createdAt": "2026-10-10T12:00:03.000Z",
                  "sessionId": "cm1abcd2345efgh6789ijkl",
                  "number": "201100302759",
                  "data": {
                    "messageId": "3EB0A1B2C3D4E5F60718",
                    "reference": "order-1042",
                    "to": "201099887766",
                    "status": "read",
                    "error": null,
                    "timestamp": "2026-10-10T12:00:09.000Z"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Received"
          },
          "410": {
            "description": "Stop sending (webhook disabled)"
          }
        }
      }
    },
    "interactive.reply": {
      "post": {
        "summary": "interactive.reply event",
        "description": "Sent to your webhook URL (v2). Answer 2xx within 10 s. 410 disables the webhook; other failures are retried after 10s, 1m, 5m, 15m and 30m.",
        "parameters": [
          {
            "in": "header",
            "required": true,
            "name": "X-Wasla-Signature",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256(secret, \"<t>.<raw body>\")>"
          },
          {
            "in": "header",
            "required": true,
            "name": "X-Wasla-Event",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "required": true,
            "name": "X-Wasla-Delivery",
            "schema": {
              "type": "string"
            },
            "description": "Same for every retry of one delivery"
          },
          {
            "in": "header",
            "required": true,
            "name": "X-Wasla-Webhook-Version",
            "schema": {
              "type": "string",
              "const": "2"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "id",
                  "type",
                  "apiVersion",
                  "createdAt",
                  "sessionId",
                  "number",
                  "data"
                ],
                "properties": {
                  "id": {
                    "type": "string",
                    "example": "evt_5f0c2b7d9e1a4c3b8a6f2d10",
                    "description": "Unique event id — dedupe on it"
                  },
                  "type": {
                    "type": "string",
                    "const": "interactive.reply"
                  },
                  "apiVersion": {
                    "type": "string",
                    "const": "2026-10"
                  },
                  "createdAt": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "sessionId": {
                    "type": "string"
                  },
                  "number": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Your WhatsApp number (digits)"
                  },
                  "data": {
                    "type": "object",
                    "properties": {
                      "interactionId": {
                        "type": "string"
                      },
                      "messageId": {
                        "type": "string",
                        "description": "The interactive message that was answered"
                      },
                      "reference": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "from": {
                        "type": "object",
                        "properties": {
                          "phone": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "example": "201099887766"
                          },
                          "lid": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "WhatsApp privacy id when the phone is hidden"
                          },
                          "name": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "example": "منى"
                          }
                        }
                      },
                      "reply": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "title": {
                            "type": "string"
                          },
                          "index": {
                            "type": "integer"
                          },
                          "source": {
                            "enum": [
                              "button",
                              "list",
                              "number",
                              "title"
                            ]
                          }
                        }
                      },
                      "replyMessageId": {
                        "type": "string"
                      },
                      "timestamp": {
                        "type": "string",
                        "format": "date-time"
                      }
                    }
                  }
                },
                "example": {
                  "id": "evt_5f0c2b7d9e1a4c3b8a6f2d10",
                  "type": "interactive.reply",
                  "apiVersion": "2026-10",
                  "createdAt": "2026-10-10T12:00:03.000Z",
                  "sessionId": "cm1abcd2345efgh6789ijkl",
                  "number": "201100302759",
                  "data": {
                    "interactionId": "int_8f2c1d9a7b3e4f56a1b2c3d4",
                    "messageId": "3EB0A1B2C3D4E5F60718",
                    "reference": "order-1042",
                    "from": {
                      "phone": "201099887766",
                      "lid": null,
                      "name": "منى"
                    },
                    "reply": {
                      "id": "confirm",
                      "title": "تأكيد",
                      "index": 1,
                      "source": "number"
                    },
                    "replyMessageId": "3EB0FFEE0011223344",
                    "timestamp": "2026-10-10T12:03:00.000Z"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Received"
          },
          "410": {
            "description": "Stop sending (webhook disabled)"
          }
        }
      }
    },
    "poll.vote": {
      "post": {
        "summary": "poll.vote event",
        "description": "Sent to your webhook URL (v2). Answer 2xx within 10 s. 410 disables the webhook; other failures are retried after 10s, 1m, 5m, 15m and 30m.",
        "parameters": [
          {
            "in": "header",
            "required": true,
            "name": "X-Wasla-Signature",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256(secret, \"<t>.<raw body>\")>"
          },
          {
            "in": "header",
            "required": true,
            "name": "X-Wasla-Event",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "required": true,
            "name": "X-Wasla-Delivery",
            "schema": {
              "type": "string"
            },
            "description": "Same for every retry of one delivery"
          },
          {
            "in": "header",
            "required": true,
            "name": "X-Wasla-Webhook-Version",
            "schema": {
              "type": "string",
              "const": "2"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "id",
                  "type",
                  "apiVersion",
                  "createdAt",
                  "sessionId",
                  "number",
                  "data"
                ],
                "properties": {
                  "id": {
                    "type": "string",
                    "example": "evt_5f0c2b7d9e1a4c3b8a6f2d10",
                    "description": "Unique event id — dedupe on it"
                  },
                  "type": {
                    "type": "string",
                    "const": "poll.vote"
                  },
                  "apiVersion": {
                    "type": "string",
                    "const": "2026-10"
                  },
                  "createdAt": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "sessionId": {
                    "type": "string"
                  },
                  "number": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Your WhatsApp number (digits)"
                  },
                  "data": {
                    "type": "object",
                    "description": "A customer voted on a poll sent by this number. One event per ballot change; selectedOptions is the whole current ballot ([] = vote removed). Not sent for your own votes nor for history imports.",
                    "required": [
                      "messageId",
                      "reference",
                      "from",
                      "selectedOptions",
                      "timestamp"
                    ],
                    "properties": {
                      "messageId": {
                        "type": "string",
                        "description": "The poll message (id returned by the send)"
                      },
                      "reference": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "description": "The reference sent with the poll"
                      },
                      "from": {
                        "type": "object",
                        "properties": {
                          "phone": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "example": "201099887766"
                          },
                          "lid": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "WhatsApp privacy id when the phone is hidden"
                          },
                          "name": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "example": "منى"
                          }
                        }
                      },
                      "selectedOptions": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "Option titles as sent; [] = the vote was removed"
                      },
                      "timestamp": {
                        "type": "string",
                        "format": "date-time"
                      }
                    }
                  }
                },
                "example": {
                  "id": "evt_5f0c2b7d9e1a4c3b8a6f2d10",
                  "type": "poll.vote",
                  "apiVersion": "2026-10",
                  "createdAt": "2026-10-10T12:00:03.000Z",
                  "sessionId": "cm1abcd2345efgh6789ijkl",
                  "number": "201100302759",
                  "data": {
                    "messageId": "3EB0A1B2C3D4E5F60718",
                    "reference": "survey-7",
                    "from": {
                      "phone": "201099887766",
                      "lid": null,
                      "name": "منى"
                    },
                    "selectedOptions": [
                      "الأحد"
                    ],
                    "timestamp": "2026-10-10T12:04:00.000Z"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Received"
          },
          "410": {
            "description": "Stop sending (webhook disabled)"
          }
        }
      }
    },
    "contact.opted_out": {
      "post": {
        "summary": "contact.opted_out event",
        "description": "Sent to your webhook URL (v2). Answer 2xx within 10 s. 410 disables the webhook; other failures are retried after 10s, 1m, 5m, 15m and 30m.",
        "parameters": [
          {
            "in": "header",
            "required": true,
            "name": "X-Wasla-Signature",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256(secret, \"<t>.<raw body>\")>"
          },
          {
            "in": "header",
            "required": true,
            "name": "X-Wasla-Event",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "required": true,
            "name": "X-Wasla-Delivery",
            "schema": {
              "type": "string"
            },
            "description": "Same for every retry of one delivery"
          },
          {
            "in": "header",
            "required": true,
            "name": "X-Wasla-Webhook-Version",
            "schema": {
              "type": "string",
              "const": "2"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "id",
                  "type",
                  "apiVersion",
                  "createdAt",
                  "sessionId",
                  "number",
                  "data"
                ],
                "properties": {
                  "id": {
                    "type": "string",
                    "example": "evt_5f0c2b7d9e1a4c3b8a6f2d10",
                    "description": "Unique event id — dedupe on it"
                  },
                  "type": {
                    "type": "string",
                    "const": "contact.opted_out"
                  },
                  "apiVersion": {
                    "type": "string",
                    "const": "2026-10"
                  },
                  "createdAt": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "sessionId": {
                    "type": "string"
                  },
                  "number": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Your WhatsApp number (digits)"
                  },
                  "data": {
                    "type": "object",
                    "properties": {
                      "phone": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "lid": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "keyword": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "timestamp": {
                        "type": "string",
                        "format": "date-time"
                      }
                    }
                  }
                },
                "example": {
                  "id": "evt_5f0c2b7d9e1a4c3b8a6f2d10",
                  "type": "contact.opted_out",
                  "apiVersion": "2026-10",
                  "createdAt": "2026-10-10T12:00:03.000Z",
                  "sessionId": "cm1abcd2345efgh6789ijkl",
                  "number": "201100302759",
                  "data": {
                    "phone": "201099887766",
                    "lid": null,
                    "keyword": "إلغاء",
                    "timestamp": "2026-10-10T12:05:00.000Z"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Received"
          },
          "410": {
            "description": "Stop sending (webhook disabled)"
          }
        }
      }
    },
    "contact.opted_in": {
      "post": {
        "summary": "contact.opted_in event",
        "description": "Sent to your webhook URL (v2). Answer 2xx within 10 s. 410 disables the webhook; other failures are retried after 10s, 1m, 5m, 15m and 30m.",
        "parameters": [
          {
            "in": "header",
            "required": true,
            "name": "X-Wasla-Signature",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256(secret, \"<t>.<raw body>\")>"
          },
          {
            "in": "header",
            "required": true,
            "name": "X-Wasla-Event",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "required": true,
            "name": "X-Wasla-Delivery",
            "schema": {
              "type": "string"
            },
            "description": "Same for every retry of one delivery"
          },
          {
            "in": "header",
            "required": true,
            "name": "X-Wasla-Webhook-Version",
            "schema": {
              "type": "string",
              "const": "2"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "id",
                  "type",
                  "apiVersion",
                  "createdAt",
                  "sessionId",
                  "number",
                  "data"
                ],
                "properties": {
                  "id": {
                    "type": "string",
                    "example": "evt_5f0c2b7d9e1a4c3b8a6f2d10",
                    "description": "Unique event id — dedupe on it"
                  },
                  "type": {
                    "type": "string",
                    "const": "contact.opted_in"
                  },
                  "apiVersion": {
                    "type": "string",
                    "const": "2026-10"
                  },
                  "createdAt": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "sessionId": {
                    "type": "string"
                  },
                  "number": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Your WhatsApp number (digits)"
                  },
                  "data": {
                    "type": "object",
                    "properties": {
                      "phone": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "lid": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "keyword": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "timestamp": {
                        "type": "string",
                        "format": "date-time"
                      }
                    }
                  }
                },
                "example": {
                  "id": "evt_5f0c2b7d9e1a4c3b8a6f2d10",
                  "type": "contact.opted_in",
                  "apiVersion": "2026-10",
                  "createdAt": "2026-10-10T12:00:03.000Z",
                  "sessionId": "cm1abcd2345efgh6789ijkl",
                  "number": "201100302759",
                  "data": {
                    "phone": "201099887766",
                    "lid": null,
                    "keyword": null,
                    "timestamp": "2026-10-11T09:00:00.000Z"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Received"
          },
          "410": {
            "description": "Stop sending (webhook disabled)"
          }
        }
      }
    },
    "session.status": {
      "post": {
        "summary": "session.status event",
        "description": "Sent to your webhook URL (v2). Answer 2xx within 10 s. 410 disables the webhook; other failures are retried after 10s, 1m, 5m, 15m and 30m.",
        "parameters": [
          {
            "in": "header",
            "required": true,
            "name": "X-Wasla-Signature",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256(secret, \"<t>.<raw body>\")>"
          },
          {
            "in": "header",
            "required": true,
            "name": "X-Wasla-Event",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "required": true,
            "name": "X-Wasla-Delivery",
            "schema": {
              "type": "string"
            },
            "description": "Same for every retry of one delivery"
          },
          {
            "in": "header",
            "required": true,
            "name": "X-Wasla-Webhook-Version",
            "schema": {
              "type": "string",
              "const": "2"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "id",
                  "type",
                  "apiVersion",
                  "createdAt",
                  "sessionId",
                  "number",
                  "data"
                ],
                "properties": {
                  "id": {
                    "type": "string",
                    "example": "evt_5f0c2b7d9e1a4c3b8a6f2d10",
                    "description": "Unique event id — dedupe on it"
                  },
                  "type": {
                    "type": "string",
                    "const": "session.status"
                  },
                  "apiVersion": {
                    "type": "string",
                    "const": "2026-10"
                  },
                  "createdAt": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "sessionId": {
                    "type": "string"
                  },
                  "number": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Your WhatsApp number (digits)"
                  },
                  "data": {
                    "type": "object",
                    "properties": {
                      "status": {
                        "enum": [
                          "connected",
                          "disconnected",
                          "banned",
                          "logged_out"
                        ]
                      },
                      "reason": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "timestamp": {
                        "type": "string",
                        "format": "date-time"
                      }
                    }
                  }
                },
                "example": {
                  "id": "evt_5f0c2b7d9e1a4c3b8a6f2d10",
                  "type": "session.status",
                  "apiVersion": "2026-10",
                  "createdAt": "2026-10-10T12:00:03.000Z",
                  "sessionId": "cm1abcd2345efgh6789ijkl",
                  "number": "201100302759",
                  "data": {
                    "status": "disconnected",
                    "reason": null,
                    "timestamp": "2026-10-10T13:00:00.000Z"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Received"
          },
          "410": {
            "description": "Stop sending (webhook disabled)"
          }
        }
      }
    },
    "webhook.test": {
      "post": {
        "summary": "webhook.test event",
        "description": "Sent to your webhook URL (v2). Answer 2xx within 10 s. 410 disables the webhook; other failures are retried after 10s, 1m, 5m, 15m and 30m.",
        "parameters": [
          {
            "in": "header",
            "required": true,
            "name": "X-Wasla-Signature",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex HMAC-SHA256(secret, \"<t>.<raw body>\")>"
          },
          {
            "in": "header",
            "required": true,
            "name": "X-Wasla-Event",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "header",
            "required": true,
            "name": "X-Wasla-Delivery",
            "schema": {
              "type": "string"
            },
            "description": "Same for every retry of one delivery"
          },
          {
            "in": "header",
            "required": true,
            "name": "X-Wasla-Webhook-Version",
            "schema": {
              "type": "string",
              "const": "2"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "id",
                  "type",
                  "apiVersion",
                  "createdAt",
                  "sessionId",
                  "number",
                  "data"
                ],
                "properties": {
                  "id": {
                    "type": "string",
                    "example": "evt_5f0c2b7d9e1a4c3b8a6f2d10",
                    "description": "Unique event id — dedupe on it"
                  },
                  "type": {
                    "type": "string",
                    "const": "webhook.test"
                  },
                  "apiVersion": {
                    "type": "string",
                    "const": "2026-10"
                  },
                  "createdAt": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "sessionId": {
                    "type": "string"
                  },
                  "number": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Your WhatsApp number (digits)"
                  },
                  "data": {
                    "type": "object",
                    "properties": {
                      "message": {
                        "type": "string"
                      },
                      "timestamp": {
                        "type": "string",
                        "format": "date-time"
                      }
                    }
                  }
                },
                "example": {
                  "id": "evt_5f0c2b7d9e1a4c3b8a6f2d10",
                  "type": "webhook.test",
                  "apiVersion": "2026-10",
                  "createdAt": "2026-10-10T12:00:03.000Z",
                  "sessionId": "cm1abcd2345efgh6789ijkl",
                  "number": "201100302759",
                  "data": {
                    "message": "This is a test event from Mursilat",
                    "timestamp": "2026-10-10T12:00:00.000Z"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Received"
          },
          "410": {
            "description": "Stop sending (webhook disabled)"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ContactCardDoc": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "example": "خدمة العملاء",
            "maxLength": 100
          },
          "phones": {
            "example": [
              "+201001234567"
            ],
            "description": "1-3 phones with country code",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "email": {
            "type": "string",
            "example": "support@example.com",
            "maxLength": 120
          },
          "organization": {
            "type": "string",
            "example": "متجر النور",
            "maxLength": 100
          }
        },
        "required": [
          "name",
          "phones"
        ]
      },
      "DeleteRequest": {
        "type": "object",
        "properties": {
          "forEveryone": {
            "type": "boolean",
            "example": true,
            "description": "true = for everyone (own, ≤48 h); false = for me"
          }
        },
        "required": [
          "forEveryone"
        ]
      },
      "EditRequest": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string",
            "example": "الموعد اتغير لـ 5 مساءً",
            "maxLength": 4096
          }
        },
        "required": [
          "text"
        ]
      },
      "InteractionAnswerDoc": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "confirm"
          },
          "title": {
            "type": "string",
            "example": "تأكيد"
          },
          "index": {
            "type": "number",
            "example": 1
          },
          "source": {
            "type": "string",
            "enum": [
              "button",
              "list",
              "number",
              "title"
            ]
          },
          "replyMessageId": {
            "type": "string",
            "example": "3EB0FFEE0011223344"
          },
          "answeredAt": {
            "type": "string",
            "example": "2026-10-10T12:03:00.000Z"
          }
        },
        "required": [
          "id",
          "title",
          "index",
          "source",
          "replyMessageId",
          "answeredAt"
        ]
      },
      "InteractionOptionDoc": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "confirm"
          },
          "title": {
            "type": "string",
            "example": "تأكيد"
          },
          "index": {
            "type": "number",
            "example": 1
          }
        },
        "required": [
          "id",
          "title",
          "index"
        ]
      },
      "InteractionResponse": {
        "type": "object",
        "properties": {
          "interactionId": {
            "type": "string",
            "example": "int_8f2c1d9a7b3e4f56a1b2c3d4"
          },
          "messageId": {
            "type": "string",
            "example": "3EB0A1B2C3D4E5F60718"
          },
          "type": {
            "type": "string",
            "enum": [
              "buttons",
              "list",
              "cta_url"
            ]
          },
          "reference": {
            "type": [
              "object",
              "null"
            ],
            "example": "order-1042"
          },
          "status": {
            "type": "string",
            "enum": [
              "OPEN",
              "ANSWERED",
              "EXPIRED"
            ]
          },
          "options": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InteractionOptionDoc"
            }
          },
          "answer": {
            "type": [
              "object",
              "null"
            ],
            "allOf": [
              {
                "$ref": "#/components/schemas/InteractionAnswerDoc"
              }
            ]
          },
          "expiresAt": {
            "type": "string",
            "example": "2026-10-11T12:00:00.000Z"
          },
          "createdAt": {
            "type": "string",
            "example": "2026-10-10T12:00:00.000Z"
          }
        },
        "required": [
          "interactionId",
          "messageId",
          "type",
          "status",
          "options",
          "expiresAt",
          "createdAt"
        ]
      },
      "InteractiveButton": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "confirm",
            "maxLength": 64,
            "pattern": "^[A-Za-z0-9_.:-]+$"
          },
          "title": {
            "type": "string",
            "example": "تأكيد",
            "maxLength": 20
          }
        },
        "required": [
          "id",
          "title"
        ]
      },
      "InteractiveCta": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "example": "تتبع الشحنة",
            "maxLength": 20
          },
          "url": {
            "type": "string",
            "example": "https://example.com/track/1042",
            "format": "uri"
          }
        },
        "required": [
          "title",
          "url"
        ]
      },
      "InteractiveList": {
        "type": "object",
        "properties": {
          "buttonText": {
            "type": "string",
            "example": "اختار",
            "maxLength": 20
          },
          "sections": {
            "description": "1-10 sections, 1-10 rows in total",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InteractiveListSection"
            }
          }
        },
        "required": [
          "buttonText",
          "sections"
        ]
      },
      "InteractiveListRow": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "prices",
            "maxLength": 64,
            "pattern": "^[A-Za-z0-9_.:-]+$"
          },
          "title": {
            "type": "string",
            "example": "الأسعار",
            "maxLength": 24
          },
          "description": {
            "type": "string",
            "example": "اعرف أسعارنا",
            "maxLength": 72
          }
        },
        "required": [
          "id",
          "title"
        ]
      },
      "InteractiveListSection": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "example": "الخدمات",
            "maxLength": 24,
            "description": "Required when there is more than one section"
          },
          "rows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InteractiveListRow"
            }
          }
        },
        "required": [
          "rows"
        ]
      },
      "InteractiveSendRequest": {
        "type": "object",
        "properties": {
          "to": {
            "type": "string",
            "example": "201001234567",
            "description": "Recipient phone with country code (digits)"
          },
          "type": {
            "type": "string",
            "enum": [
              "buttons",
              "list",
              "cta_url"
            ],
            "example": "buttons"
          },
          "header": {
            "description": "Max 60 characters",
            "allOf": [
              {
                "$ref": "#/components/schemas/InteractiveTextPart"
              }
            ]
          },
          "body": {
            "description": "1-1024 characters",
            "allOf": [
              {
                "$ref": "#/components/schemas/InteractiveTextPart"
              }
            ]
          },
          "footer": {
            "description": "Max 60 characters",
            "allOf": [
              {
                "$ref": "#/components/schemas/InteractiveTextPart"
              }
            ]
          },
          "buttons": {
            "description": "type=buttons: 1-3 buttons, unique ids and titles",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InteractiveButton"
            }
          },
          "list": {
            "description": "type=list",
            "allOf": [
              {
                "$ref": "#/components/schemas/InteractiveList"
              }
            ]
          },
          "cta": {
            "description": "type=cta_url (public https URL)",
            "allOf": [
              {
                "$ref": "#/components/schemas/InteractiveCta"
              }
            ]
          },
          "fallback": {
            "type": "string",
            "enum": [
              "numbered",
              "none"
            ],
            "default": "numbered",
            "description": "Append numbered options + a hint so customers whose app shows no buttons can answer by typing"
          },
          "locale": {
            "type": "string",
            "enum": [
              "ar",
              "en"
            ],
            "default": "ar",
            "description": "Language of the fallback hint line"
          },
          "reference": {
            "type": "string",
            "example": "order-1042",
            "maxLength": 128,
            "description": "Your id, echoed in webhooks"
          },
          "expiresInMinutes": {
            "type": "number",
            "example": 1440,
            "minimum": 5,
            "maximum": 10080,
            "default": 1440,
            "description": "Reply-matching window in minutes"
          }
        },
        "required": [
          "to",
          "type",
          "body"
        ]
      },
      "InteractiveSendResponse": {
        "type": "object",
        "properties": {
          "messageId": {
            "type": "string",
            "example": "3EB0A1B2C3D4E5F60718",
            "description": "WhatsApp message id (also used in message.status / interactive.reply)"
          },
          "interactionId": {
            "type": "string",
            "example": "int_8f2c1d9a7b3e4f56a1b2c3d4"
          },
          "status": {
            "type": "string",
            "enum": [
              "sent",
              "queued"
            ]
          },
          "format": {
            "type": "string",
            "example": "native_flow_quick_reply",
            "description": "Wire format used"
          },
          "fallbackIncluded": {
            "type": "boolean",
            "example": true
          }
        },
        "required": [
          "messageId",
          "interactionId",
          "status",
          "format",
          "fallbackIncluded"
        ]
      },
      "InteractiveTextPart": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string",
            "example": "هل تؤكد طلبك؟"
          }
        },
        "required": [
          "text"
        ]
      },
      "MediaSourceDoc": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "med_8f2c1d9a7b3e4f56a1b2c3d4",
            "description": "Id from POST /whatsapp/public/media/upload (24 h)"
          },
          "url": {
            "type": "string",
            "example": "https://example.com/catalog.pdf",
            "description": "Public http(s) URL, fetched once through the SSRF guard"
          }
        }
      },
      "MediaUploadResponse": {
        "type": "object",
        "properties": {
          "mediaId": {
            "type": "string",
            "example": "med_8f2c1d9a7b3e4f56a1b2c3d4"
          },
          "mimeType": {
            "type": "string",
            "example": "image/png"
          },
          "size": {
            "type": "number",
            "example": 48213
          },
          "fileName": {
            "type": [
              "object",
              "null"
            ],
            "example": "logo.png"
          },
          "expiresAt": {
            "type": "string",
            "example": "2026-10-11T12:00:00.000Z"
          }
        },
        "required": [
          "mediaId",
          "mimeType",
          "size",
          "expiresAt"
        ]
      },
      "MessageActionResponse": {
        "type": "object",
        "properties": {
          "messageId": {
            "type": "string",
            "example": "3EB0A1B2C3D4E5F60718"
          },
          "action": {
            "type": "string",
            "enum": [
              "react",
              "edit",
              "delete"
            ]
          }
        },
        "required": [
          "messageId",
          "action"
        ]
      },
      "ReactRequest": {
        "type": "object",
        "properties": {
          "emoji": {
            "type": "string",
            "example": "👍",
            "description": "One emoji; \"\" removes your reaction"
          }
        },
        "required": [
          "emoji"
        ]
      },
      "SendMediaResponseDto": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "message": {
            "type": "string",
            "example": "Media sent successfully"
          },
          "sessionId": {
            "type": "string",
            "example": "user-123-work"
          },
          "phoneNumber": {
            "type": "string",
            "example": "201234567890"
          },
          "mediaType": {
            "type": "string",
            "example": "image",
            "enum": [
              "image",
              "video",
              "document",
              "audio"
            ]
          },
          "messageId": {
            "type": "string",
            "description": "WhatsApp message id (also when queued); used by message.status webhooks",
            "example": "3EB0A1B2C3D4E5F60718"
          },
          "queued": {
            "type": "boolean",
            "description": "True when request is accepted into delayed queue"
          },
          "queueJobId": {
            "type": "string",
            "description": "Queue job identifier when queued"
          },
          "estimatedDelayMs": {
            "type": "number",
            "description": "Estimated queue delay in milliseconds"
          }
        },
        "required": [
          "success",
          "message",
          "sessionId",
          "phoneNumber",
          "mediaType"
        ]
      },
      "SendMessageDto": {
        "type": "object",
        "properties": {
          "phoneNumber": {
            "type": "string",
            "description": "Phone number with country code (digits only)",
            "example": "201234567890",
            "pattern": "^[0-9]{10,15}$"
          },
          "content": {
            "type": "string",
            "description": "Message content to send",
            "example": "Hello from WhatsApp API!",
            "minLength": 1,
            "maxLength": 4096
          },
          "reference": {
            "type": "string",
            "description": "Public API: your own id for this message (≤128), echoed in message.status webhooks",
            "example": "order-1042-confirmation",
            "maxLength": 128
          }
        },
        "required": [
          "phoneNumber",
          "content"
        ]
      },
      "SendMessageResponseDto": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "message": {
            "type": "string"
          },
          "sessionId": {
            "type": "string"
          },
          "phoneNumber": {
            "type": "string"
          },
          "messageId": {
            "type": "string",
            "description": "WhatsApp message id (also when queued); used by message.status webhooks",
            "example": "3EB0A1B2C3D4E5F60718"
          },
          "queued": {
            "type": "boolean",
            "description": "True when request is accepted into delayed queue"
          },
          "queueJobId": {
            "type": "string",
            "description": "Queue job identifier when queued"
          },
          "estimatedDelayMs": {
            "type": "number",
            "description": "Estimated queue delay in milliseconds"
          }
        },
        "required": [
          "success",
          "message",
          "sessionId",
          "phoneNumber"
        ]
      },
      "UnifiedSendRequest": {
        "type": "object",
        "properties": {
          "to": {
            "type": "string",
            "example": "201001234567",
            "description": "Recipient phone with country code (+, spaces allowed)"
          },
          "type": {
            "type": "string",
            "enum": [
              "text",
              "image",
              "video",
              "audio",
              "voice",
              "document",
              "sticker",
              "location",
              "contact",
              "poll",
              "event",
              "buttons",
              "list",
              "cta_url"
            ],
            "example": "text"
          },
          "reference": {
            "type": "string",
            "example": "order-1042",
            "maxLength": 128,
            "description": "Your id, echoed in message.status / interactive.reply / poll.vote"
          },
          "replyTo": {
            "type": "string",
            "example": "3EB0A1B2C3D4E5F60718",
            "description": "Quote a message of this chat (WhatsApp id or Mursilat inbox id)"
          },
          "text": {
            "type": "string",
            "example": "طلبك اتشحن 🚚 *شكرًا*",
            "maxLength": 4096,
            "description": "type=text"
          },
          "linkPreview": {
            "type": "boolean",
            "example": true,
            "description": "type=text: preview the first link (default true)"
          },
          "mentions": {
            "description": "type=text: groups only (group sends are not supported yet → MESSAGE_MENTIONS_GROUP_ONLY)",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "media": {
            "description": "image / video / audio / voice / document / sticker (or a multipart `file`)",
            "allOf": [
              {
                "$ref": "#/components/schemas/MediaSourceDoc"
              }
            ]
          },
          "caption": {
            "type": "string",
            "example": "الكتالوج الجديد",
            "maxLength": 1024,
            "description": "image / video / document"
          },
          "viewOnce": {
            "type": "boolean",
            "example": false,
            "description": "image / video / voice: view once"
          },
          "gif": {
            "type": "boolean",
            "example": false,
            "description": "video: loop like a GIF"
          },
          "videoNote": {
            "type": "boolean",
            "example": false,
            "description": "video: round video note (≤60 s, no caption)"
          },
          "fileName": {
            "type": "string",
            "example": "invoice-1042.pdf",
            "maxLength": 120,
            "description": "document"
          },
          "latitude": {
            "type": "number",
            "example": 30.0444,
            "description": "location"
          },
          "longitude": {
            "type": "number",
            "example": 31.2357,
            "description": "location"
          },
          "name": {
            "type": "string",
            "example": "فرع وسط البلد",
            "description": "location name (≤100) / poll question (≤255) / event name (≤100)"
          },
          "address": {
            "type": "string",
            "example": "12 شارع طلعت حرب، القاهرة",
            "maxLength": 200,
            "description": "location"
          },
          "contacts": {
            "description": "contact: 1-5 cards",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ContactCardDoc"
            }
          },
          "options": {
            "example": [
              "الأحد",
              "الاثنين"
            ],
            "description": "poll: 2-12 unique options (≤100)",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "selectableCount": {
            "type": "number",
            "example": 1,
            "description": "poll: 1 = single choice (default), 0 = any number"
          },
          "description": {
            "type": "string",
            "example": "افتتاح الفرع",
            "maxLength": 2048,
            "description": "event (experimental)"
          },
          "startAt": {
            "type": "string",
            "example": "2026-11-01T17:00:00.000Z",
            "description": "event"
          },
          "endAt": {
            "type": "string",
            "example": "2026-11-01T20:00:00.000Z",
            "description": "event"
          },
          "locationName": {
            "type": "string",
            "example": "فرع وسط البلد",
            "description": "event"
          },
          "extraGuestsAllowed": {
            "type": "boolean",
            "example": false,
            "description": "event"
          },
          "header": {
            "description": "buttons / list / cta_url (≤60)",
            "allOf": [
              {
                "$ref": "#/components/schemas/InteractiveTextPart"
              }
            ]
          },
          "body": {
            "description": "buttons / list / cta_url (required, ≤1024)",
            "allOf": [
              {
                "$ref": "#/components/schemas/InteractiveTextPart"
              }
            ]
          },
          "footer": {
            "description": "buttons / list / cta_url (≤60)",
            "allOf": [
              {
                "$ref": "#/components/schemas/InteractiveTextPart"
              }
            ]
          },
          "buttons": {
            "description": "buttons: 1-3",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InteractiveButton"
            }
          },
          "list": {
            "description": "list",
            "allOf": [
              {
                "$ref": "#/components/schemas/InteractiveList"
              }
            ]
          },
          "cta": {
            "description": "cta_url",
            "allOf": [
              {
                "$ref": "#/components/schemas/InteractiveCta"
              }
            ]
          },
          "fallback": {
            "type": "string",
            "enum": [
              "numbered",
              "none"
            ],
            "example": "numbered"
          },
          "locale": {
            "type": "string",
            "enum": [
              "ar",
              "en"
            ],
            "example": "ar"
          },
          "expiresInMinutes": {
            "type": "number",
            "example": 1440,
            "minimum": 5,
            "maximum": 10080
          }
        },
        "required": [
          "to",
          "type"
        ]
      },
      "UnifiedSendResponse": {
        "type": "object",
        "properties": {
          "messageId": {
            "type": "string",
            "example": "3EB0A1B2C3D4E5F60718",
            "description": "WhatsApp message id (message.status webhooks)"
          },
          "status": {
            "type": "string",
            "enum": [
              "sent",
              "queued"
            ],
            "example": "sent"
          },
          "type": {
            "type": "string",
            "enum": [
              "text",
              "image",
              "video",
              "audio",
              "voice",
              "document",
              "sticker",
              "location",
              "contact",
              "poll",
              "event",
              "buttons",
              "list",
              "cta_url"
            ],
            "example": "poll"
          },
          "reference": {
            "type": [
              "object",
              "null"
            ],
            "example": "survey-7"
          },
          "interactionId": {
            "type": [
              "object",
              "null"
            ],
            "example": null,
            "description": "buttons / list / cta_url"
          },
          "format": {
            "type": [
              "object",
              "null"
            ],
            "example": null,
            "description": "Interactive wire format"
          },
          "fallbackIncluded": {
            "type": [
              "object",
              "null"
            ],
            "example": null
          },
          "estimatedDelayMs": {
            "type": [
              "object",
              "null"
            ],
            "example": null,
            "description": "When queued"
          }
        },
        "required": [
          "messageId",
          "status",
          "type"
        ]
      }
    },
    "securitySchemes": {
      "x-api-key": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "API key of the number (Numbers → Developer)"
      }
    }
  }
}
