---
title: "Send an SMS or MMS"
method: POST
path: "/api/v1/messages"
tags: ["Messaging"]
---

# Send an SMS or MMS

`POST /api/v1/messages`

## Request

- Base URL: `https://api.callnode.io`
- URL: `https://api.callnode.io/api/v1/messages`
- Auth: API key in header `X-Api-Key` and API key in header `X-Timestamp` and API key in header `X-Signature`

Sends a message from one of your numbers. Supplying `media` makes it an MMS.
Four gates run in order: number ownership, recipient opt-out status, the TCPA
window, and carrier registration (10DLC for local numbers, Toll-Free
Verification for toll-free).

## Headers

- `X-Idempotency-Key` string, uuid

## Request body

- SendMessageRequest
  - `to` string, required: Plus sign followed by 7–15 digits.
  - `from` string, required: Plus sign followed by 7–15 digits.
  - `body` string: Message text. Required unless `media` is supplied.
  - `media` string[]: Any entry makes this an MMS. Each entry is a public URL or the file itself as a base64 data URL (`data:image/png;base64,...`). JPG, PNG, GIF, WebP, MP4 and PDF; up to 5 MB each. CallNode stores a copy and delivers from its own URL. An inline file of an unsupported type or size is a 400 `invalid_media`.
  - `statusWebhookUrl` string, uri: URL we POST delivery status updates to.
  - `tcpaOverride` boolean
  - `metadata` object

## Response `200`

Message accepted by the carrier.

- SendMessageResponse
  - `id` string
  - `status` string
  - `cost` number
  - `segments` integer
  - `idempotencyReplay` boolean: True when this response replays an earlier request with the same idempotency key.

## Other responses

- `400`: Malformed request or failed validation.
- `401`: Missing, unknown, or badly signed credentials — check the HMAC and the timestamp skew.
- `403`: Blocked by a gate: `tcpa_window_violation`, `recipient_opted_out`, `campaign_not_registered` (local), `tollfree_not_verified` (toll-free), or `policy_blocked` when the status webhook or the from-number's messaging webhook points at a service CallNode identifies as fraud tooling.
- `429`: Rate limit exceeded. See the rate-limit response headers.

---

[API](https://skmtc.dev/callnode/apis/callnode-outbound-api.md) · [All operations](https://skmtc.dev/callnode/apis/callnode-outbound-api/llms.txt) · [OpenAPI document](https://skmtc.dev/callnode/apis/callnode-outbound-api/revisions/c7da6ad06509?raw)
