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

# Batching

[Publishing](/qstash/howto/publishing) is great for sending one message
at a time, but sometimes you want to send a batch of messages at once.

This can be useful to send messages to a single or multiple destinations.
QStash provides the `batch` endpoint to help
you with this.

If the format of the messages are valid, the response will be an array of
responses for each message in the batch. When batching URL Groups, the response
will be an array of responses for each destination in the URL Group. If one
message fails to be sent, that message will have an error response, but the
other messages will still be sent.

<Note>You can publish to destination, URL Group or queue in the same batch request.</Note>

## Batching messages with destinations

<Info>You can also send messages to the same destination!</Info>

<CodeGroup>
  ```shell cURL theme={"system"}
  curl -XPOST https://qstash.upstash.io/v2/batch \
      -H 'Authorization: Bearer XXX' \
      -H "Content-type: application/json" \
      -d '
       [
        {
          "destination": "https://example.com/destination1"
        },
        {
          "destination": "https://example.com/destination2"
        }
       ]'
  ```

  ```typescript TypeScript theme={"system"}
  import { Client } from "@upstash/qstash";

  // Each message is the same as the one you would send with the publish endpoint
  const client = new Client({ token: "<QSTASH_TOKEN>" });
  const res = await client.batchJSON([
    {
      url: "https://example.com/destination1",
    },
    {
      url: "https://example.com/destination2",
    },
  ]);
  ```

  ```python Python theme={"system"}
  from qstash import QStash

  client = QStash("<QSTASH-TOKEN>")
  client.message.batch_json(
      [
          {"url": "https://example.com/destination1"},
          {"url": "https://example.com/destination2"},
      ]
  )
  ```
</CodeGroup>

## Batching messages with URL Groups

If you have a [URL Group](/qstash/howto/url-group-endpoint), you can batch send with
the URL Group as well.

<CodeGroup>
  ```shell cURL theme={"system"}
  curl -XPOST https://qstash.upstash.io/v2/batch \
      -H 'Authorization: Bearer XXX' \
      -H "Content-type: application/json" \
      -d '
       [
        {
          "destination": "myUrlGroup"
        },
        {
          "destination": "https://example.com/destination2"
        }
       ]'
  ```

  ```typescript TypeScript theme={"system"}
  const client = new Client({ token: "<QSTASH_TOKEN>" });

  // Each message is the same as the one you would send with the publish endpoint
  const res = await client.batchJSON([
    {
      urlGroup: "myUrlGroup",
    },
    {
      url: "https://example.com/destination2",
    },
  ]);
  ```

  ```python Python theme={"system"}
  from qstash import QStash

  client = QStash("<QSTASH-TOKEN>")
  client.message.batch_json(
      [
          {"url_group": "my-url-group"},
          {"url": "https://example.com/destination2"},
      ]
  )
  ```
</CodeGroup>

## Batching messages with queue

If you have a [queue](/qstash/features/queues), you can batch send with
the queue. It is the same as publishing to a destination, but you need to set the queue name.

<CodeGroup>
  ```shell cURL theme={"system"}
  curl -XPOST https://qstash.upstash.io/v2/batch \
      -H 'Authorization: Bearer XXX' \
      -H "Content-type: application/json" \
      -d '
       [
        {
          "queue": "my-queue",
          "destination": "https://example.com/destination1"
        },
        {
          "queue": "my-second-queue",
          "destination": "https://example.com/destination2"
        }
       ]'
  ```

  ```typescript TypeScript theme={"system"}
  const client = new Client({ token: "<QSTASH_TOKEN>" });

  const res = await client.batchJSON([
    {
      queueName: "my-queue",
      url: "https://example.com/destination1",
    },
    {
      queueName: "my-second-queue",
      url: "https://example.com/destination2",
    },
  ]);
  ```

  ```python Python theme={"system"}
  from upstash_qstash import QStash
  from upstash_qstash.message import BatchRequest

  qstash = QStash("<QSTASH_TOKEN>")

  messages = [
      BatchRequest(
          queue="my-queue",
          url="https://httpstat.us/200",
          body=f"hi 1",
          retries=0
      ),
      BatchRequest(
          queue="my-second-queue",
          url="https://httpstat.us/200",
          body=f"hi 2",
          retries=0
      ),
  ]

  qstash.message.batch(messages)
  ```
</CodeGroup>

## Batching messages with headers and body

You can provide custom headers and a body for each message in the batch.

<CodeGroup>
  ```shell cURL theme={"system"}
  curl -XPOST https://qstash.upstash.io/v2/batch   -H "Authorization: Bearer XXX" \
      -H "Content-Type: application/json" \
      -d '
      [
        {
            "destination": "myUrlGroup",
            "headers":{
              "Upstash-Delay":"5s",
              "Upstash-Forward-Hello":"123456"
            },
            "body": "Hello World"
        },
        {
            "destination": "https://example.com/destination1",
            "headers":{
              "Upstash-Delay":"7s",
              "Upstash-Forward-Hello":"789"
            }
        },
        {
            "destination": "https://example.com/destination2",
            "headers":{
              "Upstash-Delay":"9s",
              "Upstash-Forward-Hello":"again"
            }
        }
      ]'
  ```

  ```typescript TypeScript theme={"system"}
  const client = new Client({ token: "<QSTASH_TOKEN>" });

  // Each message is the same as the one you would send with the publish endpoint
  const msgs = [
    {
      urlGroup: "myUrlGroup",
      delay: 5,
      body: "Hello World",
      headers: {
        hello: "123456",
      },
    },
    {
      url: "https://example.com/destination1",
      delay: 7,
      headers: {
        hello: "789",
      },
    },
    {
      url: "https://example.com/destination2",
      delay: 9,
      headers: {
        hello: "again",
      },
      body: {
        Some: "Data",
      },
    },
  ];

  const res = await client.batchJSON(msgs);
  ```

  ```python Python theme={"system"}
  from qstash import QStash

  client = QStash("<QSTASH-TOKEN>")
  client.message.batch_json(
      [
          {
              "url_group": "my-url-group",
              "delay": "5s",
              "body": {"hello": "world"},
              "headers": {"random": "header"},
          },
          {
              "url": "https://example.com/destination1",
              "delay": "1m",
          },
          {
              "url": "https://example.com/destination2",
              "body": {"hello": "again"},
          },
      ]
  )
  ```
</CodeGroup>

#### The response for this will look like

```json theme={"system"}
[
  [
    {
      "messageId": "msg_...",
      "url": "https://myUrlGroup-endpoint1.com"
    },
    {
      "messageId": "msg_...",
      "url": "https://myUrlGroup-endpoint2.com"
    }
  ],
  {
    "messageId": "msg_..."
  },
  {
    "messageId": "msg_..."
  }
]
```
