{"openapi":"3.1.0","info":{"title":"PulseApi","version":"1.0.0","description":"WhatsApp gateway API. Every call needs an API key in an Authorization header: `Authorization: Bearer sk_live_…`. Create keys in the console at /console."},"servers":[{"url":"https://api.massandvoid.in"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"Account","description":"Sign up, API keys and account details."},{"name":"Phones","description":"Pair, inspect and remove WhatsApp numbers."},{"name":"Messages","description":"Send anything WhatsApp can carry, and read what came back."},{"name":"Queue","description":"See what is waiting to go out on a number, and cancel it."},{"name":"Logs","description":"Account-wide message and webhook delivery history."},{"name":"Media","description":"Upload attachments once, reference them by id."},{"name":"Groups","description":"Create and manage WhatsApp groups."},{"name":"Contacts","description":"Check numbers, block and unblock."},{"name":"Profile","description":"The paired number’s own name, status and photo."},{"name":"Webhooks","description":"Get events pushed to your server, signed."},{"name":"Maytapi compatible","description":"Maytapi’s sendMessage, answered as-is, so existing integrations move with a config change."}],"webhooks":{"message.received":{"post":{"summary":"An inbound message arrived","description":"Sent for every message someone sends to a paired number. When the message is a button tap or list selection, `data.reply` carries the id you supplied when sending, so route on `reply.id` rather than the display text.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventMessageReceived"}}}},"responses":{"200":{"description":"Return any 2xx within 10 seconds."}}}},"message.sent":{"post":{"summary":"A queued message left the server","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventMessageSent"}}}},"responses":{"200":{"description":"Return any 2xx."}}}},"message.status":{"post":{"summary":"Delivery status changed (delivered, read, failed)","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventMessageStatus"}}}},"responses":{"200":{"description":"Return any 2xx."}}}},"phone.status":{"post":{"summary":"A number connected, disconnected, or was logged out","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventPhoneStatus"}}}},"responses":{"200":{"description":"Return any 2xx."}}}},"phone.qr":{"post":{"summary":"A fresh pairing QR is available","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventPhoneQr"}}}},"responses":{"200":{"description":"Return any 2xx."}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Your sk_live_… API key"},"maytapiKey":{"type":"apiKey","in":"header","name":"x-maytapi-key","description":"The same API key, in Maytapi’s header"}},"schemas":{"Envelope":{"type":"object","description":"Every webhook body has this shape. Verify the `x-pulseapi-signature` header (`t=<unix>,v1=<hex HMAC-SHA256 of \"<t>.<body>\">` with your endpoint secret) before trusting it.","properties":{"id":{"type":"string","description":"Delivery id"},"type":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"data":{"type":"object"}}},"EventMessageReceived":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"type":"object","properties":{"type":{"type":"string","const":"message.received"},"data":{"type":"object","properties":{"messageId":{"type":"string"},"phoneId":{"type":"string"},"chatJid":{"type":"string","example":"919876543210@s.whatsapp.net"},"senderJid":{"type":"string"},"pushName":{"type":["string","null"],"description":"Sender’s display name"},"type":{"type":"string","example":"conversation"},"text":{"type":["string","null"]},"quotedWaMessageId":{"type":["string","null"]},"reply":{"type":["object","null"],"description":"Present only for a button tap or list selection.","properties":{"source":{"type":"string","enum":["button","list","native","template"]},"id":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"}}},"media":{"type":["object","null"],"properties":{"mediaId":{"type":"string"},"url":{"type":"string","description":"GET this with your API key"},"mimetype":{"type":"string"},"filename":{"type":["string","null"]},"sizeBytes":{"type":"integer"}}},"timestamp":{"type":"string","format":"date-time"}}}}}]},"EventMessageSent":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"type":"object","properties":{"type":{"type":"string","const":"message.sent"},"data":{"type":"object","properties":{"messageId":{"type":"string"},"phoneId":{"type":"string"},"chatJid":{"type":"string"},"waMessageId":{"type":"string"}}}}}]},"EventMessageStatus":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"type":"object","properties":{"type":{"type":"string","const":"message.status"},"data":{"type":"object","properties":{"messageId":{"type":"string"},"phoneId":{"type":"string"},"chatJid":{"type":"string"},"status":{"type":"string","enum":["delivered","read","failed"]},"error":{"type":["string","null"]}}}}}]},"EventPhoneStatus":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"type":"object","properties":{"type":{"type":"string","const":"phone.status"},"data":{"type":"object","properties":{"phoneId":{"type":"string"},"status":{"type":"string"},"reason":{"type":["string","null"]},"msisdn":{"type":["string","null"]}}}}}]},"EventPhoneQr":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"type":"object","properties":{"type":{"type":"string","const":"phone.qr"},"data":{"type":"object","properties":{"phoneId":{"type":"string"},"dataUrl":{"type":"string","description":"PNG data: URI of the QR"}}}}}]},"Phone":{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string"},"msisdn":{"type":["string","null"]},"status":{"type":"string","enum":["provisioning","awaiting_scan","connecting","connected","disconnected","logged_out","banned"]}}},"Message":{"type":"object","properties":{"id":{"type":"string"},"direction":{"type":"string","enum":["inbound","outbound"]},"status":{"type":"string","enum":["queued","sending","sent","delivered","read","failed","received"]},"chatJid":{"type":"string"},"waMessageId":{"type":["string","null"]},"mediaUrl":{"type":"string","description":"Present when the message has an attachment"},"createdAt":{"type":"string","format":"date-time"}}},"Profile":{"type":"object","properties":{"jid":{"type":"string"},"msisdn":{"type":"string"},"name":{"type":"string"},"status":{"type":"string","description":"The \"about\" text."},"profilePictureUrl":{"type":"string"}}},"Chat":{"type":"object","properties":{"chatJid":{"type":"string"},"isGroup":{"type":"boolean"},"name":{"type":["string","null"],"description":"Contact's WhatsApp name, or their number; null for a group."},"unreadCount":{"type":"integer","description":"Inbound messages since you last read."},"messageCount":{"type":"integer"},"lastMessage":{"type":"object","properties":{"id":{"type":"string"},"direction":{"type":"string","enum":["inbound","outbound"]},"fromMe":{"type":"boolean"},"type":{"type":"string"},"status":{"type":"string"},"waMessageId":{"type":["string","null"]},"preview":{"type":"string","description":"Text, or a label like \"📷 Photo\"."},"timestamp":{"type":"string","format":"date-time"}}}}},"Reply":{"type":"object","description":"Present on an inbound message when the recipient tapped a button or picked a list row. Route on `id` — it is the value you supplied when sending, so it survives label changes and translation. Also delivered on the message.received webhook.","properties":{"source":{"type":"string","enum":["button","list","native","template"]},"id":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"}}},"Group":{"type":"object","properties":{"jid":{"type":"string"},"subject":{"type":"string"},"description":{"type":"string"},"owner":{"type":"string"},"participants":{"type":"array","items":{"type":"object","properties":{"jid":{"type":"string"},"isAdmin":{"type":"boolean"},"isSuperAdmin":{"type":"boolean"}}}}}},"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}},"paths":{"/v1/signup":{"post":{"operationId":"signup","summary":"Create an account and its first API key","description":"Public. Disabled unless the deployment turns it on. Returns the API key exactly once.","tags":["Account"],"security":[],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","maxLength":80},"email":{"type":"string","format":"email"},"code":{"type":"string","description":"Invite code, if the deployment requires one."}}}}}},"responses":{"201":{"description":"Account created","content":{"application/json":{"schema":{"type":"object","properties":{"tenant":{"type":"object"},"apiKey":{"type":"string","description":"Shown once. Store it now."}}}}}},"403":{"description":"Signup disabled or invite code required","content":{"application/json":{"schema":{"type":"object"}}}},"429":{"description":"Too many signups from this address","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v1/me":{"get":{"operationId":"getAccount","summary":"Your account and its limits","tags":["Account"],"responses":{"200":{"description":"Account","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v1/keys":{"get":{"operationId":"listKeys","summary":"List your API keys (prefixes only)","tags":["Account"],"responses":{"200":{"description":"Keys","content":{"application/json":{"schema":{"type":"object"}}}}}},"post":{"operationId":"createKey","summary":"Create another API key (returned once)","tags":["Account"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v1/keys/{id}":{"delete":{"operationId":"revokeKey","summary":"Revoke an API key","tags":["Account"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Revoked"}}}},"/v1/phones":{"get":{"operationId":"listPhones","summary":"List connected numbers","tags":["Phones"],"responses":{"200":{"description":"The tenant’s phones","content":{"application/json":{"schema":{"type":"object"}}}}}},"post":{"operationId":"createPhone","summary":"Provision a number (returns a QR to scan)","tags":["Phones"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["label"],"properties":{"label":{"type":"string"}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v1/phones/{id}":{"patch":{"operationId":"updatePhone","summary":"Rename, mark established, or change anti-ban settings","description":"Every field is optional. `established` starts the number on the day-7 rung. `safeMode` adds a typing indicator, uneven gaps and occasional breaks. `quietHours` (null to clear) holds sends between two local hours. `pacing` switches between the automatic ladder and your own gap/cap — custom figures are your number’s risk to carry.","tags":["Phones"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Phone ID, e.g. ph_4w72h0ay7ctghgwz"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"label":{"type":"string","maxLength":80},"established":{"type":"boolean"},"safeMode":{"type":"boolean"},"timezone":{"type":"string","example":"Asia/Kolkata"},"proxyUrl":{"type":["string","null"],"example":"socks5://user:pass@1.2.3.4:1080","description":"Per-number proxy; null removes it. The number reconnects through it."},"quietHours":{"type":["object","null"],"properties":{"start":{"type":"integer","minimum":0,"maximum":23,"example":22},"end":{"type":"integer","minimum":0,"maximum":23,"example":8},"timezone":{"type":"string","example":"Asia/Kolkata"}}},"pacing":{"oneOf":[{"type":"object","required":["mode"],"properties":{"mode":{"const":"auto"}}},{"type":"object","required":["mode","intervalSeconds","dailyCap"],"properties":{"mode":{"const":"custom"},"intervalSeconds":{"type":"number","minimum":1,"maximum":3600},"dailyCap":{"type":"integer","minimum":1,"maximum":10000}}}]}}}}}},"responses":{"200":{"description":"Updated phone","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Phone"}}}}}},"get":{"operationId":"getPhone","summary":"Status and current sending allowance","tags":["Phones"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Phone ID, e.g. ph_4w72h0ay7ctghgwz"}],"responses":{"200":{"description":"Phone status","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object"}}}}}},"delete":{"operationId":"deletePhone","summary":"Log out and remove a number","tags":["Phones"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Phone ID, e.g. ph_4w72h0ay7ctghgwz"}],"responses":{"202":{"description":"Logging out","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v1/phones/{id}/warmup":{"get":{"operationId":"getWarmup","summary":"Anti-ban picture: ladder position, running pace, 7-day history, reply ratio","tags":["Phones"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Phone ID, e.g. ph_4w72h0ay7ctghgwz"}],"responses":{"200":{"description":"Warm-up state","content":{"application/json":{"schema":{"type":"object","properties":{"day":{"type":"integer","description":"Days on the ladder incl. head start"},"established":{"type":"boolean"},"ladder":{"type":"array","items":{"type":"object"}},"rung":{"type":"object"},"next":{"type":["object","null"]},"running":{"type":"object","properties":{"dailyCap":{"type":"integer"},"minIntervalMs":{"type":"integer"},"source":{"type":"string","enum":["ladder","custom"]}}},"usedToday":{"type":"integer"},"safeMode":{"type":"boolean"},"quietHours":{"type":["object","null"]},"history":{"type":"array","items":{"type":"object"}},"health":{"type":"object","properties":{"sent7d":{"type":"integer"},"received7d":{"type":"integer"},"replyRatio":{"type":["number","null"]},"verdict":{"type":"string","enum":["quiet","healthy","watch","risky"]}}}}}}}}}}},"/v1/keys/{id}/reveal":{"get":{"operationId":"revealKey","summary":"Show an API key again (dashboard login only)","description":"Returns the full key. Only a logged-in dashboard session may call this — never another API key — and only for keys created after keys became viewable.","tags":["Account"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The key","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"apiKey":{"type":"string"}}}}}},"403":{"description":"Called with an API key rather than a session"},"422":{"description":"Revoked, or created before keys were stored"}}}},"/v1/support":{"get":{"operationId":"listSupportTickets","summary":"Your support tickets","tags":["Account"],"responses":{"200":{"description":"Tickets","content":{"application/json":{"schema":{"type":"object"}}}}}},"post":{"operationId":"createSupportTicket","summary":"Send a message to PulseApi support, with screenshots","tags":["Account"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["subject","message"],"properties":{"category":{"type":"string","enum":["sending","connection","billing","integration","feature","other"]},"subject":{"type":"string","maxLength":160},"message":{"type":"string","maxLength":8000},"attachments":{"type":"array","maxItems":4,"items":{"type":"object","properties":{"filename":{"type":"string"},"dataUri":{"type":"string","description":"data:image/png;base64,…"}}}},"context":{"type":"object","additionalProperties":{"type":"string"}}}}}}},"responses":{"201":{"description":"Ticket created","content":{"application/json":{"schema":{"type":"object","properties":{"ticket":{"type":"object"},"emailed":{"type":"boolean"}}}}}}}}},"/v1/stats/public":{"get":{"operationId":"publicStats","summary":"Platform-wide live figures shown on the landing page (no auth)","tags":["Account"],"security":[],"responses":{"200":{"description":"Counts","content":{"application/json":{"schema":{"type":"object","properties":{"messagesDelivered":{"type":"integer"},"numbersConnected":{"type":"integer"},"accounts":{"type":"integer"}}}}}}}}},"/api/{product_id}/{phone_id}/sendMessage":{"post":{"operationId":"maytapiSendMessage","summary":"Send a message with Maytapi’s request shape","description":"Drop-in for Maytapi’s sendMessage. product_id is your account id, phone_id the number’s numeric alias (or ph_… id), authenticated with x-maytapi-key (Bearer and x-api-key also work). type \"text\" sends message as text; type \"media\" takes an http(s) URL or a data:…;base64 URI in message, with text as caption and filename as the document name. Answers 200 {success:true,data:{chatId,msgId}} when queued and a non-200 {success:false,message} otherwise.","tags":["Maytapi compatible"],"security":[{"maytapiKey":[]},{"bearerAuth":[]}],"parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string"},"description":"Your account id (ten_…)"},{"name":"phone_id","in":"path","required":true,"schema":{"type":"string"},"description":"Numeric alias such as 10001, or the ph_… id"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["to_number","message"],"properties":{"to_number":{"type":"string","description":"Bare digits with country code, e.g. 919830000001"},"type":{"type":"string","enum":["text","media","location"],"default":"text"},"message":{"type":"string","description":"Text, or for media a URL / data:…;base64 URI, or \"lat,lng\" for location"},"text":{"type":"string","description":"Caption (media) or place name (location)"},"filename":{"type":"string"}}}}}},"responses":{"200":{"description":"Queued","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","properties":{"chatId":{"type":"string"},"msgId":{"type":"string"},"phoneId":{"type":"integer"}}}}}}}},"400":{"description":"{success:false,message}"},"401":{"description":"{success:false,message}"},"404":{"description":"Unknown product or phone — {success:false,message}"},"422":{"description":"Number needs a fresh scan — {success:false,message}"}}}},"/v1/phones/{id}/proxy-test":{"post":{"operationId":"testProxy","summary":"Check a proxy: exit IP and latency, without saving","tags":["Phones"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Phone ID, e.g. ph_4w72h0ay7ctghgwz"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","description":"Omit to test the saved proxy"}}}}}},"responses":{"200":{"description":"Probe result","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"ip":{"type":"string"},"latencyMs":{"type":"integer"},"error":{"type":"string"}}}}}}}}},"/v1/phones/{id}/qr":{"get":{"operationId":"getQr","summary":"Current pairing QR code","tags":["Phones"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Phone ID, e.g. ph_4w72h0ay7ctghgwz"}],"responses":{"200":{"description":"QR, or null if none pending","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v1/phones/{id}/messages":{"post":{"operationId":"sendMessage","summary":"Send a message","description":"Accepts text, image, video, audio, document, sticker, location, contact, reaction and forward. Media can be a URL, inline base64, or a mediaId from POST /v1/media. Send an Idempotency-Key header and a retry returns the original result rather than sending twice.","tags":["Messages"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Phone ID, e.g. ph_4w72h0ay7ctghgwz"},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["to","content"],"properties":{"to":{"type":"string","example":"+919876543210","description":"Phone number with country code, or a JID"},"content":{"oneOf":[{"type":"object","required":["kind","text"],"properties":{"kind":{"const":"text"},"text":{"type":"string"},"linkPreview":{"type":"boolean"}}},{"type":"object","required":["kind","source"],"properties":{"kind":{"const":"image"},"source":{"oneOf":[{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}},{"type":"object","required":["base64"],"properties":{"base64":{"type":"string","description":"Raw base64, or a data: URI"}}},{"type":"object","required":["mediaId"],"properties":{"mediaId":{"type":"string","description":"From POST /v1/media"}}}]},"caption":{"type":"string"},"mimetype":{"type":"string"}}},{"type":"object","required":["kind","source"],"properties":{"kind":{"const":"video"},"source":{"oneOf":[{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}},{"type":"object","required":["base64"],"properties":{"base64":{"type":"string","description":"Raw base64, or a data: URI"}}},{"type":"object","required":["mediaId"],"properties":{"mediaId":{"type":"string","description":"From POST /v1/media"}}}]},"caption":{"type":"string"},"gif":{"type":"boolean"}}},{"type":"object","required":["kind","source"],"properties":{"kind":{"const":"audio"},"source":{"oneOf":[{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}},{"type":"object","required":["base64"],"properties":{"base64":{"type":"string","description":"Raw base64, or a data: URI"}}},{"type":"object","required":["mediaId"],"properties":{"mediaId":{"type":"string","description":"From POST /v1/media"}}}]},"ptt":{"type":"boolean"}}},{"type":"object","required":["kind","source","filename"],"properties":{"kind":{"const":"document"},"source":{"oneOf":[{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}},{"type":"object","required":["base64"],"properties":{"base64":{"type":"string","description":"Raw base64, or a data: URI"}}},{"type":"object","required":["mediaId"],"properties":{"mediaId":{"type":"string","description":"From POST /v1/media"}}}]},"filename":{"type":"string"},"mimetype":{"type":"string"},"caption":{"type":"string"}}},{"type":"object","required":["kind","source"],"properties":{"kind":{"const":"sticker"},"source":{"oneOf":[{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}},{"type":"object","required":["base64"],"properties":{"base64":{"type":"string","description":"Raw base64, or a data: URI"}}},{"type":"object","required":["mediaId"],"properties":{"mediaId":{"type":"string","description":"From POST /v1/media"}}}]}}},{"type":"object","required":["kind","latitude","longitude"],"properties":{"kind":{"const":"location"},"latitude":{"type":"number"},"longitude":{"type":"number"},"name":{"type":"string"},"address":{"type":"string"}}},{"type":"object","required":["kind","displayName","vcard"],"properties":{"kind":{"const":"contact"},"displayName":{"type":"string"},"vcard":{"type":"string"}}},{"type":"object","required":["kind","targetWaMessageId","emoji"],"properties":{"kind":{"const":"reaction"},"targetWaMessageId":{"type":"string"},"emoji":{"type":"string"}}},{"type":"object","required":["kind","waMessageId","fromChatJid"],"properties":{"kind":{"const":"forward"},"waMessageId":{"type":"string"},"fromChatJid":{"type":"string"}}},{"type":"object","description":"Up to three tappable quick replies. The tap arrives on the message.received webhook as reply.id.","required":["kind","body","buttons"],"properties":{"kind":{"const":"buttons"},"body":{"type":"string","maxLength":4096},"buttons":{"type":"array","minItems":1,"maxItems":3,"items":{"type":"object","required":["id","title"],"properties":{"id":{"type":"string","maxLength":256,"description":"Returned verbatim as reply.id when the recipient taps this button."},"title":{"type":"string","maxLength":20,"description":"Label shown on the button."}}}},"footer":{"type":"string","maxLength":60},"header":{"description":"Optional header shown above the body.","oneOf":[{"type":"object","required":["kind","text"],"properties":{"kind":{"const":"text"},"text":{"type":"string","maxLength":60}}},{"type":"object","required":["kind","source"],"properties":{"kind":{"const":"image"},"source":{"oneOf":[{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}},{"type":"object","required":["base64"],"properties":{"base64":{"type":"string","description":"Raw base64, or a data: URI"}}},{"type":"object","required":["mediaId"],"properties":{"mediaId":{"type":"string","description":"From POST /v1/media"}}}]}}},{"type":"object","required":["kind","source"],"properties":{"kind":{"const":"video"},"source":{"oneOf":[{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}},{"type":"object","required":["base64"],"properties":{"base64":{"type":"string","description":"Raw base64, or a data: URI"}}},{"type":"object","required":["mediaId"],"properties":{"mediaId":{"type":"string","description":"From POST /v1/media"}}}]}}},{"type":"object","required":["kind","source","filename"],"properties":{"kind":{"const":"document"},"source":{"oneOf":[{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}},{"type":"object","required":["base64"],"properties":{"base64":{"type":"string","description":"Raw base64, or a data: URI"}}},{"type":"object","required":["mediaId"],"properties":{"mediaId":{"type":"string","description":"From POST /v1/media"}}}]},"filename":{"type":"string"},"mimetype":{"type":"string"}}}]},"render":{"type":"string","enum":["native","legacy"],"default":"native","description":"Wire encoding. \"native\" is the modern interactiveMessage most current clients render; \"legacy\" is the older buttonsMessage/listMessage, useful for audiences on older builds. Neither renders on every client — see the caveat in the docs."}}},{"type":"object","description":"A single-select menu of up to ten rows across all sections.","required":["kind","body","buttonText","sections"],"properties":{"kind":{"const":"list"},"body":{"type":"string","maxLength":4096},"buttonText":{"type":"string","maxLength":20,"description":"Label that opens the menu."},"sections":{"type":"array","minItems":1,"items":{"type":"object","required":["rows"],"properties":{"title":{"type":"string","maxLength":24},"rows":{"type":"array","minItems":1,"items":{"type":"object","required":["id","title"],"properties":{"id":{"type":"string","maxLength":256,"description":"Returned as reply.id when selected."},"title":{"type":"string","maxLength":24},"description":{"type":"string","maxLength":72}}}}}}},"title":{"type":"string","maxLength":60},"footer":{"type":"string","maxLength":60},"render":{"type":"string","enum":["native","legacy"],"default":"native","description":"Wire encoding. \"native\" is the modern interactiveMessage most current clients render; \"legacy\" is the older buttonsMessage/listMessage, useful for audiences on older builds. Neither renders on every client — see the caveat in the docs."}}},{"type":"object","description":"Action buttons: open a URL, dial a number, or copy text. These do not send a reply back.","required":["kind","body","buttons"],"properties":{"kind":{"const":"cta"},"body":{"type":"string","maxLength":4096},"buttons":{"type":"array","minItems":1,"maxItems":3,"items":{"oneOf":[{"type":"object","required":["type","title","url"],"properties":{"type":{"const":"url"},"title":{"type":"string","maxLength":20},"url":{"type":"string","format":"uri"}}},{"type":"object","required":["type","title","phone"],"properties":{"type":{"const":"call"},"title":{"type":"string","maxLength":20},"phone":{"type":"string"}}},{"type":"object","required":["type","title","copyText"],"properties":{"type":{"const":"copy"},"title":{"type":"string","maxLength":20},"copyText":{"type":"string","maxLength":200}}},{"type":"object","required":["type","title","id"],"properties":{"type":{"const":"reply"},"title":{"type":"string","maxLength":20},"id":{"type":"string","maxLength":256}}}]}},"footer":{"type":"string","maxLength":60},"header":{"description":"Optional header shown above the body.","oneOf":[{"type":"object","required":["kind","text"],"properties":{"kind":{"const":"text"},"text":{"type":"string","maxLength":60}}},{"type":"object","required":["kind","source"],"properties":{"kind":{"const":"image"},"source":{"oneOf":[{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}},{"type":"object","required":["base64"],"properties":{"base64":{"type":"string","description":"Raw base64, or a data: URI"}}},{"type":"object","required":["mediaId"],"properties":{"mediaId":{"type":"string","description":"From POST /v1/media"}}}]}}},{"type":"object","required":["kind","source"],"properties":{"kind":{"const":"video"},"source":{"oneOf":[{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}},{"type":"object","required":["base64"],"properties":{"base64":{"type":"string","description":"Raw base64, or a data: URI"}}},{"type":"object","required":["mediaId"],"properties":{"mediaId":{"type":"string","description":"From POST /v1/media"}}}]}}},{"type":"object","required":["kind","source","filename"],"properties":{"kind":{"const":"document"},"source":{"oneOf":[{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}},{"type":"object","required":["base64"],"properties":{"base64":{"type":"string","description":"Raw base64, or a data: URI"}}},{"type":"object","required":["mediaId"],"properties":{"mediaId":{"type":"string","description":"From POST /v1/media"}}}]},"filename":{"type":"string"},"mimetype":{"type":"string"}}}]}}},{"type":"object","description":"A native WhatsApp poll. Votes arrive as poll update events.","required":["kind","name","options"],"properties":{"kind":{"const":"poll"},"name":{"type":"string","maxLength":255},"options":{"type":"array","minItems":2,"maxItems":12,"items":{"type":"string","maxLength":100}},"selectableCount":{"type":"integer","minimum":1,"default":1}}}]},"replyTo":{"type":"string","description":"WhatsApp message id to quote"}}}}}},"responses":{"202":{"description":"Accepted and queued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Message"}}}},"422":{"description":"Phone not connected","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"operationId":"listMessages","summary":"Message history","tags":["Messages"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Phone ID, e.g. ph_4w72h0ay7ctghgwz"},{"name":"limit","in":"query","schema":{"type":"integer","maximum":100}},{"name":"before","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"chat","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Messages, newest first","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v1/phones/{id}/chats":{"get":{"operationId":"listChats","summary":"Conversation inbox — one row per chat, newest first","description":"Derived from stored messages, so a chat appears here once a message has flowed through PulseApi. Each row carries the last message and an unread count.","tags":["Messages"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Phone ID, e.g. ph_4w72h0ay7ctghgwz"},{"name":"limit","in":"query","schema":{"type":"integer","maximum":100}},{"name":"before","in":"query","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Chats, most recent activity first","content":{"application/json":{"schema":{"type":"object","properties":{"chats":{"type":"array","items":{"$ref":"#/components/schemas/Chat"}},"nextBefore":{"type":["string","null"],"format":"date-time"}}}}}}}}},"/v1/phones/{id}/messages/{waMessageId}":{"delete":{"operationId":"deleteMessage","summary":"Delete a message for everyone","tags":["Messages"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Phone ID, e.g. ph_4w72h0ay7ctghgwz"},{"name":"waMessageId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Deleted"}}},"patch":{"operationId":"editMessage","summary":"Edit a message you sent","tags":["Messages"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Phone ID, e.g. ph_4w72h0ay7ctghgwz"},{"name":"waMessageId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["text"],"properties":{"text":{"type":"string"}}}}}},"responses":{"200":{"description":"Edited","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v1/phones/{id}/chats/{chat}/read":{"post":{"operationId":"markRead","summary":"Mark messages as read","tags":["Messages"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Phone ID, e.g. ph_4w72h0ay7ctghgwz"},{"name":"chat","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["waMessageIds"],"properties":{"waMessageIds":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"Marked","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v1/phones/{id}/chats/{chat}/typing":{"post":{"operationId":"setTyping","summary":"Show a typing or recording indicator","tags":["Messages"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Phone ID, e.g. ph_4w72h0ay7ctghgwz"},{"name":"chat","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["state"],"properties":{"state":{"type":"string","enum":["composing","recording","paused"]}}}}}},"responses":{"200":{"description":"Sent","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v1/media":{"post":{"operationId":"uploadMedia","summary":"Upload an attachment and get a reusable mediaId","tags":["Media"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["base64"],"properties":{"base64":{"type":"string"},"filename":{"type":"string"},"mimetype":{"type":"string"}}}}}},"responses":{"201":{"description":"Stored","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v1/media/{id}":{"get":{"operationId":"downloadMedia","summary":"Download an attachment","tags":["Media"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The file","content":{"application/octet-stream":{}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v1/phones/{id}/groups":{"get":{"operationId":"listGroups","summary":"List groups this number is in","tags":["Groups"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Phone ID, e.g. ph_4w72h0ay7ctghgwz"}],"responses":{"200":{"description":"Groups","content":{"application/json":{"schema":{"type":"object"}}}}}},"post":{"operationId":"createGroup","summary":"Create a group","tags":["Groups"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Phone ID, e.g. ph_4w72h0ay7ctghgwz"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["subject","participants"],"properties":{"subject":{"type":"string"},"participants":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Group"}}}}}}},"/v1/phones/{id}/groups/{groupId}":{"get":{"operationId":"getGroup","summary":"Group metadata and participants","tags":["Groups"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Phone ID, e.g. ph_4w72h0ay7ctghgwz"},{"name":"groupId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Group","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Group"}}}}}},"patch":{"operationId":"renameGroup","summary":"Change the group subject","tags":["Groups"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Phone ID, e.g. ph_4w72h0ay7ctghgwz"},{"name":"groupId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["subject"],"properties":{"subject":{"type":"string"}}}}}},"responses":{"200":{"description":"Renamed","content":{"application/json":{"schema":{"type":"object"}}}}}},"delete":{"operationId":"leaveGroup","summary":"Leave a group","tags":["Groups"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Phone ID, e.g. ph_4w72h0ay7ctghgwz"},{"name":"groupId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Left"}}}},"/v1/phones/{id}/groups/{groupId}/participants":{"post":{"operationId":"updateGroupParticipants","summary":"Add, remove, promote or demote participants","tags":["Groups"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Phone ID, e.g. ph_4w72h0ay7ctghgwz"},{"name":"groupId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["participants","action"],"properties":{"participants":{"type":"array","items":{"type":"string"}},"action":{"type":"string","enum":["add","remove","promote","demote"]}}}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v1/phones/{id}/groups/{groupId}/invite":{"get":{"operationId":"getGroupInvite","summary":"Group invite link","tags":["Groups"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Phone ID, e.g. ph_4w72h0ay7ctghgwz"},{"name":"groupId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Invite code and URL","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v1/phones/{id}/contacts/{number}":{"get":{"operationId":"checkContact","summary":"Is this number on WhatsApp?","tags":["Contacts"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Phone ID, e.g. ph_4w72h0ay7ctghgwz"},{"name":"number","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Contact info","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v1/phones/{id}/contacts/{number}/block":{"post":{"operationId":"blockContact","summary":"Block or unblock a contact","tags":["Contacts"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Phone ID, e.g. ph_4w72h0ay7ctghgwz"},{"name":"number","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"action":{"type":"string","enum":["block","unblock"],"default":"block"}}}}}},"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v1/phones/{id}/blocklist":{"get":{"operationId":"listBlocked","summary":"Numbers this phone has blocked","tags":["Contacts"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Phone ID, e.g. ph_4w72h0ay7ctghgwz"}],"responses":{"200":{"description":"Blocked JIDs","content":{"application/json":{"schema":{"type":"object","properties":{"blocked":{"type":"array","items":{"type":"string"}}}}}}}}}},"/v1/phones/{id}/profile":{"get":{"operationId":"getProfile","summary":"This number's own profile","tags":["Profile"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Phone ID, e.g. ph_4w72h0ay7ctghgwz"}],"responses":{"200":{"description":"Profile","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Profile"}}}}}},"patch":{"operationId":"updateProfile","summary":"Set display name and/or about text","tags":["Profile"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Phone ID, e.g. ph_4w72h0ay7ctghgwz"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":25},"status":{"type":"string","maxLength":139,"description":"The \"about\" text."}}}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v1/phones/{id}/profile/picture":{"put":{"operationId":"setProfilePicture","summary":"Set the profile photo","description":"Body is a media source: { url }, { base64 } or { mediaId }.","tags":["Profile"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Phone ID, e.g. ph_4w72h0ay7ctghgwz"}],"requestBody":{"content":{"application/json":{"schema":{"oneOf":[{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}},{"type":"object","required":["base64"],"properties":{"base64":{"type":"string","description":"Raw base64, or a data: URI"}}},{"type":"object","required":["mediaId"],"properties":{"mediaId":{"type":"string","description":"From POST /v1/media"}}}]}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"type":"object"}}}}}},"delete":{"operationId":"removeProfilePicture","summary":"Remove the profile photo","tags":["Profile"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Phone ID, e.g. ph_4w72h0ay7ctghgwz"}],"responses":{"204":{"description":"Removed"}}}},"/v1/phones/{id}/presence":{"post":{"operationId":"setPresence","summary":"Appear online or offline","tags":["Profile"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Phone ID, e.g. ph_4w72h0ay7ctghgwz"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["state"],"properties":{"state":{"type":"string","enum":["available","unavailable"]}}}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v1/messages":{"get":{"operationId":"searchMessages","summary":"Message log across all numbers","description":"Newest first. Filter by number, direction, status, chat, type, a time window, or free text (`q` matches message text, caption and chat number). Page with `before`.","tags":["Logs"],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","maximum":200,"default":50}},{"name":"before","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"since","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"until","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"phoneId","in":"query","schema":{"type":"string"}},{"name":"direction","in":"query","schema":{"type":"string","enum":["inbound","outbound"]}},{"name":"status","in":"query","schema":{"type":"string","enum":["queued","sending","sent","delivered","read","failed","received"]}},{"name":"type","in":"query","schema":{"type":"string"}},{"name":"chat","in":"query","schema":{"type":"string"},"description":"Phone number or JID"},{"name":"q","in":"query","schema":{"type":"string","maxLength":200}}],"responses":{"200":{"description":"Messages and a `nextBefore` cursor","content":{"application/json":{"schema":{"type":"object","properties":{"messages":{"type":"array","items":{"$ref":"#/components/schemas/Message"}},"nextBefore":{"type":["string","null"],"format":"date-time"}}}}}}}}},"/v1/messages/stats":{"get":{"operationId":"messageStats","summary":"Counts for the last 24 hours","tags":["Logs"],"responses":{"200":{"description":"Totals","content":{"application/json":{"schema":{"type":"object","properties":{"since":{"type":"string","format":"date-time"},"inbound":{"type":"integer"},"outbound":{"type":"integer"},"failed":{"type":"integer"},"pending":{"type":"integer"}}}}}}}}},"/v1/messages/{id}":{"get":{"operationId":"getMessage","summary":"One message by id","tags":["Messages"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Message","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Message"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object"}}}}}},"delete":{"operationId":"cancelMessage","summary":"Cancel a queued message","description":"Only a message that has not left yet can be cancelled; anything else returns 422.","tags":["Queue"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Cancelled","content":{"application/json":{"schema":{"type":"object","properties":{"cancelled":{"type":"boolean"}}}}}},"422":{"description":"Already sent","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/phones/{id}/queue":{"get":{"operationId":"getQueue","summary":"What is waiting to send on this number","description":"Pending messages in send order, with today’s usage against the warm-up cap and an estimate of how long the backlog takes at the current pace.","tags":["Queue"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Phone ID, e.g. ph_4w72h0ay7ctghgwz"},{"name":"limit","in":"query","schema":{"type":"integer","maximum":200,"default":50}}],"responses":{"200":{"description":"Queue","content":{"application/json":{"schema":{"type":"object","properties":{"phoneId":{"type":"string"},"phoneStatus":{"type":"string"},"counts":{"type":"object","properties":{"queued":{"type":"integer"},"sending":{"type":"integer"},"pending":{"type":"integer"}}},"throughput":{"type":"object","properties":{"dailyCap":{"type":"integer"},"usedToday":{"type":"integer"},"remainingToday":{"type":"integer"},"minIntervalMs":{"type":"integer"},"warmupDay":{"type":"integer"},"estimatedSeconds":{"type":"integer"},"spillsToTomorrow":{"type":"integer"}}},"messages":{"type":"array","items":{"$ref":"#/components/schemas/Message"}}}}}}}}},"delete":{"operationId":"clearQueue","summary":"Cancel everything waiting on this number","tags":["Queue"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Phone ID, e.g. ph_4w72h0ay7ctghgwz"}],"responses":{"200":{"description":"How many were cancelled","content":{"application/json":{"schema":{"type":"object","properties":{"cancelled":{"type":"integer"}}}}}}}}},"/v1/phones/{id}/pairing-code":{"post":{"operationId":"requestPairingCode","summary":"Pair by 8-character code instead of QR","tags":["Phones"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Phone ID, e.g. ph_4w72h0ay7ctghgwz"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["msisdn"],"properties":{"msisdn":{"type":"string","description":"Number with country code"}}}}}},"responses":{"202":{"description":"Requested; poll GET for the code","content":{"application/json":{"schema":{"type":"object"}}}}}},"get":{"operationId":"getPairingCode","summary":"Read the pending pairing code","tags":["Phones"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Phone ID, e.g. ph_4w72h0ay7ctghgwz"}],"responses":{"200":{"description":"Code, or null if none pending","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v1/account":{"patch":{"operationId":"updateAccount","summary":"Account settings","tags":["Account"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":80},"notifyEmail":{"type":["string","null"],"format":"email"},"timezone":{"type":"string","example":"Asia/Kolkata"}}}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"type":"object"}}}}}},"delete":{"operationId":"deleteAccount","summary":"Delete the account and everything in it (owner session only)","tags":["Account"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["confirm"],"properties":{"confirm":{"type":"string","description":"The account name, typed exactly"}}}}}},"responses":{"204":{"description":"Deleted"}}}},"/v1/account/members":{"get":{"operationId":"listMembers","summary":"Team members","tags":["Account"],"responses":{"200":{"description":"Members","content":{"application/json":{"schema":{"type":"object"}}}}}},"post":{"operationId":"addMember","summary":"Add a team member by email (owner only)","tags":["Account"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email"}}}}}},"responses":{"201":{"description":"Added","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v1/billing":{"get":{"operationId":"getBilling","summary":"Plan, trial state, catalogue and payment history","description":"Every account starts with a short full-feature trial and must then subscribe. While expired, the API answers 402 to everything except this, /v1/me, /v1/account and /v1/keys.","tags":["Account"],"responses":{"200":{"description":"Billing state","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v1/media/{id}/info":{"get":{"operationId":"getMediaInfo","summary":"Metadata for an upload without the bytes","tags":["Media"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Media info","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v1/webhooks/{id}":{"delete":{"operationId":"deleteWebhook","summary":"Remove a webhook endpoint","tags":["Webhooks"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Deleted"}}}},"/v1/webhooks/{id}/deliveries":{"get":{"operationId":"listEndpointDeliveries","summary":"Recent deliveries to one endpoint","tags":["Webhooks"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deliveries","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v1/webhooks/deliveries":{"get":{"operationId":"listDeliveries","summary":"Webhook delivery log across all endpoints","tags":["Logs"],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","maximum":200,"default":50}},{"name":"before","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"endpointId","in":"query","schema":{"type":"string"}},{"name":"status","in":"query","schema":{"type":"string","enum":["pending","succeeded","failed","exhausted"]}},{"name":"event","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Deliveries and a `nextBefore` cursor","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v1/webhooks/deliveries/{id}/retry":{"post":{"operationId":"retryDelivery","summary":"Send a failed delivery again","description":"Resets the attempt budget and re-queues the same payload.","tags":["Logs"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Queued","content":{"application/json":{"schema":{"type":"object"}}}},"422":{"description":"Still in progress","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v1/webhooks":{"get":{"operationId":"listWebhooks","summary":"List webhook endpoints","tags":["Webhooks"],"responses":{"200":{"description":"Endpoints","content":{"application/json":{"schema":{"type":"object"}}}}}},"post":{"operationId":"createWebhook","summary":"Register a webhook (returns the signing secret once)","tags":["Webhooks"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["url","events"],"properties":{"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["message.received","message.sent","message.status","phone.status","phone.qr"]}}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object"}}}}}}}}}