{"openapi":"3.1.0","info":{"title":"WA Gateway API","version":"2.0.0","description":"Send and receive WhatsApp messages from your own software with WA Gateway.\n\nAuthenticate with `Authorization: Bearer <API key>`. Keys come from the dashboard (API keys),\nor from `POST /api/v1/signup/verify` when an account is created through the API.\n\nA person always approves a payment (M-Pesa PIN or card details); the API only starts it."},"servers":[{"url":"https://whatsapp.nergaa.cloud"}],"security":[{"apiKey":[]}],"tags":[{"name":"Account","description":"Sign up, and who this key belongs to."},{"name":"Billing","description":"Plans, the subscription, and paying for it."},{"name":"Numbers","description":"WhatsApp numbers linked to the account, and linking new ones."},{"name":"Messages","description":"Sending messages, and the message log."},{"name":"Webhooks","description":"Where incoming messages and status changes are posted."},{"name":"Chats","description":"Acting on messages already in a chat, groups, and the conversations on a number."},{"name":"Catalog","description":"The WhatsApp Business catalog of a linked business number, and syncing it from your item list."}],"paths":{"/api/v1/plans":{"get":{"tags":["Billing"],"operationId":"listPlans","summary":"List the plans on offer","security":[],"responses":{"200":{"description":"The public plans.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"plans":{"type":"array","items":{"$ref":"#/components/schemas/Plan"}}}}}}}}}},"/api/v1/signup":{"post":{"tags":["Account"],"operationId":"startSignup","summary":"Start creating an account","description":"Sends a 6-digit code to the WhatsApp number given (or the email, if WhatsApp cannot be used). Nothing is created until the code is confirmed with `POST /api/v1/signup/verify`, so a person must take part.","security":[],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupStart"},"example":{"email":"owner@shop.co.ke","phone":"254712345678","company":"Shop Ltd","name":"Jane Wanjiku"}}}},"responses":{"202":{"description":"A code is on its way.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"channel":{"type":"string","enum":["whatsapp","email"]},"sent_to":{"type":"string"},"expires_in":{"type":"integer"}}}}}},"400":{"description":"The request is wrong; `error` says why.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests, or the monthly message limit was reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/signup/verify":{"post":{"tags":["Account"],"operationId":"verifySignup","summary":"Confirm the code and get an API key","security":[],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["email","code"],"properties":{"email":{"type":"string","format":"email"},"code":{"type":"string","example":"482915"}}}}}},"responses":{"201":{"description":"The account, its first number and an API key (shown once).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupResult"}}}},"400":{"description":"The request is wrong; `error` says why.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests, or the monthly message limit was reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/me":{"get":{"tags":["Account"],"operationId":"getMe","summary":"The account this key belongs to, its plan and usage","responses":{"200":{"description":"Account and usage.","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/billing":{"get":{"tags":["Billing"],"operationId":"getBilling","summary":"The subscription, plan, available plans and recent payments","responses":{"200":{"description":"Billing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Billing"}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/billing/pay":{"post":{"tags":["Billing"],"operationId":"startPayment","summary":"Start paying for a plan","description":"`paypal` returns a `checkout_url` on PayPal, where the person pays with PayPal or any card. `mpesa` sends a payment prompt to the phone; the person enters their PIN. `checkout` returns a `checkout_url` to give the person (card, Apple Pay, Google Pay or M-Pesa). Follow the result with `GET /api/v1/billing/payments/{id}`.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayRequest"},"example":{"plan_id":"pln_3f9a…","method":"mpesa","phone":"254712345678"}}}},"responses":{"201":{"description":"The payment, pending until the person approves it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Payment"}}}},"400":{"description":"The request is wrong; `error` says why.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Suspended, or a plan limit was reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/billing/payments/{id}":{"get":{"tags":["Billing"],"operationId":"getPayment","summary":"A payment's current status","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The payment.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Payment"}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such number, payment or webhook.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/instances":{"get":{"tags":["Numbers"],"operationId":"listNumbers","summary":"List the account's WhatsApp numbers","responses":{"200":{"description":"Numbers.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"instances":{"type":"array","items":{"$ref":"#/components/schemas/Number"}}}}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Numbers"],"operationId":"createNumber","summary":"Add a number (then link a phone to it)","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","example":"Sales desk"},"slug":{"type":"string","description":"Optional id; made from the name if left out."}}}}}},"responses":{"201":{"description":"The new number.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Number"}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Suspended, or a plan limit was reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/instances/{id}":{"get":{"tags":["Numbers"],"operationId":"getNumber","summary":"One number's state","parameters":[{"name":"id","in":"path","required":true,"description":"The number's id, as shown in the dashboard (for example `sales-desk`).","schema":{"type":"string"}}],"responses":{"200":{"description":"The number.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Number"}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such number, payment or webhook.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Numbers"],"operationId":"deleteNumber","summary":"Unlink and delete a number","parameters":[{"name":"id","in":"path","required":true,"description":"The number's id, as shown in the dashboard (for example `sales-desk`).","schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such number, payment or webhook.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/instances/{id}/start":{"post":{"tags":["Numbers"],"operationId":"linkByQr","summary":"Start linking: returns a QR code to scan","description":"The person opens WhatsApp → Linked devices → Link a device and scans `qr` (a PNG data URL). It changes about every 20 seconds; fetch it again with `GET …/qr`.","parameters":[{"name":"id","in":"path","required":true,"description":"The number's id, as shown in the dashboard (for example `sales-desk`).","schema":{"type":"string"}}],"responses":{"200":{"description":"State and QR code.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkState"}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Suspended, or a plan limit was reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such number, payment or webhook.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/instances/{id}/pair":{"post":{"tags":["Numbers"],"operationId":"linkByCode","summary":"Start linking with a code typed on the phone","parameters":[{"name":"id","in":"path","required":true,"description":"The number's id, as shown in the dashboard (for example `sales-desk`).","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["phone"],"properties":{"phone":{"type":"string","example":"254712345678"}}}}}},"responses":{"200":{"description":"An 8-character pairing code.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkState"}}}},"400":{"description":"The request is wrong; `error` says why.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such number, payment or webhook.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/instances/{id}/qr":{"get":{"tags":["Numbers"],"operationId":"getQr","summary":"The current QR or pairing code","parameters":[{"name":"id","in":"path","required":true,"description":"The number's id, as shown in the dashboard (for example `sales-desk`).","schema":{"type":"string"}}],"responses":{"200":{"description":"State and code.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkState"}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such number, payment or webhook.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/instances/{id}/logout":{"post":{"tags":["Numbers"],"operationId":"unlinkNumber","summary":"Unlink the phone","parameters":[{"name":"id","in":"path","required":true,"description":"The number's id, as shown in the dashboard (for example `sales-desk`).","schema":{"type":"string"}}],"responses":{"200":{"description":"Unlinked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Number"}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such number, payment or webhook.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/instances/{id}/send":{"post":{"tags":["Messages"],"operationId":"sendMessage","summary":"Send a text, image, video, audio, document, location or poll","parameters":[{"name":"id","in":"path","required":true,"description":"The number's id, as shown in the dashboard (for example `sales-desk`).","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendRequest"},"example":{"to":"254712345678","text":"Your order #1042 has shipped."}}}},"responses":{"200":{"description":"Sent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Sent"}}}},"400":{"description":"The request is wrong; `error` says why.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The subscription has ended; pay under /api/v1/billing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such number, payment or webhook.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The number is not connected yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests, or the monthly message limit was reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/instances/{id}/check":{"post":{"tags":["Messages"],"operationId":"checkNumber","summary":"Is this phone number on WhatsApp?","parameters":[{"name":"id","in":"path","required":true,"description":"The number's id, as shown in the dashboard (for example `sales-desk`).","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"number":{"type":"string","example":"254712345678"},"numbers":{"type":"array","items":{"type":"string"},"maxItems":100,"description":"Several at once; the answer is then `results`."}}}}}},"responses":{"200":{"description":"Whether it exists.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"exists":{"type":"boolean"},"jid":{"type":"string"},"results":{"type":"array","items":{"type":"object"}}}}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such number, payment or webhook.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The number is not connected yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/instances/{id}/messages/react":{"post":{"tags":["Chats"],"operationId":"reactToMessage","summary":"React to a message with an emoji (empty emoji removes it)","parameters":[{"name":"id","in":"path","required":true,"description":"The number's id, as shown in the dashboard (for example `sales-desk`).","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageRef"},"example":{"chat_id":"254712345678@s.whatsapp.net","message_id":"3EB0C1A2…","emoji":"👍"}}}},"responses":{"200":{"description":"Done.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request is wrong; `error` says why.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such number, payment or webhook.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The number is not connected yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/instances/{id}/messages/delete":{"post":{"tags":["Chats"],"operationId":"deleteMessage","summary":"Delete a message for everyone","parameters":[{"name":"id","in":"path","required":true,"description":"The number's id, as shown in the dashboard (for example `sales-desk`).","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageRef"}}}},"responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request is wrong; `error` says why.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such number, payment or webhook.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The number is not connected yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/instances/{id}/messages/edit":{"post":{"tags":["Chats"],"operationId":"editMessage","summary":"Edit the text of a message you sent","parameters":[{"name":"id","in":"path","required":true,"description":"The number's id, as shown in the dashboard (for example `sales-desk`).","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageRef"},"example":{"chat_id":"254712345678","message_id":"3EB0C1A2…","text":"Corrected text"}}}},"responses":{"200":{"description":"Edited.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request is wrong; `error` says why.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such number, payment or webhook.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The number is not connected yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/instances/{id}/messages/read":{"post":{"tags":["Chats"],"operationId":"markRead","summary":"Mark messages read (blue ticks)","parameters":[{"name":"id","in":"path","required":true,"description":"The number's id, as shown in the dashboard (for example `sales-desk`).","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageRef"},"example":{"chat_id":"254712345678","message_ids":["3EB0C1A2…"]}}}},"responses":{"200":{"description":"Marked.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request is wrong; `error` says why.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such number, payment or webhook.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The number is not connected yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/instances/{id}/messages/forward":{"post":{"tags":["Chats"],"operationId":"forwardMessage","summary":"Forward a recent message to another chat","description":"Only messages sent or received since the number last connected can be forwarded. Counts as a message sent.","parameters":[{"name":"id","in":"path","required":true,"description":"The number's id, as shown in the dashboard (for example `sales-desk`).","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageRef"},"example":{"to":"254700111222","chat_id":"254712345678","message_id":"3EB0C1A2…"}}}},"responses":{"200":{"description":"Forwarded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Sent"}}}},"400":{"description":"The request is wrong; `error` says why.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The subscription has ended; pay under /api/v1/billing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such number, payment or webhook.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The number is not connected yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests, or the monthly message limit was reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/instances/{id}/presence":{"post":{"tags":["Chats"],"operationId":"sendPresence","summary":"Show typing… or recording… in a chat","parameters":[{"name":"id","in":"path","required":true,"description":"The number's id, as shown in the dashboard (for example `sales-desk`).","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["to"],"properties":{"to":{"type":"string"},"presence":{"type":"string","enum":["composing","recording","paused","available","unavailable"],"default":"composing"}}}}}},"responses":{"200":{"description":"Shown.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request is wrong; `error` says why.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such number, payment or webhook.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The number is not connected yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/instances/{id}/groups":{"get":{"tags":["Chats"],"operationId":"listGroups","summary":"Groups this number is in, with participants","parameters":[{"name":"id","in":"path","required":true,"description":"The number's id, as shown in the dashboard (for example `sales-desk`).","schema":{"type":"string"}}],"responses":{"200":{"description":"Groups.","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such number, payment or webhook.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The number is not connected yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/instances/{id}/chats":{"get":{"tags":["Chats"],"operationId":"listChats","summary":"Conversations on this number, latest first","description":"From the message log, so only messages that passed through this gateway.","parameters":[{"name":"id","in":"path","required":true,"description":"The number's id, as shown in the dashboard (for example `sales-desk`).","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","maximum":500,"default":50}}],"responses":{"200":{"description":"Chats.","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such number, payment or webhook.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/instances/{id}/chats/{chat}/messages":{"get":{"tags":["Chats"],"operationId":"chatMessages","summary":"One conversation's messages, newest first","parameters":[{"name":"id","in":"path","required":true,"description":"The number's id, as shown in the dashboard (for example `sales-desk`).","schema":{"type":"string"}},{"name":"chat","in":"path","required":true,"schema":{"type":"string"},"description":"A phone number or chat id (JID)."},{"name":"limit","in":"query","schema":{"type":"integer","maximum":500,"default":50}},{"name":"before","in":"query","schema":{"type":"integer"},"description":"For paging: messages older than this id."}],"responses":{"200":{"description":"Messages.","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such number, payment or webhook.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/instances/{id}/catalog":{"get":{"tags":["Catalog"],"operationId":"getCatalog","summary":"Products in a catalog, a page at a time","parameters":[{"name":"id","in":"path","required":true,"description":"The number's id, as shown in the dashboard (for example `sales-desk`).","schema":{"type":"string"}},{"name":"jid","in":"query","schema":{"type":"string"},"description":"Another business's catalog; this number's own if left out."},{"name":"limit","in":"query","schema":{"type":"integer"}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Products.","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such number, payment or webhook.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The number is not connected yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/instances/{id}/catalog/sync":{"post":{"tags":["Catalog"],"operationId":"syncCatalog","summary":"Make the catalog match your item list","description":"Products are matched by `retailer_id` (your item code). New ones are created, changed ones updated, and with `delete_missing` any product with a retailer_id not in the list is removed. Products without a retailer_id are never touched. `dry_run` reports what would change without changing anything.","parameters":[{"name":"id","in":"path","required":true,"description":"The number's id, as shown in the dashboard (for example `sales-desk`).","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CatalogSync"},"example":{"products":[{"retailer_id":"ITEM-0001","name":"Blue mug","description":"350 ml","price":650,"currency":"KES","images":["https://example.com/mug.jpg"]}],"delete_missing":false}}}},"responses":{"200":{"description":"What changed.","content":{"application/json":{"schema":{"type":"object","properties":{"created":{"type":"array","items":{"type":"object"}},"updated":{"type":"array","items":{"type":"object"}},"unchanged":{"type":"integer"},"deleted":{"type":"array","items":{"type":"object"}},"failed":{"type":"array","items":{"type":"object","properties":{"retailer_id":{"type":"string"},"error":{"type":"string"}}}}}}}}},"400":{"description":"The request is wrong; `error` says why.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such number, payment or webhook.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The number is not connected yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/instances/{id}/collections":{"get":{"tags":["Catalog"],"operationId":"getCollections","summary":"Catalog collections","parameters":[{"name":"id","in":"path","required":true,"description":"The number's id, as shown in the dashboard (for example `sales-desk`).","schema":{"type":"string"}}],"responses":{"200":{"description":"Collections.","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such number, payment or webhook.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The number is not connected yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/instances/{id}/products":{"post":{"tags":["Catalog"],"operationId":"createProduct","summary":"Add one product","parameters":[{"name":"id","in":"path","required":true,"description":"The number's id, as shown in the dashboard (for example `sales-desk`).","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Product"}}}},"responses":{"200":{"description":"Created.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request is wrong; `error` says why.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such number, payment or webhook.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The number is not connected yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Catalog"],"operationId":"deleteProducts","summary":"Delete products","parameters":[{"name":"id","in":"path","required":true,"description":"The number's id, as shown in the dashboard (for example `sales-desk`).","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["productIds"],"properties":{"productIds":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request is wrong; `error` says why.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such number, payment or webhook.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The number is not connected yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/instances/{id}/products/{productId}":{"patch":{"tags":["Catalog"],"operationId":"updateProduct","summary":"Change one product","parameters":[{"name":"id","in":"path","required":true,"description":"The number's id, as shown in the dashboard (for example `sales-desk`).","schema":{"type":"string"}},{"name":"productId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Product"}}}},"responses":{"200":{"description":"Updated.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request is wrong; `error` says why.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such number, payment or webhook.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The number is not connected yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/instances/{id}/orders/{orderId}":{"get":{"tags":["Catalog"],"operationId":"getOrder","summary":"An order a customer sent from the catalog","parameters":[{"name":"id","in":"path","required":true,"description":"The number's id, as shown in the dashboard (for example `sales-desk`).","schema":{"type":"string"}},{"name":"orderId","in":"path","required":true,"schema":{"type":"string"}},{"name":"token","in":"query","required":true,"schema":{"type":"string"},"description":"The order's token, from the incoming order message."}],"responses":{"200":{"description":"The order.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request is wrong; `error` says why.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such number, payment or webhook.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The number is not connected yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/messages":{"get":{"tags":["Messages"],"operationId":"listMessages","summary":"The message log, newest first","parameters":[{"name":"instance","in":"query","schema":{"type":"string"},"description":"Only this number."},{"name":"direction","in":"query","schema":{"type":"string","enum":["in","out"]}},{"name":"q","in":"query","schema":{"type":"string"},"description":"Search phone, name or text."},{"name":"before","in":"query","schema":{"type":"integer"},"description":"For paging: messages older than this id."},{"name":"limit","in":"query","schema":{"type":"integer","maximum":200,"default":50}}],"responses":{"200":{"description":"Messages.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"messages":{"type":"array","items":{"$ref":"#/components/schemas/LoggedMessage"}}}}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/webhooks":{"get":{"tags":["Webhooks"],"operationId":"listWebhooks","summary":"List webhooks","responses":{"200":{"description":"Webhooks.","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Webhooks"],"operationId":"createWebhook","summary":"Receive events at a URL","description":"Each POST is signed: `X-Webhook-Signature: sha256=<HMAC-SHA256 of the raw body with the secret>`.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookRequest"},"example":{"url":"https://example.com/whatsapp","events":["message"]}}}},"responses":{"201":{"description":"The webhook, with its signing secret (shown once).","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request is wrong; `error` says why.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/webhooks/{id}":{"delete":{"tags":["Webhooks"],"operationId":"deleteWebhook","summary":"Stop a webhook","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Missing or wrong API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such number, payment or webhook.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"webhooks":{"message":{"post":{"summary":"A message arrived (or was sent from the phone)","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageEvent"}}}},"responses":{"200":{"description":"Answer 2xx within 15 seconds."}}}},"receipt":{"post":{"summary":"A sent message was delivered or read","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"event":{"const":"receipt"},"session":{"type":"string"},"message_id":{"type":"string"},"status":{"type":"integer","description":"2 sent, 3 delivered, 4 read."}}}}}},"responses":{"200":{"description":"Answer 2xx."}}}}},"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"An API key from the dashboard, or from signup/verify."}},"schemas":{"Error":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"string"}}},"Plan":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"price":{"type":"number"},"currency":{"type":"string"},"period_label":{"type":"string","example":"month"},"trial_days":{"type":"integer"},"max_instances":{"type":"integer","description":"0 means unlimited."},"monthly_messages":{"type":"integer","description":"0 means unlimited."}}},"SignupStart":{"type":"object","required":["email","phone","name"],"properties":{"email":{"type":"string","format":"email"},"phone":{"type":"string","description":"The owner's WhatsApp number, with country code. The code is sent here."},"name":{"type":"string","description":"The owner's name."},"company":{"type":"string"},"plan_id":{"type":"string","description":"One of the public plans; the default plan if left out."}}},"SignupResult":{"type":"object","properties":{"ok":{"type":"boolean"},"api_key":{"type":"string","description":"Shown once. Send it as `Authorization: Bearer <api_key>`."},"account_id":{"type":"string"},"instance_id":{"type":"string","description":"The first number, ready to link."},"trial_until":{"type":"string","format":"date-time"},"dashboard_url":{"type":"string"}}},"Billing":{"type":"object","properties":{"ok":{"type":"boolean"},"subscription":{"type":"object","properties":{"status":{"type":"string","enum":["active","trial","expired","free","exempt"]},"paid_until":{"type":"string"},"trial_until":{"type":"string"},"can_send":{"type":"boolean"}}},"plan":{"$ref":"#/components/schemas/Plan"},"plans":{"type":"array","items":{"$ref":"#/components/schemas/Plan"}},"methods":{"type":"array","items":{"type":"string","enum":["paypal","mpesa","checkout"]}},"payments":{"type":"array","items":{"$ref":"#/components/schemas/Payment"}}}},"PayRequest":{"type":"object","required":["method"],"properties":{"plan_id":{"type":"string","description":"Leave out to renew the current plan."},"method":{"type":"string","enum":["paypal","mpesa","checkout"]},"phone":{"type":"string","description":"For `mpesa`: the number that gets the payment prompt."}}},"Payment":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["pending","complete","failed"]},"method":{"type":"string"},"amount":{"type":"number"},"currency":{"type":"string"},"plan_name":{"type":"string"},"checkout_url":{"type":"string","description":"For `checkout`: give this link to the person paying."},"covers_until":{"type":"string","format":"date-time"},"error":{"type":"string"}}},"Number":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string","description":"The id to use in paths."},"name":{"type":"string"},"state":{"type":"string","enum":["connected","pairing","disconnected","logged_out"]},"phone":{"type":"string"}}},"LinkState":{"type":"object","properties":{"state":{"type":"string"},"qr":{"type":"string","description":"A PNG data URL to show for scanning."},"pairing_code":{"type":"string","example":"ABCD-EFGH"},"expires_at":{"type":"string","format":"date-time"}}},"SendRequest":{"type":"object","required":["to"],"properties":{"to":{"type":"string","description":"Phone with country code (`254712345678`), or a group id."},"text":{"type":"string"},"media":{"type":"object","properties":{"kind":{"type":"string","enum":["image","video","audio","document"]},"url":{"type":"string","description":"A public URL, or…"},"base64":{"type":"string","description":"…the file itself."},"filename":{"type":"string"},"mimetype":{"type":"string"},"caption":{"type":"string"}}},"location":{"type":"object","properties":{"latitude":{"type":"number"},"longitude":{"type":"number"},"name":{"type":"string"},"address":{"type":"string"}}},"poll":{"type":"object","properties":{"name":{"type":"string","description":"The question."},"options":{"type":"array","items":{"type":"string"},"minItems":2,"maxItems":12},"multiple":{"type":"boolean","description":"Allow more than one answer."}}}}},"MessageRef":{"type":"object","required":["chat_id","message_id"],"properties":{"chat_id":{"type":"string","description":"The chat: a phone number or JID."},"message_id":{"type":"string"},"message_ids":{"type":"array","items":{"type":"string"},"description":"For read: several at once."},"from_me":{"type":"boolean","description":"Whether this number sent it."},"participant":{"type":"string","description":"In a group: who sent it."},"emoji":{"type":"string"},"text":{"type":"string"},"to":{"type":"string"}}},"Product":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"price":{"type":"number"},"currency":{"type":"string","example":"KES"},"retailerId":{"type":"string","description":"Your item code."},"url":{"type":"string"},"isHidden":{"type":"boolean"},"images":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string"},"base64":{"type":"string"}}}}}},"CatalogSync":{"type":"object","required":["products"],"properties":{"products":{"type":"array","maxItems":1000,"items":{"type":"object","required":["retailer_id"],"properties":{"retailer_id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"price":{"type":"number"},"currency":{"type":"string"},"url":{"type":"string"},"hidden":{"type":"boolean"},"images":{"type":"array","items":{"type":"string"},"description":"Image URLs. Needed for new products."}}}},"delete_missing":{"type":"boolean","default":false},"update_images":{"type":"boolean","default":false,"description":"Replace images on existing products too."},"dry_run":{"type":"boolean","default":false}}},"Sent":{"type":"object","properties":{"ok":{"type":"boolean"},"message_id":{"type":"string"},"chat_id":{"type":"string"}}},"LoggedMessage":{"type":"object","properties":{"id":{"type":"integer"},"direction":{"type":"string"},"peer":{"type":"string"},"push_name":{"type":"string"},"type":{"type":"string"},"body":{"type":"string"},"status":{"type":"string"},"created_at":{"type":"string"}}},"WebhookRequest":{"type":"object","required":["url"],"properties":{"url":{"type":"string"},"events":{"type":"array","items":{"type":"string","enum":["*","message","message.sent","receipt","connected","disconnected","logged_out","qr","pairing_code"]}},"instance":{"type":"string","description":"Only this number."},"format":{"type":"string","enum":["flat","waclient"]}}},"MessageEvent":{"type":"object","properties":{"event":{"const":"message"},"session":{"type":"string","description":"The number's id."},"message":{"type":"object","properties":{"message_id":{"type":"string"},"chat_id":{"type":"string"},"from_me":{"type":"boolean"},"is_group":{"type":"boolean"},"wa_id":{"type":"string","description":"Sender's phone."},"push_name":{"type":"string"},"message_type":{"type":"string"},"text":{"type":"string"},"media":{"type":"object"},"timestamp":{"type":"integer"}}},"at":{"type":"string","format":"date-time"}}}}}}