Case messages
List the messages of a case
The whole thread: the contact, the agent, your team and the internal notes (visibility internal). Newest first by default; order=asc reads it from the start. Files of the contact come with a signed url.
Required scope: cases:read.
path Parameters
id^cse_[0-9A-Za-z]{22}… · requiredThe id of the case (cse_…).
query Parameters
limitcursorThe nextCursor of the previous page, with the same filters.
orderdesc is the newest first. asc reads the thread from the start.
Headers
Lelemon-Subaccount^sub_[0-9A-Za-z]{22}…The subaccount (sub_…) this request acts on. Only for the keys of a platform account; without it the request acts on the account itself.
List the messages of a case › Responses
objecthasMorenextCursorAdd a message to a case
author contact needs cases:converse: the agent answers on its own and the answer reaches you by the message.created webhook; when the agent finishes its turn you also get case.turn_completed. If a monthly budget is spent it answers 402 budget_exceeded and nothing is saved: stop and do not retry until the month resets or the limit is raised. author team needs cases:send and a person in control (409 case_agent_in_control otherwise); 422 channel_window_closed on WhatsApp after 24 hours without the person, 422 no_outbound_channel when the case cannot be written back. visibility internal leaves a note for the team and needs only cases:write. attachmentIds sends files already uploaded to the case. interactive sends buttons, a list, a product, a product list or the catalog instead of text, on WhatsApp cases inside the 24 hours window; the tap of the person comes back as a message with reply {id, title}, and a cart as a message with order. Each call sends a new message: use an Idempotency-Key to retry safely. Use dryRun=true first to run the same checks (author scope, case, budget, who is in control, channel, allowlist, 24 hours window, attachments) and get 200 with the message as it would be created, with nothing sent or saved; its id is not saved and attachments comes empty.
Required scope: cases:write.
path Parameters
id^cse_[0-9A-Za-z]{22}… · requiredThe id of the case (cse_…).
query Parameters
dryRunWhen true, the request goes through the same validation as the real one and is answered with what would happen (always 200), and nothing is saved, sent or charged. The answer has the same shape as the real one plus dryRun: true; an id in it is not saved. It does not use the Idempotency-Key.
Headers
Lelemon-Subaccount^sub_[0-9A-Za-z]{22}…The subaccount (sub_…) this request acts on. Only for the keys of a platform account; without it the request acts on the account itself.
Idempotency-KeyMakes the request safe to retry. Once it starts running, its final response (2xx, 4xx or 5xx) is kept for 24 hours and the same key gets it back, without repeating the effect. A request rejected before it runs leaves the key free. A replayed create omits the secret. The same key with a different request is rejected with 409 idempotency_key_reused.
Add a message to a case › Request Body
Decision Table
| Variant | Matching Criteria |
|---|---|
| type = object · requires: author, text | |
| type = object · requires: author, text | |
| type = object · requires: author, interactive | |
| type = object · requires: author, attachmentIds |
authortextWho is speaking, for an embedded copilot. Only with author contact. It travels signed to every action and MCP server of this turn as the actor, marked as declared by your key and not verified by Lelemon. It is kept for this turn only.
Add a message to a case › Responses
dryRun=true: the message as it would be created; nothing is sent.
objectidcaseIdauthorauthorNamevisibilitytextcontentTypestatusDelivery to the channel of the case.
createdAtThe buttons, list, product or catalog the message carried. null on any other message.
Set when the person tapped a button or a list row: the id and title they tapped. null otherwise.
Set when the person sent a cart from the WhatsApp catalog. text carries their note. null otherwise.
Set when the person shared a location (answering a location_request or on their own). text carries it as a sentence the agent reads. null otherwise.
Set when the person finished a WhatsApp Flow: the fields they filled in. null otherwise.
Set when the person shared their phone answering a contact_request. A contact card the person forwards on their own is not kept. null otherwise.
Set when status is failed: why. null on any other status. Read it to know whether to retry, send a template (outside the 24-hour window) or stop.
dryRunPresent and true when the request had dryRun=true.
Redact a message
Use it when a message holds data that must not stay, for example an ID number or a password the person typed. The text is replaced by [redacted] and the file, transcription and copies of the message in logs, events and agent memory are erased. The rest of the thread stays. It cannot be undone. It is idempotent: redacting a redacted message answers 200 with the same message and publishes nothing. Publishes the webhook message.redacted, which carries ids only: pass it on to every system where you copied the message.
Required scope: cases:delete.
path Parameters
id^cse_[0-9A-Za-z]{22}… · requiredThe id of the case (cse_…).
messageId^msg_[0-9A-Za-z]{22}… · requiredThe id of the message (msg_…).
Headers
Lelemon-Subaccount^sub_[0-9A-Za-z]{22}…The subaccount (sub_…) this request acts on. Only for the keys of a platform account; without it the request acts on the account itself.
Idempotency-KeyMakes the request safe to retry. Once it starts running, its final response (2xx, 4xx or 5xx) is kept for 24 hours and the same key gets it back, without repeating the effect. A request rejected before it runs leaves the key free. A replayed create omits the secret. The same key with a different request is rejected with 409 idempotency_key_reused.
Redact a message › Responses
objectidcaseIdauthorauthorNamevisibilitytextcontentTypestatusDelivery to the channel of the case.
createdAtThe buttons, list, product or catalog the message carried. null on any other message.
Set when the person tapped a button or a list row: the id and title they tapped. null otherwise.
Set when the person sent a cart from the WhatsApp catalog. text carries their note. null otherwise.
Set when the person shared a location (answering a location_request or on their own). text carries it as a sentence the agent reads. null otherwise.
Set when the person finished a WhatsApp Flow: the fields they filled in. null otherwise.
Set when the person shared their phone answering a contact_request. A contact card the person forwards on their own is not kept. null otherwise.
Set when status is failed: why. null on any other status. Read it to know whether to retry, send a template (outside the 24-hour window) or stop.