> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.chatbridge.mx/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.chatbridge.mx/_mcp/server.

# Send batch

POST https://connect.chatbridge.mx/v1/rcs/batches
Content-Type: application/json

Sends the same RCS content (a template or free-form content) to up to 250 recipients in a single request, personalizing each number's `variables`. The send is **asynchronous**: the API responds `202 Accepted` immediately with a `batch_id` and one `message_id` per number (in the order of the request), and processes the batch in the background; the results arrive through webhooks.

The content and delivery settings (`agent_id`, `type`, `template_id`, `text`, `contentInfo`, `richCard`, `suggestions`, `ttl_message`, `ttl_events`, `fallback`) go once at the root and apply to the whole batch. Each item of `messages` carries only its `to` and its `variables`. The content validations are the same as the single send (`POST /v1/rcs/messages`) and run once; if any fails, the batch is rejected and no number is sent.

Per-recipient rules are checked in the background, so an invalid number does not stop the others: it is reported with status `INVALID_FORMAT`, `INVALID_SOURCE` or `OUTPUT_NOT_FOUND`, is not sent and consumes no credits.

`webhook_mode` selects the notifications: `INDIVIDUAL` (default) sends the regular per-number webhooks with an extra `batch_id`; `BATCH` sends a single `batchStatus` webhook with the result of every number.

Reference: https://docs.chatbridge.mx/rcs/messages/send-rcs-batch

## Authentication

- `x-api-key` header (required) — Account authentication key. The App-Key must have the RCS channel enabled.
- `Authorization` header (bearer token, required) — OAuth 2.0 access token issued by `POST /api/oauth/token` (client-credentials). Takes precedence over `x-api-key` when both are sent. See the Authentication section.

## Request

### Body (application/json)

This endpoint expects a SendRcsBatchRequest.

- `agent_id` (string, required) — RCS agent that sends the messages. Applies to the whole batch.
- `messages` (list of RcsBatchMessage, required)
- `type` (enum, optional, default: TEMPLATE) — Content type of the batch. See `SendMessageRequest.type`.
  - Allowed values: `TEMPLATE`, `TEXT`, `FILE`, `RICH_CARD`, `CAROUSEL`
- `template_id` (string, optional) — Required with `type: TEMPLATE`; forbidden with free-form types.
- `text` (string, optional) — Required with `type: TEXT` (BASIC agents). Supports `{{placeholders}}`.
- `contentInfo` (FreeContentInfo, optional) — Required with `type: FILE`.
- `richCard` (SendRcsBatchRequestRichCard, optional) — Required with `type: RICH_CARD` or `CAROUSEL`.
- `suggestions` (list of FreeSuggestion, optional) — Message-level chips (not for BASIC agents). Never send `postbackData`.
- `ttl_message` (integer, optional) — Minutes to attempt delivery of each message before it expires.
- `ttl_events` (integer, optional) — Minutes during which clicks and replies of each message are accepted.
- `fallback` (FallbackConfig, optional) — Optional SMS fallback for this send: if the RCS message is not delivered (its delivery status webhook reports `FAILED` or `EXPIRED`), the API automatically retries the same recipient over SMS with this content. A late `FAILED`/`EXPIRED` that the RCS status priority logic already discards (a suppressed downgrade, an out-of-order event) does NOT fire the fallback — only a failure that actually advances the message status does. It fires only **once** per message and it is a single hop (RCS → SMS, no further cascade). Requires the multichannel fallback to be enabled for the account (`errorCode` 380/381 otherwise). Applies the same in both sending modes.
- `webhook_mode` (enum, optional, default: INDIVIDUAL) — `INDIVIDUAL`: the regular per-number webhooks with `batch_id`. `BATCH`: a single `batchStatus` webhook for the whole batch.
  - Allowed values: `INDIVIDUAL`, `BATCH`

## Response

### 202

Batch accepted and queued. Store `batch_id` and each number's `message_id`: they correlate the webhooks with each recipient.

- `statusCode` (integer, optional)
- `message` ("ACCEPTED", optional)
- `batch_id` (string, optional) — Batch identifier; it comes in every webhook of the batch.
- `webhook_mode` (enum, optional)
  - Allowed values: `INDIVIDUAL`, `BATCH`
- `total` (integer, optional) — Numbers received.
- `messages` (list of SendRcsBatchResponseMessagesItems, optional) — One `message_id` per number, in the order of the request.

## Errors

### 400 Bad Request Error

Content validation. If any check fails the batch is rejected and no number is sent. Per-number content errors (`344`, `348`, `345`, `349`, `309`, `574`) point to the first number with a problem: its position in `messages` goes at the start of `message` and in `metadata.index` (starting at 0).

- `message` (string, optional)
- `error` (string, optional)
- `statusCode` (integer, optional)
- `errorCode` (integer, optional)
- `metadata` (map from string to any, optional)

### 401 Unauthorized Error

Authentication is missing or invalid.

- `message` (string, optional)
- `error` (string, optional)
- `statusCode` (integer, optional)
- `errorCode` (integer, optional)
- `metadata` (map from string to any, optional)

### 403 Forbidden Error

The API Key does not have access to the RCS channel, or the request used the SMS fallback without the account meeting its requirements (`errorCode` 380/381).

- `message` (string, optional)
- `error` (string, optional)
- `statusCode` (integer, optional)
- `errorCode` (integer, optional)
- `metadata` (map from string to any, optional)

### 404 Not Found Error

The template or the agent does not exist, is inactive, or does not belong to the account (`errorCode` 341 or 342).

- `message` (string, optional)
- `error` (string, optional)
- `statusCode` (integer, optional)
- `errorCode` (integer, optional)
- `metadata` (map from string to any, optional)

### 413 Content Too Large Error

The request body exceeds the maximum size allowed (~1 MB).

- `message` (string, optional)
- `error` (string, optional)
- `statusCode` (integer, optional)
- `errorCode` (integer, optional)
- `metadata` (map from string to any, optional)

### 429 Too Many Requests Error

The requests-per-minute limit was exceeded.

- `message` (string, optional)
- `error` (string, optional)
- `statusCode` (integer, optional)
- `errorCode` (integer, optional)
- `metadata` (map from string to any, optional)

### 500 Internal Server Error

Unhandled internal error; the request can be retried.

- `message` (string, optional)
- `error` (string, optional)
- `statusCode` (integer, optional)
- `errorCode` (integer, optional)
- `metadata` (map from string to any, optional)

## Types

### RcsBatchMessage

- `to` (string, required) — Destination number. National agent: 10 digits without area code (e.g. `5555555555`). International agent: E.164, with or without `+` (e.g. `+16462713111`).
- `variables` (map from string to string, optional) — Values for this number's `{{placeholders}}`. Every placeholder of the content must have a value.

### FreeContentInfo

Media file reference. The URL must be a real, reachable `http`/`https` resource; it is validated with a HEAD request (MIME type and size).

- `fileUrl` (string, required) — Public URL of the file.
- `thumbnailUrl` (string, optional) — Optional thumbnail URL.
- `type` (enum, optional)
  - Allowed values: `IMAGE`, `VIDEO`

### SendRcsBatchRequestRichCard

Required with `type: RICH_CARD` or `CAROUSEL`.

- `standaloneCard` (FreeStandaloneCard, optional)
- `carouselCard` (FreeCarouselCard, optional)

### FreeSuggestion

Each element is `reply` **or** `action` (not both). Never send `postbackData` or `next_template_id`: the backend generates them.

- `reply` (FreeSuggestionReply, optional)
- `action` (FreeSuggestionAction, optional) — Carries `text` plus exactly one action: `openUrlAction` (`url`), `dialAction` (`phoneNumber`), `viewLocationAction` (`latLong`/`label`), `shareLocationAction`, or `createCalendarEventAction` (`startTime`, `endTime`, `title`, `description`).

### FallbackConfig

Optional SMS fallback for this send: if the RCS message is not delivered (its delivery status webhook reports `FAILED` or `EXPIRED`), the API automatically retries the same recipient over SMS with this content. A late `FAILED`/`EXPIRED` that the RCS status priority logic already discards (a suppressed downgrade, an out-of-order event) does NOT fire the fallback — only a failure that actually advances the message status does. It fires only **once** per message and it is a single hop (RCS → SMS, no further cascade). Requires the multichannel fallback to be enabled for the account (`errorCode` 380/381 otherwise). Applies the same in both sending modes.

- `sms` (FallbackSms, required) — Content of the backup SMS. Exactly the same shape as the body of `POST /v1/sms/messages` (`mask`, `text`, `has_accents`, `complement`) **except** `to` — the recipient is inherited from the original RCS message and is never sent in the fallback. The `mask` is validated at the moment of the original send (an invalid or disabled mask rejects the whole request with `400`), not when the fallback fires hours later.

### SendRcsBatchResponseMessagesItems

- `to` (string, optional)
- `message_id` (string, optional)

### FreeStandaloneCard

- `cardOrientation` (enum, required)
  - Allowed values: `HORIZONTAL`, `VERTICAL`
- `cardContent` (FreeCardContent, required)

### FreeCarouselCard

- `cardWidth` (enum, required)
  - Allowed values: `SMALL`, `MEDIUM`, `LARGE`
- `cardContents` (list of FreeCardContent, required)

### FreeSuggestionReply

- `text` (string, optional)

### FreeSuggestionAction

Carries `text` plus exactly one action: `openUrlAction` (`url`), `dialAction` (`phoneNumber`), `viewLocationAction` (`latLong`/`label`), `shareLocationAction`, or `createCalendarEventAction` (`startTime`, `endTime`, `title`, `description`).

- `text` (string, optional)

### FallbackSms

Content of the backup SMS. Exactly the same shape as the body of `POST /v1/sms/messages` (`mask`, `text`, `has_accents`, `complement`) **except** `to` — the recipient is inherited from the original RCS message and is never sent in the fallback. The `mask` is validated at the moment of the original send (an invalid or disabled mask rejects the whole request with `400`), not when the fallback fires hours later.

- `mask` (string, required) — Sender mask identifier, obtained through `GET /v1/sms/masks`.
- `text` (string, required) — Text of the backup SMS.
- `has_accents` (boolean, optional, default: false) — Send `true` when the text contains accents, `ñ`, or other characters outside the GSM-7 alphabet (the SMS is encoded in UCS-2, which reduces the maximum size per segment).
- `complement` (FallbackSmsComplement, optional) — Appends a trackable short link to the end of the SMS text, generated automatically before sending.

### FreeCardContent

- `media` (FreeCardContentMedia, required)
- `title` (string, optional) — Maximum 200 characters after variable substitution.
- `description` (string, optional) — Maximum 2000 characters after variable substitution.
- `suggestions` (list of FreeSuggestion, optional) — Buttons INSIDE the card, independent from the message-level `suggestions`.

### FallbackSmsComplement

Appends a trackable short link to the end of the SMS text, generated automatically before sending.

- `link` (string, required) — Destination URL to shorten.
- `ttl_events` (integer, optional, default: 1440) — Validity of the short link for click tracking, in minutes. Default: 1440 (24 hours).

### FreeCardContentMedia

- `height` (enum, required)
  - Allowed values: `SHORT`, `MEDIUM`, `TALL`
- `contentInfo` (FreeContentInfo, required) — Media file reference. The URL must be a real, reachable `http`/`https` resource; it is validated with a HEAD request (MIME type and size).

## Examples

### Template, single batch webhook and SMS fallback

**Request**

```json
{
  "agent_id": "66f0c2a1e4b0a1b2c3d4e5f6",
  "messages": [
    {
      "to": "5555555555",
      "variables": {
        "nombre": "Ana",
        "pedido": "123"
      }
    },
    {
      "to": "5544444444",
      "variables": {
        "nombre": "Luis",
        "pedido": "456"
      }
    }
  ],
  "template_id": "66f0c2a1e4b0a1b2c3d4e5f7",
  "ttl_events": 1440,
  "fallback": {
    "sms": {
      "mask": "6a4bffd5e77672e33fd5304f",
      "text": "Tu pedido esta listo."
    }
  },
  "webhook_mode": "BATCH"
}
```

**Response**

```json
{
  "statusCode": 202,
  "message": "ACCEPTED",
  "batch_id": "6710a2b3c4d5e6f708192a3b",
  "webhook_mode": "BATCH",
  "total": 2,
  "messages": [
    {
      "to": "5555555555",
      "message_id": "c2b6e1a4-1f3d-4b7a-8c1e-2a6f9d3b7e10"
    },
    {
      "to": "5544444444",
      "message_id": "9f1a2b3c-4d5e-4f60-8a1b-2c3d4e5f6071"
    }
  ]
}
```

**SDK Code**

```python Template, single batch webhook and SMS fallback
import requests

url = "https://connect.chatbridge.mx/v1/rcs/batches"

payload = {
    "agent_id": "66f0c2a1e4b0a1b2c3d4e5f6",
    "messages": [
        {
            "to": "5555555555",
            "variables": {
                "nombre": "Ana",
                "pedido": "123"
            }
        },
        {
            "to": "5544444444",
            "variables": {
                "nombre": "Luis",
                "pedido": "456"
            }
        }
    ],
    "template_id": "66f0c2a1e4b0a1b2c3d4e5f7",
    "ttl_events": 1440,
    "fallback": { "sms": {
            "mask": "6a4bffd5e77672e33fd5304f",
            "text": "Tu pedido esta listo."
        } },
    "webhook_mode": "BATCH"
}
headers = {
    "x-api-key": "<apiKey>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript Template, single batch webhook and SMS fallback
const url = 'https://connect.chatbridge.mx/v1/rcs/batches';
const options = {
  method: 'POST',
  headers: {'x-api-key': '<apiKey>', 'Content-Type': 'application/json'},
  body: '{"agent_id":"66f0c2a1e4b0a1b2c3d4e5f6","messages":[{"to":"5555555555","variables":{"nombre":"Ana","pedido":"123"}},{"to":"5544444444","variables":{"nombre":"Luis","pedido":"456"}}],"template_id":"66f0c2a1e4b0a1b2c3d4e5f7","ttl_events":1440,"fallback":{"sms":{"mask":"6a4bffd5e77672e33fd5304f","text":"Tu pedido esta listo."}},"webhook_mode":"BATCH"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Template, single batch webhook and SMS fallback
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://connect.chatbridge.mx/v1/rcs/batches"

	payload := strings.NewReader("{\n  \"agent_id\": \"66f0c2a1e4b0a1b2c3d4e5f6\",\n  \"messages\": [\n    {\n      \"to\": \"5555555555\",\n      \"variables\": {\n        \"nombre\": \"Ana\",\n        \"pedido\": \"123\"\n      }\n    },\n    {\n      \"to\": \"5544444444\",\n      \"variables\": {\n        \"nombre\": \"Luis\",\n        \"pedido\": \"456\"\n      }\n    }\n  ],\n  \"template_id\": \"66f0c2a1e4b0a1b2c3d4e5f7\",\n  \"ttl_events\": 1440,\n  \"fallback\": {\n    \"sms\": {\n      \"mask\": \"6a4bffd5e77672e33fd5304f\",\n      \"text\": \"Tu pedido esta listo.\"\n    }\n  },\n  \"webhook_mode\": \"BATCH\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("x-api-key", "<apiKey>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Template, single batch webhook and SMS fallback
require 'uri'
require 'net/http'

url = URI("https://connect.chatbridge.mx/v1/rcs/batches")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<apiKey>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"agent_id\": \"66f0c2a1e4b0a1b2c3d4e5f6\",\n  \"messages\": [\n    {\n      \"to\": \"5555555555\",\n      \"variables\": {\n        \"nombre\": \"Ana\",\n        \"pedido\": \"123\"\n      }\n    },\n    {\n      \"to\": \"5544444444\",\n      \"variables\": {\n        \"nombre\": \"Luis\",\n        \"pedido\": \"456\"\n      }\n    }\n  ],\n  \"template_id\": \"66f0c2a1e4b0a1b2c3d4e5f7\",\n  \"ttl_events\": 1440,\n  \"fallback\": {\n    \"sms\": {\n      \"mask\": \"6a4bffd5e77672e33fd5304f\",\n      \"text\": \"Tu pedido esta listo.\"\n    }\n  },\n  \"webhook_mode\": \"BATCH\"\n}"

response = http.request(request)
puts response.read_body
```

```java Template, single batch webhook and SMS fallback
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://connect.chatbridge.mx/v1/rcs/batches")
  .header("x-api-key", "<apiKey>")
  .header("Content-Type", "application/json")
  .body("{\n  \"agent_id\": \"66f0c2a1e4b0a1b2c3d4e5f6\",\n  \"messages\": [\n    {\n      \"to\": \"5555555555\",\n      \"variables\": {\n        \"nombre\": \"Ana\",\n        \"pedido\": \"123\"\n      }\n    },\n    {\n      \"to\": \"5544444444\",\n      \"variables\": {\n        \"nombre\": \"Luis\",\n        \"pedido\": \"456\"\n      }\n    }\n  ],\n  \"template_id\": \"66f0c2a1e4b0a1b2c3d4e5f7\",\n  \"ttl_events\": 1440,\n  \"fallback\": {\n    \"sms\": {\n      \"mask\": \"6a4bffd5e77672e33fd5304f\",\n      \"text\": \"Tu pedido esta listo.\"\n    }\n  },\n  \"webhook_mode\": \"BATCH\"\n}")
  .asString();
```

```php Template, single batch webhook and SMS fallback
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://connect.chatbridge.mx/v1/rcs/batches', [
  'body' => '{
  "agent_id": "66f0c2a1e4b0a1b2c3d4e5f6",
  "messages": [
    {
      "to": "5555555555",
      "variables": {
        "nombre": "Ana",
        "pedido": "123"
      }
    },
    {
      "to": "5544444444",
      "variables": {
        "nombre": "Luis",
        "pedido": "456"
      }
    }
  ],
  "template_id": "66f0c2a1e4b0a1b2c3d4e5f7",
  "ttl_events": 1440,
  "fallback": {
    "sms": {
      "mask": "6a4bffd5e77672e33fd5304f",
      "text": "Tu pedido esta listo."
    }
  },
  "webhook_mode": "BATCH"
}',
  'headers' => [
    'Content-Type' => 'application/json',
    'x-api-key' => '<apiKey>',
  ],
]);

echo $response->getBody();
```

```csharp Template, single batch webhook and SMS fallback
using RestSharp;

var client = new RestClient("https://connect.chatbridge.mx/v1/rcs/batches");
var request = new RestRequest(Method.POST);
request.AddHeader("x-api-key", "<apiKey>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"agent_id\": \"66f0c2a1e4b0a1b2c3d4e5f6\",\n  \"messages\": [\n    {\n      \"to\": \"5555555555\",\n      \"variables\": {\n        \"nombre\": \"Ana\",\n        \"pedido\": \"123\"\n      }\n    },\n    {\n      \"to\": \"5544444444\",\n      \"variables\": {\n        \"nombre\": \"Luis\",\n        \"pedido\": \"456\"\n      }\n    }\n  ],\n  \"template_id\": \"66f0c2a1e4b0a1b2c3d4e5f7\",\n  \"ttl_events\": 1440,\n  \"fallback\": {\n    \"sms\": {\n      \"mask\": \"6a4bffd5e77672e33fd5304f\",\n      \"text\": \"Tu pedido esta listo.\"\n    }\n  },\n  \"webhook_mode\": \"BATCH\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Template, single batch webhook and SMS fallback
import Foundation

let headers = [
  "x-api-key": "<apiKey>",
  "Content-Type": "application/json"
]
let parameters = [
  "agent_id": "66f0c2a1e4b0a1b2c3d4e5f6",
  "messages": [
    [
      "to": "5555555555",
      "variables": [
        "nombre": "Ana",
        "pedido": "123"
      ]
    ],
    [
      "to": "5544444444",
      "variables": [
        "nombre": "Luis",
        "pedido": "456"
      ]
    ]
  ],
  "template_id": "66f0c2a1e4b0a1b2c3d4e5f7",
  "ttl_events": 1440,
  "fallback": ["sms": [
      "mask": "6a4bffd5e77672e33fd5304f",
      "text": "Tu pedido esta listo."
    ]],
  "webhook_mode": "BATCH"
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://connect.chatbridge.mx/v1/rcs/batches")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### Free-form text (BASIC agent)

**Request**

```json
{
  "agent_id": "66f0c2a1e4b0a1b2c3d4e5f8",
  "messages": [
    {
      "to": "5555555555",
      "variables": {
        "codigo": "4821",
        "nombre": "Ana"
      }
    },
    {
      "to": "5544444444",
      "variables": {
        "codigo": "9930",
        "nombre": "Luis"
      }
    }
  ],
  "type": "TEXT",
  "text": "Hola {{nombre}}, tu codigo es {{codigo}}"
}
```

**Response**

```json
{
  "statusCode": 202,
  "message": "ACCEPTED",
  "batch_id": "6710a2b3c4d5e6f708192a3b",
  "webhook_mode": "BATCH",
  "total": 2,
  "messages": [
    {
      "to": "5555555555",
      "message_id": "c2b6e1a4-1f3d-4b7a-8c1e-2a6f9d3b7e10"
    },
    {
      "to": "5544444444",
      "message_id": "9f1a2b3c-4d5e-4f60-8a1b-2c3d4e5f6071"
    }
  ]
}
```

**SDK Code**

```python Free-form text (BASIC agent)
import requests

url = "https://connect.chatbridge.mx/v1/rcs/batches"

payload = {
    "agent_id": "66f0c2a1e4b0a1b2c3d4e5f8",
    "messages": [
        {
            "to": "5555555555",
            "variables": {
                "codigo": "4821",
                "nombre": "Ana"
            }
        },
        {
            "to": "5544444444",
            "variables": {
                "codigo": "9930",
                "nombre": "Luis"
            }
        }
    ],
    "type": "TEXT",
    "text": "Hola {{nombre}}, tu codigo es {{codigo}}"
}
headers = {
    "x-api-key": "<apiKey>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript Free-form text (BASIC agent)
const url = 'https://connect.chatbridge.mx/v1/rcs/batches';
const options = {
  method: 'POST',
  headers: {'x-api-key': '<apiKey>', 'Content-Type': 'application/json'},
  body: '{"agent_id":"66f0c2a1e4b0a1b2c3d4e5f8","messages":[{"to":"5555555555","variables":{"codigo":"4821","nombre":"Ana"}},{"to":"5544444444","variables":{"codigo":"9930","nombre":"Luis"}}],"type":"TEXT","text":"Hola {{nombre}}, tu codigo es {{codigo}}"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Free-form text (BASIC agent)
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://connect.chatbridge.mx/v1/rcs/batches"

	payload := strings.NewReader("{\n  \"agent_id\": \"66f0c2a1e4b0a1b2c3d4e5f8\",\n  \"messages\": [\n    {\n      \"to\": \"5555555555\",\n      \"variables\": {\n        \"codigo\": \"4821\",\n        \"nombre\": \"Ana\"\n      }\n    },\n    {\n      \"to\": \"5544444444\",\n      \"variables\": {\n        \"codigo\": \"9930\",\n        \"nombre\": \"Luis\"\n      }\n    }\n  ],\n  \"type\": \"TEXT\",\n  \"text\": \"Hola {{nombre}}, tu codigo es {{codigo}}\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("x-api-key", "<apiKey>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Free-form text (BASIC agent)
require 'uri'
require 'net/http'

url = URI("https://connect.chatbridge.mx/v1/rcs/batches")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<apiKey>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"agent_id\": \"66f0c2a1e4b0a1b2c3d4e5f8\",\n  \"messages\": [\n    {\n      \"to\": \"5555555555\",\n      \"variables\": {\n        \"codigo\": \"4821\",\n        \"nombre\": \"Ana\"\n      }\n    },\n    {\n      \"to\": \"5544444444\",\n      \"variables\": {\n        \"codigo\": \"9930\",\n        \"nombre\": \"Luis\"\n      }\n    }\n  ],\n  \"type\": \"TEXT\",\n  \"text\": \"Hola {{nombre}}, tu codigo es {{codigo}}\"\n}"

response = http.request(request)
puts response.read_body
```

```java Free-form text (BASIC agent)
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://connect.chatbridge.mx/v1/rcs/batches")
  .header("x-api-key", "<apiKey>")
  .header("Content-Type", "application/json")
  .body("{\n  \"agent_id\": \"66f0c2a1e4b0a1b2c3d4e5f8\",\n  \"messages\": [\n    {\n      \"to\": \"5555555555\",\n      \"variables\": {\n        \"codigo\": \"4821\",\n        \"nombre\": \"Ana\"\n      }\n    },\n    {\n      \"to\": \"5544444444\",\n      \"variables\": {\n        \"codigo\": \"9930\",\n        \"nombre\": \"Luis\"\n      }\n    }\n  ],\n  \"type\": \"TEXT\",\n  \"text\": \"Hola {{nombre}}, tu codigo es {{codigo}}\"\n}")
  .asString();
```

```php Free-form text (BASIC agent)
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://connect.chatbridge.mx/v1/rcs/batches', [
  'body' => '{
  "agent_id": "66f0c2a1e4b0a1b2c3d4e5f8",
  "messages": [
    {
      "to": "5555555555",
      "variables": {
        "codigo": "4821",
        "nombre": "Ana"
      }
    },
    {
      "to": "5544444444",
      "variables": {
        "codigo": "9930",
        "nombre": "Luis"
      }
    }
  ],
  "type": "TEXT",
  "text": "Hola {{nombre}}, tu codigo es {{codigo}}"
}',
  'headers' => [
    'Content-Type' => 'application/json',
    'x-api-key' => '<apiKey>',
  ],
]);

echo $response->getBody();
```

```csharp Free-form text (BASIC agent)
using RestSharp;

var client = new RestClient("https://connect.chatbridge.mx/v1/rcs/batches");
var request = new RestRequest(Method.POST);
request.AddHeader("x-api-key", "<apiKey>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"agent_id\": \"66f0c2a1e4b0a1b2c3d4e5f8\",\n  \"messages\": [\n    {\n      \"to\": \"5555555555\",\n      \"variables\": {\n        \"codigo\": \"4821\",\n        \"nombre\": \"Ana\"\n      }\n    },\n    {\n      \"to\": \"5544444444\",\n      \"variables\": {\n        \"codigo\": \"9930\",\n        \"nombre\": \"Luis\"\n      }\n    }\n  ],\n  \"type\": \"TEXT\",\n  \"text\": \"Hola {{nombre}}, tu codigo es {{codigo}}\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Free-form text (BASIC agent)
import Foundation

let headers = [
  "x-api-key": "<apiKey>",
  "Content-Type": "application/json"
]
let parameters = [
  "agent_id": "66f0c2a1e4b0a1b2c3d4e5f8",
  "messages": [
    [
      "to": "5555555555",
      "variables": [
        "codigo": "4821",
        "nombre": "Ana"
      ]
    ],
    [
      "to": "5544444444",
      "variables": [
        "codigo": "9930",
        "nombre": "Luis"
      ]
    ]
  ],
  "type": "TEXT",
  "text": "Hola {{nombre}}, tu codigo es {{codigo}}"
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://connect.chatbridge.mx/v1/rcs/batches")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### Card with a different image per number

**Request**

```json
{
  "agent_id": "66f0c2a1e4b0a1b2c3d4e5f6",
  "messages": [
    {
      "to": "5555555555",
      "variables": {
        "imagen": "https://cdn.ejemplo.mx/pedidos/123.png",
        "nombre": "Ana",
        "pedido": "123"
      }
    },
    {
      "to": "5544444444",
      "variables": {
        "imagen": "https://cdn.ejemplo.mx/pedidos/456.png",
        "nombre": "Luis",
        "pedido": "456"
      }
    }
  ],
  "type": "RICH_CARD",
  "richCard": {
    "standaloneCard": {
      "cardOrientation": "VERTICAL",
      "cardContent": {
        "media": {
          "height": "MEDIUM",
          "contentInfo": {
            "fileUrl": "{{imagen}}"
          }
        },
        "title": "Hola {{nombre}}",
        "description": "Tu pedido {{pedido}} ya va en camino."
      }
    }
  }
}
```

**Response**

```json
{
  "statusCode": 202,
  "message": "ACCEPTED",
  "batch_id": "6710a2b3c4d5e6f708192a3b",
  "webhook_mode": "BATCH",
  "total": 2,
  "messages": [
    {
      "to": "5555555555",
      "message_id": "c2b6e1a4-1f3d-4b7a-8c1e-2a6f9d3b7e10"
    },
    {
      "to": "5544444444",
      "message_id": "9f1a2b3c-4d5e-4f60-8a1b-2c3d4e5f6071"
    }
  ]
}
```

**SDK Code**

```python Card with a different image per number
import requests

url = "https://connect.chatbridge.mx/v1/rcs/batches"

payload = {
    "agent_id": "66f0c2a1e4b0a1b2c3d4e5f6",
    "messages": [
        {
            "to": "5555555555",
            "variables": {
                "imagen": "https://cdn.ejemplo.mx/pedidos/123.png",
                "nombre": "Ana",
                "pedido": "123"
            }
        },
        {
            "to": "5544444444",
            "variables": {
                "imagen": "https://cdn.ejemplo.mx/pedidos/456.png",
                "nombre": "Luis",
                "pedido": "456"
            }
        }
    ],
    "type": "RICH_CARD",
    "richCard": { "standaloneCard": {
            "cardOrientation": "VERTICAL",
            "cardContent": {
                "media": {
                    "height": "MEDIUM",
                    "contentInfo": { "fileUrl": "{{imagen}}" }
                },
                "title": "Hola {{nombre}}",
                "description": "Tu pedido {{pedido}} ya va en camino."
            }
        } }
}
headers = {
    "x-api-key": "<apiKey>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript Card with a different image per number
const url = 'https://connect.chatbridge.mx/v1/rcs/batches';
const options = {
  method: 'POST',
  headers: {'x-api-key': '<apiKey>', 'Content-Type': 'application/json'},
  body: '{"agent_id":"66f0c2a1e4b0a1b2c3d4e5f6","messages":[{"to":"5555555555","variables":{"imagen":"https://cdn.ejemplo.mx/pedidos/123.png","nombre":"Ana","pedido":"123"}},{"to":"5544444444","variables":{"imagen":"https://cdn.ejemplo.mx/pedidos/456.png","nombre":"Luis","pedido":"456"}}],"type":"RICH_CARD","richCard":{"standaloneCard":{"cardOrientation":"VERTICAL","cardContent":{"media":{"height":"MEDIUM","contentInfo":{"fileUrl":"{{imagen}}"}},"title":"Hola {{nombre}}","description":"Tu pedido {{pedido}} ya va en camino."}}}}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Card with a different image per number
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://connect.chatbridge.mx/v1/rcs/batches"

	payload := strings.NewReader("{\n  \"agent_id\": \"66f0c2a1e4b0a1b2c3d4e5f6\",\n  \"messages\": [\n    {\n      \"to\": \"5555555555\",\n      \"variables\": {\n        \"imagen\": \"https://cdn.ejemplo.mx/pedidos/123.png\",\n        \"nombre\": \"Ana\",\n        \"pedido\": \"123\"\n      }\n    },\n    {\n      \"to\": \"5544444444\",\n      \"variables\": {\n        \"imagen\": \"https://cdn.ejemplo.mx/pedidos/456.png\",\n        \"nombre\": \"Luis\",\n        \"pedido\": \"456\"\n      }\n    }\n  ],\n  \"type\": \"RICH_CARD\",\n  \"richCard\": {\n    \"standaloneCard\": {\n      \"cardOrientation\": \"VERTICAL\",\n      \"cardContent\": {\n        \"media\": {\n          \"height\": \"MEDIUM\",\n          \"contentInfo\": {\n            \"fileUrl\": \"{{imagen}}\"\n          }\n        },\n        \"title\": \"Hola {{nombre}}\",\n        \"description\": \"Tu pedido {{pedido}} ya va en camino.\"\n      }\n    }\n  }\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("x-api-key", "<apiKey>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Card with a different image per number
require 'uri'
require 'net/http'

url = URI("https://connect.chatbridge.mx/v1/rcs/batches")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<apiKey>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"agent_id\": \"66f0c2a1e4b0a1b2c3d4e5f6\",\n  \"messages\": [\n    {\n      \"to\": \"5555555555\",\n      \"variables\": {\n        \"imagen\": \"https://cdn.ejemplo.mx/pedidos/123.png\",\n        \"nombre\": \"Ana\",\n        \"pedido\": \"123\"\n      }\n    },\n    {\n      \"to\": \"5544444444\",\n      \"variables\": {\n        \"imagen\": \"https://cdn.ejemplo.mx/pedidos/456.png\",\n        \"nombre\": \"Luis\",\n        \"pedido\": \"456\"\n      }\n    }\n  ],\n  \"type\": \"RICH_CARD\",\n  \"richCard\": {\n    \"standaloneCard\": {\n      \"cardOrientation\": \"VERTICAL\",\n      \"cardContent\": {\n        \"media\": {\n          \"height\": \"MEDIUM\",\n          \"contentInfo\": {\n            \"fileUrl\": \"{{imagen}}\"\n          }\n        },\n        \"title\": \"Hola {{nombre}}\",\n        \"description\": \"Tu pedido {{pedido}} ya va en camino.\"\n      }\n    }\n  }\n}"

response = http.request(request)
puts response.read_body
```

```java Card with a different image per number
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://connect.chatbridge.mx/v1/rcs/batches")
  .header("x-api-key", "<apiKey>")
  .header("Content-Type", "application/json")
  .body("{\n  \"agent_id\": \"66f0c2a1e4b0a1b2c3d4e5f6\",\n  \"messages\": [\n    {\n      \"to\": \"5555555555\",\n      \"variables\": {\n        \"imagen\": \"https://cdn.ejemplo.mx/pedidos/123.png\",\n        \"nombre\": \"Ana\",\n        \"pedido\": \"123\"\n      }\n    },\n    {\n      \"to\": \"5544444444\",\n      \"variables\": {\n        \"imagen\": \"https://cdn.ejemplo.mx/pedidos/456.png\",\n        \"nombre\": \"Luis\",\n        \"pedido\": \"456\"\n      }\n    }\n  ],\n  \"type\": \"RICH_CARD\",\n  \"richCard\": {\n    \"standaloneCard\": {\n      \"cardOrientation\": \"VERTICAL\",\n      \"cardContent\": {\n        \"media\": {\n          \"height\": \"MEDIUM\",\n          \"contentInfo\": {\n            \"fileUrl\": \"{{imagen}}\"\n          }\n        },\n        \"title\": \"Hola {{nombre}}\",\n        \"description\": \"Tu pedido {{pedido}} ya va en camino.\"\n      }\n    }\n  }\n}")
  .asString();
```

```php Card with a different image per number
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://connect.chatbridge.mx/v1/rcs/batches', [
  'body' => '{
  "agent_id": "66f0c2a1e4b0a1b2c3d4e5f6",
  "messages": [
    {
      "to": "5555555555",
      "variables": {
        "imagen": "https://cdn.ejemplo.mx/pedidos/123.png",
        "nombre": "Ana",
        "pedido": "123"
      }
    },
    {
      "to": "5544444444",
      "variables": {
        "imagen": "https://cdn.ejemplo.mx/pedidos/456.png",
        "nombre": "Luis",
        "pedido": "456"
      }
    }
  ],
  "type": "RICH_CARD",
  "richCard": {
    "standaloneCard": {
      "cardOrientation": "VERTICAL",
      "cardContent": {
        "media": {
          "height": "MEDIUM",
          "contentInfo": {
            "fileUrl": "{{imagen}}"
          }
        },
        "title": "Hola {{nombre}}",
        "description": "Tu pedido {{pedido}} ya va en camino."
      }
    }
  }
}',
  'headers' => [
    'Content-Type' => 'application/json',
    'x-api-key' => '<apiKey>',
  ],
]);

echo $response->getBody();
```

```csharp Card with a different image per number
using RestSharp;

var client = new RestClient("https://connect.chatbridge.mx/v1/rcs/batches");
var request = new RestRequest(Method.POST);
request.AddHeader("x-api-key", "<apiKey>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"agent_id\": \"66f0c2a1e4b0a1b2c3d4e5f6\",\n  \"messages\": [\n    {\n      \"to\": \"5555555555\",\n      \"variables\": {\n        \"imagen\": \"https://cdn.ejemplo.mx/pedidos/123.png\",\n        \"nombre\": \"Ana\",\n        \"pedido\": \"123\"\n      }\n    },\n    {\n      \"to\": \"5544444444\",\n      \"variables\": {\n        \"imagen\": \"https://cdn.ejemplo.mx/pedidos/456.png\",\n        \"nombre\": \"Luis\",\n        \"pedido\": \"456\"\n      }\n    }\n  ],\n  \"type\": \"RICH_CARD\",\n  \"richCard\": {\n    \"standaloneCard\": {\n      \"cardOrientation\": \"VERTICAL\",\n      \"cardContent\": {\n        \"media\": {\n          \"height\": \"MEDIUM\",\n          \"contentInfo\": {\n            \"fileUrl\": \"{{imagen}}\"\n          }\n        },\n        \"title\": \"Hola {{nombre}}\",\n        \"description\": \"Tu pedido {{pedido}} ya va en camino.\"\n      }\n    }\n  }\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Card with a different image per number
import Foundation

let headers = [
  "x-api-key": "<apiKey>",
  "Content-Type": "application/json"
]
let parameters = [
  "agent_id": "66f0c2a1e4b0a1b2c3d4e5f6",
  "messages": [
    [
      "to": "5555555555",
      "variables": [
        "imagen": "https://cdn.ejemplo.mx/pedidos/123.png",
        "nombre": "Ana",
        "pedido": "123"
      ]
    ],
    [
      "to": "5544444444",
      "variables": [
        "imagen": "https://cdn.ejemplo.mx/pedidos/456.png",
        "nombre": "Luis",
        "pedido": "456"
      ]
    ]
  ],
  "type": "RICH_CARD",
  "richCard": ["standaloneCard": [
      "cardOrientation": "VERTICAL",
      "cardContent": [
        "media": [
          "height": "MEDIUM",
          "contentInfo": ["fileUrl": "{{imagen}}"]
        ],
        "title": "Hola {{nombre}}",
        "description": "Tu pedido {{pedido}} ya va en camino."
      ]
    ]]
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://connect.chatbridge.mx/v1/rcs/batches")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### A different file per number

**Request**

```json
{
  "agent_id": "66f0c2a1e4b0a1b2c3d4e5f6",
  "messages": [
    {
      "to": "5555555555",
      "variables": {
        "factura": "https://cdn.ejemplo.mx/facturas/A-001.pdf"
      }
    },
    {
      "to": "5544444444",
      "variables": {
        "factura": "https://cdn.ejemplo.mx/facturas/A-002.pdf"
      }
    }
  ],
  "type": "FILE",
  "contentInfo": {
    "fileUrl": "{{factura}}"
  }
}
```

**Response**

```json
{
  "statusCode": 202,
  "message": "ACCEPTED",
  "batch_id": "6710a2b3c4d5e6f708192a3b",
  "webhook_mode": "BATCH",
  "total": 2,
  "messages": [
    {
      "to": "5555555555",
      "message_id": "c2b6e1a4-1f3d-4b7a-8c1e-2a6f9d3b7e10"
    },
    {
      "to": "5544444444",
      "message_id": "9f1a2b3c-4d5e-4f60-8a1b-2c3d4e5f6071"
    }
  ]
}
```

**SDK Code**

```python A different file per number
import requests

url = "https://connect.chatbridge.mx/v1/rcs/batches"

payload = {
    "agent_id": "66f0c2a1e4b0a1b2c3d4e5f6",
    "messages": [
        {
            "to": "5555555555",
            "variables": { "factura": "https://cdn.ejemplo.mx/facturas/A-001.pdf" }
        },
        {
            "to": "5544444444",
            "variables": { "factura": "https://cdn.ejemplo.mx/facturas/A-002.pdf" }
        }
    ],
    "type": "FILE",
    "contentInfo": { "fileUrl": "{{factura}}" }
}
headers = {
    "x-api-key": "<apiKey>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript A different file per number
const url = 'https://connect.chatbridge.mx/v1/rcs/batches';
const options = {
  method: 'POST',
  headers: {'x-api-key': '<apiKey>', 'Content-Type': 'application/json'},
  body: '{"agent_id":"66f0c2a1e4b0a1b2c3d4e5f6","messages":[{"to":"5555555555","variables":{"factura":"https://cdn.ejemplo.mx/facturas/A-001.pdf"}},{"to":"5544444444","variables":{"factura":"https://cdn.ejemplo.mx/facturas/A-002.pdf"}}],"type":"FILE","contentInfo":{"fileUrl":"{{factura}}"}}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go A different file per number
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://connect.chatbridge.mx/v1/rcs/batches"

	payload := strings.NewReader("{\n  \"agent_id\": \"66f0c2a1e4b0a1b2c3d4e5f6\",\n  \"messages\": [\n    {\n      \"to\": \"5555555555\",\n      \"variables\": {\n        \"factura\": \"https://cdn.ejemplo.mx/facturas/A-001.pdf\"\n      }\n    },\n    {\n      \"to\": \"5544444444\",\n      \"variables\": {\n        \"factura\": \"https://cdn.ejemplo.mx/facturas/A-002.pdf\"\n      }\n    }\n  ],\n  \"type\": \"FILE\",\n  \"contentInfo\": {\n    \"fileUrl\": \"{{factura}}\"\n  }\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("x-api-key", "<apiKey>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby A different file per number
require 'uri'
require 'net/http'

url = URI("https://connect.chatbridge.mx/v1/rcs/batches")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<apiKey>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"agent_id\": \"66f0c2a1e4b0a1b2c3d4e5f6\",\n  \"messages\": [\n    {\n      \"to\": \"5555555555\",\n      \"variables\": {\n        \"factura\": \"https://cdn.ejemplo.mx/facturas/A-001.pdf\"\n      }\n    },\n    {\n      \"to\": \"5544444444\",\n      \"variables\": {\n        \"factura\": \"https://cdn.ejemplo.mx/facturas/A-002.pdf\"\n      }\n    }\n  ],\n  \"type\": \"FILE\",\n  \"contentInfo\": {\n    \"fileUrl\": \"{{factura}}\"\n  }\n}"

response = http.request(request)
puts response.read_body
```

```java A different file per number
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://connect.chatbridge.mx/v1/rcs/batches")
  .header("x-api-key", "<apiKey>")
  .header("Content-Type", "application/json")
  .body("{\n  \"agent_id\": \"66f0c2a1e4b0a1b2c3d4e5f6\",\n  \"messages\": [\n    {\n      \"to\": \"5555555555\",\n      \"variables\": {\n        \"factura\": \"https://cdn.ejemplo.mx/facturas/A-001.pdf\"\n      }\n    },\n    {\n      \"to\": \"5544444444\",\n      \"variables\": {\n        \"factura\": \"https://cdn.ejemplo.mx/facturas/A-002.pdf\"\n      }\n    }\n  ],\n  \"type\": \"FILE\",\n  \"contentInfo\": {\n    \"fileUrl\": \"{{factura}}\"\n  }\n}")
  .asString();
```

```php A different file per number
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://connect.chatbridge.mx/v1/rcs/batches', [
  'body' => '{
  "agent_id": "66f0c2a1e4b0a1b2c3d4e5f6",
  "messages": [
    {
      "to": "5555555555",
      "variables": {
        "factura": "https://cdn.ejemplo.mx/facturas/A-001.pdf"
      }
    },
    {
      "to": "5544444444",
      "variables": {
        "factura": "https://cdn.ejemplo.mx/facturas/A-002.pdf"
      }
    }
  ],
  "type": "FILE",
  "contentInfo": {
    "fileUrl": "{{factura}}"
  }
}',
  'headers' => [
    'Content-Type' => 'application/json',
    'x-api-key' => '<apiKey>',
  ],
]);

echo $response->getBody();
```

```csharp A different file per number
using RestSharp;

var client = new RestClient("https://connect.chatbridge.mx/v1/rcs/batches");
var request = new RestRequest(Method.POST);
request.AddHeader("x-api-key", "<apiKey>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"agent_id\": \"66f0c2a1e4b0a1b2c3d4e5f6\",\n  \"messages\": [\n    {\n      \"to\": \"5555555555\",\n      \"variables\": {\n        \"factura\": \"https://cdn.ejemplo.mx/facturas/A-001.pdf\"\n      }\n    },\n    {\n      \"to\": \"5544444444\",\n      \"variables\": {\n        \"factura\": \"https://cdn.ejemplo.mx/facturas/A-002.pdf\"\n      }\n    }\n  ],\n  \"type\": \"FILE\",\n  \"contentInfo\": {\n    \"fileUrl\": \"{{factura}}\"\n  }\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift A different file per number
import Foundation

let headers = [
  "x-api-key": "<apiKey>",
  "Content-Type": "application/json"
]
let parameters = [
  "agent_id": "66f0c2a1e4b0a1b2c3d4e5f6",
  "messages": [
    [
      "to": "5555555555",
      "variables": ["factura": "https://cdn.ejemplo.mx/facturas/A-001.pdf"]
    ],
    [
      "to": "5544444444",
      "variables": ["factura": "https://cdn.ejemplo.mx/facturas/A-002.pdf"]
    ]
  ],
  "type": "FILE",
  "contentInfo": ["fileUrl": "{{factura}}"]
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://connect.chatbridge.mx/v1/rcs/batches")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```