{"openapi":"3.1.0","info":{"title":"Wamafy API","version":"1.0.0","description":"Send and receive WhatsApp messages, and manage contacts, from your own systems. Docs: https://wamafy.com/developers"},"servers":[{"url":"https://api.wamafy.com/api/v1/public"}],"security":[{"apiKey":[]}],"tags":[{"name":"Messages","description":"Send templates at any time, reply freely inside the 24-hour window, and check what happened to a message."},{"name":"Templates","description":"The pre-approved messages you send to start a conversation."},{"name":"Media","description":"Upload files to send as messages or template headers."},{"name":"Contacts","description":"Keep your customer list in step with your own system. The phone number is the key."},{"name":"Segments","description":"Saved audiences built in the dashboard, read over the API."},{"name":"Campaigns","description":"Send one template to many people in a single call, now or later, and follow how it goes."},{"name":"Payments","description":"Ask for a payment the customer makes inside WhatsApp, and see when it is paid."},{"name":"Analytics","description":"Message totals for reporting."}],"paths":{"/messages":{"post":{"operationId":"sendTemplate","summary":"Send a template message","description":"Sends one approved template. This is the message to use when you start the conversation: an order update, an OTP, a reminder. Outside the 24-hour window it is the only kind WhatsApp will deliver (see [The 24-hour window](/developers/guides/messaging-window)).\n\nGet the template names and the variables each expects from [List templates](/developers/api/list-templates).","tags":["Messages"],"security":[{"apiKey":[]}],"x-scope":"messages:send","responses":{"200":{"description":"Success","content":{"application/json":{"example":{"success":true,"data":{"messageId":"wamid.HBgMOTE5ODc2NTQzMjEwFQIAERgSQzU","to":"919876543210","from":"6f1c2a9e-1b3d-4c7a-9e2f-7d4b8a1c0e55","status":"sent","campaignName":null,"templateName":"order_update"}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-codeSamples":[{"lang":"Shell","label":"cURL","source":"# macOS, Linux or Git Bash, with WAMAFY_API_KEY set. The quoting does not work in Windows cmd or PowerShell.\ncurl -X POST \"https://api.wamafy.com/api/v1/public/messages\" \\\n  -H \"Authorization: Bearer $WAMAFY_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"to\": \"+919876543210\",\n  \"templateName\": \"order_update\",\n  \"variables\": {\n    \"1\": \"Priya\",\n    \"2\": \"#1043\"\n  }\n}'"},{"lang":"JavaScript","label":"Node.js","source":"// Node.js 18+. Save as example.mjs (it uses top-level await) and run: node example.mjs\n\nconst res = await fetch('https://api.wamafy.com/api/v1/public/messages', {\n  method: 'POST',\n  headers: {\n    Authorization: `Bearer ${process.env.WAMAFY_API_KEY}`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({\n    to: '+919876543210',\n    templateName: 'order_update',\n    variables: {\n      '1': 'Priya',\n      '2': '#1043',\n    },\n  }),\n});\n\nconst body = await res.json();\nif (!body.success) throw new Error(body.error.message);\nconsole.log(body.data);"},{"lang":"Python","label":"Python","source":"# Python 3.8+. Needs: pip install requests\nimport os\n\nimport requests\n\nres = requests.post(\n    \"https://api.wamafy.com/api/v1/public/messages\",\n    headers={\"Authorization\": f\"Bearer {os.environ['WAMAFY_API_KEY']}\"},\n    json={\n        \"to\": \"+919876543210\",\n        \"templateName\": \"order_update\",\n        \"variables\": {\n            \"1\": \"Priya\",\n            \"2\": \"#1043\",\n        },\n    },\n)\n\nbody = res.json()\nif not body[\"success\"]:\n    raise RuntimeError(body[\"error\"][\"message\"])\nprint(body[\"data\"])"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"to":{"type":"string","description":"Recipient phone number with country code, for example `+919876543210`. Spaces and dashes are ignored. A number without a country code is not guessed at and will not reach anyone."},"from":{"type":"string","description":"Which of your WhatsApp numbers to send from. Accepts the number itself, its Meta `phone_number_id` or its Wamafy id. Defaults to your default number."},"templateName":{"type":"string","description":"Name of an approved template. Optional when you pass `campaignName`, because the campaign names the template."},"variables":{"type":"object","additionalProperties":true,"description":"Values for the template placeholders. A template written as `Hi {{1}}` takes positions as keys (`\"1\"`, `\"2\"`); one written as `Hi {{customer_name}}` takes the names. Values are strings or numbers. List templates says which kind each template is (`variableFormat`) and gives the keys. See the examples below."},"campaignName":{"type":"string","description":"File the send under an API campaign so it shows in that campaign's report. See [API campaigns](/developers/guides/api-campaigns)."},"language":{"type":"string","description":"Template language. Defaults to the template's own."},"headerMediaUrl":{"type":"string","description":"Public `https` link to the image, video or document, for a template with a media header. Required for those: we refuse the send without it. List templates gives each template's `headerType`."},"buttons":{"type":"array","items":{"type":"object","properties":{"index":{"type":"integer","description":"The button's position in the template, starting at 0, as List templates reports it."},"type":{"type":"string","enum":["url","copy_code"],"description":"What kind of button it is."},"value":{"type":"string","description":"For a URL button, only the part that replaces the placeholder (`order/1043`). For a tracked link, the full destination URL instead (see [Click tracking](/developers/guides/click-tracking)). For copy code, the code."}},"required":["index","type","value"]},"description":"Values for dynamic buttons: a URL button with a placeholder, or a copy-code button. Required when the template has one, since WhatsApp rejects the send without it."},"offerExpiresAt":{"type":"string","description":"For a limited-time offer template with a countdown: when the offer ends, as an ISO 8601 time with offset. Must be in the future."},"catalogProductRetailerId":{"type":"string","description":"For a catalog template: the retailer id of the product whose image becomes the thumbnail. Optional: without it WhatsApp picks the picture."},"products":{"type":"object","properties":{"productIds":{"type":"array","items":{"type":"string"},"description":"Content IDs from Commerce Manager. A multi-product template takes 1 to 30, a single-product template exactly 1, a product carousel 2 to 10 (one card each)."},"catalogId":{"type":"string","description":"Your Meta catalog's ID. Required for a single-product template and a product carousel."},"thumbnailProductId":{"type":"string","description":"Multi-product only: the product whose picture leads the message. Defaults to the first."},"sectionTitle":{"type":"string","description":"Multi-product only: the heading over the list, up to 24 characters. Defaults to Products."}},"required":["productIds"],"description":"For a product template (multi-product, single-product or product carousel): the products to show. Required for those: we refuse the send without them. List templates gives each template's `headerType` (`mpm`, `spm`, `product_carousel`)."}},"required":["to","templateName"]},"example":{"to":"+919876543210","templateName":"order_update","variables":{"1":"Priya","2":"#1043"}}}}}}},"/messages/{messageId}":{"get":{"operationId":"getMessageStatus","summary":"Get message status","description":"Returns where a message has got to, with the time of each step. Works for templates sent through this API and for replies sent inside the 24-hour window, whether they came from the API, the inbox or a chatbot. Broadcast and drip messages are reported in the dashboard, not here.\n\nIf you would rather be told than ask, register a [status webhook](/developers/webhooks/status) and the same changes are pushed to you.","tags":["Messages"],"security":[{"apiKey":[]}],"x-scope":"messages:send","parameters":[{"name":"messageId","in":"path","required":true,"description":"The `messageId` a send returned (starts with `wamid.`).","schema":{"type":"string","description":"The `messageId` a send returned (starts with `wamid.`)."}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"success":true,"data":{"messageId":"wamid.HBgMOTE5ODc2NTQzMjEwFQIAERgSQzU","to":"919876543210","type":"template","templateName":"order_update","status":"read","sentAt":"2026-10-07T10:00:00.000Z","deliveredAt":"2026-10-07T10:00:02.000Z","readAt":"2026-10-07T10:03:41.000Z","failedAt":null,"clickedAt":null,"error":null}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-codeSamples":[{"lang":"Shell","label":"cURL","source":"# macOS, Linux or Git Bash, with WAMAFY_API_KEY set. The quoting does not work in Windows cmd or PowerShell.\ncurl \"https://api.wamafy.com/api/v1/public/messages/wamid.HBgMOTE5ODc2NTQzMjEwFQIAERgSQzU\" \\\n  -H \"Authorization: Bearer $WAMAFY_API_KEY\""},{"lang":"JavaScript","label":"Node.js","source":"// Node.js 18+. Save as example.mjs (it uses top-level await) and run: node example.mjs\n\nconst res = await fetch('https://api.wamafy.com/api/v1/public/messages/wamid.HBgMOTE5ODc2NTQzMjEwFQIAERgSQzU', {\n  headers: {\n    Authorization: `Bearer ${process.env.WAMAFY_API_KEY}`,\n  },\n});\n\nconst body = await res.json();\nif (!body.success) throw new Error(body.error.message);\nconsole.log(body.data);"},{"lang":"Python","label":"Python","source":"# Python 3.8+. Needs: pip install requests\nimport os\n\nimport requests\n\nres = requests.get(\n    \"https://api.wamafy.com/api/v1/public/messages/wamid.HBgMOTE5ODc2NTQzMjEwFQIAERgSQzU\",\n    headers={\"Authorization\": f\"Bearer {os.environ['WAMAFY_API_KEY']}\"},\n)\n\nbody = res.json()\nif not body[\"success\"]:\n    raise RuntimeError(body[\"error\"][\"message\"])\nprint(body[\"data\"])"}]}},"/window":{"get":{"operationId":"checkWindow","summary":"Check the reply window","description":"Tells you if the 24-hour window is open for a contact, and when it closes. Use it to decide between a free-form reply and a template. See [The 24-hour window](/developers/guides/messaging-window).","tags":["Messages"],"security":[{"apiKey":[]}],"x-scope":"messages:send","parameters":[{"name":"to","in":"query","required":true,"description":"The contact's phone number with country code.","schema":{"type":"string","description":"The contact's phone number with country code."}},{"name":"from","in":"query","required":false,"description":"Which of your WhatsApp numbers to send from. Accepts the number itself, its Meta `phone_number_id` or its Wamafy id. Defaults to your default number.","schema":{"type":"string","description":"Which of your WhatsApp numbers to send from. Accepts the number itself, its Meta `phone_number_id` or its Wamafy id. Defaults to your default number."}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"success":true,"data":{"to":"+919876543210","windowOpen":true,"expiresAt":"2026-10-08T09:59:58.000Z"}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-codeSamples":[{"lang":"Shell","label":"cURL","source":"# macOS, Linux or Git Bash, with WAMAFY_API_KEY set. The quoting does not work in Windows cmd or PowerShell.\ncurl \"https://api.wamafy.com/api/v1/public/window?to=%2B919876543210\" \\\n  -H \"Authorization: Bearer $WAMAFY_API_KEY\""},{"lang":"JavaScript","label":"Node.js","source":"// Node.js 18+. Save as example.mjs (it uses top-level await) and run: node example.mjs\n\nconst res = await fetch(`https://api.wamafy.com/api/v1/public/window?${new URLSearchParams({\n  to: '+919876543210',\n})}`, {\n  headers: {\n    Authorization: `Bearer ${process.env.WAMAFY_API_KEY}`,\n  },\n});\n\nconst body = await res.json();\nif (!body.success) throw new Error(body.error.message);\nconsole.log(body.data);"},{"lang":"Python","label":"Python","source":"# Python 3.8+. Needs: pip install requests\nimport os\n\nimport requests\n\nres = requests.get(\n    \"https://api.wamafy.com/api/v1/public/window\",\n    headers={\"Authorization\": f\"Bearer {os.environ['WAMAFY_API_KEY']}\"},\n    params={\n        \"to\": \"+919876543210\",\n    },\n)\n\nbody = res.json()\nif not body[\"success\"]:\n    raise RuntimeError(body[\"error\"][\"message\"])\nprint(body[\"data\"])"}]}},"/messages/text":{"post":{"operationId":"sendText","summary":"Send a text message","description":"Sends a free-form text reply. Only works while the person's 24-hour window is open, meaning they messaged you in the last 24 hours. Otherwise send a template.","tags":["Messages"],"security":[{"apiKey":[]}],"x-scope":"messages:send","responses":{"200":{"description":"Success","content":{"application/json":{"example":{"success":true,"data":{"messageId":"wamid.HBgMOTE5ODc2NTQzMjEwFQIAERgSRjI","conversationId":"2b7e4f10-8c3a-4d2e-b1f6-0a9c5e7d3b21","status":"sent"}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-codeSamples":[{"lang":"Shell","label":"cURL","source":"# macOS, Linux or Git Bash, with WAMAFY_API_KEY set. The quoting does not work in Windows cmd or PowerShell.\ncurl -X POST \"https://api.wamafy.com/api/v1/public/messages/text\" \\\n  -H \"Authorization: Bearer $WAMAFY_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"to\": \"+919876543210\",\n  \"text\": \"Yes, the blue one is in stock. Shall I keep it aside for you?\"\n}'"},{"lang":"JavaScript","label":"Node.js","source":"// Node.js 18+. Save as example.mjs (it uses top-level await) and run: node example.mjs\n\nconst res = await fetch('https://api.wamafy.com/api/v1/public/messages/text', {\n  method: 'POST',\n  headers: {\n    Authorization: `Bearer ${process.env.WAMAFY_API_KEY}`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({\n    to: '+919876543210',\n    text: 'Yes, the blue one is in stock. Shall I keep it aside for you?',\n  }),\n});\n\nconst body = await res.json();\nif (!body.success) throw new Error(body.error.message);\nconsole.log(body.data);"},{"lang":"Python","label":"Python","source":"# Python 3.8+. Needs: pip install requests\nimport os\n\nimport requests\n\nres = requests.post(\n    \"https://api.wamafy.com/api/v1/public/messages/text\",\n    headers={\"Authorization\": f\"Bearer {os.environ['WAMAFY_API_KEY']}\"},\n    json={\n        \"to\": \"+919876543210\",\n        \"text\": \"Yes, the blue one is in stock. Shall I keep it aside for you?\",\n    },\n)\n\nbody = res.json()\nif not body[\"success\"]:\n    raise RuntimeError(body[\"error\"][\"message\"])\nprint(body[\"data\"])"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"to":{"type":"string","description":"Recipient phone number with country code, for example `+919876543210`. Spaces and dashes are ignored. A number without a country code is not guessed at and will not reach anyone."},"from":{"type":"string","description":"Which of your WhatsApp numbers to send from. Accepts the number itself, its Meta `phone_number_id` or its Wamafy id. Defaults to your default number."},"text":{"type":"string","description":"The message. Up to 4,096 characters."}},"required":["to","text"]},"example":{"to":"+919876543210","text":"Yes, the blue one is in stock. Shall I keep it aside for you?"}}}}}},"/messages/interactive":{"post":{"operationId":"sendInteractive","summary":"Send buttons or a list","description":"Sends a message the person answers by tapping: up to three reply buttons, or a list menu. Pass `buttons` or `list`, not both. Only works inside the 24-hour window.\n\nTheir choice comes back on the [message.inbound](/developers/webhooks/events) webhook, with the `id` you gave the button or row in `interactiveReplyId`.","tags":["Messages"],"security":[{"apiKey":[]}],"x-scope":"messages:send","responses":{"200":{"description":"Success","content":{"application/json":{"example":{"success":true,"data":{"messageId":"wamid.HBgMOTE5ODc2NTQzMjEwFQIAERgSN0E","conversationId":"2b7e4f10-8c3a-4d2e-b1f6-0a9c5e7d3b21","status":"sent"}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-codeSamples":[{"lang":"Shell","label":"cURL","source":"# macOS, Linux or Git Bash, with WAMAFY_API_KEY set. The quoting does not work in Windows cmd or PowerShell.\ncurl -X POST \"https://api.wamafy.com/api/v1/public/messages/interactive\" \\\n  -H \"Authorization: Bearer $WAMAFY_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"to\": \"+919876543210\",\n  \"body\": \"When should we deliver?\",\n  \"buttons\": [\n    {\n      \"id\": \"today\",\n      \"title\": \"Today\"\n    },\n    {\n      \"id\": \"tomorrow\",\n      \"title\": \"Tomorrow\"\n    }\n  ]\n}'"},{"lang":"JavaScript","label":"Node.js","source":"// Node.js 18+. Save as example.mjs (it uses top-level await) and run: node example.mjs\n\nconst res = await fetch('https://api.wamafy.com/api/v1/public/messages/interactive', {\n  method: 'POST',\n  headers: {\n    Authorization: `Bearer ${process.env.WAMAFY_API_KEY}`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({\n    to: '+919876543210',\n    body: 'When should we deliver?',\n    buttons: [\n      {\n        id: 'today',\n        title: 'Today',\n      },\n      {\n        id: 'tomorrow',\n        title: 'Tomorrow',\n      },\n    ],\n  }),\n});\n\nconst body = await res.json();\nif (!body.success) throw new Error(body.error.message);\nconsole.log(body.data);"},{"lang":"Python","label":"Python","source":"# Python 3.8+. Needs: pip install requests\nimport os\n\nimport requests\n\nres = requests.post(\n    \"https://api.wamafy.com/api/v1/public/messages/interactive\",\n    headers={\"Authorization\": f\"Bearer {os.environ['WAMAFY_API_KEY']}\"},\n    json={\n        \"to\": \"+919876543210\",\n        \"body\": \"When should we deliver?\",\n        \"buttons\": [\n            {\n                \"id\": \"today\",\n                \"title\": \"Today\",\n            },\n            {\n                \"id\": \"tomorrow\",\n                \"title\": \"Tomorrow\",\n            },\n        ],\n    },\n)\n\nbody = res.json()\nif not body[\"success\"]:\n    raise RuntimeError(body[\"error\"][\"message\"])\nprint(body[\"data\"])"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"to":{"type":"string","description":"Recipient phone number with country code, for example `+919876543210`. Spaces and dashes are ignored. A number without a country code is not guessed at and will not reach anyone."},"from":{"type":"string","description":"Which of your WhatsApp numbers to send from. Accepts the number itself, its Meta `phone_number_id` or its Wamafy id. Defaults to your default number."},"body":{"type":"string","description":"Main text. Up to 1,024 characters."},"header":{"type":"string","description":"Bold line above the body. Up to 60 characters."},"footer":{"type":"string","description":"Small grey line below. Up to 60 characters."},"buttons":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Your id for the button, returned when it is tapped."},"title":{"type":"string","description":"Button text. Up to 20 characters."}},"required":["id","title"]},"description":"One to three reply buttons."},"list":{"type":"object","properties":{"buttonText":{"type":"string","description":"Text on the button that opens the list. Up to 20 characters."},"sections":{"type":"array","items":{"type":"object","additionalProperties":true},"description":"One to ten sections, each with a `title` (optional, 24 characters) and `rows`: one to ten items with `id`, `title` (24 characters) and an optional `description` (72 characters)."}},"required":["buttonText","sections"],"description":"A list menu, opened by a button."}},"required":["to","body"]},"example":{"to":"+919876543210","body":"When should we deliver?","buttons":[{"id":"today","title":"Today"},{"id":"tomorrow","title":"Tomorrow"}]}}}}}},"/messages/media":{"post":{"operationId":"sendMedia","summary":"Send a file","description":"Sends a file up to 16 MB. Give either a public `link` we fetch, or a `mediaHandle` from [Upload a file](/developers/api/upload-media). Only works inside the 24-hour window.","tags":["Messages"],"security":[{"apiKey":[]}],"x-scope":"messages:send","responses":{"200":{"description":"Success","content":{"application/json":{"example":{"success":true,"data":{"messageId":"wamid.HBgMOTE5ODc2NTQzMjEwFQIAERgSOUQ","conversationId":"2b7e4f10-8c3a-4d2e-b1f6-0a9c5e7d3b21","status":"sent"}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-codeSamples":[{"lang":"Shell","label":"cURL","source":"# macOS, Linux or Git Bash, with WAMAFY_API_KEY set. The quoting does not work in Windows cmd or PowerShell.\ncurl -X POST \"https://api.wamafy.com/api/v1/public/messages/media\" \\\n  -H \"Authorization: Bearer $WAMAFY_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"to\": \"+919876543210\",\n  \"link\": \"https://wamafy.com/smoke/sample.pdf\",\n  \"caption\": \"Your invoice\",\n  \"filename\": \"INV-1043.pdf\"\n}'"},{"lang":"JavaScript","label":"Node.js","source":"// Node.js 18+. Save as example.mjs (it uses top-level await) and run: node example.mjs\n\nconst res = await fetch('https://api.wamafy.com/api/v1/public/messages/media', {\n  method: 'POST',\n  headers: {\n    Authorization: `Bearer ${process.env.WAMAFY_API_KEY}`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({\n    to: '+919876543210',\n    link: 'https://wamafy.com/smoke/sample.pdf',\n    caption: 'Your invoice',\n    filename: 'INV-1043.pdf',\n  }),\n});\n\nconst body = await res.json();\nif (!body.success) throw new Error(body.error.message);\nconsole.log(body.data);"},{"lang":"Python","label":"Python","source":"# Python 3.8+. Needs: pip install requests\nimport os\n\nimport requests\n\nres = requests.post(\n    \"https://api.wamafy.com/api/v1/public/messages/media\",\n    headers={\"Authorization\": f\"Bearer {os.environ['WAMAFY_API_KEY']}\"},\n    json={\n        \"to\": \"+919876543210\",\n        \"link\": \"https://wamafy.com/smoke/sample.pdf\",\n        \"caption\": \"Your invoice\",\n        \"filename\": \"INV-1043.pdf\",\n    },\n)\n\nbody = res.json()\nif not body[\"success\"]:\n    raise RuntimeError(body[\"error\"][\"message\"])\nprint(body[\"data\"])"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"to":{"type":"string","description":"Recipient phone number with country code, for example `+919876543210`. Spaces and dashes are ignored. A number without a country code is not guessed at and will not reach anyone."},"from":{"type":"string","description":"Which of your WhatsApp numbers to send from. Accepts the number itself, its Meta `phone_number_id` or its Wamafy id. Defaults to your default number."},"link":{"type":"string","description":"Public URL of the file. We download it when you send, so it must be reachable without a login."},"mediaHandle":{"type":"string","description":"Handle returned by Upload a file."},"caption":{"type":"string","description":"Text shown with the file. Up to 1,024 characters."},"filename":{"type":"string","description":"File name shown for a document."}},"required":["to"]},"example":{"to":"+919876543210","link":"https://wamafy.com/smoke/sample.pdf","caption":"Your invoice","filename":"INV-1043.pdf"}}}}}},"/templates":{"get":{"operationId":"listTemplates","summary":"List templates","description":"Returns your approved templates. Each one lists the variables to fill in and its buttons, so you know exactly what [Send a template message](/developers/api/send-template) expects.","tags":["Templates"],"security":[{"apiKey":[]}],"x-scope":"templates:read","parameters":[{"name":"number","in":"query","required":false,"description":"Only the templates one of your WhatsApp numbers can send. Accepts the number, its Meta `phone_number_id` or its Wamafy id.","schema":{"type":"string","description":"Only the templates one of your WhatsApp numbers can send. Accepts the number, its Meta `phone_number_id` or its Wamafy id."}},{"name":"status","in":"query","required":false,"description":"Review status to return. Defaults to `approved`. Use `all` to follow a template you just submitted.","schema":{"type":"string","enum":["approved","pending","rejected","paused","disabled","all"],"description":"Review status to return. Defaults to `approved`. Use `all` to follow a template you just submitted."}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"success":true,"data":[{"name":"order_update","language":"en","category":"UTILITY","status":"APPROVED","bodyText":"Hi {{1}}, your order {{2}} is on its way.","headerType":null,"variableFormat":"positional","variables":[{"key":"1","example":"Priya"},{"key":"2","example":"#1043"}],"buttons":[{"index":0,"type":"url","text":"Track order","needsValue":true,"tracked":true},{"index":1,"type":"quick_reply","text":"Talk to us","needsValue":false,"tracked":false}]}]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-codeSamples":[{"lang":"Shell","label":"cURL","source":"# macOS, Linux or Git Bash, with WAMAFY_API_KEY set. The quoting does not work in Windows cmd or PowerShell.\ncurl \"https://api.wamafy.com/api/v1/public/templates\" \\\n  -H \"Authorization: Bearer $WAMAFY_API_KEY\""},{"lang":"JavaScript","label":"Node.js","source":"// Node.js 18+. Save as example.mjs (it uses top-level await) and run: node example.mjs\n\nconst res = await fetch('https://api.wamafy.com/api/v1/public/templates', {\n  headers: {\n    Authorization: `Bearer ${process.env.WAMAFY_API_KEY}`,\n  },\n});\n\nconst body = await res.json();\nif (!body.success) throw new Error(body.error.message);\nconsole.log(body.data);"},{"lang":"Python","label":"Python","source":"# Python 3.8+. Needs: pip install requests\nimport os\n\nimport requests\n\nres = requests.get(\n    \"https://api.wamafy.com/api/v1/public/templates\",\n    headers={\"Authorization\": f\"Bearer {os.environ['WAMAFY_API_KEY']}\"},\n)\n\nbody = res.json()\nif not body[\"success\"]:\n    raise RuntimeError(body[\"error\"][\"message\"])\nprint(body[\"data\"])"}]},"post":{"operationId":"createTemplate","summary":"Create a template","description":"Creates a template and submits it to Meta for review. Most are approved within minutes. Check with [List templates](/developers/api/list-templates) and `status=all` until it shows `APPROVED`.\n\nThe fields below are for a standard template. Carousel, catalog, product and limited-time offer templates are easier to build in the dashboard.","tags":["Templates"],"security":[{"apiKey":[]}],"x-scope":"templates:write","parameters":[{"name":"number","in":"query","required":false,"description":"Create it in the WhatsApp Business Account of this number. Defaults to your default number's account.","schema":{"type":"string","description":"Create it in the WhatsApp Business Account of this number. Defaults to your default number's account."}}],"responses":{"201":{"description":"Success","content":{"application/json":{"example":{"success":true,"data":{"name":"order_shipped","language":"en","category":"UTILITY","status":"PENDING"}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-codeSamples":[{"lang":"Shell","label":"cURL","source":"# macOS, Linux or Git Bash, with WAMAFY_API_KEY set. The quoting does not work in Windows cmd or PowerShell.\ncurl -X POST \"https://api.wamafy.com/api/v1/public/templates\" \\\n  -H \"Authorization: Bearer $WAMAFY_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"variant\": \"STANDARD\",\n  \"name\": \"order_shipped\",\n  \"category\": \"UTILITY\",\n  \"language\": \"en\",\n  \"header\": {\n    \"type\": \"NONE\"\n  },\n  \"body\": \"Hi {{1}}, your order {{2}} has shipped.\",\n  \"bodyExamples\": [\n    \"Priya\",\n    \"#1043\"\n  ]\n}'"},{"lang":"JavaScript","label":"Node.js","source":"// Node.js 18+. Save as example.mjs (it uses top-level await) and run: node example.mjs\n\nconst res = await fetch('https://api.wamafy.com/api/v1/public/templates', {\n  method: 'POST',\n  headers: {\n    Authorization: `Bearer ${process.env.WAMAFY_API_KEY}`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({\n    variant: 'STANDARD',\n    name: 'order_shipped',\n    category: 'UTILITY',\n    language: 'en',\n    header: {\n      type: 'NONE',\n    },\n    body: 'Hi {{1}}, your order {{2}} has shipped.',\n    bodyExamples: ['Priya', '#1043'],\n  }),\n});\n\nconst body = await res.json();\nif (!body.success) throw new Error(body.error.message);\nconsole.log(body.data);"},{"lang":"Python","label":"Python","source":"# Python 3.8+. Needs: pip install requests\nimport os\n\nimport requests\n\nres = requests.post(\n    \"https://api.wamafy.com/api/v1/public/templates\",\n    headers={\"Authorization\": f\"Bearer {os.environ['WAMAFY_API_KEY']}\"},\n    json={\n        \"variant\": \"STANDARD\",\n        \"name\": \"order_shipped\",\n        \"category\": \"UTILITY\",\n        \"language\": \"en\",\n        \"header\": {\n            \"type\": \"NONE\",\n        },\n        \"body\": \"Hi {{1}}, your order {{2}} has shipped.\",\n        \"bodyExamples\": [\"Priya\", \"#1043\"],\n    },\n)\n\nbody = res.json()\nif not body[\"success\"]:\n    raise RuntimeError(body[\"error\"][\"message\"])\nprint(body[\"data\"])"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"variant":{"type":"string","enum":["STANDARD","CAROUSEL","CATALOG","PRODUCT_LIST","SINGLE_PRODUCT","PRODUCT_CAROUSEL","LIMITED_TIME_OFFER"],"description":"Template kind. Use `STANDARD`."},"name":{"type":"string","description":"Lowercase letters, numbers and underscores, for example `order_shipped`."},"category":{"type":"string","enum":["MARKETING","UTILITY","AUTHENTICATION"],"description":"How Meta classifies and prices it."},"language":{"type":"string","description":"Language code. Defaults to `en`."},"header":{"type":"object","additionalProperties":true,"description":"Use `{ \"type\": \"NONE\" }` for no header, `{ \"type\": \"TEXT\", \"text\": \"...\" }` for a text header, or `IMAGE`, `VIDEO` or `DOCUMENT` with a `mediaHandle` from [Upload a file](/developers/api/upload-media)."},"body":{"type":"string","description":"Message text, with placeholders such as `{{1}}`."},"bodyExamples":{"type":"array","items":{"type":"string"},"description":"An example value for each positional placeholder, in order. Meta needs these to review the template."},"bodyExamplesNamed":{"type":"array","items":{"type":"object","additionalProperties":true},"description":"For named placeholders: `{ \"param_name\": \"...\", \"example\": \"...\" }` for each."},"footer":{"type":"string","description":"Small grey line under the body."},"buttons":{"type":"array","items":{"type":"object","additionalProperties":true},"description":"Up to 10 buttons. Each has a `type` (`QUICK_REPLY`, `URL`, `PHONE_NUMBER`, `COPY_CODE`) and `text`. A `URL` button takes `url`; put `{{1}}` at the end to make the link dynamic, and give an `example`. A `PHONE_NUMBER` button takes `phoneNumber`."}},"required":["variant","name","category","header","body"]},"example":{"variant":"STANDARD","name":"order_shipped","category":"UTILITY","language":"en","header":{"type":"NONE"},"body":"Hi {{1}}, your order {{2}} has shipped.","bodyExamples":["Priya","#1043"]}}}}}},"/media":{"post":{"operationId":"uploadMedia","summary":"Upload a file","description":"Uploads a file and returns a `mediaHandle` to pass to [Send a file](/developers/api/send-media) or to a template's media header. Send it as `multipart/form-data` with the file in a field called `file`.\n\nAccepted: JPEG and PNG images, MP4 and 3GP video, audio, PDF and common office documents.","tags":["Media"],"security":[{"apiKey":[]}],"x-scope":"media:write","responses":{"201":{"description":"Success","content":{"application/json":{"example":{"success":true,"data":{"mediaHandle":"wamafy-media/4f0c.../9a1e.pdf","mimeType":"application/pdf","size":20481,"filename":"invoice.pdf"}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-codeSamples":[{"lang":"Shell","label":"cURL","source":"# macOS, Linux or Git Bash, with WAMAFY_API_KEY set. The quoting does not work in Windows cmd or PowerShell.\ncurl -X POST \"https://api.wamafy.com/api/v1/public/media\" \\\n  -H \"Authorization: Bearer $WAMAFY_API_KEY\" \\\n  -F \"file=@invoice.pdf\""},{"lang":"JavaScript","label":"Node.js","source":"// Node.js 20+. Save as example.mjs (it uses import and top-level await) and run: node example.mjs\n\nimport { openAsBlob } from 'node:fs';\n\nconst form = new FormData();\nform.append('file', await openAsBlob('invoice.pdf', { type: 'application/pdf' }), 'invoice.pdf');\n\nconst res = await fetch('https://api.wamafy.com/api/v1/public/media', {\n  method: 'POST',\n  headers: {\n    Authorization: `Bearer ${process.env.WAMAFY_API_KEY}`,\n  },\n  body: form,\n});\n\nconst body = await res.json();\nif (!body.success) throw new Error(body.error.message);\nconsole.log(body.data);"},{"lang":"Python","label":"Python","source":"# Python 3.8+. Needs: pip install requests\nimport os\n\nimport requests\n\nres = requests.post(\n    \"https://api.wamafy.com/api/v1/public/media\",\n    headers={\"Authorization\": f\"Bearer {os.environ['WAMAFY_API_KEY']}\"},\n    files={\"file\": open(\"invoice.pdf\", \"rb\")},\n)\n\nbody = res.json()\nif not body[\"success\"]:\n    raise RuntimeError(body[\"error\"][\"message\"])\nprint(body[\"data\"])"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"The file to upload."}},"required":["file"]}}}}}},"/contacts":{"get":{"operationId":"listContacts","summary":"List contacts","description":"Returns your contacts, newest first, a page at a time.","tags":["Contacts"],"security":[{"apiKey":[]}],"x-scope":"contacts:read","parameters":[{"name":"search","in":"query","required":false,"description":"Matches name, phone or email.","schema":{"type":"string","description":"Matches name, phone or email."}},{"name":"tag","in":"query","required":false,"description":"Only contacts with this tag.","schema":{"type":"string","description":"Only contacts with this tag."}},{"name":"status","in":"query","required":false,"description":"Contact status.","schema":{"type":"string","enum":["active","opted_out","invalid"],"description":"Contact status."}},{"name":"consentStatus","in":"query","required":false,"description":"Marketing consent.","schema":{"type":"string","enum":["unverified","opted_in","opted_out"],"description":"Marketing consent."}},{"name":"page","in":"query","required":false,"description":"Page number, from 1. Defaults to 1.","schema":{"type":"integer","description":"Page number, from 1. Defaults to 1."}},{"name":"limit","in":"query","required":false,"description":"Per page, up to 100. Defaults to 25.","schema":{"type":"integer","description":"Per page, up to 100. Defaults to 25."}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"success":true,"data":[{"id":"9d3f6b2a-4e1c-4a8b-9f0d-2c7e5a1b3d64","phone":"919876543210","name":"Priya Sharma","firstName":"Priya","lastName":"Sharma","company":"Acme Retail","language":"en","email":"priya@example.com","tags":["vip"],"status":"active","consentStatus":"opted_in","source":"api","customFields":{"city":"Mumbai"},"createdAt":"2026-09-02T08:15:00.000Z","updatedAt":"2026-10-07T10:00:00.000Z"}],"pagination":{"page":1,"limit":50,"total":1,"pageCount":1}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-codeSamples":[{"lang":"Shell","label":"cURL","source":"# macOS, Linux or Git Bash, with WAMAFY_API_KEY set. The quoting does not work in Windows cmd or PowerShell.\ncurl \"https://api.wamafy.com/api/v1/public/contacts?tag=vip&limit=50\" \\\n  -H \"Authorization: Bearer $WAMAFY_API_KEY\""},{"lang":"JavaScript","label":"Node.js","source":"// Node.js 18+. Save as example.mjs (it uses top-level await) and run: node example.mjs\n\nconst res = await fetch(`https://api.wamafy.com/api/v1/public/contacts?${new URLSearchParams({\n  tag: 'vip',\n  limit: '50',\n})}`, {\n  headers: {\n    Authorization: `Bearer ${process.env.WAMAFY_API_KEY}`,\n  },\n});\n\nconst body = await res.json();\nif (!body.success) throw new Error(body.error.message);\nconsole.log(body.data);"},{"lang":"Python","label":"Python","source":"# Python 3.8+. Needs: pip install requests\nimport os\n\nimport requests\n\nres = requests.get(\n    \"https://api.wamafy.com/api/v1/public/contacts\",\n    headers={\"Authorization\": f\"Bearer {os.environ['WAMAFY_API_KEY']}\"},\n    params={\n        \"tag\": \"vip\",\n        \"limit\": \"50\",\n    },\n)\n\nbody = res.json()\nif not body[\"success\"]:\n    raise RuntimeError(body[\"error\"][\"message\"])\nprint(body[\"data\"])"}]},"post":{"operationId":"upsertContact","summary":"Create or update a contact","description":"Creates the contact, or updates it when one with this phone number already exists. Phone is the key, so you can call this every time something changes on your side without checking first.","tags":["Contacts"],"security":[{"apiKey":[]}],"x-scope":"contacts:write","responses":{"201":{"description":"Success","content":{"application/json":{"example":{"success":true,"data":{"id":"9d3f6b2a-4e1c-4a8b-9f0d-2c7e5a1b3d64","phone":"919876543210","name":"Priya Sharma","firstName":"Priya","lastName":"Sharma","company":"Acme Retail","language":"en","email":"priya@example.com","tags":["vip"],"status":"active","consentStatus":"opted_in","source":"api","customFields":{"city":"Mumbai"},"createdAt":"2026-09-02T08:15:00.000Z","updatedAt":"2026-10-07T10:00:00.000Z","created":true}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-codeSamples":[{"lang":"Shell","label":"cURL","source":"# macOS, Linux or Git Bash, with WAMAFY_API_KEY set. The quoting does not work in Windows cmd or PowerShell.\ncurl -X POST \"https://api.wamafy.com/api/v1/public/contacts\" \\\n  -H \"Authorization: Bearer $WAMAFY_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"phone\": \"+919876543210\",\n  \"firstName\": \"Priya\",\n  \"lastName\": \"Sharma\",\n  \"tags\": [\n    \"vip\"\n  ],\n  \"customFields\": {\n    \"city\": \"Mumbai\"\n  }\n}'"},{"lang":"JavaScript","label":"Node.js","source":"// Node.js 18+. Save as example.mjs (it uses top-level await) and run: node example.mjs\n\nconst res = await fetch('https://api.wamafy.com/api/v1/public/contacts', {\n  method: 'POST',\n  headers: {\n    Authorization: `Bearer ${process.env.WAMAFY_API_KEY}`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({\n    phone: '+919876543210',\n    firstName: 'Priya',\n    lastName: 'Sharma',\n    tags: ['vip'],\n    customFields: {\n      city: 'Mumbai',\n    },\n  }),\n});\n\nconst body = await res.json();\nif (!body.success) throw new Error(body.error.message);\nconsole.log(body.data);"},{"lang":"Python","label":"Python","source":"# Python 3.8+. Needs: pip install requests\nimport os\n\nimport requests\n\nres = requests.post(\n    \"https://api.wamafy.com/api/v1/public/contacts\",\n    headers={\"Authorization\": f\"Bearer {os.environ['WAMAFY_API_KEY']}\"},\n    json={\n        \"phone\": \"+919876543210\",\n        \"firstName\": \"Priya\",\n        \"lastName\": \"Sharma\",\n        \"tags\": [\"vip\"],\n        \"customFields\": {\n            \"city\": \"Mumbai\",\n        },\n    },\n)\n\nbody = res.json()\nif not body[\"success\"]:\n    raise RuntimeError(body[\"error\"][\"message\"])\nprint(body[\"data\"])"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"phone":{"type":"string","description":"Phone number with country code."},"countryCode":{"type":"string","description":"Country calling code, if you keep it separately from `phone`."},"name":{"type":"string","description":"Full name. When left out on create, built from `firstName` and `lastName`."},"firstName":{"type":"string","description":"First name."},"lastName":{"type":"string","description":"Last name."},"company":{"type":"string","description":"Company."},"language":{"type":"string","description":"Language code, for example `en` or `hi`."},"email":{"type":"string","description":"Email address."},"tags":{"type":"array","items":{"type":"string"},"description":"Up to 30 tags. Replaces the existing tags."},"consentStatus":{"type":"string","enum":["unverified","opted_in","opted_out"],"description":"Marketing consent."},"customFields":{"type":"object","additionalProperties":true,"description":"Your custom contact attributes by key, as set up under Settings, Contact attributes."}},"required":["phone"]},"example":{"phone":"+919876543210","firstName":"Priya","lastName":"Sharma","tags":["vip"],"customFields":{"city":"Mumbai"}}}}}}},"/contacts/{phone}":{"get":{"operationId":"getContact","summary":"Get a contact","description":"Returns one contact.","tags":["Contacts"],"security":[{"apiKey":[]}],"x-scope":"contacts:read","parameters":[{"name":"phone","in":"path","required":true,"description":"The contact's phone number with country code. Anything other than digits is ignored, so `+91 98765 43210` works.","schema":{"type":"string","description":"The contact's phone number with country code. Anything other than digits is ignored, so `+91 98765 43210` works."}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"success":true,"data":{"id":"9d3f6b2a-4e1c-4a8b-9f0d-2c7e5a1b3d64","phone":"919876543210","name":"Priya Sharma","firstName":"Priya","lastName":"Sharma","company":"Acme Retail","language":"en","email":"priya@example.com","tags":["vip"],"status":"active","consentStatus":"opted_in","source":"api","customFields":{"city":"Mumbai"},"createdAt":"2026-09-02T08:15:00.000Z","updatedAt":"2026-10-07T10:00:00.000Z"}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-codeSamples":[{"lang":"Shell","label":"cURL","source":"# macOS, Linux or Git Bash, with WAMAFY_API_KEY set. The quoting does not work in Windows cmd or PowerShell.\ncurl \"https://api.wamafy.com/api/v1/public/contacts/919876543210\" \\\n  -H \"Authorization: Bearer $WAMAFY_API_KEY\""},{"lang":"JavaScript","label":"Node.js","source":"// Node.js 18+. Save as example.mjs (it uses top-level await) and run: node example.mjs\n\nconst res = await fetch('https://api.wamafy.com/api/v1/public/contacts/919876543210', {\n  headers: {\n    Authorization: `Bearer ${process.env.WAMAFY_API_KEY}`,\n  },\n});\n\nconst body = await res.json();\nif (!body.success) throw new Error(body.error.message);\nconsole.log(body.data);"},{"lang":"Python","label":"Python","source":"# Python 3.8+. Needs: pip install requests\nimport os\n\nimport requests\n\nres = requests.get(\n    \"https://api.wamafy.com/api/v1/public/contacts/919876543210\",\n    headers={\"Authorization\": f\"Bearer {os.environ['WAMAFY_API_KEY']}\"},\n)\n\nbody = res.json()\nif not body[\"success\"]:\n    raise RuntimeError(body[\"error\"][\"message\"])\nprint(body[\"data\"])"}]},"patch":{"operationId":"updateContact","summary":"Update a contact","description":"Updates only the fields you send. `customFields` is merged key by key, so `{ \"customFields\": { \"city\": \"Pune\" } }` changes the city and leaves your other attributes alone.","tags":["Contacts"],"security":[{"apiKey":[]}],"x-scope":"contacts:write","parameters":[{"name":"phone","in":"path","required":true,"description":"The contact's phone number with country code. Anything other than digits is ignored, so `+91 98765 43210` works.","schema":{"type":"string","description":"The contact's phone number with country code. Anything other than digits is ignored, so `+91 98765 43210` works."}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"success":true,"data":{"id":"9d3f6b2a-4e1c-4a8b-9f0d-2c7e5a1b3d64","phone":"919876543210","name":"Priya Sharma","firstName":"Priya","lastName":"Sharma","company":"Acme Retail","language":"en","email":"priya@example.com","tags":["vip","repeat"],"status":"active","consentStatus":"opted_in","source":"api","customFields":{"city":"Pune"},"createdAt":"2026-09-02T08:15:00.000Z","updatedAt":"2026-10-07T10:00:00.000Z"}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-codeSamples":[{"lang":"Shell","label":"cURL","source":"# macOS, Linux or Git Bash, with WAMAFY_API_KEY set. The quoting does not work in Windows cmd or PowerShell.\ncurl -X PATCH \"https://api.wamafy.com/api/v1/public/contacts/919876543210\" \\\n  -H \"Authorization: Bearer $WAMAFY_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"tags\": [\n    \"vip\",\n    \"repeat\"\n  ],\n  \"customFields\": {\n    \"city\": \"Pune\"\n  }\n}'"},{"lang":"JavaScript","label":"Node.js","source":"// Node.js 18+. Save as example.mjs (it uses top-level await) and run: node example.mjs\n\nconst res = await fetch('https://api.wamafy.com/api/v1/public/contacts/919876543210', {\n  method: 'PATCH',\n  headers: {\n    Authorization: `Bearer ${process.env.WAMAFY_API_KEY}`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({\n    tags: ['vip', 'repeat'],\n    customFields: {\n      city: 'Pune',\n    },\n  }),\n});\n\nconst body = await res.json();\nif (!body.success) throw new Error(body.error.message);\nconsole.log(body.data);"},{"lang":"Python","label":"Python","source":"# Python 3.8+. Needs: pip install requests\nimport os\n\nimport requests\n\nres = requests.patch(\n    \"https://api.wamafy.com/api/v1/public/contacts/919876543210\",\n    headers={\"Authorization\": f\"Bearer {os.environ['WAMAFY_API_KEY']}\"},\n    json={\n        \"tags\": [\"vip\", \"repeat\"],\n        \"customFields\": {\n            \"city\": \"Pune\",\n        },\n    },\n)\n\nbody = res.json()\nif not body[\"success\"]:\n    raise RuntimeError(body[\"error\"][\"message\"])\nprint(body[\"data\"])"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Full name. When left out on create, built from `firstName` and `lastName`."},"firstName":{"type":"string","description":"First name."},"lastName":{"type":"string","description":"Last name."},"company":{"type":"string","description":"Company."},"language":{"type":"string","description":"Language code, for example `en` or `hi`."},"email":{"type":"string","description":"Email address."},"tags":{"type":"array","items":{"type":"string"},"description":"Up to 30 tags. Replaces the existing tags."},"consentStatus":{"type":"string","enum":["unverified","opted_in","opted_out"],"description":"Marketing consent."},"customFields":{"type":"object","additionalProperties":true,"description":"Your custom contact attributes by key, as set up under Settings, Contact attributes."},"status":{"type":"string","enum":["active","opted_out","invalid"],"description":"Contact status."}}},"example":{"tags":["vip","repeat"],"customFields":{"city":"Pune"}}}}}}},"/contacts/{phone}/opt-out":{"post":{"operationId":"optOutContact","summary":"Opt a contact out","description":"Marks the contact as opted out. Broadcasts and other marketing sends skip them from then on.","tags":["Contacts"],"security":[{"apiKey":[]}],"x-scope":"contacts:write","parameters":[{"name":"phone","in":"path","required":true,"description":"The contact's phone number with country code. Anything other than digits is ignored, so `+91 98765 43210` works.","schema":{"type":"string","description":"The contact's phone number with country code. Anything other than digits is ignored, so `+91 98765 43210` works."}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"success":true,"data":{"id":"9d3f6b2a-4e1c-4a8b-9f0d-2c7e5a1b3d64","phone":"919876543210","name":"Priya Sharma","firstName":"Priya","lastName":"Sharma","company":"Acme Retail","language":"en","email":"priya@example.com","tags":["vip"],"status":"opted_out","consentStatus":"opted_out","source":"api","customFields":{"city":"Mumbai"},"createdAt":"2026-09-02T08:15:00.000Z","updatedAt":"2026-10-07T10:00:00.000Z"}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-codeSamples":[{"lang":"Shell","label":"cURL","source":"# macOS, Linux or Git Bash, with WAMAFY_API_KEY set. The quoting does not work in Windows cmd or PowerShell.\ncurl -X POST \"https://api.wamafy.com/api/v1/public/contacts/919876543210/opt-out\" \\\n  -H \"Authorization: Bearer $WAMAFY_API_KEY\""},{"lang":"JavaScript","label":"Node.js","source":"// Node.js 18+. Save as example.mjs (it uses top-level await) and run: node example.mjs\n\nconst res = await fetch('https://api.wamafy.com/api/v1/public/contacts/919876543210/opt-out', {\n  method: 'POST',\n  headers: {\n    Authorization: `Bearer ${process.env.WAMAFY_API_KEY}`,\n  },\n});\n\nconst body = await res.json();\nif (!body.success) throw new Error(body.error.message);\nconsole.log(body.data);"},{"lang":"Python","label":"Python","source":"# Python 3.8+. Needs: pip install requests\nimport os\n\nimport requests\n\nres = requests.post(\n    \"https://api.wamafy.com/api/v1/public/contacts/919876543210/opt-out\",\n    headers={\"Authorization\": f\"Bearer {os.environ['WAMAFY_API_KEY']}\"},\n)\n\nbody = res.json()\nif not body[\"success\"]:\n    raise RuntimeError(body[\"error\"][\"message\"])\nprint(body[\"data\"])"}]}},"/contacts/{phone}/opt-in":{"post":{"operationId":"optInContact","summary":"Opt a contact in","description":"Sets the contact's consent to `opted_in`.\n\nAn opt-out is final here: a contact who opted out cannot be opted back in over the API. They have to opt in again themselves, for example by messaging you.","tags":["Contacts"],"security":[{"apiKey":[]}],"x-scope":"contacts:write","parameters":[{"name":"phone","in":"path","required":true,"description":"The contact's phone number with country code. Anything other than digits is ignored, so `+91 98765 43210` works.","schema":{"type":"string","description":"The contact's phone number with country code. Anything other than digits is ignored, so `+91 98765 43210` works."}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"success":true,"data":{"id":"9d3f6b2a-4e1c-4a8b-9f0d-2c7e5a1b3d64","phone":"919876543210","name":"Priya Sharma","firstName":"Priya","lastName":"Sharma","company":"Acme Retail","language":"en","email":"priya@example.com","tags":["vip"],"status":"active","consentStatus":"opted_in","source":"api","customFields":{"city":"Mumbai"},"createdAt":"2026-09-02T08:15:00.000Z","updatedAt":"2026-10-07T10:00:00.000Z"}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-codeSamples":[{"lang":"Shell","label":"cURL","source":"# macOS, Linux or Git Bash, with WAMAFY_API_KEY set. The quoting does not work in Windows cmd or PowerShell.\ncurl -X POST \"https://api.wamafy.com/api/v1/public/contacts/919876543210/opt-in\" \\\n  -H \"Authorization: Bearer $WAMAFY_API_KEY\""},{"lang":"JavaScript","label":"Node.js","source":"// Node.js 18+. Save as example.mjs (it uses top-level await) and run: node example.mjs\n\nconst res = await fetch('https://api.wamafy.com/api/v1/public/contacts/919876543210/opt-in', {\n  method: 'POST',\n  headers: {\n    Authorization: `Bearer ${process.env.WAMAFY_API_KEY}`,\n  },\n});\n\nconst body = await res.json();\nif (!body.success) throw new Error(body.error.message);\nconsole.log(body.data);"},{"lang":"Python","label":"Python","source":"# Python 3.8+. Needs: pip install requests\nimport os\n\nimport requests\n\nres = requests.post(\n    \"https://api.wamafy.com/api/v1/public/contacts/919876543210/opt-in\",\n    headers={\"Authorization\": f\"Bearer {os.environ['WAMAFY_API_KEY']}\"},\n)\n\nbody = res.json()\nif not body[\"success\"]:\n    raise RuntimeError(body[\"error\"][\"message\"])\nprint(body[\"data\"])"}]}},"/contacts/{phone}/messages":{"get":{"operationId":"listContactMessages","summary":"List a contact's messages","description":"Returns messages to and from a contact, newest first. To page back, pass the `nextBefore` value from the last response as `before`.","tags":["Contacts"],"security":[{"apiKey":[]}],"x-scope":"messages:read","parameters":[{"name":"phone","in":"path","required":true,"description":"The contact's phone number with country code. Anything other than digits is ignored, so `+91 98765 43210` works.","schema":{"type":"string","description":"The contact's phone number with country code. Anything other than digits is ignored, so `+91 98765 43210` works."}},{"name":"before","in":"query","required":false,"description":"Only messages older than this ISO 8601 time.","schema":{"type":"string","description":"Only messages older than this ISO 8601 time."}},{"name":"limit","in":"query","required":false,"description":"Up to 100. Defaults to 50.","schema":{"type":"integer","description":"Up to 100. Defaults to 50."}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"success":true,"data":[{"id":"5e2a7c91-3b4d-4f6e-8a1c-9d0b2e4f6a73","direction":"inbound","type":"text","text":"Is the blue one in stock?","mediaMimeType":null,"mediaCaption":null,"messageId":"wamid.HBgMOTE5ODc2NTQzMjEwFQIAEhgUM0E","status":"received","sentAt":"2026-10-07T09:58:12.000Z"}],"pagination":{"limit":20,"nextBefore":null}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-codeSamples":[{"lang":"Shell","label":"cURL","source":"# macOS, Linux or Git Bash, with WAMAFY_API_KEY set. The quoting does not work in Windows cmd or PowerShell.\ncurl \"https://api.wamafy.com/api/v1/public/contacts/919876543210/messages?limit=20\" \\\n  -H \"Authorization: Bearer $WAMAFY_API_KEY\""},{"lang":"JavaScript","label":"Node.js","source":"// Node.js 18+. Save as example.mjs (it uses top-level await) and run: node example.mjs\n\nconst res = await fetch(`https://api.wamafy.com/api/v1/public/contacts/919876543210/messages?${new URLSearchParams({\n  limit: '20',\n})}`, {\n  headers: {\n    Authorization: `Bearer ${process.env.WAMAFY_API_KEY}`,\n  },\n});\n\nconst body = await res.json();\nif (!body.success) throw new Error(body.error.message);\nconsole.log(body.data);"},{"lang":"Python","label":"Python","source":"# Python 3.8+. Needs: pip install requests\nimport os\n\nimport requests\n\nres = requests.get(\n    \"https://api.wamafy.com/api/v1/public/contacts/919876543210/messages\",\n    headers={\"Authorization\": f\"Bearer {os.environ['WAMAFY_API_KEY']}\"},\n    params={\n        \"limit\": \"20\",\n    },\n)\n\nbody = res.json()\nif not body[\"success\"]:\n    raise RuntimeError(body[\"error\"][\"message\"])\nprint(body[\"data\"])"}]}},"/contacts/{phone}/trigger-flow":{"post":{"operationId":"triggerFlow","summary":"Start a chatbot for a contact","description":"Starts a published chatbot for this contact, as if they had triggered it. Anything in `variables` is available in the chatbot as `{{name}}`.","tags":["Contacts"],"security":[{"apiKey":[]}],"x-scope":"flows:trigger","parameters":[{"name":"phone","in":"path","required":true,"description":"The contact's phone number with country code. Anything other than digits is ignored, so `+91 98765 43210` works.","schema":{"type":"string","description":"The contact's phone number with country code. Anything other than digits is ignored, so `+91 98765 43210` works."}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"success":true,"data":{"status":"started"}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-codeSamples":[{"lang":"Shell","label":"cURL","source":"# macOS, Linux or Git Bash, with WAMAFY_API_KEY set. The quoting does not work in Windows cmd or PowerShell.\ncurl -X POST \"https://api.wamafy.com/api/v1/public/contacts/919876543210/trigger-flow\" \\\n  -H \"Authorization: Bearer $WAMAFY_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"flowId\": \"7a1b3c5d-2e4f-4a6b-8c0d-1e3f5a7b9c2d\",\n  \"variables\": {\n    \"order_id\": \"#1043\"\n  }\n}'"},{"lang":"JavaScript","label":"Node.js","source":"// Node.js 18+. Save as example.mjs (it uses top-level await) and run: node example.mjs\n\nconst res = await fetch('https://api.wamafy.com/api/v1/public/contacts/919876543210/trigger-flow', {\n  method: 'POST',\n  headers: {\n    Authorization: `Bearer ${process.env.WAMAFY_API_KEY}`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({\n    flowId: '7a1b3c5d-2e4f-4a6b-8c0d-1e3f5a7b9c2d',\n    variables: {\n      order_id: '#1043',\n    },\n  }),\n});\n\nconst body = await res.json();\nif (!body.success) throw new Error(body.error.message);\nconsole.log(body.data);"},{"lang":"Python","label":"Python","source":"# Python 3.8+. Needs: pip install requests\nimport os\n\nimport requests\n\nres = requests.post(\n    \"https://api.wamafy.com/api/v1/public/contacts/919876543210/trigger-flow\",\n    headers={\"Authorization\": f\"Bearer {os.environ['WAMAFY_API_KEY']}\"},\n    json={\n        \"flowId\": \"7a1b3c5d-2e4f-4a6b-8c0d-1e3f5a7b9c2d\",\n        \"variables\": {\n            \"order_id\": \"#1043\",\n        },\n    },\n)\n\nbody = res.json()\nif not body[\"success\"]:\n    raise RuntimeError(body[\"error\"][\"message\"])\nprint(body[\"data\"])"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"flowId":{"type":"string","description":"The chatbot's id, shown in its URL in the dashboard."},"variables":{"type":"object","additionalProperties":true,"description":"Values for the chatbot to use. Strings, numbers or booleans."}},"required":["flowId"]},"example":{"flowId":"7a1b3c5d-2e4f-4a6b-8c0d-1e3f5a7b9c2d","variables":{"order_id":"#1043"}}}}}}},"/segments":{"get":{"operationId":"listSegments","summary":"List segments","description":"Returns your saved segments. A segment is a set of rules (tagged `vip` and ordered twice, say) that is checked again each time it is used. Build them in the dashboard; the API reads them.","tags":["Segments"],"security":[{"apiKey":[]}],"x-scope":"contacts:read","responses":{"200":{"description":"Success","content":{"application/json":{"example":{"success":true,"data":[{"id":"0f2c8a1e-6b3d-4c9a-8e2f-5d7b1a3c9e40","name":"VIP buyers","description":"Tagged vip, ordered at least twice","conditions":2,"approximateContacts":128,"countedAt":"2026-10-07T06:00:00.000Z","createdAt":"2026-09-20T10:00:00.000Z"}]}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-codeSamples":[{"lang":"Shell","label":"cURL","source":"# macOS, Linux or Git Bash, with WAMAFY_API_KEY set. The quoting does not work in Windows cmd or PowerShell.\ncurl \"https://api.wamafy.com/api/v1/public/segments\" \\\n  -H \"Authorization: Bearer $WAMAFY_API_KEY\""},{"lang":"JavaScript","label":"Node.js","source":"// Node.js 18+. Save as example.mjs (it uses top-level await) and run: node example.mjs\n\nconst res = await fetch('https://api.wamafy.com/api/v1/public/segments', {\n  headers: {\n    Authorization: `Bearer ${process.env.WAMAFY_API_KEY}`,\n  },\n});\n\nconst body = await res.json();\nif (!body.success) throw new Error(body.error.message);\nconsole.log(body.data);"},{"lang":"Python","label":"Python","source":"# Python 3.8+. Needs: pip install requests\nimport os\n\nimport requests\n\nres = requests.get(\n    \"https://api.wamafy.com/api/v1/public/segments\",\n    headers={\"Authorization\": f\"Bearer {os.environ['WAMAFY_API_KEY']}\"},\n)\n\nbody = res.json()\nif not body[\"success\"]:\n    raise RuntimeError(body[\"error\"][\"message\"])\nprint(body[\"data\"])"}]}},"/segments/{id}/contacts":{"get":{"operationId":"listSegmentContacts","summary":"List segment contacts","description":"Works out the segment's members at the moment you call, and returns them a page at a time.\n\nTo message everyone in a segment you do not need this: pass `segmentId` to [Start a campaign](/developers/api/start-campaign) and it is done in one call.","tags":["Segments"],"security":[{"apiKey":[]}],"x-scope":"contacts:read","parameters":[{"name":"id","in":"path","required":true,"description":"The segment's id from List segments.","schema":{"type":"string","description":"The segment's id from List segments."}},{"name":"limit","in":"query","required":false,"description":"Up to 500. Defaults to 100.","schema":{"type":"integer","description":"Up to 500. Defaults to 100."}},{"name":"offset","in":"query","required":false,"description":"How many to skip. Defaults to 0.","schema":{"type":"integer","description":"How many to skip. Defaults to 0."}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"success":true,"data":[{"id":"9d3f6b2a-4e1c-4a8b-9f0d-2c7e5a1b3d64","phone":"919876543210","name":"Priya Sharma","email":null,"tags":["vip"]}],"meta":{"total":128,"limit":500,"offset":0,"hasMore":false}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-codeSamples":[{"lang":"Shell","label":"cURL","source":"# macOS, Linux or Git Bash, with WAMAFY_API_KEY set. The quoting does not work in Windows cmd or PowerShell.\ncurl \"https://api.wamafy.com/api/v1/public/segments/0f2c8a1e-6b3d-4c9a-8e2f-5d7b1a3c9e40/contacts?limit=500\" \\\n  -H \"Authorization: Bearer $WAMAFY_API_KEY\""},{"lang":"JavaScript","label":"Node.js","source":"// Node.js 18+. Save as example.mjs (it uses top-level await) and run: node example.mjs\n\nconst res = await fetch(`https://api.wamafy.com/api/v1/public/segments/0f2c8a1e-6b3d-4c9a-8e2f-5d7b1a3c9e40/contacts?${new URLSearchParams({\n  limit: '500',\n})}`, {\n  headers: {\n    Authorization: `Bearer ${process.env.WAMAFY_API_KEY}`,\n  },\n});\n\nconst body = await res.json();\nif (!body.success) throw new Error(body.error.message);\nconsole.log(body.data);"},{"lang":"Python","label":"Python","source":"# Python 3.8+. Needs: pip install requests\nimport os\n\nimport requests\n\nres = requests.get(\n    \"https://api.wamafy.com/api/v1/public/segments/0f2c8a1e-6b3d-4c9a-8e2f-5d7b1a3c9e40/contacts\",\n    headers={\"Authorization\": f\"Bearer {os.environ['WAMAFY_API_KEY']}\"},\n    params={\n        \"limit\": \"500\",\n    },\n)\n\nbody = res.json()\nif not body[\"success\"]:\n    raise RuntimeError(body[\"error\"][\"message\"])\nprint(body[\"data\"])"}]}},"/campaigns":{"post":{"operationId":"startCampaign","summary":"Start a campaign","description":"Creates a broadcast and starts it straight away, or at `scheduledAt`. Sending carries on in the background; follow it with [Get a campaign](/developers/api/get-campaign) or under Campaigns in the dashboard.\n\nPick the audience with `segmentId` or `tags`. With neither, it goes to every active contact.","tags":["Campaigns"],"security":[{"apiKey":[]}],"x-scope":"campaigns:send","responses":{"201":{"description":"Success","content":{"application/json":{"example":{"success":true,"data":{"campaignId":"3c5e7a9b-1d2f-4a6c-8e0b-2d4f6a8c0e13","name":"Diwali VIP","status":"sending","scheduledAt":null}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-codeSamples":[{"lang":"Shell","label":"cURL","source":"# macOS, Linux or Git Bash, with WAMAFY_API_KEY set. The quoting does not work in Windows cmd or PowerShell.\ncurl -X POST \"https://api.wamafy.com/api/v1/public/campaigns\" \\\n  -H \"Authorization: Bearer $WAMAFY_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"templateName\": \"diwali_offer\",\n  \"segmentId\": \"0f2c8a1e-6b3d-4c9a-8e2f-5d7b1a3c9e40\",\n  \"variables\": {\n    \"1\": \"friend\"\n  },\n  \"name\": \"Diwali VIP\"\n}'"},{"lang":"JavaScript","label":"Node.js","source":"// Node.js 18+. Save as example.mjs (it uses top-level await) and run: node example.mjs\n\nconst res = await fetch('https://api.wamafy.com/api/v1/public/campaigns', {\n  method: 'POST',\n  headers: {\n    Authorization: `Bearer ${process.env.WAMAFY_API_KEY}`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({\n    templateName: 'diwali_offer',\n    segmentId: '0f2c8a1e-6b3d-4c9a-8e2f-5d7b1a3c9e40',\n    variables: {\n      '1': 'friend',\n    },\n    name: 'Diwali VIP',\n  }),\n});\n\nconst body = await res.json();\nif (!body.success) throw new Error(body.error.message);\nconsole.log(body.data);"},{"lang":"Python","label":"Python","source":"# Python 3.8+. Needs: pip install requests\nimport os\n\nimport requests\n\nres = requests.post(\n    \"https://api.wamafy.com/api/v1/public/campaigns\",\n    headers={\"Authorization\": f\"Bearer {os.environ['WAMAFY_API_KEY']}\"},\n    json={\n        \"templateName\": \"diwali_offer\",\n        \"segmentId\": \"0f2c8a1e-6b3d-4c9a-8e2f-5d7b1a3c9e40\",\n        \"variables\": {\n            \"1\": \"friend\",\n        },\n        \"name\": \"Diwali VIP\",\n    },\n)\n\nbody = res.json()\nif not body[\"success\"]:\n    raise RuntimeError(body[\"error\"][\"message\"])\nprint(body[\"data\"])"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"templateName":{"type":"string","description":"Name of an approved template."},"segmentId":{"type":"string","description":"Send to a saved segment. Its members are worked out when the campaign starts. Cannot be combined with `tags`."},"tags":{"type":"array","items":{"type":"string"},"description":"Send to contacts with any of these tags."},"variables":{"type":"object","additionalProperties":true,"description":"Template variable values. Each recipient gets their own: put `{{lead.first_name}}`, `{{lead.company}}`, `{{custom.city}}` and so on in a value to fill it from their contact. A variable named `customer_name`, `name`, `first_name`, `last_name`, `company`, `email`, `phone` or `language` fills from the contact by itself; the value you send is used only for contacts without one."},"from":{"type":"string","description":"Which of your numbers to send from. Defaults to your default number."},"name":{"type":"string","description":"Campaign name. One is made up if you leave it out."},"scheduledAt":{"type":"string","description":"Start later instead of now, as an ISO 8601 time with offset such as `2027-10-29T10:00:00+05:30`. Must be in the future. Needs a plan that includes scheduling."},"headerMediaUrl":{"type":"string","description":"Public `https` link to the header image, video or document, used instead of the file saved with the template. Can contain `{{lead.X}}` for a different file per contact. Needed only when the template has a media header and no file saved in Wamafy."},"buttons":{"type":"array","items":{"type":"object","properties":{"index":{"type":"integer","description":"The button's position in the template, starting at 0, as List templates reports it."},"type":{"type":"string","enum":["url","copy_code"],"description":"What kind of button it is."},"value":{"type":"string","description":"For a link button, the part that replaces the placeholder (`offers/diwali`); for a tracked link, the full destination URL. For copy code, the code."}},"required":["index","type","value"]},"description":"Values for dynamic buttons: a link button with a placeholder, or a copy-code button. Required for each one the template has. A value can contain `{{lead.X}}`."},"offerExpiresAt":{"type":"string","description":"For a limited-time offer template with a countdown: when the offer ends, as an ISO 8601 time with offset."}},"required":["templateName"]},"example":{"templateName":"diwali_offer","segmentId":"0f2c8a1e-6b3d-4c9a-8e2f-5d7b1a3c9e40","variables":{"1":"friend"},"name":"Diwali VIP"}}}}}},"/campaigns/{campaignId}":{"get":{"operationId":"getCampaign","summary":"Get a campaign","description":"Returns a broadcast you started with [Start a campaign](/developers/api/start-campaign): whether it is scheduled, sending or done, and where its recipients have got to.\n\nThe counts only ever narrow: every delivered message was sent, and every read one was delivered, even when WhatsApp never sent the delivered receipt.","tags":["Campaigns"],"security":[{"apiKey":[]}],"x-scope":"campaigns:read","parameters":[{"name":"campaignId","in":"path","required":true,"description":"The `campaignId` Start a campaign returned.","schema":{"type":"string","description":"The `campaignId` Start a campaign returned."}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"success":true,"data":{"campaignId":"3c5e7a9b-1d2f-4a6c-8e0b-2d4f6a8c0e13","name":"Diwali VIP","templateName":"diwali_offer","status":"completed","scheduledAt":null,"startedAt":"2026-10-07T10:00:00.000Z","completedAt":"2026-10-07T10:02:11.000Z","recipients":{"total":1240,"pending":0,"sent":1218,"delivered":1190,"read":802,"failed":22}}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-codeSamples":[{"lang":"Shell","label":"cURL","source":"# macOS, Linux or Git Bash, with WAMAFY_API_KEY set. The quoting does not work in Windows cmd or PowerShell.\ncurl \"https://api.wamafy.com/api/v1/public/campaigns/3c5e7a9b-1d2f-4a6c-8e0b-2d4f6a8c0e13\" \\\n  -H \"Authorization: Bearer $WAMAFY_API_KEY\""},{"lang":"JavaScript","label":"Node.js","source":"// Node.js 18+. Save as example.mjs (it uses top-level await) and run: node example.mjs\n\nconst res = await fetch('https://api.wamafy.com/api/v1/public/campaigns/3c5e7a9b-1d2f-4a6c-8e0b-2d4f6a8c0e13', {\n  headers: {\n    Authorization: `Bearer ${process.env.WAMAFY_API_KEY}`,\n  },\n});\n\nconst body = await res.json();\nif (!body.success) throw new Error(body.error.message);\nconsole.log(body.data);"},{"lang":"Python","label":"Python","source":"# Python 3.8+. Needs: pip install requests\nimport os\n\nimport requests\n\nres = requests.get(\n    \"https://api.wamafy.com/api/v1/public/campaigns/3c5e7a9b-1d2f-4a6c-8e0b-2d4f6a8c0e13\",\n    headers={\"Authorization\": f\"Bearer {os.environ['WAMAFY_API_KEY']}\"},\n)\n\nbody = res.json()\nif not body[\"success\"]:\n    raise RuntimeError(body[\"error\"][\"message\"])\nprint(body[\"data\"])"}]}},"/payments":{"post":{"operationId":"requestPayment","summary":"Ask for a payment","description":"Sends WhatsApp's own payment request, Review and pay. The customer pays without leaving WhatsApp, with Google Pay, PhonePe or any UPI app, and the money goes to your own payment gateway.\n\nIf the customer wrote to you in the last 24 hours, the request goes as a message and needs no template. Otherwise WhatsApp only allows a template, so name one in `templateName`: a Utility template with a Review and pay button, created in the dashboard. Pass `templateName` every time and it is used only when needed. See [The 24-hour window](/developers/guides/messaging-window).\n\nFirst, switch on Payments within WhatsApp for the number in the dashboard (Settings, Integrations, Payments). Follow the payment with [Get a payment](/developers/api/get-payment).","tags":["Payments"],"security":[{"apiKey":[]}],"x-scope":"payments:send","responses":{"201":{"description":"Success","content":{"application/json":{"example":{"success":true,"data":{"id":"5d7f9b1c-3e5a-4c7e-9a1b-3c5e7a9b1d24","referenceId":"wp-mv5jrp6d-aba359af","status":"created","amount":499,"currency":"INR","to":"919876543210","paymentId":null,"paidAt":null,"expiresAt":"2026-10-13T10:30:00.000Z","refundedAmount":0,"refunds":[],"createdAt":"2026-10-13T10:00:00.000Z","sentAs":"message","messageId":"wamid.HBgMOTE5ODc2NTQzMjEwFQIAERgSQzU"}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-codeSamples":[{"lang":"Shell","label":"cURL","source":"# macOS, Linux or Git Bash, with WAMAFY_API_KEY set. The quoting does not work in Windows cmd or PowerShell.\ncurl -X POST \"https://api.wamafy.com/api/v1/public/payments\" \\\n  -H \"Authorization: Bearer $WAMAFY_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"to\": \"+919876543210\",\n  \"amount\": 499,\n  \"description\": \"Order 1042\",\n  \"message\": \"Your order is packed and ready to go.\"\n}'"},{"lang":"JavaScript","label":"Node.js","source":"// Node.js 18+. Save as example.mjs (it uses top-level await) and run: node example.mjs\n\nconst res = await fetch('https://api.wamafy.com/api/v1/public/payments', {\n  method: 'POST',\n  headers: {\n    Authorization: `Bearer ${process.env.WAMAFY_API_KEY}`,\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({\n    to: '+919876543210',\n    amount: 499,\n    description: 'Order 1042',\n    message: 'Your order is packed and ready to go.',\n  }),\n});\n\nconst body = await res.json();\nif (!body.success) throw new Error(body.error.message);\nconsole.log(body.data);"},{"lang":"Python","label":"Python","source":"# Python 3.8+. Needs: pip install requests\nimport os\n\nimport requests\n\nres = requests.post(\n    \"https://api.wamafy.com/api/v1/public/payments\",\n    headers={\"Authorization\": f\"Bearer {os.environ['WAMAFY_API_KEY']}\"},\n    json={\n        \"to\": \"+919876543210\",\n        \"amount\": 499,\n        \"description\": \"Order 1042\",\n        \"message\": \"Your order is packed and ready to go.\",\n    },\n)\n\nbody = res.json()\nif not body[\"success\"]:\n    raise RuntimeError(body[\"error\"][\"message\"])\nprint(body[\"data\"])"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"to":{"type":"string","description":"The customer's phone number with country code, for example `+919876543210`."},"amount":{"type":"number","description":"Rupees, from 1 to 500000, up to 2 decimals."},"description":{"type":"string","description":"What is being paid for, shown on the payment screen. Up to 60 characters."},"message":{"type":"string","description":"The text above Review and pay, when it goes as a message. Defaults to the description."},"from":{"type":"string","description":"Which of your WhatsApp numbers to send from. Defaults to the number the customer last wrote to, then your default number."},"templateName":{"type":"string","description":"A template with a Review and pay button, used when the customer has not written to you in the last 24 hours."},"language":{"type":"string","description":"The template's language. Defaults to the template's own."},"variables":{"type":"object","additionalProperties":true,"description":"The template's variables, as for [Send a template message](/developers/api/send-template)."},"headerMediaUrl":{"type":"string","description":"A public https link to the file, when the template has an image, video or document header."}},"required":["to","amount","description"]},"example":{"to":"+919876543210","amount":499,"description":"Order 1042","message":"Your order is packed and ready to go."}}}}}},"/payments/{id}":{"get":{"operationId":"getPayment","summary":"Get a payment","description":"Reads back a payment asked for with [Ask for a payment](/developers/api/request-payment), with any refunds made on it. To be told instead of asking, use the [payment.paid](/developers/webhooks/events) webhook.","tags":["Payments"],"security":[{"apiKey":[]}],"x-scope":"payments:read","parameters":[{"name":"id","in":"path","required":true,"description":"The `id` that Ask for a payment returned.","schema":{"type":"string","description":"The `id` that Ask for a payment returned."}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"success":true,"data":{"id":"5d7f9b1c-3e5a-4c7e-9a1b-3c5e7a9b1d24","referenceId":"wp-mv5jrp6d-aba359af","status":"created","amount":499,"currency":"INR","to":"919876543210","paymentId":null,"paidAt":null,"expiresAt":"2026-10-13T10:30:00.000Z","refundedAmount":0,"refunds":[],"createdAt":"2026-10-13T10:00:00.000Z"}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-codeSamples":[{"lang":"Shell","label":"cURL","source":"# macOS, Linux or Git Bash, with WAMAFY_API_KEY set. The quoting does not work in Windows cmd or PowerShell.\ncurl \"https://api.wamafy.com/api/v1/public/payments/5d7f9b1c-3e5a-4c7e-9a1b-3c5e7a9b1d24\" \\\n  -H \"Authorization: Bearer $WAMAFY_API_KEY\""},{"lang":"JavaScript","label":"Node.js","source":"// Node.js 18+. Save as example.mjs (it uses top-level await) and run: node example.mjs\n\nconst res = await fetch('https://api.wamafy.com/api/v1/public/payments/5d7f9b1c-3e5a-4c7e-9a1b-3c5e7a9b1d24', {\n  headers: {\n    Authorization: `Bearer ${process.env.WAMAFY_API_KEY}`,\n  },\n});\n\nconst body = await res.json();\nif (!body.success) throw new Error(body.error.message);\nconsole.log(body.data);"},{"lang":"Python","label":"Python","source":"# Python 3.8+. Needs: pip install requests\nimport os\n\nimport requests\n\nres = requests.get(\n    \"https://api.wamafy.com/api/v1/public/payments/5d7f9b1c-3e5a-4c7e-9a1b-3c5e7a9b1d24\",\n    headers={\"Authorization\": f\"Bearer {os.environ['WAMAFY_API_KEY']}\"},\n)\n\nbody = res.json()\nif not body[\"success\"]:\n    raise RuntimeError(body[\"error\"][\"message\"])\nprint(body[\"data\"])"}]}},"/analytics":{"get":{"operationId":"getAnalytics","summary":"Get message stats","description":"Returns message totals for a period and a per-day count, in your workspace's time zone, the same figures as the dashboard.","tags":["Analytics"],"security":[{"apiKey":[]}],"x-scope":"analytics:read","parameters":[{"name":"from","in":"query","required":false,"description":"Start, as an ISO 8601 time. Defaults to 30 days ago.","schema":{"type":"string","description":"Start, as an ISO 8601 time. Defaults to 30 days ago."}},{"name":"to","in":"query","required":false,"description":"End, as an ISO 8601 time. Defaults to now.","schema":{"type":"string","description":"End, as an ISO 8601 time. Defaults to now."}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"success":true,"data":{"range":{"from":"2026-09-01T00:00:00.000Z","to":"2026-10-01T00:00:00.000Z"},"totals":{"sent":1240,"delivered":1198,"read":903,"failed":12,"readRate":0.728},"daily":[{"date":"2026-09-30","count":41}]}}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-codeSamples":[{"lang":"Shell","label":"cURL","source":"# macOS, Linux or Git Bash, with WAMAFY_API_KEY set. The quoting does not work in Windows cmd or PowerShell.\ncurl \"https://api.wamafy.com/api/v1/public/analytics?from=2026-09-01T00%3A00%3A00Z&to=2026-10-01T00%3A00%3A00Z\" \\\n  -H \"Authorization: Bearer $WAMAFY_API_KEY\""},{"lang":"JavaScript","label":"Node.js","source":"// Node.js 18+. Save as example.mjs (it uses top-level await) and run: node example.mjs\n\nconst res = await fetch(`https://api.wamafy.com/api/v1/public/analytics?${new URLSearchParams({\n  from: '2026-09-01T00:00:00Z',\n  to: '2026-10-01T00:00:00Z',\n})}`, {\n  headers: {\n    Authorization: `Bearer ${process.env.WAMAFY_API_KEY}`,\n  },\n});\n\nconst body = await res.json();\nif (!body.success) throw new Error(body.error.message);\nconsole.log(body.data);"},{"lang":"Python","label":"Python","source":"# Python 3.8+. Needs: pip install requests\nimport os\n\nimport requests\n\nres = requests.get(\n    \"https://api.wamafy.com/api/v1/public/analytics\",\n    headers={\"Authorization\": f\"Bearer {os.environ['WAMAFY_API_KEY']}\"},\n    params={\n        \"from\": \"2026-09-01T00:00:00Z\",\n        \"to\": \"2026-10-01T00:00:00Z\",\n    },\n)\n\nbody = res.json()\nif not body[\"success\"]:\n    raise RuntimeError(body[\"error\"][\"message\"])\nprint(body[\"data\"])"}]}}},"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"Your API key, from Settings, API Access. Sent as `Authorization: Bearer wamafy_live_...`."}},"schemas":{"Error":{"type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["success","error"]}}}}