{
  "info": {
    "name": "Mursilat Public API v2",
    "description": "Set baseUrl and apiKey (wsl_live_…) in the collection variables. Writes send a fresh Idempotency-Key.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "auth": {
    "type": "bearer",
    "bearer": [
      {
        "key": "token",
        "value": "{{apiKey}}",
        "type": "string"
      }
    ]
  },
  "variable": [
    {
      "key": "baseUrl",
      "value": "https://mursilat.com/api"
    },
    {
      "key": "apiKey",
      "value": "wsl_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    },
    {
      "key": "numberId",
      "value": "cm1abcd2345efgh6789ijkl"
    },
    {
      "key": "messageId",
      "value": "3EB0A1B2C3D4E5F60718"
    },
    {
      "key": "campaignId",
      "value": "cm2camp0001xyz"
    },
    {
      "key": "ruleId",
      "value": "cm3rule0001xyz"
    },
    {
      "key": "otpId",
      "value": "otp_8f2c1d9a7b3e4f56a1b2c3d4"
    },
    {
      "key": "groupId",
      "value": "120363025246125486@g.us"
    },
    {
      "key": "deliveryId",
      "value": "dlv_3c1f0a9b8e7d6c5b4a392817"
    }
  ],
  "item": [
    {
      "name": "Account & keys",
      "description": "Create account API keys in Settings → API keys: choose scopes, numbers and optionally allowed IPs. The key is shown once.",
      "item": [
        {
          "name": "Who am I (connectivity test)",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v2/me",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "me"
              ]
            },
            "description": "Returns the account, the key prefix, scopes, numbers and your IP as seen by Mursilat.\n\nScope: any"
          }
        }
      ]
    },
    {
      "name": "Numbers",
      "description": "Add numbers, pair them with a QR or a pairing code, follow their connection and manage their webhooks. Tip: a WhatsApp Business number with a real profile (name, photo, description) is trusted more by customers and by WhatsApp.",
      "item": [
        {
          "name": "List numbers",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers"
              ]
            },
            "description": "Numbers this key can use, newest first.\n\nScope: numbers:read"
          }
        },
        {
          "name": "Add a number and start pairing",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"فرع المعادي\",\n  \"pairing\": {\n    \"method\": \"qr\"\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Creates a number slot (your plan’s number limit applies) and returns a QR (raw + PNG data URL), or with pairing.method \"code\" + phone an 8-character code to type in WhatsApp.\n\nScope: numbers:write"
          }
        },
        {
          "name": "Get a number",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers/{{numberId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers",
                "{{numberId}}"
              ]
            },
            "description": "Status, health level, warm-up stage and webhook state.\n\nScope: numbers:read"
          }
        },
        {
          "name": "Rename a number",
          "request": {
            "method": "PATCH",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers/{{numberId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers",
                "{{numberId}}"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"فرع مدينة نصر\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Display name in Mursilat only.\n\nScope: numbers:write"
          }
        },
        {
          "name": "Connection status",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers/{{numberId}}/status",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers",
                "{{numberId}}",
                "status"
              ]
            },
            "description": "Live connection state of the number.\n\nScope: numbers:read"
          }
        },
        {
          "name": "Current QR",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers/{{numberId}}/qr",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers",
                "{{numberId}}",
                "qr"
              ]
            },
            "description": "The QR refreshes about every 20 seconds; fetch again after expiresAt.\n\nScope: numbers:write"
          }
        },
        {
          "name": "Pairing code (no QR)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers/{{numberId}}/pairing-code",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers",
                "{{numberId}}",
                "pairing-code"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"phone\": \"201001234567\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "For servers without a screen: WhatsApp → Linked devices → Link with phone number, then type the code.\n\nScope: numbers:write"
          }
        },
        {
          "name": "Reconnect",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers/{{numberId}}/reconnect",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers",
                "{{numberId}}",
                "reconnect"
              ]
            },
            "description": "Paired numbers reconnect without a QR; unpaired ones return a new QR.\n\nScope: numbers:write"
          }
        },
        {
          "name": "Log out (unlink)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers/{{numberId}}/logout",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers",
                "{{numberId}}",
                "logout"
              ]
            },
            "description": "Unlinks the device and deletes its credentials. Pair again to use it.\n\nScope: numbers:write"
          }
        },
        {
          "name": "Delete a number",
          "request": {
            "method": "DELETE",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers/{{numberId}}?confirm=cm1abcd2345efgh6789ijkl",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers",
                "{{numberId}}"
              ],
              "query": [
                {
                  "key": "confirm",
                  "value": "cm1abcd2345efgh6789ijkl"
                }
              ]
            },
            "description": "Permanent. Frees a slot of your plan.\n\nScope: numbers:write"
          }
        },
        {
          "name": "Check numbers on WhatsApp (1–50)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers/{{numberId}}/contacts/check",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers",
                "{{numberId}}",
                "contacts",
                "check"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"phones\": [\n    \"201001234567\",\n    \"966501234567\"\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Cache first (30 days), then live lookups within a per-minute budget that protects your number.\n\nScope: numbers:read"
          }
        },
        {
          "name": "Webhook of a number",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers/{{numberId}}/webhook",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers",
                "{{numberId}}",
                "webhook"
              ]
            },
            "description": "URL (query hidden), events and state.\n\nScope: webhooks:read"
          }
        },
        {
          "name": "Set the webhook of a number",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers/{{numberId}}/webhook",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers",
                "{{numberId}}",
                "webhook"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"url\": \"https://example.com/mursilat\",\n  \"events\": [\n    \"message.received\",\n    \"message.status\",\n    \"interactive.reply\"\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Public https URL only (private addresses refused). The signing secret is returned once.\n\nScope: webhooks:write"
          }
        },
        {
          "name": "Remove the webhook of a number",
          "request": {
            "method": "DELETE",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers/{{numberId}}/webhook",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers",
                "{{numberId}}",
                "webhook"
              ]
            },
            "description": "Pending retries to the old URL are cancelled.\n\nScope: webhooks:write"
          }
        },
        {
          "name": "Send a test event",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers/{{numberId}}/webhook/test",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers",
                "{{numberId}}",
                "webhook",
                "test"
              ]
            },
            "description": "Delivers webhook.test; check the delivery log.\n\nScope: webhooks:write"
          }
        },
        {
          "name": "Rotate the signing secret",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers/{{numberId}}/webhook/rotate-secret",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers",
                "{{numberId}}",
                "webhook",
                "rotate-secret"
              ]
            },
            "description": "The new secret is shown once; the old one stops at once.\n\nScope: webhooks:write"
          }
        }
      ]
    },
    {
      "name": "Messages",
      "description": "One endpoint for every message type, now or scheduled. Every send goes through the Number Shield (warm-up caps, pacing, opt-outs, content rules) and your plan quota. Status endpoints return metadata only: the API never returns message content.",
      "item": [
        {
          "name": "Send a message (any type)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/messages",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "messages"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"numberId\": \"cm1abcd2345efgh6789ijkl\",\n  \"to\": \"201001234567\",\n  \"type\": \"text\",\n  \"text\": \"طلبك اتشحن 🚚 *شكرًا*\",\n  \"reference\": \"order-1042\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Types: text, image, video (GIF / round video note), audio, voice, document, sticker, location, contact, poll, event, buttons, list, cta_url. Scheduling (scheduleAt) is available on request — see Schedule a message.\n\nScope: messages:send"
          }
        },
        {
          "name": "Send a file (multipart)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/messages",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "messages"
              ]
            },
            "body": {
              "mode": "formdata",
              "formdata": [
                {
                  "key": "numberId",
                  "type": "text",
                  "value": "cm1abcd2345efgh6789ijkl"
                },
                {
                  "key": "to",
                  "type": "text",
                  "value": "201001234567"
                },
                {
                  "key": "type",
                  "type": "text",
                  "value": "document"
                },
                {
                  "key": "caption",
                  "type": "text",
                  "value": "فاتورتك"
                },
                {
                  "key": "file",
                  "type": "file",
                  "src": []
                }
              ]
            },
            "description": "Same fields as JSON plus a file part. Bytes are sniffed; the name is never trusted.\n\nScope: messages:send"
          }
        },
        {
          "name": "Schedule a message",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/messages",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "messages"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"numberId\": \"cm1abcd2345efgh6789ijkl\",\n  \"to\": \"201001234567\",\n  \"type\": \"text\",\n  \"text\": \"تذكير بموعدك بكرة الساعة 5\",\n  \"scheduleAt\": \"2026-10-14T13:00:00+02:00\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Available on request: scheduling is off by default (422 SCHEDULING_DISABLED) because a scheduled message is the only content Mursilat keeps at rest — encrypted, at most 30 days, deleted once it leaves. Ask support to enable it. Cancel with DELETE /v2/messages/{id}.\n\nScope: messages:send"
          }
        },
        {
          "name": "Upload media once, send many times",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/media",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "media"
              ]
            },
            "body": {
              "mode": "formdata",
              "formdata": [
                {
                  "key": "numberId",
                  "type": "text",
                  "value": "cm1abcd2345efgh6789ijkl"
                },
                {
                  "key": "file",
                  "type": "file",
                  "src": []
                }
              ]
            },
            "description": "Returns a media id valid 24 h on the same number. Also accepts JSON {\"numberId\", \"url\"}.\n\nScope: messages:send"
          }
        },
        {
          "name": "List sent messages (status only)",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v2/messages?reference=order-1042",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "messages"
              ],
              "query": [
                {
                  "key": "reference",
                  "value": "order-1042"
                }
              ]
            },
            "description": "Messages sent through API v2 in the last 30 days — never content.\n\nScope: messages:read"
          }
        },
        {
          "name": "Message status timeline",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v2/messages/{{messageId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "messages",
                "{{messageId}}"
              ]
            },
            "description": "queued → sent → delivered → read, or failed with the error code.\n\nScope: messages:read"
          }
        },
        {
          "name": "React to a message",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/messages/{{messageId}}/reactions",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "messages",
                "{{messageId}}",
                "reactions"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"emoji\": \"👍\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "One emoji; \"\" removes your reaction. For received messages pass numberId.\n\nScope: messages:send"
          }
        },
        {
          "name": "Edit a sent text (≤15 min)",
          "request": {
            "method": "PATCH",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/messages/{{messageId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "messages",
                "{{messageId}}"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"text\": \"الموعد اتغير لـ 5 مساءً\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Your own text messages only; the new text passes the content rules.\n\nScope: messages:send"
          }
        },
        {
          "name": "Delete — or cancel a scheduled message",
          "request": {
            "method": "DELETE",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/messages/{{messageId}}?forEveryone=true",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "messages",
                "{{messageId}}"
              ],
              "query": [
                {
                  "key": "forEveryone",
                  "value": "true"
                }
              ]
            },
            "description": "A scheduled message is cancelled and its stored copy deleted.\n\nScope: messages:send"
          }
        }
      ]
    },
    {
      "name": "Campaigns (bulk)",
      "description": "Send one message to many people safely: the Number Shield paces it, respects quiet hours, skips opted-out and invalid numbers and pauses on bad signals. Content and recipients are deleted automatically after the campaign ends (keep window up to 24 h); only totals remain.",
      "item": [
        {
          "name": "Create and start a campaign",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/campaigns?ref={name}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "campaigns"
              ],
              "query": [
                {
                  "key": "ref",
                  "value": "{name}"
                }
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"numberId\": \"cm1abcd2345efgh6789ijkl\",\n  \"name\": \"عرض الجمعة\",\n  \"content\": {\n    \"type\": \"cta_url\",\n    \"body\": {\n      \"text\": \"أهلاً {name|عميلنا} 👋 خصم 20% لحد الجمعة\"\n    },\n    \"cta\": {\n      \"title\": \"شوف العرض\",\n      \"url\": \"https://example.com/offer?ref={name}\"\n    }\n  },\n  \"recipients\": [\n    {\n      \"phone\": \"201001234567\",\n      \"variables\": {\n        \"name\": \"منى\"\n      }\n    },\n    {\n      \"phone\": \"966501234567\"\n    }\n  ],\n  \"optInConfirmed\": true,\n  \"speed\": \"SAFE\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Content: text, image/video/audio/document (media.url), location, contact, cta_url, buttons, list. Recipients inline (≤10 000 with variables), contactListId or audience.\n\nScope: campaigns:write"
          }
        },
        {
          "name": "List campaigns",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v2/campaigns",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "campaigns"
              ]
            },
            "description": "Newest first; progress counts only.\n\nScope: campaigns:read"
          }
        },
        {
          "name": "Progress, pause reason and ETA",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v2/campaigns/{{campaignId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "campaigns",
                "{{campaignId}}"
              ]
            },
            "description": "ETA comes from the warm-up caps of the number and its pacing.\n\nScope: campaigns:read"
          }
        },
        {
          "name": "Recipients and button replies",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v2/campaigns/{{campaignId}}/recipients?status=FAILED",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "campaigns",
                "{{campaignId}}",
                "recipients"
              ],
              "query": [
                {
                  "key": "status",
                  "value": "FAILED"
                }
              ]
            },
            "description": "Available while running and during the keep window.\n\nScope: campaigns:read"
          }
        },
        {
          "name": "Start a draft",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/campaigns/{{campaignId}}/start",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "campaigns",
                "{{campaignId}}",
                "start"
              ]
            },
            "description": "For campaigns created with start=false.\n\nScope: campaigns:write"
          }
        },
        {
          "name": "Pause",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/campaigns/{{campaignId}}/pause",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "campaigns",
                "{{campaignId}}",
                "pause"
              ]
            },
            "description": "Queued sends stop at once.\n\nScope: campaigns:write"
          }
        },
        {
          "name": "Resume",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/campaigns/{{campaignId}}/resume",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "campaigns",
                "{{campaignId}}",
                "resume"
              ]
            },
            "description": "Platform / safety pauses cannot be lifted by you; time-boxed ones resume after they end.\n\nScope: campaigns:write"
          }
        },
        {
          "name": "Cancel",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/campaigns/{{campaignId}}/cancel",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "campaigns",
                "{{campaignId}}",
                "cancel"
              ]
            },
            "description": "Queued recipients are skipped.\n\nScope: campaigns:write"
          }
        },
        {
          "name": "Delete a draft / finished campaign",
          "request": {
            "method": "DELETE",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/campaigns/{{campaignId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "campaigns",
                "{{campaignId}}"
              ]
            },
            "description": "Running campaigns must be cancelled first.\n\nScope: campaigns:write"
          }
        }
      ]
    },
    {
      "name": "Auto-replies",
      "description": "Keyword (exact, contains, starts with, or a regular expression), welcome (first message) and away (outside business hours) rules per number. Opt-out keywords always win; replies go out as replies (short pacing).",
      "item": [
        {
          "name": "List rules",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers/{{numberId}}/auto-replies",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers",
                "{{numberId}}",
                "auto-replies"
              ]
            },
            "description": "Rules of the number plus rules for all numbers (scope: allNumbers).\n\nScope: autoreplies:read"
          }
        },
        {
          "name": "Create a rule",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers/{{numberId}}/auto-replies",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers",
                "{{numberId}}",
                "auto-replies"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"الأسعار\",\n  \"trigger\": {\n    \"type\": \"KEYWORD\",\n    \"match\": \"CONTAINS\",\n    \"keywords\": [\n      \"سعر\",\n      \"بكام\",\n      \"price\"\n    ]\n  },\n  \"reply\": {\n    \"text\": \"أهلاً {name|بيك} 👋 الأسعار: https://example.com/prices\"\n  },\n  \"cooldownMinutes\": 60\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "match: EXACT / CONTAINS / STARTS_WITH compare literal keywords after Arabic normalisation (أ/إ/آ, ى/ي, ة/ه, diacritics). REGEX takes trigger.patterns: RE2 regular expressions (linear time — no catastrophic backtracking). \"regex\" / \"starts_with\" in lower case and trigger.matchType are accepted.\n\nScope: autoreplies:write"
          }
        },
        {
          "name": "Get a rule",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers/{{numberId}}/auto-replies/{{ruleId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers",
                "{{numberId}}",
                "auto-replies",
                "{{ruleId}}"
              ]
            },
            "description": "With trigger stats.\n\nScope: autoreplies:read"
          }
        },
        {
          "name": "Update / toggle a rule",
          "request": {
            "method": "PATCH",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers/{{numberId}}/auto-replies/{{ruleId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers",
                "{{numberId}}",
                "auto-replies",
                "{{ruleId}}"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"enabled\": false\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Partial update; enabled toggles it.\n\nScope: autoreplies:write"
          }
        },
        {
          "name": "Delete a rule",
          "request": {
            "method": "DELETE",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers/{{numberId}}/auto-replies/{{ruleId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers",
                "{{numberId}}",
                "auto-replies",
                "{{ruleId}}"
              ]
            },
            "description": "Permanent.\n\nScope: autoreplies:write"
          }
        },
        {
          "name": "Enable all rules",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers/{{numberId}}/auto-replies/enable-all",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers",
                "{{numberId}}",
                "auto-replies",
                "enable-all"
              ]
            },
            "description": "Add ?includeAccountWide=true for rules of all numbers too.\n\nScope: autoreplies:write"
          }
        },
        {
          "name": "Disable all rules",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers/{{numberId}}/auto-replies/disable-all",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers",
                "{{numberId}}",
                "auto-replies",
                "disable-all"
              ]
            },
            "description": "Same filter as enable-all.\n\nScope: autoreplies:write"
          }
        },
        {
          "name": "Delete all rules",
          "request": {
            "method": "DELETE",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers/{{numberId}}/auto-replies?confirm=DELETE_ALL",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers",
                "{{numberId}}",
                "auto-replies"
              ],
              "query": [
                {
                  "key": "confirm",
                  "value": "DELETE_ALL"
                }
              ]
            },
            "description": "Needs ?confirm=DELETE_ALL.\n\nScope: autoreplies:write"
          }
        },
        {
          "name": "Which rule would answer? (no send)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers/{{numberId}}/auto-replies/test",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers",
                "{{numberId}}",
                "auto-replies",
                "test"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"text\": \"عايز اعرف السعر\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Try a text before going live.\n\nScope: autoreplies:read"
          }
        },
        {
          "name": "Reply delay",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers/{{numberId}}/auto-reply-settings",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers",
                "{{numberId}}",
                "auto-reply-settings"
              ]
            },
            "description": "Random delay between min and max seconds.\n\nScope: autoreplies:read"
          }
        },
        {
          "name": "Set the reply delay",
          "request": {
            "method": "PATCH",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers/{{numberId}}/auto-reply-settings",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers",
                "{{numberId}}",
                "auto-reply-settings"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"delaySeconds\": {\n    \"min\": 3,\n    \"max\": 8\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "0–120 s; feels human and spreads load.\n\nScope: autoreplies:write"
          }
        }
      ]
    },
    {
      "name": "OTP (verification codes)",
      "description": "Mursilat generates the code, sends it from your number and keeps only a hash — the code is never returned, stored or logged. Verify with a constant-time check and limited attempts. Deliverability: send OTPs only to people who asked for them, the text is fixed and localized — only your app name is added.",
      "item": [
        {
          "name": "Send a code",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/otp",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "otp"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"numberId\": \"cm1abcd2345efgh6789ijkl\",\n  \"to\": \"201001234567\",\n  \"length\": 6,\n  \"ttlSeconds\": 300,\n  \"maxAttempts\": 5,\n  \"app\": \"متجر النور\",\n  \"copyButton\": true\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "length 4–8, ttlSeconds 60–900, maxAttempts 1–10, app name (letters, digits, spaces; no links). Fixed localized text. Max 5 codes per recipient and 200 recipients per account per hour; opted-out numbers are refused.\n\nScope: otp"
          }
        },
        {
          "name": "Verify a code",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/otp/{{otpId}}/verify",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "otp",
                "{{otpId}}",
                "verify"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"code\": \"048213\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Each call spends one attempt; send the code as a string. reason: INVALID_CODE | EXPIRED | TOO_MANY_ATTEMPTS | ALREADY_VERIFIED.\n\nScope: otp"
          }
        },
        {
          "name": "OTP status",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v2/otp/{{otpId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "otp",
                "{{otpId}}"
              ]
            },
            "description": "pending | verified | expired | locked | failed.\n\nScope: otp"
          }
        }
      ]
    },
    {
      "name": "Number Shield & stats",
      "description": "See how healthy a number is, pause it, make it slower than the Number Shield (never faster) and read daily statistics. No tool can promise a number is never restricted; these lower the risk.",
      "item": [
        {
          "name": "Health",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers/{{numberId}}/health",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers",
                "{{numberId}}",
                "health"
              ]
            },
            "description": "Score, level, reasons, warm-up stage and caps, usage today, pauses, restrictions (reach-out lock), trusted links.\n\nScope: stats:read"
          }
        },
        {
          "name": "Pause a number",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers/{{numberId}}/pause",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers",
                "{{numberId}}",
                "pause"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"minutes\": 120\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "5 min – 7 days. Campaigns and sends to new contacts wait; replies to recent chats still work.\n\nScope: numbers:write"
          }
        },
        {
          "name": "Lift your pause",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers/{{numberId}}/resume",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers",
                "{{numberId}}",
                "resume"
              ]
            },
            "description": "Pauses set by the Number Shield end on their own.\n\nScope: numbers:write"
          }
        },
        {
          "name": "Your limits",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers/{{numberId}}/limits",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers",
                "{{numberId}}",
                "limits"
              ]
            },
            "description": "Limits you set on the number.\n\nScope: stats:read"
          }
        },
        {
          "name": "Set stricter limits",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers/{{numberId}}/limits",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers",
                "{{numberId}}",
                "limits"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"maxPerDay\": 150,\n  \"maxPerHour\": 20,\n  \"minGapSeconds\": 30\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Applied on every send of the number on top of the Number Shield; the stricter value wins.\n\nScope: numbers:write"
          }
        },
        {
          "name": "Remove your limits",
          "request": {
            "method": "DELETE",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers/{{numberId}}/limits",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers",
                "{{numberId}}",
                "limits"
              ]
            },
            "description": "The Number Shield caps stay.\n\nScope: numbers:write"
          }
        },
        {
          "name": "Daily statistics",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers/{{numberId}}/stats?from=2026-10-07&to=2026-10-13",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers",
                "{{numberId}}",
                "stats"
              ],
              "query": [
                {
                  "key": "from",
                  "value": "2026-10-07"
                },
                {
                  "key": "to",
                  "value": "2026-10-13"
                }
              ]
            },
            "description": "sent, delivered, read, failed, replied, opt-outs per day (≤92 days).\n\nScope: stats:read"
          }
        },
        {
          "name": "Today across numbers",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v2/stats/today",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "stats",
                "today"
              ]
            },
            "description": "Totals and per number.\n\nScope: stats:read"
          }
        }
      ]
    },
    {
      "name": "Groups",
      "description": "Read the groups of a number. Sending to groups is blocked by the Number Shield on purpose: spam reports from groups get numbers banned fastest. This is a safety decision, not a missing feature.",
      "item": [
        {
          "name": "List groups",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers/{{numberId}}/groups",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers",
                "{{numberId}}",
                "groups"
              ]
            },
            "description": "Subject, size and whether the number is admin.\n\nScope: groups:read"
          }
        },
        {
          "name": "Group info",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v2/numbers/{{numberId}}/groups/{{groupId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "numbers",
                "{{numberId}}",
                "groups",
                "{{groupId}}"
              ]
            },
            "description": "Participants and invite link only when the number is admin.\n\nScope: groups:read"
          }
        }
      ]
    },
    {
      "name": "Webhooks",
      "description": "Real-time events signed with HMAC-SHA256 (X-Wasla-Signature: t=…,v1=…), retried for about an hour. One account-level URL for all numbers, and/or one per number. The delivery log keeps metadata only (7 days).",
      "item": [
        {
          "name": "Event catalog",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v2/webhooks/events",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "webhooks",
                "events"
              ]
            },
            "description": "All event types with a description.\n\nScope: webhooks:read"
          }
        },
        {
          "name": "Account webhook",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v2/webhook",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "webhook"
              ]
            },
            "description": "One URL for every number.\n\nScope: webhooks:read"
          }
        },
        {
          "name": "Set the account webhook",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/webhook",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "webhook"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"url\": \"https://example.com/mursilat\",\n  \"events\": null\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Public https URL (SSRF-checked). Secret returned once on creation.\n\nScope: webhooks:write"
          }
        },
        {
          "name": "Remove the account webhook",
          "request": {
            "method": "DELETE",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/webhook",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "webhook"
              ]
            },
            "description": "Queued retries are cancelled.\n\nScope: webhooks:write"
          }
        },
        {
          "name": "Send a test event",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/webhook/test",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "webhook",
                "test"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"numberId\": \"cm1abcd2345efgh6789ijkl\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "webhook.test to the account webhook.\n\nScope: webhooks:write"
          }
        },
        {
          "name": "Rotate the account webhook secret",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/webhook/rotate-secret",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "webhook",
                "rotate-secret"
              ]
            },
            "description": "Shown once.\n\nScope: webhooks:write"
          }
        },
        {
          "name": "Delivery log",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v2/webhooks/deliveries?status=FAILED",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "webhooks",
                "deliveries"
              ],
              "query": [
                {
                  "key": "status",
                  "value": "FAILED"
                }
              ]
            },
            "description": "Metadata only — event payloads are never returned.\n\nScope: webhooks:read"
          }
        },
        {
          "name": "One delivery",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v2/webhooks/deliveries/{{deliveryId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "webhooks",
                "deliveries",
                "{{deliveryId}}"
              ]
            },
            "description": "With every attempt (time, HTTP status, duration, error).\n\nScope: webhooks:read"
          }
        },
        {
          "name": "Redeliver (retry window)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/webhooks/deliveries/{{deliveryId}}/redeliver",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "webhooks",
                "deliveries",
                "{{deliveryId}}",
                "redeliver"
              ]
            },
            "description": "Same event id; possible for about an hour after the event.\n\nScope: webhooks:write"
          }
        }
      ]
    },
    {
      "name": "Website button & WhatsApp links",
      "description": "A chat button for your website (one script tag) and tracked wa.me links / QR codes for ads, bios and print. Every click gets a short ref code in the prefilled text; when the visitor writes, Mursilat links the chat to the page / ad / campaign (webhook conversation.attributed). Inbound-first chats are the safest for your number. No visitor IP, cookie or full URL is stored.",
      "item": [
        {
          "name": "List website buttons",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v2/widgets?limit=25",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "widgets"
              ],
              "query": [
                {
                  "key": "limit",
                  "value": "25"
                }
              ]
            },
            "description": "Buttons of the numbers this key can see, newest first, with 7-day clicks / conversations.\n\nScope: widgets:read"
          }
        },
        {
          "name": "Create a website button",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/widgets",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "widgets"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"Main website\",\n  \"numberId\": \"cm1abcd2345efgh6789ijkl\",\n  \"allowedDomains\": [\n    \"example.com\"\n  ],\n  \"settings\": {\n    \"buttonText\": {\n      \"ar\": \"كلمنا واتساب\",\n      \"en\": \"Chat with us\"\n    },\n    \"attribution\": {\n      \"enabled\": true,\n      \"label\": \"ref\",\n      \"position\": \"end\"\n    }\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "numberId and allowedDomains are required; settings are optional (defaults like the dashboard). The answer carries the embed snippet. Plan limits: starter 1, growth 5, business unlimited; hiding \"Powered by Mursilat\" needs growth+.\n\nScope: widgets:write"
          }
        },
        {
          "name": "Get a website button",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v2/widgets/{{widgetId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "widgets",
                "{{widgetId}}"
              ]
            },
            "description": "Settings, domains, snippet and 7-day counts.\n\nScope: widgets:read"
          }
        },
        {
          "name": "Update a website button",
          "request": {
            "method": "PATCH",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/widgets/{{widgetId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "widgets",
                "{{widgetId}}"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"enabled\": false\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Any of name, enabled, numberId, allowedDomains, settings (a complete settings object replaces the old one; the public config refreshes within 5 minutes).\n\nScope: widgets:write"
          }
        },
        {
          "name": "Delete a website button",
          "request": {
            "method": "DELETE",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/widgets/{{widgetId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "widgets",
                "{{widgetId}}"
              ]
            },
            "description": "The snippet stops rendering; its clicks and stats are deleted.\n\nScope: widgets:write"
          }
        },
        {
          "name": "Website button statistics",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v2/widgets/{{widgetId}}/stats?from=2026-10-01&to=2026-10-14",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "widgets",
                "{{widgetId}}",
                "stats"
              ],
              "query": [
                {
                  "key": "from",
                  "value": "2026-10-01"
                },
                {
                  "key": "to",
                  "value": "2026-10-14"
                }
              ]
            },
            "description": "Impressions (only when enabled, sampled), clicks, attributed conversations and conversion rate — per day, page, utm source / medium, campaign, agent, device and referrer domain. Counts only.\n\nScope: widgets:read"
          }
        },
        {
          "name": "List tracked WhatsApp links",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v2/links?limit=25",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "links"
              ],
              "query": [
                {
                  "key": "limit",
                  "value": "25"
                }
              ]
            },
            "description": "Links of the numbers this key can see, newest first.\n\nScope: links:read"
          }
        },
        {
          "name": "Create a tracked WhatsApp link",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/links",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "links"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"Instagram bio\",\n  \"numberId\": \"cm1abcd2345efgh6789ijkl\",\n  \"message\": \"عايز أعرف الأسعار\",\n  \"utm\": {\n    \"source\": \"instagram\",\n    \"medium\": \"bio\"\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "https://mursilat.com/l/<slug> records an anonymous click and redirects (302) to wa.me with the prefilled text + ref code — never anywhere else. Slug: random 10 chars (unguessable) or a custom word. utm_* on the visited URL override the defaults. QR codes (SVG / PNG) are in the dashboard.\n\nScope: links:write"
          }
        },
        {
          "name": "Get a tracked link",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v2/links/{{linkId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "links",
                "{{linkId}}"
              ]
            },
            "description": "URL, prefilled text, utm defaults and 7-day counts.\n\nScope: links:read"
          }
        },
        {
          "name": "Update a tracked link",
          "request": {
            "method": "PATCH",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/links/{{linkId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "links",
                "{{linkId}}"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"enabled\": false\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Any of name, numberId, message, utm, slug (null = new random slug), attribution, enabled (a disabled link answers 410).\n\nScope: links:write"
          }
        },
        {
          "name": "Delete a tracked link",
          "request": {
            "method": "DELETE",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v2/links/{{linkId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "links",
                "{{linkId}}"
              ]
            },
            "description": "The URL stops working (404); clicks and stats are deleted.\n\nScope: links:write"
          }
        },
        {
          "name": "Tracked link statistics",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v2/links/{{linkId}}/stats?from=2026-10-01&to=2026-10-14",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v2",
                "links",
                "{{linkId}}",
                "stats"
              ],
              "query": [
                {
                  "key": "from",
                  "value": "2026-10-01"
                },
                {
                  "key": "to",
                  "value": "2026-10-14"
                }
              ]
            },
            "description": "Clicks, attributed conversations and conversion rate per day, utm source / medium, campaign, device and referrer domain.\n\nScope: links:read"
          }
        }
      ]
    }
  ]
}
