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

# Send SMS

> Send an SMS message from your Magpipe number

## Overview

Sends an SMS text message to a phone number using one of your Magpipe numbers as the sender.

## Request

### Headers

<ParamField header="Authorization" type="string" required>
  Bearer token for authentication.
</ParamField>

<ParamField header="Content-Type" type="string" required>
  Must be `application/json`
</ParamField>

### Body Parameters

<ParamField body="to" type="string" required>
  Recipient phone number in E.164 format.

  **Example:** `"+14155551234"`

  **Constraints:**

  * Must start with `+` followed by country code
  * 10-15 digits total
</ParamField>

<ParamField body="from" type="string" required>
  Your Magpipe phone number to send from. Must be SMS-enabled.

  **Example:** `"+16045551234"`
</ParamField>

<ParamField body="body" type="string" required>
  The message content.

  **Example:** `"Your appointment is confirmed for tomorrow at 2pm."`

  **Constraints:**

  * Maximum 1600 characters
  * Messages over 160 characters are sent as multiple segments
</ParamField>

<ParamField body="media_urls" type="array">
  Array of URLs for MMS media attachments.

  **Example:** `["https://example.com/image.jpg"]`

  **Constraints:**

  * Maximum 10 media items
  * Supported formats: jpg, png, gif, pdf
  * Maximum 5MB per file
</ParamField>

<ParamField body="scheduled_at" type="string">
  ISO 8601 timestamp to schedule the message for later delivery.

  **Example:** `"2024-01-16T10:00:00Z"`

  **Constraints:**

  * Must be in the future
  * Maximum 7 days ahead
</ParamField>

## Response

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

<ResponseField name="message_id" type="string">
  Unique identifier for the message.
</ResponseField>

<ResponseField name="status" type="string">
  Current message status:

  * `queued` - Message is queued for delivery
  * `sent` - Message sent to carrier
  * `scheduled` - Message scheduled for future delivery
</ResponseField>

<ResponseField name="segments" type="integer">
  Number of SMS segments the message was split into.
</ResponseField>

<ResponseField name="created_at" type="string">
  ISO 8601 timestamp.
</ResponseField>

## Example Request

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://api.magpipe.ai/functions/v1/send-sms" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "to": "+14155551234",
      "from": "+16045551234",
      "body": "Your appointment is confirmed for tomorrow at 2pm. Reply YES to confirm or NO to reschedule."
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    'https://api.magpipe.ai/functions/v1/send-sms',
    {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${apiKey}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        to: '+14155551234',
        from: '+16045551234',
        body: 'Your appointment is confirmed for tomorrow at 2pm.',
      }),
    }
  );

  const data = await response.json();
  console.log(data.message_id);
  ```

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

  response = requests.post(
      'https://api.magpipe.ai/functions/v1/send-sms',
      headers={
          'Authorization': f'Bearer {api_key}',
          'Content-Type': 'application/json',
      },
      json={
          'to': '+14155551234',
          'from': '+16045551234',
          'body': 'Your appointment is confirmed for tomorrow at 2pm.',
      }
  )

  data = response.json()
  print(data['message_id'])
  ```
</RequestExample>

## Example Response

<ResponseExample>
  ```json 200 Success theme={null}
  {
    "success": true,
    "message_id": "msg_a1b2c3d4-5678-9012-3456-789012345678",
    "status": "sent",
    "segments": 1,
    "from_number": "+16045551234",
    "to_number": "+14155551234",
    "created_at": "2024-01-15T10:30:00.000Z"
  }
  ```
</ResponseExample>

## Error Responses

<ResponseExample>
  ```json 400 Bad Request theme={null}
  {
    "error": {
      "code": "INVALID_PHONE_NUMBER",
      "message": "The 'to' field must be a valid E.164 phone number"
    }
  }
  ```
</ResponseExample>

<ResponseExample>
  ```json 401 Unauthorized theme={null}
  {
    "error": {
      "code": "UNAUTHORIZED",
      "message": "Invalid or expired access token"
    }
  }
  ```
</ResponseExample>

<ResponseExample>
  ```json 422 Unprocessable Entity theme={null}
  {
    "error": {
      "code": "SMS_NOT_ENABLED",
      "message": "The 'from' number does not have SMS capability"
    }
  }
  ```
</ResponseExample>

## Message Status Webhook

When the message status changes, a webhook is sent to your configured URL:

```json theme={null}
{
  "event": "message.status_changed",
  "message_id": "msg_a1b2c3d4-5678-9012-3456-789012345678",
  "status": "delivered",
  "to_number": "+14155551234",
  "from_number": "+16045551234",
  "timestamp": "2024-01-15T10:30:05.000Z"
}
```

### Message Status Values

| Status        | Description                      |
| ------------- | -------------------------------- |
| `queued`      | Message queued for sending       |
| `sent`        | Message sent to carrier          |
| `delivered`   | Confirmed delivered to recipient |
| `undelivered` | Could not be delivered           |
| `failed`      | Failed to send                   |

## SMS Segment Calculation

SMS messages are split into segments:

| Character Set          | Characters per Segment |
| ---------------------- | ---------------------- |
| GSM-7 (standard)       | 160 characters         |
| Unicode (emojis, etc.) | 70 characters          |

Messages split across multiple segments include headers, reducing usable characters to 153 (GSM-7) or 67 (Unicode) per segment.
