---
title: Procesamiento por lotes
url: https://platform.claude.com/docs/es/build-with-claude/batch-processing
description: Procesa grandes volúmenes de solicitudes de Messages de forma asíncrona con la Message Batches API, reduciendo los costos en un 50 por ciento y aumentando el rendimiento.
featureMetadata:
  status: stable
  zdr:
    eligibility: not-eligible
    note: Retención de 29 días; se requiere almacenamiento asíncrono.
  supportedModels:
    - claude-fable-5-2
    - claude-mythos-5-2
    - claude-fable-5-1
    - claude-mythos-5-1
    - claude-fable-5
    - claude-mythos-5
    - claude-mythos-preview
    - claude-opus-5-5
    - claude-opus-5
    - claude-sonnet-5-5
    - claude-sonnet-5
    - claude-haiku-5-5
    - claude-haiku-4-5-20251001
    - claude-opus-4-8
    - claude-opus-4-7
    - claude-opus-4-6
    - claude-sonnet-4-6
    - claude-opus-4-5-20251101
    - claude-sonnet-4-5-20250929
  supportedPlatforms:
    Claude API: stable
    Claude Platform on AWS: stable
    Claude Models on Google Cloud (Anthropic managed): stable
---

El “batch processing” (procesamiento por lotes) es un enfoque poderoso para gestionar grandes volúmenes de solicitudes de manera eficiente. En lugar de procesar las solicitudes una a la vez con respuestas inmediatas, el procesamiento por lotes te permite enviar varias solicitudes juntas para su procesamiento asíncrono. Este patrón es especialmente útil cuando:

* Necesitas procesar grandes volúmenes de datos
* No se requieren respuestas inmediatas
* Quieres optimizar la eficiencia de costos
* Estás ejecutando evaluaciones o análisis a gran escala

La Message Batches API implementa este patrón.

# Message Batches API

La Message Batches API es una forma poderosa y rentable de procesar de forma asíncrona grandes volúmenes de solicitudes de [Messages](https://platform.claude.com/docs/es/api/messages/create). Este enfoque es muy adecuado para tareas que no requieren respuestas inmediatas; la mayoría de los lotes terminan en menos de 1 hora, a la vez que se reducen los costos en un 50 por ciento y aumenta el “throughput” (rendimiento).

Además de esta guía, puedes [explorar directamente la referencia de la API](https://platform.claude.com/docs/es/api/messages/batches/create).

## Cómo funciona la Message Batches API

Cuando envías una solicitud a la Message Batches API:

1. El sistema crea un nuevo lote de mensajes con las solicitudes de Messages proporcionadas.
2. Luego, el lote se procesa de forma asíncrona, y cada solicitud se gestiona de forma independiente.
3. Puedes consultar el estado del lote y recuperar los resultados cuando el procesamiento haya terminado para todas las solicitudes.

Esto es especialmente útil para operaciones masivas que no requieren resultados inmediatos, como:

* Evaluaciones a gran escala: procesa miles de casos de prueba de manera eficiente.
* Moderación de contenido: analiza grandes volúmenes de contenido generado por usuarios de forma asíncrona.
* Análisis de datos: genera información o resúmenes para grandes conjuntos de datos.
* Generación masiva de contenido: crea grandes cantidades de texto para diversos fines (por ejemplo, descripciones de productos, resúmenes de artículos).

### Limitaciones de los lotes

* Un lote de mensajes está limitado a 100,000 solicitudes de Message o a 256 MB de tamaño, lo que se alcance primero.
* El sistema procesa cada lote lo más rápido posible, y la mayoría de los lotes se completan en 1 hora. Puedes acceder a los resultados del lote cuando todos los mensajes se hayan completado o después de 24 horas, lo que ocurra primero. Los lotes expiran si el procesamiento no se completa en 24 horas.
* Los resultados de los lotes están disponibles durante 29 días después de su creación. Después de eso, aún puedes ver el lote, pero sus resultados ya no están disponibles para descargar.
* Los lotes están limitados a un [Workspace en la Claude Console](https://platform.claude.com/settings/workspaces). Puedes ver todos los lotes (y sus resultados) que se crearon dentro del Workspace en el que se ejecuta tu solicitud.
* Los límites de velocidad se aplican tanto a las solicitudes HTTP de la Batches API como a la cantidad de solicitudes dentro de un lote que esperan ser procesadas. Consulta [Límites de velocidad de la Message Batches API](https://platform.claude.com/docs/es/api/rate-limits#message-batches-api). Además, el procesamiento podría ralentizarse según la demanda actual y tu volumen de solicitudes. En ese caso, es posible que veas más solicitudes que expiran después de 24 horas.
* Debido al alto rendimiento y al procesamiento concurrente, los lotes pueden exceder ligeramente el [límite de gasto](https://platform.claude.com/docs/es/manage-claude/workspaces#setting-workspace-limits) configurado en la Claude Console para tu Workspace.
* Cada solicitud en un lote debe tener un [`max_tokens`](https://platform.claude.com/docs/es/api/messages/create#create.max_tokens) de al menos `1`. `max_tokens: 0` ([precalentamiento de caché](https://platform.claude.com/docs/es/build-with-claude/prompt-caching#pre-warming-the-cache)) no es compatible dentro de un lote, porque una entrada de caché efímera escrita durante el procesamiento por lotes probablemente expiraría antes de que se ejecute la solicitud posterior.

### Modelos compatibles

Todos los [modelos activos](https://platform.claude.com/docs/es/models/overview) son compatibles con la Message Batches API.

### Qué se puede procesar por lotes

Casi cualquier solicitud que puedas hacer a la Messages API puede incluirse en un lote. Esto incluye:

* Visión
* Uso de herramientas, incluidas todas las [herramientas de servidor](https://platform.claude.com/docs/es/agents-and-tools/tool-use/server-tools) (búsqueda web, obtención web, ejecución de código, conectores MCP, asesor y búsqueda de herramientas)
* Mensajes del sistema
* Conversaciones de varios turnos
* Pensamiento extendido
* La mayoría de las funciones beta

Como cada solicitud del lote se procesa de forma independiente, puedes combinar distintos tipos de solicitudes dentro de un mismo lote.

Un pequeño número de parámetros de la Messages API **no** son compatibles en las solicitudes por lotes. Incluir cualquiera de ellos devuelve un error de validación:

| Parámetro                                                                                                                                        | Motivo                                                                                                                                                                                                                                               |
| ------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `stream: true`                                                                                                                                   | Los resultados del lote se devuelven como un único archivo, no como un stream.                                                                                                                                                                       |
| `speed` ([Modo rápido](https://platform.claude.com/docs/es/build-with-claude/fast-mode))                                                         | El modo rápido ajusta la latencia síncrona, lo cual no se aplica al procesamiento asíncrono por lotes.                                                                                                                                               |
| `fallbacks` ([Fallback del lado del servidor](https://platform.claude.com/docs/es/build-with-claude/refusals-and-fallback#server-side-fallback)) | El fallback del lado del servidor no se aplica a los lotes. Para reintentar solicitudes rechazadas, consulta [Rechazos en Message Batches](https://platform.claude.com/docs/es/build-with-claude/refusals-and-fallback#refusals-in-message-batches). |
| `max_tokens: 0`                                                                                                                                  | Consulta [Limitaciones de los lotes](https://platform.claude.com/docs/es/build-with-claude/batch-processing#batch-limitations).                                                                                                                      |

<Tip>
  Como los lotes pueden tardar más de 5 minutos en procesarse, considera usar la [duración de caché de 1 hora](https://platform.claude.com/docs/es/build-with-claude/prompt-caching#1-hour-cache-duration) con el almacenamiento en caché de prompts para obtener mejores tasas de aciertos de caché al procesar lotes con contexto compartido.
</Tip>

## Precios

La Batches API ofrece ahorros de costos significativos. Todo el uso se cobra al 50 por ciento de los precios estándar de la API.

| Model                                                                                                                                                                  | Batch input  | Batch output  |
| :--------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------- | :------------ |
| Claude Fable 5.2                                                                                                                                                       | $4 / MTok    | $20 / MTok    |
| Claude Mythos 5.2 ([limited availability](https://support.claude.com/en/articles/14604842))                                                                            | $4 / MTok    | $20 / MTok    |
| Claude Fable 5.1                                                                                                                                                       | $5 / MTok    | $25 / MTok    |
| Claude Mythos 5.1 ([limited availability](https://support.claude.com/en/articles/14604842))                                                                            | $5 / MTok    | $25 / MTok    |
| Claude Fable 5                                                                                                                                                         | $5 / MTok    | $25 / MTok    |
| Claude Mythos 5 ([limited availability](https://support.claude.com/en/articles/14604842))                                                                              | $5 / MTok    | $25 / MTok    |
| Claude Opus 5.5                                                                                                                                                        | $2 / MTok    | $10 / MTok    |
| Claude Opus 5                                                                                                                                                          | $2.50 / MTok | $12.50 / MTok |
| Claude Opus 4.8                                                                                                                                                        | $2.50 / MTok | $12.50 / MTok |
| Claude Opus 4.7                                                                                                                                                        | $2.50 / MTok | $12.50 / MTok |
| Claude Opus 4.6                                                                                                                                                        | $2.50 / MTok | $12.50 / MTok |
| Claude Opus 4.5                                                                                                                                                        | $2.50 / MTok | $12.50 / MTok |
| Claude Opus 4.1 ([retired, except on Claude Models on Google Cloud (Google managed) and Bedrock](https://platform.claude.com/docs/es/about-claude/model-deprecations)) | $7.50 / MTok | $37.50 / MTok |
| Claude Opus 4 ([retired, except on Claude Models on Google Cloud (Google managed)](https://platform.claude.com/docs/es/about-claude/model-deprecations))               | $7.50 / MTok | $37.50 / MTok |
| Claude Sonnet 5.5                                                                                                                                                      | $1 / MTok    | $5 / MTok     |
| Claude Sonnet 5                                                                                                                                                        | $1 / MTok    | $5 / MTok     |
| Claude Sonnet 4.6                                                                                                                                                      | $1.50 / MTok | $7.50 / MTok  |
| Claude Sonnet 4.5                                                                                                                                                      | $1.50 / MTok | $7.50 / MTok  |
| Claude Sonnet 4 ([retired, except on Claude Models on Google Cloud (Google managed) and Bedrock](https://platform.claude.com/docs/es/about-claude/model-deprecations)) | $1.50 / MTok | $7.50 / MTok  |
| Claude Haiku 5.5 (for prompts up to 100,000 tokens)                                                                                                                    | $0.05 / MTok | $0.25 / MTok  |
| Claude Haiku 5.5 (for prompts over 100,000 tokens)                                                                                                                     | $0.25 / MTok | $1.25 / MTok  |
| Claude Haiku 4.5                                                                                                                                                       | $0.50 / MTok | $2.50 / MTok  |

* **MTok:** Million tokens. $5 / MTok is $5 for every million tokens.
* **Limited access:** Available only to organizations verified through Anthropic’s verification programs, such as the [Cyber Verification Program](https://support.claude.com/en/articles/14604842). To request access, apply to the program that covers your use case.
* **Retired:** May still be available on other cloud platforms. See [Model deprecations](https://platform.claude.com/docs/es/about-claude/model-deprecations) for more.

## Cómo usar la Message Batches API

### Prepara y crea tu lote

Un lote de mensajes se compone de una lista de solicitudes para crear un Message. La estructura de una solicitud individual comprende:

* Un [`custom_id`](https://platform.claude.com/docs/es/api/messages/batches/create#create.requests.custom_id) único para identificar la solicitud de Messages. Debe tener entre 1 y 64 caracteres y contener solo caracteres alfanuméricos, guiones y guiones bajos (que coincidan con `^[a-zA-Z0-9_-]{1,64}$`).
* Un objeto [`params`](https://platform.claude.com/docs/es/api/messages/batches/create#create.requests.params) con los parámetros estándar de la [Messages API](https://platform.claude.com/docs/es/api/messages/create)

Puedes [crear un lote](https://platform.claude.com/docs/es/api/messages/batches/create) pasando esta lista en el parámetro `requests`:

<CodeGroup>
  ```bash cURL
  curl https://api.anthropic.com/v1/messages/batches \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2026-10-21" \
    -H "content-type: application/json" \
    -d '{
      "requests": [
        {
          "custom_id": "my-first-request",
          "params": {
            "model": "claude-opus-5-5",
            "max_tokens": 1024,
            "messages": [
              {"role": "user", "content": "Hello, world"}
            ]
          }
        },
        {
          "custom_id": "my-second-request",
          "params": {
            "model": "claude-opus-5-5",
            "max_tokens": 1024,
            "messages": [
              {"role": "user", "content": "Hi again, friend"}
            ]
          }
        }
      ]
    }'
  ```

  ```bash CLI
  ant messages:batches create <<'YAML'
  requests:
    - custom_id: my-first-request
      params:
        model: claude-opus-5-5
        max_tokens: 1024
        messages:
          - role: user
            content: Hello, world
    - custom_id: my-second-request
      params:
        model: claude-opus-5-5
        max_tokens: 1024
        messages:
          - role: user
            content: Hi again, friend
  YAML
  ```

  ```python Python
  from anthropic.types.message_create_params import MessageCreateParamsNonStreaming
  from anthropic.types.messages.batch_create_params import Request

  client = anthropic.Anthropic()

  message_batch = client.messages.batches.create(
      requests=[
          Request(
              custom_id="my-first-request",
              params=MessageCreateParamsNonStreaming(
                  model="claude-opus-5-5",
                  max_tokens=1024,
                  messages=[
                      {
                          "role": "user",
                          "content": "Hello, world",
                      }
                  ],
              ),
          ),
          Request(
              custom_id="my-second-request",
              params=MessageCreateParamsNonStreaming(
                  model="claude-opus-5-5",
                  max_tokens=1024,
                  messages=[
                      {
                          "role": "user",
                          "content": "Hi again, friend",
                      }
                  ],
              ),
          ),
      ]
  )

  print(message_batch)
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const messageBatch = await client.messages.batches.create({
    requests: [
      {
        custom_id: "my-first-request",
        params: {
          model: "claude-opus-5-5",
          max_tokens: 1024,
          messages: [{ role: "user", content: "Hello, world" }]
        }
      },
      {
        custom_id: "my-second-request",
        params: {
          model: "claude-opus-5-5",
          max_tokens: 1024,
          messages: [{ role: "user", content: "Hi again, friend" }]
        }
      }
    ]
  });

  console.log(messageBatch);
  ```

  ```csharp C#
  using Anthropic;
  using Anthropic.Models.Messages;
  using Anthropic.Models.Messages.Batches;

  AnthropicClient client = new();

  var batch = await client.Messages.Batches.Create(new BatchCreateParams
  {
      Requests =
      [
          new()
          {
              CustomID = "my-first-request",
              Params = new()
              {
                  Model = Model.ClaudeOpus5_5,
                  MaxTokens = 1024,
                  Messages = [new UserMessageParam { Content = "Hello, world" }]
              }
          },
          new()
          {
              CustomID = "my-second-request",
              Params = new()
              {
                  Model = Model.ClaudeOpus5_5,
                  MaxTokens = 1024,
                  Messages = [new UserMessageParam { Content = "Hi again, friend" }]
              }
          }
      ]
  });

  Console.WriteLine(batch);
  ```

  ```go Go
  client := anthropic.NewClient()

  batch, _ := client.Messages.Batches.New(context.Background(),
  	anthropic.MessageBatchNewParams{
  		Requests: []anthropic.MessageBatchNewParamsRequest{
  			{
  				CustomID: "my-first-request",
  				Params: anthropic.MessageBatchNewParamsRequestParams{
  					Model:     anthropic.ModelClaudeOpus5_5,
  					MaxTokens: 1024,
  					Messages: []anthropic.MessageParam{
  						anthropic.NewUserMessage(
  							anthropic.NewTextBlock("Hello, world"),
  						),
  					},
  				},
  			},
  			{
  				CustomID: "my-second-request",
  				Params: anthropic.MessageBatchNewParamsRequestParams{
  					Model:     anthropic.ModelClaudeOpus5_5,
  					MaxTokens: 1024,
  					Messages: []anthropic.MessageParam{
  						anthropic.NewUserMessage(
  							anthropic.NewTextBlock("Hi again, friend"),
  						),
  					},
  				},
  			},
  		},
  	})

  fmt.Println(batch.ID)
  ```

  ```java Java
  AnthropicClient client = AnthropicOkHttpClient.fromEnv();

  BatchCreateParams params = BatchCreateParams.builder()
      .addRequest(
          BatchCreateParams.Request.builder()
              .customId("my-first-request")
              .params(
                  BatchCreateParams.Request.Params.builder()
                      .model(Model.CLAUDE_OPUS_5_5)
                      .maxTokens(1024)
                      .addUserMessage("Hello, world")
                      .build()
              )
              .build()
      )
      .addRequest(
          BatchCreateParams.Request.builder()
              .customId("my-second-request")
              .params(
                  BatchCreateParams.Request.Params.builder()
                      .model(Model.CLAUDE_OPUS_5_5)
                      .maxTokens(1024)
                      .addUserMessage("Hi again, friend")
                      .build()
              )
              .build()
      )
      .build();

  MessageBatch messageBatch = client.messages().batches().create(params);

  System.out.println(messageBatch);
  ```

  ```php PHP
  $client = new Client();

  $batch = $client->messages->batches->create(
      requests: [
          [
              'custom_id' => 'my-first-request',
              'params' => [
                  'model' => 'claude-opus-5-5',
                  'max_tokens' => 1024,
                  'messages' => [
                      ['role' => 'user', 'content' => 'Hello, world']
                  ]
              ]
          ],
          [
              'custom_id' => 'my-second-request',
              'params' => [
                  'model' => 'claude-opus-5-5',
                  'max_tokens' => 1024,
                  'messages' => [
                      ['role' => 'user', 'content' => 'Hi again, friend']
                  ]
              ]
          ]
      ],
  );

  echo $batch->id;
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  batch = client.messages.batches.create(
    requests: [
      {
        custom_id: "my-first-request",
        params: {
          model: Anthropic::Model::CLAUDE_OPUS_5_5,
          max_tokens: 1024,
          messages: [
            { role: "user", content: "Hello, world" }
          ]
        }
      },
      {
        custom_id: "my-second-request",
        params: {
          model: Anthropic::Model::CLAUDE_OPUS_5_5,
          max_tokens: 1024,
          messages: [
            { role: "user", content: "Hi again, friend" }
          ]
        }
      }
    ]
  )

  puts batch
  ```
</CodeGroup>

En este ejemplo, dos solicitudes separadas se agrupan en un lote para su procesamiento asíncrono. Cada solicitud tiene un `custom_id` único y contiene los parámetros estándar que usarías para una llamada a la Messages API.

<Tip>
  **Prueba tus solicitudes por lotes con la Messages API**

  La API valida el objeto `params` de cada solicitud de mensaje de forma asíncrona, y devuelve los errores de validación cuando ha terminado el procesamiento de todo el lote. Para comprobar que construyes tu entrada correctamente, verifica primero la estructura de tu solicitud con la [Messages API](https://platform.claude.com/docs/es/api/messages/create).
</Tip>

Cuando se crea un lote por primera vez, la respuesta tiene un estado de procesamiento `in_progress`.

```json Output
{
  "id": "msgbatch_01HkcTjaV5uDC8jWR4ZsDV8d",
  "type": "message_batch",
  "processing_status": "in_progress",
  "request_counts": {
    "processing": 2,
    "succeeded": 0,
    "errored": 0,
    "canceled": 0,
    "expired": 0
  },
  "ended_at": null,
  "created_at": "2024-09-24T18:37:24.100435Z",
  "expires_at": "2024-09-25T18:37:24.100435Z",
  "cancel_initiated_at": null,
  "results_url": null
}
```

### Seguimiento de tu lote

El campo [`processing_status`](https://platform.claude.com/docs/es/api/messages/batches/retrieve#message_batch.processing_status) del lote de mensajes indica la etapa de procesamiento en la que se encuentra el lote. Comienza como `in_progress` y luego se actualiza a `ended` una vez que todas las solicitudes del lote han terminado de procesarse y los resultados están listos. Puedes supervisar el estado de tu lote visitando la [Console](https://platform.claude.com/settings/workspaces/default/batches) o usando el endpoint de recuperación.

(See the `messages/batches/retrieve` method in [the API reference](https://platform.claude.com/docs/es/api/messages/batches/retrieve).)

#### Sondeo para verificar la finalización del lote de mensajes

Para sondear un lote de mensajes, necesitarás su `id`, que se proporciona en la respuesta al crear un lote o al listar los lotes. Puedes implementar un bucle de sondeo que verifique el estado del lote periódicamente hasta que el procesamiento haya terminado:

<CodeGroup>
  ```bash cURL
  # Verifica el estado; repite hasta que processing_status sea "ended"
  curl "https://api.anthropic.com/v1/messages/batches/$MESSAGE_BATCH_ID" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2026-10-21"
  ```

  ```bash CLI
  # Verifica el estado; repite hasta que processing_status sea "ended"
  ant messages:batches retrieve --message-batch-id "$MESSAGE_BATCH_ID"
  ```

  ```python Python
  import time

  client = anthropic.Anthropic()

  MESSAGE_BATCH_ID = "msgbatch_01HkcTjaV5uDC8jWR4ZsDV8d"

  message_batch = None
  while True:
      message_batch = client.messages.batches.retrieve(MESSAGE_BATCH_ID)
      if message_batch.processing_status == "ended":
          break

      print(f"Batch {MESSAGE_BATCH_ID} is still processing...")
      time.sleep(60)
  print(message_batch)
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const messageBatchId = "msgbatch_01HkcTjaV5uDC8jWR4ZsDV8d";

  let messageBatch;
  while (true) {
    messageBatch = await client.messages.batches.retrieve(messageBatchId);
    if (messageBatch.processing_status === "ended") {
      break;
    }

    console.log(`Batch ${messageBatchId} is still processing... waiting`);
    await new Promise((resolve) => setTimeout(resolve, 60_000));
  }
  console.log(messageBatch);
  ```

  ```csharp C#
  AnthropicClient client = new();
  string messageBatchId = Environment.GetEnvironmentVariable("MESSAGE_BATCH_ID");

  MessageBatch messageBatch = null;
  while (true)
  {
      messageBatch = await client.Messages.Batches.Retrieve(messageBatchId);
      if (messageBatch.ProcessingStatus == "ended")
      {
          break;
      }

      Console.WriteLine($"Batch {messageBatchId} is still processing...");
      await Task.Delay(60000);
  }
  Console.WriteLine(messageBatch);
  ```

  ```go Go
  client := anthropic.NewClient()
  messageBatchID := os.Getenv("MESSAGE_BATCH_ID")

  var messageBatch *anthropic.MessageBatch
  for {
  	var err error
  	messageBatch, err = client.Messages.Batches.Get(context.TODO(), messageBatchID, anthropic.MessageBatchGetParams{})
  	if err != nil {
  		log.Fatal(err)
  	}
  	if messageBatch.ProcessingStatus == "ended" {
  		break
  	}

  	fmt.Printf("Batch %s is still processing...\n", messageBatchID)
  	time.Sleep(60 * time.Second)
  }
  fmt.Println(messageBatch)
  ```

  ```java Java
  import com.anthropic.models.messages.batches.MessageBatch;
  // ...
          AnthropicClient client = AnthropicOkHttpClient.fromEnv();
          String messageBatchId = "msgbatch_01HkcTjaV5uDC8jWR4ZsDV8d";

          MessageBatch messageBatch = null;
          while (true) {
              messageBatch = client.messages().batches().retrieve(messageBatchId);
              if (messageBatch.processingStatus().equals(MessageBatch.ProcessingStatus.ENDED)) {
                  break;
              }

              System.out.println("Batch " + messageBatchId + " is still processing...");
              Thread.sleep(60000);
          }
          System.out.println(messageBatch);
  ```

  ```php PHP
  $client = new Client();
  $messageBatchId = getenv('MESSAGE_BATCH_ID');

  $messageBatch = null;
  while (true) {
      $messageBatch = $client->messages->batches->retrieve(
          messageBatchID: $messageBatchId,
      );
      if ($messageBatch->processingStatus === 'ended') {
          break;
      }

      echo "Batch {$messageBatchId} is still processing...\n";
      sleep(60);
  }
  echo json_encode($messageBatch, JSON_PRETTY_PRINT);
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  message_batch_id = ENV["MESSAGE_BATCH_ID"]
  message_batch = nil
  loop do
    message_batch = client.messages.batches.retrieve(message_batch_id)
    break if message_batch.processing_status == :ended

    puts "Batch #{message_batch_id} is still processing..."
    sleep 60
  end
  puts message_batch
  ```
</CodeGroup>

### Listar todos los lotes de mensajes

Puedes listar todos los lotes de mensajes de tu Workspace usando el [endpoint de listado](https://platform.claude.com/docs/es/api/messages/batches/list). Los resultados están paginados. El SDK obtiene páginas adicionales según sea necesario:

<CodeGroup>
  ```bash cURL
  # Obtiene una página. Mientras has_more de la respuesta sea true, pasa su
  # last_id como after_id para obtener la siguiente página. (Los SDK y la CLI
  # realizan la paginación automáticamente.)
  curl -s "https://api.anthropic.com/v1/messages/batches?limit=20" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2026-10-21"
  ```

  ```bash CLI
  # Obtiene automáticamente más páginas según sea necesario
  ant messages:batches list --limit 20
  ```

  ```python Python
  client = anthropic.Anthropic()

  # Obtiene automáticamente más páginas según sea necesario.
  for message_batch in client.messages.batches.list(limit=20):
      print(message_batch)
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  // Obtiene automáticamente más páginas según sea necesario.
  for await (const messageBatch of client.messages.batches.list({
    limit: 20
  })) {
    console.log(messageBatch);
  }
  ```

  ```csharp C#
  AnthropicClient client = new();

  var parameters = new BatchListParams
  {
      Limit = 20
  };

  // Obtiene automáticamente más páginas según sea necesario
  var page = await client.Messages.Batches.List(parameters);
  await foreach (var messageBatch in page.Paginate())
  {
      Console.WriteLine(messageBatch);
  }
  ```

  ```go Go
  client := anthropic.NewClient()

  // Obtiene automáticamente más páginas según sea necesario
  iter := client.Messages.Batches.ListAutoPaging(context.TODO(), anthropic.MessageBatchListParams{
  	Limit: anthropic.Int(20),
  })

  for iter.Next() {
  	messageBatch := iter.Current()
  	fmt.Println(messageBatch)
  }

  if err := iter.Err(); err != nil {
  	log.Fatal(err)
  }
  ```

  ```java Java
  AnthropicClient client = AnthropicOkHttpClient.fromEnv();

  // Obtiene automáticamente más páginas según sea necesario
  for (MessageBatch messageBatch : client
      .messages()
      .batches()
      .list(BatchListParams.builder()
          .limit(20)
          .build())
      .autoPager()) {
      System.out.println(messageBatch);
  }
  ```

  ```php PHP
  $client = new Client();

  // Obtiene automáticamente más páginas según sea necesario
  foreach ($client->messages->batches->list(limit: 20)->pagingEachItem() as $messageBatch) {
      echo $messageBatch->id . "\n";
  }
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  # Obtiene automáticamente más páginas según sea necesario
  client.messages.batches.list(limit: 20).auto_paging_each do |message_batch|
    puts message_batch
  end
  ```
</CodeGroup>

### Recuperar los resultados del lote

Una vez que ha terminado el procesamiento del lote, cada solicitud de Messages del lote tiene un resultado. Hay cuatro tipos de resultado:

| Tipo de resultado | Descripción                                                                                                                                                                         |
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `succeeded`       | La solicitud fue exitosa. Incluye el resultado del mensaje.                                                                                                                         |
| `errored`         | La solicitud encontró un error y no se creó un mensaje. Los posibles errores incluyen solicitudes no válidas y errores internos del servidor. No se te cobra por estas solicitudes. |
| `canceled`        | El usuario canceló el lote antes de que esta solicitud pudiera enviarse al modelo. No se te cobra por estas solicitudes.                                                            |
| `expired`         | El lote alcanzó su expiración de 24 horas antes de que esta solicitud pudiera enviarse al modelo. No se te cobra por estas solicitudes.                                             |

El objeto `request_counts` del lote cuenta las solicitudes que aún se están procesando y las solicitudes con cada tipo de resultado.

(See `message_batch.request_counts` on `messages/batches/retrieve` in [the API reference](https://platform.claude.com/docs/es/api/messages/batches/retrieve#message_batch.request_counts).)

Los resultados del lote están disponibles para descargar en la propiedad [`results_url`](https://platform.claude.com/docs/es/api/messages/batches/retrieve#message_batch.results_url) del lote de mensajes y, si los permisos de tu organización lo permiten, en la Console. Como los resultados pueden ser grandes, [recibe los resultados mediante streaming](https://platform.claude.com/docs/es/api/messages/batches/results) en lugar de descargarlos todos a la vez.

<CodeGroup>
  ```bash cURL
  # Hace streaming de los resultados .jsonl del lote, un resultado por línea.
  # Para manejar cada resultado (reintentos, errores de validación), usa el Anthropic SDK.
  curl "https://api.anthropic.com/v1/messages/batches/msgbatch_01HkcTjaV5uDC8jWR4ZsDV8d/results" \
    -H "anthropic-version: 2026-10-21" \
    -H "x-api-key: $ANTHROPIC_API_KEY"
  ```

  ```bash CLI
  # Imprime un resultado por línea, por ejemplo `{"custom_id":"test-1","result":{"type":"succeeded",…}}`.
  # Para gestionar cada resultado (reintentos, errores de validación), usa los ejemplos
  # del Anthropic SDK en las otras pestañas.
  ant messages:batches results \
    --message-batch-id msgbatch_01HkcTjaV5uDC8jWR4ZsDV8d \
    --format jsonl
  ```

  ```python Python
  client = anthropic.Anthropic()

  # Haz streaming del archivo de resultados en fragmentos eficientes en memoria, procesando uno a la vez
  for result in client.messages.batches.results(
      "msgbatch_01HkcTjaV5uDC8jWR4ZsDV8d",
  ):
      outcome = result.result
      match outcome.type:
          case "succeeded":
              print(f"Success! {result.custom_id}")
          case "errored":
              if outcome.error.error.type == "invalid_request_error":
                  # El cuerpo de la solicitud debe corregirse antes de reenviar la solicitud
                  print(f"Validation error {result.custom_id}")
              else:
                  # La solicitud se puede reintentar directamente
                  print(f"Server error {result.custom_id}")
          case "expired":
              print(f"Request expired {result.custom_id}")
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  // Procesa el archivo de resultados por streaming en fragmentos eficientes en memoria, uno a la vez
  for await (const result of await client.messages.batches.results(
    "msgbatch_01HkcTjaV5uDC8jWR4ZsDV8d"
  )) {
    switch (result.result.type) {
      case "succeeded":
        console.log(`Success! ${result.custom_id}`);
        break;
      case "errored":
        if (result.result.error.error.type === "invalid_request_error") {
          // El cuerpo de la solicitud debe corregirse antes de reenviarla
          console.log(`Validation error: ${result.custom_id}`);
        } else {
          // La solicitud se puede reintentar directamente
          console.log(`Server error: ${result.custom_id}`);
        }
        break;
      case "expired":
        console.log(`Request expired: ${result.custom_id}`);
        break;
    }
  }
  ```

  ```csharp C#
  AnthropicClient client = new();

  await foreach (var result in client.Messages.Batches.ResultsStreaming("msgbatch_01HkcTjaV5uDC8jWR4ZsDV8d"))
  {
      switch (result.Result.Type.Raw())
      {
          case "succeeded":
              Console.WriteLine($"Success! {result.CustomID}");
              break;
          case "errored":
              if (result.Result.TryPickErrored(out var errored)
                  && errored.Error.Error.Type.Raw() == "invalid_request_error")
              {
                  Console.WriteLine($"Validation error: {result.CustomID}");
              }
              else
              {
                  Console.WriteLine($"Server error: {result.CustomID}");
              }
              break;
          case "expired":
              Console.WriteLine($"Request expired: {result.CustomID}");
              break;
      }
  }
  ```

  ```go Go
  client := anthropic.NewClient()

  stream := client.Messages.Batches.ResultsStreaming(context.TODO(), "msgbatch_01HkcTjaV5uDC8jWR4ZsDV8d", anthropic.MessageBatchResultsParams{})

  for stream.Next() {
  	result := stream.Current()

  	switch variant := result.Result.AsAny().(type) {
  	case anthropic.MessageBatchSucceededResult:
  		fmt.Printf("Success! %s\n", result.CustomID)
  	case anthropic.MessageBatchErroredResult:
  		fmt.Printf("Error: %s - %s\n", result.CustomID, variant.Error.Error.Message)
  	case anthropic.MessageBatchExpiredResult:
  		fmt.Printf("Request expired: %s\n", result.CustomID)
  	}
  }

  if err := stream.Err(); err != nil {
  	log.Fatal(err)
  }
  ```

  ```java Java
  import com.anthropic.core.http.StreamResponse;
  import com.anthropic.models.messages.batches.BatchResultsParams;
  import com.anthropic.models.messages.batches.MessageBatchIndividualResponse;
  // ...
          AnthropicClient client = AnthropicOkHttpClient.fromEnv();

          // Haz streaming del archivo de resultados en fragmentos eficientes en memoria, procesando uno a la vez
          try (
              StreamResponse<MessageBatchIndividualResponse> streamResponse = client
                  .messages()
                  .batches()
                  .resultsStreaming(
                      BatchResultsParams.builder()
                          .messageBatchId("msgbatch_01HkcTjaV5uDC8jWR4ZsDV8d")
                          .build()
                  )
          ) {
              streamResponse
                  .stream()
                  .forEach(result -> {
                      switch (result.result().type().value()) {
                          case SUCCEEDED -> System.out.println("Success! " + result.customId());
                          case ERRORED -> {
                              if (result.result().asErrored().error().error().isInvalidRequestError()) {
                                  // El cuerpo de la solicitud debe corregirse antes de reenviar la solicitud
                                  System.out.println("Validation error: " + result.customId());
                              } else {
                                  // La solicitud se puede reintentar directamente
                                  System.out.println("Server error: " + result.customId());
                              }
                          }
                          case EXPIRED -> System.out.println("Request expired: " + result.customId());
                      }
                  });
          }
  ```

  ```php PHP
  use Anthropic\Messages\Batches\MessageBatchErroredResult;
  use Anthropic\Messages\Batches\MessageBatchExpiredResult;
  use Anthropic\Messages\Batches\MessageBatchSucceededResult;

  $client = new Client();

  foreach ($client->messages->batches->resultsStream(messageBatchID: 'msgbatch_01HkcTjaV5uDC8jWR4ZsDV8d') as $result) {
      switch (true) {
          case $result->result instanceof MessageBatchSucceededResult:
              echo "Success! {$result->customID}\n";
              break;
          case $result->result instanceof MessageBatchErroredResult:
              if ($result->result->error->error->type === 'invalid_request_error') {
                  echo "Validation error: {$result->customID}\n";
              } else {
                  echo "Server error: {$result->customID}\n";
              }
              break;
          case $result->result instanceof MessageBatchExpiredResult:
              echo "Request expired: {$result->customID}\n";
              break;
      }
  }
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  client.messages.batches.results_streaming("msgbatch_01HkcTjaV5uDC8jWR4ZsDV8d").each do |result|
    outcome = result.result
    case outcome
    when Anthropic::Models::Messages::MessageBatchSucceededResult
      puts "Success! #{result.custom_id}"
    when Anthropic::Models::Messages::MessageBatchErroredResult
      if outcome.error.error.type == :invalid_request_error
        puts "Validation error: #{result.custom_id}"
      else
        puts "Server error: #{result.custom_id}"
      end
    when Anthropic::Models::Messages::MessageBatchExpiredResult
      puts "Request expired: #{result.custom_id}"
    end
  end
  ```
</CodeGroup>

Los resultados están en formato `.jsonl`, donde cada línea es un objeto JSON válido que representa el resultado de una única solicitud del lote de mensajes. Para cada resultado recibido por streaming, puedes hacer algo diferente según su `custom_id` y su tipo de resultado. Este es un conjunto de resultados de ejemplo:

```jsonl .jsonl file
{"custom_id":"my-second-request","result":{"type":"succeeded","message":{"id":"msg_014VwiXbi91y3JMjcpyGBHX5","type":"message","role":"assistant","model":"claude-opus-5-5","content":[{"type":"text","text":"Hello again! It's nice to see you. How can I assist you today? Is there anything specific you'd like to chat about or any questions you have?"}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":11,"output_tokens":36}}}}
{"custom_id":"my-first-request","result":{"type":"succeeded","message":{"id":"msg_01FqfsLoHwgeFbguDgpz48m7","type":"message","role":"assistant","model":"claude-opus-5-5","content":[{"type":"text","text":"Hello! How can I assist you today? Feel free to ask me any questions or let me know if there's anything you'd like to chat about."}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":10,"output_tokens":34}}}}
```

Si tu resultado tiene un error, su `result.error` se establecerá en la [estructura de error](https://platform.claude.com/docs/es/api/errors#error-shapes) estándar.

Los resultados del lote usan la versión de la API de la solicitud que creó el lote.

<Tip>
  **Los resultados del lote podrían no coincidir con el orden de entrada**

  Los resultados del lote pueden devolverse en cualquier orden y podrían no coincidir con el orden de las solicitudes cuando se creó el lote. En el ejemplo anterior, el resultado de la segunda solicitud del lote se devuelve antes que el de la primera. Para hacer coincidir correctamente los resultados con sus solicitudes correspondientes, usa siempre el campo `custom_id`.
</Tip>

### Cancelar un lote de mensajes

Puedes cancelar un lote de mensajes que se esté procesando actualmente usando el [endpoint de cancelación](https://platform.claude.com/docs/es/api/messages/batches/cancel). Inmediatamente después de la cancelación, el `processing_status` de un lote es `canceling`. Puedes usar la misma técnica de sondeo descrita anteriormente para esperar hasta que la cancelación finalice. Los lotes cancelados terminan con un estado `ended` y podrían contener resultados parciales de las solicitudes que se procesaron antes de la cancelación.

<CodeGroup>
  ```bash cURL
  curl -X POST https://api.anthropic.com/v1/messages/batches/$MESSAGE_BATCH_ID/cancel \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2026-10-21"
  ```

  ```bash CLI
  ant messages:batches cancel --message-batch-id "$MESSAGE_BATCH_ID"
  ```

  ```python Python
  client = anthropic.Anthropic()

  MESSAGE_BATCH_ID = "msgbatch_01HkcTjaV5uDC8jWR4ZsDV8d"

  message_batch = client.messages.batches.cancel(
      MESSAGE_BATCH_ID,
  )
  print(message_batch)
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const messageBatch = await client.messages.batches.cancel(MESSAGE_BATCH_ID);
  console.log(messageBatch);
  ```

  ```csharp C#
  AnthropicClient client = new();
  string messageBatchId = Environment.GetEnvironmentVariable("MESSAGE_BATCH_ID");

  var messageBatch = await client.Messages.Batches.Cancel(messageBatchId);
  Console.WriteLine(messageBatch);
  ```

  ```go Go
  client := anthropic.NewClient()
  messageBatchID := os.Getenv("MESSAGE_BATCH_ID")

  messageBatch, err := client.Messages.Batches.Cancel(context.TODO(), messageBatchID, anthropic.MessageBatchCancelParams{})
  if err != nil {
  	log.Fatal(err)
  }
  fmt.Println(messageBatch)
  ```

  ```java Java
  import com.anthropic.models.messages.batches.*;
  // ...
          AnthropicClient client = AnthropicOkHttpClient.fromEnv();

          MessageBatch messageBatch = client
              .messages()
              .batches()
              .cancel("msgbatch_01HkcTjaV5uDC8jWR4ZsDV8d");
          System.out.println(messageBatch);
  ```

  ```php PHP
  $client = new Client();

  $messageBatch = $client->messages->batches->cancel(
      messageBatchID: 'msgbatch_example_id',
  );
  echo $messageBatch;
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  message_batch_id = ENV.fetch("MESSAGE_BATCH_ID")
  message_batch = client.messages.batches.cancel(message_batch_id)
  puts message_batch
  ```
</CodeGroup>

La respuesta muestra el lote en estado `canceling`:

```json Output
{
  "id": "msgbatch_013Zva2CMHLNnXjNJJKqJ2EF",
  "type": "message_batch",
  "processing_status": "canceling",
  "request_counts": {
    "processing": 2,
    "succeeded": 0,
    "errored": 0,
    "canceled": 0,
    "expired": 0
  },
  "ended_at": null,
  "created_at": "2024-09-24T18:37:24.100435Z",
  "expires_at": "2024-09-25T18:37:24.100435Z",
  "cancel_initiated_at": "2024-09-24T18:39:03.114875Z",
  "results_url": null
}
```

### Usar el almacenamiento en caché de prompts con Message Batches

La Message Batches API admite el “prompt caching” (almacenamiento en caché de prompts), lo que te permite reducir potencialmente los costos y el tiempo de procesamiento de las solicitudes por lotes. Los descuentos de precios del almacenamiento en caché de prompts y de Message Batches pueden acumularse, lo que proporciona un ahorro de costos aún mayor cuando ambas funciones se usan juntas. Sin embargo, como las solicitudes por lotes se procesan de forma asíncrona y concurrente, los aciertos de caché se proporcionan en la medida de lo posible. Los usuarios suelen experimentar tasas de aciertos de caché que van del 30 por ciento al 98 por ciento, según sus patrones de tráfico.

Para maximizar la probabilidad de aciertos de caché en tus solicitudes por lotes:

1. Incluye bloques `cache_control` idénticos en cada solicitud de Message dentro de tu lote.
2. Mantén un flujo constante de solicitudes para evitar que las entradas de caché expiren después de su vida útil de 5 minutos.
3. Estructura tus solicitudes para compartir la mayor cantidad posible de contenido almacenado en caché.

Ejemplo de implementación del almacenamiento en caché de prompts en un lote:

<CodeGroup>
  ```bash cURL
  curl https://api.anthropic.com/v1/messages/batches \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2026-10-21" \
    -H "content-type: application/json" \
    -d '{
      "requests": [
        {
          "custom_id": "my-first-request",
          "params": {
            "model": "claude-opus-5-5",
            "max_tokens": 1024,
            "system": [
              {
                "type": "text",
                "text": "You are an AI assistant tasked with analyzing literary works. Your goal is to provide insightful commentary on themes, characters, and writing style.\n"
              },
              {
                "type": "text",
                "text": "<the entire contents of Pride and Prejudice>",
                "cache_control": {"type": "ephemeral"}
              }
            ],
            "messages": [
              {"role": "user", "content": "Analyze the major themes in Pride and Prejudice."}
            ]
          }
        },
        {
          "custom_id": "my-second-request",
          "params": {
            "model": "claude-opus-5-5",
            "max_tokens": 1024,
            "system": [
              {
                "type": "text",
                "text": "You are an AI assistant tasked with analyzing literary works. Your goal is to provide insightful commentary on themes, characters, and writing style.\n"
              },
              {
                "type": "text",
                "text": "<the entire contents of Pride and Prejudice>",
                "cache_control": {"type": "ephemeral"}
              }
            ],
            "messages": [
              {"role": "user", "content": "Write a summary of Pride and Prejudice."}
            ]
          }
        }
      ]
    }'
  ```

  ```bash CLI
  ant messages:batches create <<'YAML'
  requests:
    - custom_id: my-first-request
      params:
        model: claude-opus-5-5
        max_tokens: 1024
        system:
          - type: text
            text: >
              You are an AI assistant tasked with analyzing literary works. Your
              goal is to provide insightful commentary on themes, characters, and
              writing style.
          - type: text
            text: "<the entire contents of Pride and Prejudice>"
            cache_control:
              type: ephemeral
        messages:
          - role: user
            content: Analyze the major themes in Pride and Prejudice.
    - custom_id: my-second-request
      params:
        model: claude-opus-5-5
        max_tokens: 1024
        system:
          - type: text
            text: >
              You are an AI assistant tasked with analyzing literary works. Your
              goal is to provide insightful commentary on themes, characters, and
              writing style.
          - type: text
            text: "<the entire contents of Pride and Prejudice>"
            cache_control:
              type: ephemeral
        messages:
          - role: user
            content: Write a summary of Pride and Prejudice.
  YAML
  ```

  ```python Python
  from anthropic.types.message_create_params import MessageCreateParamsNonStreaming
  from anthropic.types.messages.batch_create_params import Request

  client = anthropic.Anthropic()

  message_batch = client.messages.batches.create(
      requests=[
          Request(
              custom_id="my-first-request",
              params=MessageCreateParamsNonStreaming(
                  model="claude-opus-5-5",
                  max_tokens=1024,
                  system=[
                      {
                          "type": "text",
                          "text": "You are an AI assistant tasked with analyzing literary works. Your goal is to provide insightful commentary on themes, characters, and writing style.\n",
                      },
                      {
                          "type": "text",
                          "text": "<the entire contents of Pride and Prejudice>",
                          "cache_control": {"type": "ephemeral"},
                      },
                  ],
                  messages=[
                      {
                          "role": "user",
                          "content": "Analyze the major themes in Pride and Prejudice.",
                      }
                  ],
              ),
          ),
          Request(
              custom_id="my-second-request",
              params=MessageCreateParamsNonStreaming(
                  model="claude-opus-5-5",
                  max_tokens=1024,
                  system=[
                      {
                          "type": "text",
                          "text": "You are an AI assistant tasked with analyzing literary works. Your goal is to provide insightful commentary on themes, characters, and writing style.\n",
                      },
                      {
                          "type": "text",
                          "text": "<the entire contents of Pride and Prejudice>",
                          "cache_control": {"type": "ephemeral"},
                      },
                  ],
                  messages=[
                      {
                          "role": "user",
                          "content": "Write a summary of Pride and Prejudice.",
                      }
                  ],
              ),
          ),
      ]
  )
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const messageBatch = await client.messages.batches.create({
    requests: [
      {
        custom_id: "my-first-request",
        params: {
          model: "claude-opus-5-5",
          max_tokens: 1024,
          system: [
            {
              type: "text",
              text: "You are an AI assistant tasked with analyzing literary works. Your goal is to provide insightful commentary on themes, characters, and writing style.\n"
            },
            {
              type: "text",
              text: "<the entire contents of Pride and Prejudice>",
              cache_control: { type: "ephemeral" }
            }
          ],
          messages: [
            { role: "user", content: "Analyze the major themes in Pride and Prejudice." }
          ]
        }
      },
      {
        custom_id: "my-second-request",
        params: {
          model: "claude-opus-5-5",
          max_tokens: 1024,
          system: [
            {
              type: "text",
              text: "You are an AI assistant tasked with analyzing literary works. Your goal is to provide insightful commentary on themes, characters, and writing style.\n"
            },
            {
              type: "text",
              text: "<the entire contents of Pride and Prejudice>",
              cache_control: { type: "ephemeral" }
            }
          ],
          messages: [{ role: "user", content: "Write a summary of Pride and Prejudice." }]
        }
      }
    ]
  });
  ```

  ```csharp C#
  using Anthropic;
  using Anthropic.Models.Messages;
  using Anthropic.Models.Messages.Batches;

  AnthropicClient client = new()
  {
      ApiKey = Environment.GetEnvironmentVariable("ANTHROPIC_API_KEY")
  };

  var messageBatch = await client.Messages.Batches.Create(new BatchCreateParams
  {
      Requests =
      [
          new()
          {
              CustomID = "my-first-request",
              Params = new()
              {
                  Model = Model.ClaudeOpus5_5,
                  MaxTokens = 1024,
                  System = new List<TextBlockParam>
                  {
                      new()
                      {
                          Text = "You are an AI assistant tasked with analyzing literary works. Your goal is to provide insightful commentary on themes, characters, and writing style.\n"
                      },
                      new()
                      {
                          Text = "<the entire contents of Pride and Prejudice>",
                          CacheControl = new()
                      }
                  },
                  Messages =
                  [
                      new UserMessageParam { Content = "Analyze the major themes in Pride and Prejudice." }
                  ]
              }
          },
          new()
          {
              CustomID = "my-second-request",
              Params = new()
              {
                  Model = Model.ClaudeOpus5_5,
                  MaxTokens = 1024,
                  System = new List<TextBlockParam>
                  {
                      new()
                      {
                          Text = "You are an AI assistant tasked with analyzing literary works. Your goal is to provide insightful commentary on themes, characters, and writing style.\n"
                      },
                      new()
                      {
                          Text = "<the entire contents of Pride and Prejudice>",
                          CacheControl = new()
                      }
                  },
                  Messages =
                  [
                      new UserMessageParam { Content = "Write a summary of Pride and Prejudice." }
                  ]
              }
          }
      ]
  });
  ```

  ```go Go
  client := anthropic.NewClient()

  messageBatch, err := client.Messages.Batches.New(context.TODO(), anthropic.MessageBatchNewParams{
  	Requests: []anthropic.MessageBatchNewParamsRequest{
  		{
  			CustomID: "my-first-request",
  			Params: anthropic.MessageBatchNewParamsRequestParams{
  				Model:     anthropic.ModelClaudeOpus5_5,
  				MaxTokens: 1024,
  				System: []anthropic.TextBlockParam{
  					{
  						Text: "You are an AI assistant tasked with analyzing literary works. Your goal is to provide insightful commentary on themes, characters, and writing style.\n",
  					},
  					{
  						Text:         "<the entire contents of Pride and Prejudice>",
  						CacheControl: anthropic.NewCacheControlEphemeralParam(),
  					},
  				},
  				Messages: []anthropic.MessageParam{
  					anthropic.NewUserMessage(anthropic.NewTextBlock("Analyze the major themes in Pride and Prejudice.")),
  				},
  			},
  		},
  		{
  			CustomID: "my-second-request",
  			Params: anthropic.MessageBatchNewParamsRequestParams{
  				Model:     anthropic.ModelClaudeOpus5_5,
  				MaxTokens: 1024,
  				System: []anthropic.TextBlockParam{
  					{
  						Text: "You are an AI assistant tasked with analyzing literary works. Your goal is to provide insightful commentary on themes, characters, and writing style.\n",
  					},
  					{
  						Text:         "<the entire contents of Pride and Prejudice>",
  						CacheControl: anthropic.NewCacheControlEphemeralParam(),
  					},
  				},
  				Messages: []anthropic.MessageParam{
  					anthropic.NewUserMessage(anthropic.NewTextBlock("Write a summary of Pride and Prejudice.")),
  				},
  			},
  		},
  	},
  })
  if err != nil {
  	log.Fatal(err)
  }
  fmt.Println(messageBatch)
  ```

  ```java Java
  import com.anthropic.models.messages.CacheControlEphemeral;
  // ...
  import com.anthropic.models.messages.batches.*;
  // ...
          AnthropicClient client = AnthropicOkHttpClient.fromEnv();

          BatchCreateParams createParams = BatchCreateParams.builder()
              .addRequest(
                  BatchCreateParams.Request.builder()
                      .customId("my-first-request")
                      .params(
                          BatchCreateParams.Request.Params.builder()
                              .model(Model.CLAUDE_OPUS_5_5)
                              .maxTokens(1024)
                              .systemOfTextBlockParams(
                                  List.of(
                                      TextBlockParam.builder()
                                          .text(
                                              "You are an AI assistant tasked with analyzing literary works. Your goal is to provide insightful commentary on themes, characters, and writing style.\n"
                                          )
                                          .build(),
                                      TextBlockParam.builder()
                                          .text("<the entire contents of Pride and Prejudice>")
                                          .cacheControl(CacheControlEphemeral.builder().build())
                                          .build()
                                  )
                              )
                              .addUserMessage("Analyze the major themes in Pride and Prejudice.")
                              .build()
                      )
                      .build()
              )
              .addRequest(
                  BatchCreateParams.Request.builder()
                      .customId("my-second-request")
                      .params(
                          BatchCreateParams.Request.Params.builder()
                              .model(Model.CLAUDE_OPUS_5_5)
                              .maxTokens(1024)
                              .systemOfTextBlockParams(
                                  List.of(
                                      TextBlockParam.builder()
                                          .text(
                                              "You are an AI assistant tasked with analyzing literary works. Your goal is to provide insightful commentary on themes, characters, and writing style.\n"
                                          )
                                          .build(),
                                      TextBlockParam.builder()
                                          .text("<the entire contents of Pride and Prejudice>")
                                          .cacheControl(CacheControlEphemeral.builder().build())
                                          .build()
                                  )
                              )
                              .addUserMessage("Write a summary of Pride and Prejudice.")
                              .build()
                      )
                      .build()
              )
              .build();

          MessageBatch messageBatch = client.messages().batches().create(createParams);
  ```

  ```php PHP
  $client = new Client();

  $messageBatch = $client->messages->batches->create(
      requests: [
          [
              'custom_id' => 'my-first-request',
              'params' => [
                  'model' => 'claude-opus-5-5',
                  'max_tokens' => 1024,
                  'system' => [
                      [
                          'type' => 'text',
                          'text' => 'You are an AI assistant tasked with analyzing literary works. Your goal is to provide insightful commentary on themes, characters, and writing style.\n'
                      ],
                      [
                          'type' => 'text',
                          'text' => '<the entire contents of Pride and Prejudice>',
                          'cache_control' => ['type' => 'ephemeral']
                      ]
                  ],
                  'messages' => [
                      ['role' => 'user', 'content' => 'Analyze the major themes in Pride and Prejudice.']
                  ]
              ]
          ],
          [
              'custom_id' => 'my-second-request',
              'params' => [
                  'model' => 'claude-opus-5-5',
                  'max_tokens' => 1024,
                  'system' => [
                      [
                          'type' => 'text',
                          'text' => 'You are an AI assistant tasked with analyzing literary works. Your goal is to provide insightful commentary on themes, characters, and writing style.\n'
                      ],
                      [
                          'type' => 'text',
                          'text' => '<the entire contents of Pride and Prejudice>',
                          'cache_control' => ['type' => 'ephemeral']
                      ]
                  ],
                  'messages' => [
                      ['role' => 'user', 'content' => 'Write a summary of Pride and Prejudice.']
                  ]
              ]
          ]
      ],
  );
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  message_batch = client.messages.batches.create(
    requests: [
      {
        custom_id: "my-first-request",
        params: {
          model: Anthropic::Model::CLAUDE_OPUS_5_5,
          max_tokens: 1024,
          system: [
            {
              type: "text",
              text: "You are an AI assistant tasked with analyzing literary works. Your goal is to provide insightful commentary on themes, characters, and writing style.\n"
            },
            {
              type: "text",
              text: "<the entire contents of Pride and Prejudice>",
              cache_control: { type: "ephemeral" }
            }
          ],
          messages: [
            { role: "user", content: "Analyze the major themes in Pride and Prejudice." }
          ]
        }
      },
      {
        custom_id: "my-second-request",
        params: {
          model: Anthropic::Model::CLAUDE_OPUS_5_5,
          max_tokens: 1024,
          system: [
            {
              type: "text",
              text: "You are an AI assistant tasked with analyzing literary works. Your goal is to provide insightful commentary on themes, characters, and writing style.\n"
            },
            {
              type: "text",
              text: "<the entire contents of Pride and Prejudice>",
              cache_control: { type: "ephemeral" }
            }
          ],
          messages: [
            { role: "user", content: "Write a summary of Pride and Prejudice." }
          ]
        }
      }
    ]
  )
  ```
</CodeGroup>

En este ejemplo, ambas solicitudes del lote incluyen mensajes del sistema idénticos y el texto completo de Orgullo y prejuicio marcado con `cache_control` para aumentar la probabilidad de aciertos de caché.

### Herramientas de servidor y el bucle agéntico

Todas las [herramientas de servidor](https://platform.claude.com/docs/es/agents-and-tools/tool-use/server-tools) (búsqueda web, obtención web, ejecución de código, conectores MCP, asesor y búsqueda de herramientas) funcionan en solicitudes por lotes. El worker de lotes ejecuta el mismo bucle agéntico del lado del servidor que la Messages API síncrona.

Como no hay una conexión abierta que mantener, el bucle por lotes puede ejecutar **más iteraciones en un turno** que una solicitud síncrona antes de devolver `stop_reason: "pause_turn"`. Si un resultado del lote vuelve con `pause_turn`, el turno no se completó; puedes continuarlo enviando el contenido pausado del asistente en una solicitud posterior (por lotes o síncrona) exactamente como se muestra en el [patrón de continuación de pause\_turn](https://platform.claude.com/docs/es/agents-and-tools/tool-use/server-tools#the-server-side-loop-and-pause-turn).

Además, el worker de lotes limita `web_search` para cada organización, de modo que el procesamiento por lotes altamente concurrente no agote el límite de velocidad de búsqueda web de tu organización. El lote reintenta automáticamente las solicitudes limitadas; no necesitas gestionar esto tú mismo, pero los lotes de búsqueda web muy grandes podrían tardar más en completarse.

### Salida extendida (beta)

El encabezado beta `output-300k-2026-03-24` eleva el límite de `max_tokens` a 300,000 para las solicitudes por lotes que usan Claude Opus 5.5, Claude Opus 5, Claude Opus 4.8, Claude Opus 4.7, Claude Opus 4.6, Claude Sonnet 5.5, Claude Sonnet 5, Claude Sonnet 4.6 o Claude Haiku 5.5. Incluye el encabezado para generar salidas mucho más largas que el límite estándar de 128k de `max_tokens` en un solo turno.

<Note>
  La salida extendida está disponible únicamente en la Message Batches API, no en la Messages API síncrona. Está disponible en la Claude API y Claude Platform on AWS.
</Note>

Usa la salida extendida para la generación de contenido extenso, como borradores del tamaño de un libro y documentación técnica, extracción exhaustiva de datos estructurados, grandes estructuras de generación de código y largas cadenas de razonamiento.

Una sola generación de 300k tokens puede tardar más de una hora en completarse, así que planifica tus envíos de lotes teniendo en cuenta la ventana de procesamiento de 24 horas. Se aplican los precios estándar de lotes (50 por ciento de los precios estándar de la API).

<CodeGroup>
  ```bash cURL
  curl https://api.anthropic.com/v1/messages/batches \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2026-10-21" \
    -H "anthropic-beta: output-300k-2026-03-24" \
    -H "content-type: application/json" \
    -d '{
      "requests": [
        {
          "custom_id": "long-form-request",
          "params": {
            "model": "claude-opus-5-5",
            "max_tokens": 300000,
            "messages": [
              {"role": "user", "content": "Write a comprehensive technical guide to building distributed systems, covering architecture patterns, consistency models, fault tolerance, and operational best practices."}
            ]
          }
        }
      ]
    }'
  ```

  ```bash CLI
  ant beta:messages:batches create --beta output-300k-2026-03-24 <<'YAML'
  requests:
    - custom_id: long-form-request
      params:
        model: claude-opus-5-5
        max_tokens: 300000
        messages:
          - role: user
            content: >-
              Write a comprehensive technical guide to building distributed
              systems, covering architecture patterns, consistency models,
              fault tolerance, and operational best practices.
  YAML
  ```

  ```python Python
  from anthropic.types.beta.message_create_params import MessageCreateParamsNonStreaming
  from anthropic.types.beta.messages.batch_create_params import Request

  client = anthropic.Anthropic()

  message_batch = client.beta.messages.batches.create(
      betas=["output-300k-2026-03-24"],
      requests=[
          Request(
              custom_id="long-form-request",
              params=MessageCreateParamsNonStreaming(
                  model="claude-opus-5-5",
                  max_tokens=300_000,
                  messages=[
                      {
                          "role": "user",
                          "content": "Write a comprehensive technical guide to building distributed systems, covering architecture patterns, consistency models, fault tolerance, and operational best practices.",
                      }
                  ],
              ),
          ),
      ],
  )

  print(message_batch)
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const messageBatch = await client.beta.messages.batches.create({
    betas: ["output-300k-2026-03-24"],
    requests: [
      {
        custom_id: "long-form-request",
        params: {
          model: "claude-opus-5-5",
          max_tokens: 300000,
          messages: [
            {
              role: "user",
              content:
                "Write a comprehensive technical guide to building distributed systems, covering architecture patterns, consistency models, fault tolerance, and operational best practices."
            }
          ]
        }
      }
    ]
  });

  console.log(messageBatch);
  ```

  ```csharp C#
  using Anthropic;
  using Anthropic.Models.Beta.Messages;
  using Anthropic.Models.Beta.Messages.Batches;
  using Model = Anthropic.Models.Messages.Model;

  AnthropicClient client = new();

  var batch = await client.Beta.Messages.Batches.Create(new BatchCreateParams
  {
      Betas = ["output-300k-2026-03-24"],
      Requests =
      [
          new()
          {
              CustomID = "long-form-request",
              Params = new()
              {
                  Model = Model.ClaudeOpus5_5,
                  MaxTokens = 300_000,
                  Messages =
                  [
                      new BetaUserMessageParam { Content = "Write a comprehensive technical guide to building distributed systems, covering architecture patterns, consistency models, fault tolerance, and operational best practices." }
                  ]
              }
          }
      ]
  });

  Console.WriteLine(batch);
  ```

  ```go Go
  client := anthropic.NewClient()

  batch, err := client.Beta.Messages.Batches.New(context.Background(),
  	anthropic.BetaMessageBatchNewParams{
  		Betas: []anthropic.AnthropicBeta{"output-300k-2026-03-24"},
  		Requests: []anthropic.BetaMessageBatchNewParamsRequest{
  			{
  				CustomID: "long-form-request",
  				Params: anthropic.BetaMessageBatchNewParamsRequestParams{
  					Model:     anthropic.ModelClaudeOpus5_5,
  					MaxTokens: 300_000,
  					Messages: []anthropic.BetaMessageParam{
  						anthropic.NewBetaUserMessage(
  							anthropic.NewBetaTextBlock("Write a comprehensive technical guide to building distributed systems, covering architecture patterns, consistency models, fault tolerance, and operational best practices."),
  						),
  					},
  				},
  			},
  		},
  	})
  if err != nil {
  	panic(err)
  }

  fmt.Println(batch.ID)
  ```

  ```java Java
  import com.anthropic.models.beta.messages.batches.*;

  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      BatchCreateParams params = BatchCreateParams.builder()
          .addBeta("output-300k-2026-03-24")
          .addRequest(
              BatchCreateParams.Request.builder()
                  .customId("long-form-request")
                  .params(
                      BatchCreateParams.Request.Params.builder()
                          .model(Model.CLAUDE_OPUS_5_5)
                          .maxTokens(300_000L)
                          .addUserMessage("Write a comprehensive technical guide to building distributed systems, covering architecture patterns, consistency models, fault tolerance, and operational best practices.")
                          .build()
                  )
                  .build()
          )
          .build();

      BetaMessageBatch messageBatch = client.beta().messages().batches().create(params);

      IO.println(messageBatch);
  }
  ```

  ```php PHP
  $client = new Client();

  $batch = $client->beta->messages->batches->create(
      betas: ['output-300k-2026-03-24'],
      requests: [
          [
              'custom_id' => 'long-form-request',
              'params' => [
                  'model' => 'claude-opus-5-5',
                  'max_tokens' => 300_000,
                  'messages' => [
                      ['role' => 'user', 'content' => 'Write a comprehensive technical guide to building distributed systems, covering architecture patterns, consistency models, fault tolerance, and operational best practices.']
                  ]
              ]
          ]
      ],
  );

  echo $batch->id;
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  batch = client.beta.messages.batches.create(
    betas: ["output-300k-2026-03-24"],
    requests: [
      {
        custom_id: "long-form-request",
        params: {
          model: Anthropic::Model::CLAUDE_OPUS_5_5,
          max_tokens: 300_000,
          messages: [
            { role: "user", content: "Write a comprehensive technical guide to building distributed systems, covering architecture patterns, consistency models, fault tolerance, and operational best practices." }
          ]
        }
      }
    ]
  )

  puts batch
  ```
</CodeGroup>

### Mejores prácticas para un procesamiento por lotes eficaz

Para usar la Batches API de forma eficaz:

* Supervisa regularmente el estado del procesamiento de los lotes e implementa una lógica de reintentos adecuada para las solicitudes fallidas.
* Usa valores de `custom_id` significativos para hacer coincidir fácilmente los resultados con las solicitudes, ya que el orden no está garantizado.
* Considera dividir conjuntos de datos muy grandes en varios lotes para facilitar su gestión.
* Haz una prueba de una sola estructura de solicitud con la Messages API para evitar errores de validación.

### Solución de problemas comunes

Si experimentas un comportamiento inesperado:

* Verifica que el tamaño total de la solicitud por lotes no supere los 256 MB. Si el tamaño de la solicitud es demasiado grande, es posible que recibas un error 413 `request_too_large`.
* Comprueba que estás usando [modelos compatibles](https://platform.claude.com/docs/es/build-with-claude/batch-processing#supported-models) para todas las solicitudes del lote.
* Asegúrate de que cada solicitud del lote tenga un `custom_id` único.
* Asegúrate de que hayan pasado menos de 29 días desde el momento `created_at` del lote (no desde el `ended_at` del procesamiento). Después de 29 días, los resultados ya no están disponibles para descargar.
* Confirma que el lote no se haya cancelado.

Ten en cuenta que el fallo de una solicitud en un lote no afecta el procesamiento de las demás solicitudes.

## Almacenamiento y privacidad de los lotes

* **Aislamiento del Workspace:** los lotes están aislados dentro del Workspace en el que se crean. Solo pueden acceder a ellos las solicitudes de API de ese mismo Workspace o los usuarios con permiso para ver los lotes del Workspace en la Console.

* **Disponibilidad de los resultados:** los resultados de los lotes están disponibles durante 29 días después de crear el lote, lo que da tiempo suficiente para su recuperación y procesamiento.

## Preguntas frecuentes

<AccordionGroup>
  <Accordion title="¿Cuánto tarda en procesarse un lote?">
    Los lotes pueden tardar hasta 24 horas en procesarse, pero muchos se completan antes. El tiempo real de procesamiento depende del tamaño del lote, la demanda actual y tu volumen de solicitudes. Es posible que un lote expire y no se complete en 24 horas.
  </Accordion>

  <Accordion title="¿La Batches API está disponible para todos los modelos?">
    Consulta [Modelos compatibles](https://platform.claude.com/docs/es/build-with-claude/batch-processing#supported-models) para ver la lista de modelos compatibles.
  </Accordion>

  <Accordion title="¿Puedo usar la Message Batches API con otras funciones de la API?">
    Sí, la Message Batches API admite casi todas las funciones disponibles en la Messages API, incluida la mayoría de las funciones beta. Un pequeño número de parámetros (`stream`, `speed`, `fallbacks` y `max_tokens: 0`) no son compatibles. Consulta [Qué se puede procesar por lotes](https://platform.claude.com/docs/es/build-with-claude/batch-processing#what-can-be-batched) para ver la lista completa.
  </Accordion>

  <Accordion title="¿Cómo afecta la Message Batches API a los precios?">
    La Message Batches API ofrece un descuento del 50 por ciento en todo el uso en comparación con los precios estándar de la API. Esto se aplica a los tokens de entrada, los tokens de salida y cualquier token especial. Para obtener más información sobre los precios, visita [Precios](https://claude.com/pricing#anthropic-api).
  </Accordion>

  <Accordion title="¿Puedo actualizar un lote después de haberlo enviado?">
    No, una vez que se ha enviado un lote, no se puede modificar. Si necesitas hacer cambios, cancela el lote actual y envía uno nuevo. Ten en cuenta que la cancelación podría no surtir efecto de inmediato.
  </Accordion>

  <Accordion title="¿Hay límites de velocidad en la Message Batches API y cómo interactúan con los límites de velocidad de la Messages API?">
    La Message Batches API tiene límites de velocidad basados en solicitudes HTTP, además de límites en la cantidad de solicitudes pendientes de procesamiento. Consulta [Límites de velocidad de la Message Batches API](https://platform.claude.com/docs/es/api/rate-limits#message-batches-api). El uso de la Batches API no afecta los límites de velocidad de la Messages API.
  </Accordion>

  <Accordion title="¿Cómo gestiono los errores en mis solicitudes por lotes?">
    Cuando recuperas los resultados, cada solicitud tiene un campo `result` que indica si tuvo el resultado `succeeded`, `errored`, `canceled` o `expired`. Para los resultados `errored`, se proporciona información adicional sobre el error. Consulta el objeto de respuesta de error en la [referencia de la API](https://platform.claude.com/docs/es/api/messages/batches/create).
  </Accordion>

  <Accordion title="¿Cómo gestiona la Message Batches API la privacidad y la separación de datos?">
    La Message Batches API está diseñada con sólidas medidas de privacidad y separación de datos:

    1. Los lotes y sus resultados están aislados dentro del Workspace en el que se crearon. Esto significa que solo pueden acceder a ellos las solicitudes de API de ese mismo Workspace.
    2. Cada solicitud dentro de un lote se procesa de forma independiente, sin filtración de datos entre solicitudes.
    3. Los resultados solo están disponibles durante un tiempo limitado (29 días) y siguen la [política de retención de datos](https://support.claude.com/en/articles/7996866-how-long-do-you-store-personal-data) de Anthropic.
    4. La descarga de los resultados de los lotes en la Console se puede deshabilitar a nivel de organización o por workspace.
  </Accordion>

  <Accordion title="¿Puedo usar el almacenamiento en caché de prompts en la Message Batches API?">
    Sí, es posible usar el almacenamiento en caché de prompts con la Message Batches API. Sin embargo, como las solicitudes por lotes asíncronas pueden procesarse de forma concurrente y en cualquier orden, los aciertos de caché se proporcionan en la medida de lo posible.
  </Accordion>
</AccordionGroup>

## Disponibilidad

Procesamiento por lotes está disponible en todos los modelos.

### Compatibilidad con la API

#### [Messages API](https://platform.claude.com/docs/es/build-with-claude/working-with-messages)

* Disponibilidad: Disponible

| Estado     | Plataformas en la nube                                                                                                                                                                                                                                                         |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Disponible | Claude API, [Claude Platform on AWS](https://platform.claude.com/docs/es/build-with-claude/claude-platform-on-aws), [Claude Models on Google Cloud (Anthropic managed)](https://platform.claude.com/docs/es/build-with-claude/claude-models-on-google-cloud/anthropic-managed) |

#### [Managed Agents](https://platform.claude.com/docs/es/managed-agents/overview)

* Disponibilidad: No disponible

### Manejo de datos

[Descripción general del manejo de datos](https://platform.claude.com/docs/es/manage-claude/api-and-data-retention#feature-eligibility)

| Elemento | Retención de datos cero                                                                                                                                              | HIPAA       |
| -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- |
| Estado   | No elegible                                                                                                                                                          | No elegible |
| Detalles | Retención de 29 días; se requiere almacenamiento asíncrono. [Más información](https://platform.claude.com/docs/es/build-with-claude/batch-processing#data-retention) | —           |

Endpoints aplicables:

* `/v1/messages/batches`

El procesamiento por lotes almacena los datos de solicitudes y respuestas durante un máximo de 29 días después de la creación del lote. Puedes eliminar un lote de mensajes en cualquier momento después del procesamiento usando el endpoint [`DELETE /v1/messages/batches/{batch_id}`](https://platform.claude.com/docs/es/api/messages/batches/delete). Para eliminar un lote en curso, cancélalo primero. El procesamiento asíncrono requiere el almacenamiento del lado del servidor tanto de las entradas como de las salidas hasta que se complete el lote y se recuperen los resultados.

## Próximos pasos

<CardGroup cols={2}>
  <Card title="Resultados de búsqueda" icon="magnifying-glass" href="https://platform.claude.com/docs/es/build-with-claude/search-results">
    Obtén citas naturales para aplicaciones RAG proporcionando resultados de búsqueda con atribución de fuentes.
  </Card>

  <Card title="Almacenamiento en caché de prompts" icon="database" href="https://platform.claude.com/docs/es/build-with-claude/prompt-caching">
    Reduce el costo y la latencia almacenando en caché los prefijos de prompts compartidos entre las solicitudes de un lote.
  </Card>
</CardGroup>
