Cancel a message
POST/v1/messages/{message_id}/cancel
Cancels a message that is still scheduled or queued and releases its held funds, which return to your available balance at the next settlement step, within about a minute. Only messages sent through the API are cancelled here; a campaign's messages are cancelled with the campaign. A message that is already cancelled is returned unchanged. Send no body, or an empty JSON object {}: any member is refused with 422.
- Scope
messages:send
Request
Every request needs an API key in the Authorization header, and the key needs the scope the endpoint names.
Parameters
message_idpathstringRequiredThe ID of the message to cancel.
- Matches ^msg_[0-9A-HJKMNP-TV-Z]{26}$
Idempotency-Keyheaderstring1 to 64 characters from A-Z, a-z, 0-9,
_and-. Repeating a request with the same key and body within 24 hours returns the stored success response without acting again; the same key with a different body is refused with 409.- Matches ^[A-Za-z0-9_-]{1,64}$
POST /v1/messages/msg_01M3KR6CEGVQVV5PV6Q9J1G6SP/cancelResponses
200 OK
ReturnsMessageEnvelope
The message.
Headers
Cache-ControlstringRequiredResponses are never cached.
Idempotent-ReplayedstringPresent when this is the stored response of an earlier request with the same Idempotency-Key.
RateLimit-LimitintegerRequests per second your account may sustain.
RateLimit-RemainingintegerWhole requests left in your account's bucket.
RateLimit-ResetintegerSeconds until the bucket is full again.
X-Request-IdstringRequiredThis request's ID, also given as
request_idin error bodies. Quote it to support.
{ "data": { "id": "msg_01M3KR6CEGVQVV5PV6Q9J1G6SP", "object": "message", "amount": "0.0000", "body": "Your ACME code is 482913. It expires in 5 minutes.", "campaign_id": null, "channel": "sms", "client_reference": "order-78123", "completed_at": "2026-09-28T10:16:02.000Z", "created_at": "2026-09-28T10:15:30.000Z", "currency": "NGN", "direction": "outbound", "encoding": "gsm7", "error": { "code": "cancelled_by_user", "message": "Cancelled by the user." }, "from": "ACME", "held_amount": "3.5000", "mode": "live", "scheduled_at": null, "segments": 1, "sent_at": null, "source": "api", "status": "cancelled", "to": "+2348031234567", "unit_price": null, "updated_at": "2026-09-28T10:16:02.000Z" }}Errors
Each code links to its page. Branch on the code, never on the title or detail.
- 401 Unauthorized
- 403 Forbidden
- 404 Not Found
- 409 Conflict
- 413 Content Too Large
- 415 Unsupported Media Type
- 422 Unprocessable Content
- 429 Too Many Requests
- 500 Internal Server Error
- 503 Service Unavailable
{ "type": "https://docs.messaging.500calls.com/errors/validation_error", "title": "Validation error", "status": 422, "code": "validation_error", "detail": "1 field failed validation.", "request_id": "req_01M3KR6CQ26S90NG2V790GVFTX", "errors": [ { "field": "reason", "code": "unknown_field", "message": "Extra inputs are not permitted" } ]}Code samples
Each sample reads your key from the API_KEY_500CALLS environment variable.
curl -X POST 'https://api.messaging.500calls.com/v1/messages/msg_01M3KR6CEGVQVV5PV6Q9J1G6SP/cancel' \ -H "Authorization: Bearer $API_KEY_500CALLS" \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: order-78123-otp' \ -d '{}'import osimport requestsresponse = requests.post( "https://api.messaging.500calls.com/v1/messages/msg_01M3KR6CEGVQVV5PV6Q9J1G6SP/cancel", headers={ "Authorization": f"Bearer {os.environ['API_KEY_500CALLS']}", "Idempotency-Key": "order-78123-otp", }, json={}, timeout=30,)print(response.status_code, response.json())const response = await fetch("https://api.messaging.500calls.com/v1/messages/msg_01M3KR6CEGVQVV5PV6Q9J1G6SP/cancel", { method: "POST", headers: { Authorization: `Bearer ${process.env.API_KEY_500CALLS}`, "Content-Type": "application/json", "Idempotency-Key": "order-78123-otp", }, body: JSON.stringify({}),});console.log(response.status, await response.json());<?php$curl = curl_init('https://api.messaging.500calls.com/v1/messages/msg_01M3KR6CEGVQVV5PV6Q9J1G6SP/cancel');curl_setopt_array($curl, [ CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_HTTPHEADER => [ 'Authorization: Bearer ' . getenv('API_KEY_500CALLS'), 'Content-Type: application/json', 'Idempotency-Key: order-78123-otp', ], CURLOPT_POSTFIELDS => json_encode(new stdClass()), CURLOPT_RETURNTRANSFER => true,]);$body = curl_exec($curl);$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);echo $status, PHP_EOL, $body, PHP_EOL;