> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tracklysms.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Send Raw Single Message

> Send a single raw SMS message with optional skip flags for advanced control.

Send a single SMS message. This endpoint accepts a set of `skip_*` flags intended for granular control over validation and rate-limiting behavior.

<Warning>
  **The `skip_*` flags are currently accepted but have no effect.** The endpoint does not read them, so every check runs regardless of what you pass. Until the flags are wired up, this endpoint behaves the same as [`POST /v2/send`](/api-reference/v2/messages/send-single) except that it does not perform link wrapping or contact-data macro substitution.
</Warning>

<Warning>
  The following checks are **always enforced**:

  * Your account must own the sending list
  * Phone numbers must be in E.164 format
  * Your account must be in active status
</Warning>

## Body Parameters

<ParamField body="to" type="string" required>
  Recipient phone number in E.164 format (e.g. `+14155551234`).
</ParamField>

<ParamField body="list_number" type="string" required>
  Sending list phone number in E.164 format. Must belong to your account.
</ParamField>

<ParamField body="body" type="string" required>
  Message body text. Use the `{{messageId}}` placeholder to insert the unique message ID into the body at send time.
</ParamField>

<ParamField body="skip_duplicate_check" type="boolean" default="false">
  Intended to skip the duplicate message check. **Currently accepted but ignored — this flag has no effect.**
</ParamField>

<ParamField body="skip_rate_limit" type="boolean" default="false">
  Intended to skip per-list rate limiting. **Currently accepted but ignored — this flag has no effect.**
</ParamField>

<ParamField body="skip_contact_validation" type="boolean" default="false">
  Intended to skip contact validation such as opt-out and block list checks. **Currently accepted but ignored — this flag has no effect.**
</ParamField>

<ParamField body="skip_journey_check" type="boolean" default="false">
  Intended to skip the journey enrollment check. **Currently accepted but ignored — this flag has no effect.**
</ParamField>

<ParamField body="metadata" type="object">
  Optional key-value metadata dictionary. **Currently accepted but not stored or returned** — the endpoint discards this field, so it cannot yet be used to correlate messages with your own systems.
</ParamField>

## Response Fields

<ResponseField name="success" type="boolean">
  Whether the message was successfully queued.
</ResponseField>

<ResponseField name="message_id" type="string">
  An opaque, variable-length message identifier for tracking delivery and clicks.
</ResponseField>

<ResponseField name="status" type="string">
  Current message status. Will be `"queued"` on successful submission.
</ResponseField>

## Examples

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST https://api.tracklysms.com/api/v2/send-raw \
    -H "X-Api-Key: trk_your_api_key_here" \
    -H "Content-Type: application/json" \
    -d '{
      "to": "+14155551234",
      "list_number": "+18005551000",
      "body": "URGENT: Your verification code is 482901. Ref: {{messageId}}",
      "skip_duplicate_check": true,
      "skip_rate_limit": true
    }'
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://api.tracklysms.com/api/v2/send-raw",
      headers={
          "X-Api-Key": "trk_your_api_key_here",
          "Content-Type": "application/json",
      },
      json={
          "to": "+14155551234",
          "list_number": "+18005551000",
          "body": "URGENT: Your verification code is 482901. Ref: {{messageId}}",
          "skip_duplicate_check": True,
          "skip_rate_limit": True,
      },
  )

  data = response.json()
  print(data["message_id"])
  ```

  ```javascript Node.js theme={null}
  const response = await fetch("https://api.tracklysms.com/api/v2/send-raw", {
    method: "POST",
    headers: {
      "X-Api-Key": "trk_your_api_key_here",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      to: "+14155551234",
      list_number: "+18005551000",
      body: "URGENT: Your verification code is 482901. Ref: {{messageId}}",
      skip_duplicate_check: true,
      skip_rate_limit: true,
    }),
  });

  const data = await response.json();
  console.log(data.message_id);
  ```
</RequestExample>

<ResponseExample>
  ```json Success (201) theme={null}
  {
    "success": true,
    "message_id": "x7y8z9w0",
    "status": "queued"
  }
  ```

  ```json Error (400) theme={null}
  {
    "error": "Invalid recipient phone number format",
    "code": "invalid_phone"
  }
  ```
</ResponseExample>

## Error Codes

| HTTP Status | Error Code               | Description                                                                                                                                |
| ----------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
| 400         | `missing_to`             | The `to` field is required but was not provided.                                                                                           |
| 400         | `missing_list_number`    | The `list_number` field is required but was not provided.                                                                                  |
| 400         | `missing_body`           | The `body` field is required but was not provided.                                                                                         |
| 400         | `invalid_phone`          | The `to` field is not a valid E.164 phone number.                                                                                          |
| 400         | `invalid_list_number`    | The `list_number` field is not a valid E.164 phone number.                                                                                 |
| 400         | `list_not_found`         | The sending list was not found or does not belong to your account.                                                                         |
| 400         | `webhook_not_configured` | Webhook verification required before sending (BYOC lists).                                                                                 |
| 400         | `pending_confirmation`   | The recipient has not confirmed their double opt-in yet, so they cannot be messaged.                                                       |
| 400         | `doi_expired`            | The recipient never confirmed their double opt-in and the confirmation window has expired.                                                 |
| 400         | `warmup_limit`           | The recipient is not yet eligible to be messaged under the list's warm-up schedule.                                                        |
| 502         | `kafka_producer_failure` | The message could not be queued for delivery (transient). The 502 body includes `errorCode: "KAFKA_PRODUCER_FAILURE"`; retry with backoff. |

Authenticated requests can also fail with `401 invalid_credentials`, `403 account_suspended`, or `429 rate_limited` — see [Error Codes](/api-reference/v2/error-codes).

## Next Steps

<CardGroup cols={2}>
  <Card title="Campaign Execution" icon="rocket" href="/guides/campaigns/execution">
    How messages flow from queue to delivery
  </Card>

  <Card title="Create Contact" icon="user-plus" href="/api-reference/v2/contacts/create-contact">
    Add contacts before sending
  </Card>
</CardGroup>
