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

# Send SMS Batch

> Send SMS messages to a large list of recipients from a pre-uploaded CSV file. Processing is handled asynchronously via a background workflow.

<Info>
  **Enterprise Feature** - SMS batch sending is only available on Enterprise plans. Contact your Bland representative for access.
</Info>

### Before You Begin: Upload Your CSV

Before calling this endpoint, you must upload your recipient CSV file and get a `file_id`.

Upload your CSV via `POST https://api.bland.ai/v1/files/attach` with `file_type: "batches"`. The response will include a `file_id` (UUID) that you pass to this endpoint.

**CSV format requirements:**

* Must include a column named exactly **`phone_number`** containing E.164-formatted numbers (e.g. `+14155551234`). Numbers without a leading `+` are automatically prefixed.
* The `phone_number` column **cannot be remapped** via `column_mapping` — the column must be named `phone_number` in the CSV itself.
* Additional columns become dynamic variables available in your pathway via `{{column_name}}` syntax.
* Columns named `request_data.fieldname` (dot notation) are automatically parsed into the recipient's `request_data` object.
* JSON arrays of objects are also accepted as an alternative to CSV.

Example CSV:

```csv theme={null}
phone_number,first_name,request_data.account_id
+14155551234,Alice,acc_001
+10987654321,Bob,acc_002
```

***

### Headers

<ParamField header="authorization" type="string" required>
  Your API key for authentication.
</ParamField>

### Body Parameters

<ParamField body="file_id" type="string" required>
  The ID of a previously uploaded CSV file containing recipient phone numbers. The file must have been uploaded with `file_type: "batches"`. See [Before You Begin](#before-you-begin-upload-your-csv) above.
</ParamField>

<ParamField body="global" type="object" required>
  Default SMS parameters applied to every message in the batch.

  <Expandable title="global object">
    <ParamField body="agent_number" type="string" required>
      The E.164 formatted phone number to send messages from. Must be an SMS-enabled inbound number configured on your account.
    </ParamField>

    <ParamField body="agent_message" type="string">
      The initial outbound message to send to each recipient. If omitted, the pathway configured on the number will handle the opening message.
    </ParamField>

    <ParamField body="request_data" type="object">
      Default request data to associate with each conversation. Per-recipient `request_data` from the CSV is merged on top of this, with recipient values taking precedence.
    </ParamField>

    <ParamField body="metadata" type="object">
      Custom metadata to attach to each conversation. Returned in all webhook payloads for correlating conversations with your internal systems.
    </ParamField>

    <ParamField body="disposition_ids" type="string[]">
      An array of outcome IDs to run when each conversation ends. If omitted, the outcomes configured on the SMS number are used. See [Outcomes](/tutorials/outcomes).
    </ParamField>

    <ParamField body="citation_schema_ids" type="string[]">
      An array of citation schema IDs to extract when each conversation ends. If omitted, the citation schemas configured on the SMS number are used. See [Citations](/enterprise-features/citations).
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="column_mapping" type="object">
  Maps column names in your CSV to SMS send parameter names. Use this when your CSV column names don't match the expected field names.

  Use this to map non-phone columns to `request_data` or other SMS parameters. **Note:** `phone_number` cannot be used as a target — the phone number column in your CSV must be named `phone_number` exactly.

  Map columns to `request_data` to make them available as pathway variables:

  ```json theme={null}
  {
    "customer_name": "request_data",
    "preferred_lang": "request_data"
  }
  ```

  Only `request_data` is supported as a target — per-recipient fields like `pathway_id` or `persona_id` cannot be overridden from the CSV. Alternatively, use dot notation column names in your CSV directly (e.g. `request_data.customer_name`) to avoid needing `column_mapping` at all.
</ParamField>

### Response

<ResponseField name="data" type="object">
  Confirmation that the batch was accepted for processing.

  <Expandable title="data object">
    <ResponseField name="message" type="string">
      Confirmation message indicating the batch was queued.
    </ResponseField>

    <ResponseField name="batch_id" type="string">
      The `file_id` used for this batch, for reference.
    </ResponseField>

    <ResponseField name="workflow_id" type="string">
      The ID of the background workflow processing this batch.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="errors" type="null|array">
  `null` on success, or a list of error objects if the request failed.
</ResponseField>

<ResponseExample>
  ```json Request theme={null}
  {
    "file_id": "file_abc123",
    "global": {
      "agent_number": "+14155551234",
      "pathway_id": "pathway_xyz789",
      "channel": "sms"
    },
    "column_mapping": {
      "customer_name": "request_data"
    }
  }
  ```

  ```json Response (Success) theme={null}
  {
    "data": {
      "message": "SMS batch processing initiated via Temporal workflow",
      "batch_id": "file_abc123",
      "workflow_id": "workflow_def456"
    },
    "errors": null
  }
  ```

  ```json Error Response (Missing file_id) theme={null}
  {
    "data": null,
    "errors": [
      {
        "error": "MISSING_FILE_ID",
        "message": "file_id is required"
      }
    ]
  }
  ```

  ```json Error Response (File not found) theme={null}
  {
    "data": null,
    "errors": [
      {
        "error": "FILE_NOT_FOUND",
        "message": "File not found or invalid file type for SMS batches"
      }
    ]
  }
  ```

  ```json Error Response (Agent number not found) theme={null}
  {
    "data": null,
    "errors": [
      {
        "error": "AGENT_NUMBER_NOT_FOUND",
        "message": "Agent number not found or not configured for SMS"
      }
    ]
  }
  ```
</ResponseExample>

***

Docs for agents: [llms.txt](/llms.txt)
