Skip to main content
500CallsDocs
Browse the docs

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_idpathstringRequired

    The ID of the message to cancel.

    • Matches ^msg_[0-9A-HJKMNP-TV-Z]{26}$
  • Idempotency-Keyheaderstring

    1 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}$
Example request
POST /v1/messages/msg_01M3KR6CEGVQVV5PV6Q9J1G6SP/cancel

Responses

200 OK

ReturnsMessageEnvelope

Headers

  • Cache-ControlstringRequired

    Responses are never cached.

  • Idempotent-Replayedstring

    Present when this is the stored response of an earlier request with the same Idempotency-Key.

  • RateLimit-Limitinteger

    Requests per second your account may sustain.

  • RateLimit-Remaininginteger

    Whole requests left in your account's bucket.

  • RateLimit-Resetinteger

    Seconds until the bucket is full again.

  • X-Request-IdstringRequired

    This request's ID, also given as request_id in error bodies. Quote it to support.

Example response
{  "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.

Example 422 response
{  "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
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 '{}'
Python
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())
Node.js
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
<?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;