# Cancel

`POST` `https://api.pushwoosh.com/messaging/v2/cancel`

Cancels a previously created message, identified by its `message_code`. Cancellation is available only while the message is in one of these states:

- **pending:** created but not yet picked up for sending.
- **waiting:** scheduled for a future send time.
- **processing:** currently being prepared for delivery.

<Aside type="caution" title="Important">

- If the message is in `processing`, cancel only stops deliveries that have not gone out yet. Anyone who already received the message may still have it.

- If the message was already canceled or has finished sending, the API returns `400`. This call is not idempotent. Check the message status before you retry.
</Aside>

To check whether a message is still in a cancelable state, see [Checking message status](#checking-message-status).


## Request

Authenticate with your [Server API token](/developer/api-reference/api-access-token/#server-api-token) in the `Authorization: Token <API_TOKEN>` header.

| Field | Type | Required | Description |
|---|---|---|---|
| `message_code` | string | Yes | [Message code](/developer/api-reference/api-identifiers/#message-code) of the message to cancel, as returned by [`Notify`](/developer/api-reference/messaging-api-v2/notify/) in `result.message_code`. |

### Example request

```bash
curl -X POST https://api.pushwoosh.com/messaging/v2/cancel \
  -H "Authorization: Token YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "message_code": "XXXX-XXXXXXXX-XXXXXXXX"
  }'
```

## Response

On success, returns HTTP 200 with an empty JSON body.

```json
{}
```

## Errors

Errors use the standard gRPC-Gateway error envelope: `{ "code": ..., "message": ..., "details": [...] }`.

| HTTP status | Condition |
|---|---|
| `400` | `message_code` is missing. |
| `400` | The message is not in a cancelable state (it is no longer `pending`, `waiting`, or `processing`). |
| `403` | The message belongs to another account. |
| `404` | No message exists for the given `message_code`. |
| `500` | An internal error occurred while loading the message or publishing the cancellation. Retry the request. |


**Example**

Canceling a message that no longer exists returns HTTP `404`:

```json
{
  "code": 5,
  "message": "message not found",
  "details": []
}
```

## Checking message status

Before canceling, you can verify whether a message is still in a cancelable state. Besides reading the **Status** column in the messages table in the Control Panel ([**Campaigns → One-time messages**](/product/statistics-and-analytics/message-history/)), you can query the status programmatically with [`messages:list`](/developer/api-reference/statistics-api/message-statistics-api/#messageslist):

- Pass the `message_code` in the `filters.messages_codes` array (alongside the required `filters.application`).
- Read the `status` field of the matching entry in `items[]`.

<Aside type="note">
`messages:list` is part of the Statistics API and uses a different auth header than this endpoint: `Authorization: Api <Server Key>`.
</Aside>

## Related

<CardGrid>
  <LinkCard title="Notify" href="/developer/api-reference/messaging-api-v2/notify/" />
  <LinkCard title="Update" href="/developer/api-reference/messaging-api-v2/update/" />
  <LinkCard title="Message statistics" href="/developer/api-reference/statistics-api/message-statistics-api/#messageslist" />
  <LinkCard title="Messaging API v2 overview" href="/developer/api-reference/messaging-api-v2/" />
  <LinkCard title="Migration from v1" href="/developer/api-reference/messaging-api-v2/migration-from-v1/" />
</CardGrid>