Skip to content
API PlatformDevelopers
POST/v1/conversations/{conversation_id}/closebeta

Close a conversation

Needs
Manage conversations: notes, assign, close, tags, reminders (inbox:write)
Plan
Any plan with API access
Limits
60 a minute per key
Dry run
Yes — every check runs with ?dry_run=true, nothing changes
Confirm
Header Api-Confirm: close
Undo
Reopen it with Reopen a conversation (a new episode starts; the automations that ran on close are not undone).

Closes a conversation with a closing reason: it ends the current episode, stops its SLA clock and fires conversation.closed automations and webhooks. Optionally adds an internal note first.

Send Api-Confirm: close. Closing one that is already closed changes nothing (changed: false). A new message from the customer reopens it.

Try it

Path

The conversation id.

Body

The id of one of the workspace's closing reasons (set up in the inbox settings).

An internal note to add before closing (never shown to the customer).

Protects against doing it twice if you retry: a retry with the same key gets the first answer back instead of running again.

Test mode (dry run): nothing will change
Turns test mode off for this page only. It switches back when you leave the page.

Code and response

curl -X POST 'https://mcp.wa-api.cloud/v1/conversations/77410/close?dry_run=true' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "closed_reason_id": "3",
  "note": "Order shipped; the customer confirmed."
}'

The code reads your key from $API_KEY.

Parameters

Parameters
FieldTypeWhat it is
conversation_idrequiredstring · pathThe conversation id.pattern ^\d{1,19}$Signed in? Pick one from your data with “My data”.

Body

Body fields
FieldTypeWhat it is
closed_reason_idrequiredstringThe id of one of the workspace's closing reasons (set up in the inbox settings).pattern ^\d{1,19}$
notestringAn internal note to add before closing (never shown to the customer).1–5000 characters

Headers

Headers
FieldTypeWhat it is
AuthorizationrequiredheaderBearer $API_KEY — your API key.
Api-VersionheaderThe API version to use, e.g. 2026-10-01. Default: the version your key is pinned to.one of: 2026-10-01 · pattern ^\d{4}-\d{2}-\d{2}$
Idempotency-KeyheaderAny unique string (8–128 characters). A retry with the same key returns the first answer instead of running twice. Kept 24 hours.pattern ^[A-Za-z0-9._:-]+$ · 8–128 characters
Api-ConfirmrequiredheaderType the operation's verb (e.g. delete, submit) to confirm a change that cannot be undone or that WhatsApp or your customers see. Not needed with dry_run=true.

Response 200

The conversation's new state.

Response fields
FieldTypeWhat it is
conversationrequiredobject
idrequiredstring
staterequiredstring or null
assignee_staff_idrequiredstring or null
team_idrequiredstring or null
tagsrequiredarray of object
idrequiredstring
namerequiredstring
changedrequiredboolean
note_idrequiredstring or null
dry_runbooleantrue when this was a dry run: every check ran and nothing changed.

Errors

Errors are application/problem+json. Branch on code.

StatusCodeWhen
400invalid_input

A field is missing or has the wrong format. errors[] points at each field. closed_reason_id is missing or not a closing reason of this workspace.

401unauthenticated

The Authorization header is missing, the key is unknown, expired or revoked.

403entitlement_required

The workspace's plan does not include API access (api_access).

403insufficient_scope

The key does not have the permission this operation needs.

404not_found

No conversation with this id.

409conflict

Also returned while a request with the same Idempotency-Key is still running.

428confirm_required

Send the header Api-Confirm: close to confirm. Not needed with dry_run=true.

429rate_limited

The key or workspace went over its rate limit. Wait for Retry-After seconds.

503upstream_unavailable

A service behind the API is briefly unavailable. Safe to retry with backoff.

504timeout

The change did not finish in time. Retry with the same Idempotency-Key: it never runs twice.

Examples

Close a resolved conversation

Request body

{
  "closed_reason_id": "3",
  "note": "Order shipped; the customer confirmed."
}

Response 200

{
  "conversation": {
    "id": "77410",
    "state": "closed",
    "assignee_staff_id": "1203",
    "team_id": null,
    "tags": [
      {
        "id": "4",
        "name": "new-lead"
      }
    ]
  },
  "changed": true,
  "note_id": "90332"
}

Webhook events

These events can fire after this call. Subscribe an endpoint to hear about them.

Operation path

The same operation is also at POST /v1/ops/inbox_close_conversation, with every field in the JSON body.