---
title: "Cancel or reschedule an SMS"
description: "Cancel a scheduled or queued SMS (its reserved credit is refunded), or move a scheduled one to a new send time with scheduled_at. `PATCH /api/v1/sms/{id}`"
url: https://www.unitpost.com/docs/sms/patch-sms-id
section: "SMS API reference"
updated: 2026-10-06
---
# Cancel or reschedule an SMS

`PATCH /api/v1/sms/{id}`

Cancel a `scheduled` or `queued` SMS (its reserved credit is refunded), or move a `scheduled` one to a new send time with `scheduled_at`. Send exactly one of `cancel: true` or `scheduled_at`. Only a text the carrier has not been handed can be changed — afterwards this returns `409`, as it does for a text that belongs to a campaign. Quiet hours still apply to the new time. Look up the current state first with [Retrieve an SMS message](https://www.unitpost.com/docs/sms/get-sms-id). Requires the `sms:send` capability.

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes | The SMS message id (`sms_…`). |

## Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `cancel` | boolean | no | Cancel a `queued` or `scheduled` text. Its reserved credit is refunded. |
| `scheduled_at` | string | no | Move a `scheduled` text to this future ISO-8601 time. |

## Response fields (200)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | string | yes | — |
| `id` | string | yes | — |
| `to` | string | yes | — |
| `from` | string \| null | yes | — |
| `direction` | enum | yes | One of: `outbound`, `inbound`. |
| `status` | enum | yes | One of: `queued`, `scheduled`, `sending`, `sent`, `delivered`, `failed`, `suppressed`, `canceled`, `received`. |
| `type` | enum | yes | One of: `transactional`, `marketing`. |
| `body` | string \| null | yes | — |
| `segments` | integer | yes | — |
| `country` | string \| null | yes | — |
| `scheduled_at` | string \| null | yes | — |
| `last_error` | string \| null | yes | Legacy free-text error. Prefer `error.code`. |
| `error` | object \| null | yes | Set on `suppressed` messages: the stable skip reason and its sentence. Null otherwise. |
| `created_at` | string | yes | — |

## Responses

| Status | Description |
| --- | --- |
| 200 | The updated SMS message. |
| 401 | Missing or invalid API key. |
| 403 | Insufficient scope. |
| 404 | Message not found. |
| 409 | The text is not in a cancelable / reschedulable state. |
| 422 | Validation error. |
| 502 | The new time couldn't be handed to the delivery engine; the text keeps its original time. |

## Example request

```bash
curl -X PATCH 'https://www.unitpost.com/api/v1/sms/sms_123' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'User-Agent: my-app/1.0' \
  -H 'Content-Type: application/json' \
  -d '{
    "cancel": true
  }'
```

## Example response (200)

```json
{
  "object": "sms",
  "id": "id_123",
  "to": "customer@example.com",
  "from": "you@yourdomain.com",
  "direction": "outbound",
  "status": "queued",
  "type": "transactional",
  "body": "string",
  "segments": 0,
  "country": "string",
  "scheduled_at": "2026-01-01T00:00:00.000Z",
  "last_error": "string",
  "error": {
    "code": "out_of_reach",
    "message": "string"
  },
  "created_at": "2026-01-01T00:00:00.000Z"
}
```

## Links

- HTML reference (with Node.js, Python, Ruby, PHP, Go, Java, Rust, .NET and CLI examples): https://www.unitpost.com/docs/sms/patch-sms-id
- OpenAPI 3.1 (full schemas): https://www.unitpost.com/api/v1/openapi.json
