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

# Processamento em lote

> Envie grandes volumes de solicitações de forma assíncrona usando a API de Lotes. Processe conclusões de chat, embeddings e gerações de imagens em massa com uma janela de conclusão de 24 horas.

A API de Lotes permite que você envie grupos de solicitações como um único trabalho que é processado de forma assíncrona.
Isso é útil quando você precisa executar muitas solicitações e não precisa dos resultados imediatamente — por exemplo, ao rodar avaliações, gerar embeddings para um grande conjunto de dados ou classificar conteúdo em massa.

As solicitações em lote são executadas dentro de uma **janela de conclusão de 24 horas** e possuem limites de taxa separados e mais altos do que as chamadas síncronas da API.

## Endpoints suportados

| Endpoint                 | Descrição                         |
| ------------------------ | --------------------------------- |
| `/v1/chat/completions`   | Solicitações de conclusão de chat |
| `/v1/embeddings`         | Geração de embeddings             |
| `/v1/images/generations` | Geração de imagens                |

Todas as solicitações em um único lote devem ter como alvo o mesmo endpoint.

## Ciclo de vida

Um lote passa pelos seguintes status:

```
validating → in_progress → finalizing → completed
     ↓            ↓
   failed     cancelling → cancelled
```

| Status        | Descrição                                                                                       |
| ------------- | ----------------------------------------------------------------------------------------------- |
| `validating`  | O arquivo de entrada está sendo verificado quanto a erros de formato e conteúdo.                |
| `failed`      | A validação falhou — o arquivo de entrada contém erros. Verifique `batch.errors` para detalhes. |
| `in_progress` | As solicitações estão sendo processadas.                                                        |
| `finalizing`  | Todas as solicitações foram processadas e os arquivos de saída estão sendo gerados.             |
| `completed`   | O lote foi finalizado. Baixe os resultados de `output_file_id`.                                 |
| `cancelling`  | Um cancelamento foi solicitado. Solicitações em andamento estão sendo finalizadas.              |
| `cancelled`   | O lote foi cancelado. Resultados parciais podem estar disponíveis.                              |
| `expired`     | O lote não foi concluído dentro da janela de 24 horas.                                          |

## Passo 1 — Prepare o arquivo de entrada

Crie um arquivo JSONL onde cada linha é uma solicitação. Cada linha tem quatro campos:

| Campo       | Tipo   | Descrição                                                                                                         |
| ----------- | ------ | ----------------------------------------------------------------------------------------------------------------- |
| `custom_id` | string | Seu identificador para esta solicitação. Usado para relacionar entrada e saída. Deve ser único dentro do arquivo. |
| `method`    | string | `"POST"` — o único método suportado.                                                                              |
| `url`       | string | O caminho do endpoint — deve corresponder ao `endpoint` que você declara ao criar o lote.                         |
| `body`      | object | O corpo da solicitação — os mesmos parâmetros que você enviaria para o endpoint síncrono.                         |

```jsonl theme={null}
{"custom_id": "request-1", "method": "POST", "url": "/v1/chat/completions", "body": {"model": "meetkai:functionary-pt", "messages": [{"role": "user", "content": "Summarize the benefits of batch processing in one sentence."}], "max_tokens": 100}}
{"custom_id": "request-2", "method": "POST", "url": "/v1/chat/completions", "body": {"model": "meetkai:functionary-pt", "messages": [{"role": "user", "content": "What is the capital of France?"}], "max_tokens": 100}}
{"custom_id": "request-3", "method": "POST", "url": "/v1/chat/completions", "body": {"model": "meetkai:functionary-pt", "messages": [{"role": "user", "content": "Explain embeddings in one paragraph."}], "max_tokens": 100}}
```

Um único lote pode conter até **10.000 solicitações**.

## Passo 2 — Faça upload do arquivo de entrada

Envie o arquivo JSONL usando a API de Arquivos com `purpose: "batch"`.

<CodeGroup>
  ```bash CLI theme={null}
  mka1 llm files upload \
    --file ./batch_input.jsonl \
    --purpose batch \
    -H 'X-On-Behalf-Of: <end-user-id>'
  ```

  ```ts MKA1 SDK theme={null}
  import { SDK } from '@meetkai/mka1';

  const mka1 = new SDK({
    bearerAuth: `Bearer ${YOUR_API_KEY}`,
  });

  const file = await mka1.llm.files.upload({
    file: new File([jsonlContent], 'batch_input.jsonl', { type: 'application/jsonl' }),
    purpose: 'batch',
  });

  console.log(file.id);     // "file_abc123"
  console.log(file.status); // "processed"
  ```

  ```ts OpenAI SDK theme={null}
  import OpenAI from 'openai';

  const openai = new OpenAI({
    apiKey: '<mka1-api-key>',
    baseURL: 'https://apigw.mka1.com/api/v1/llm/',
    defaultHeaders: { 'X-On-Behalf-Of': '<end-user-id>' },
  });

  const file = await openai.files.create({
    file: new File([jsonlContent], 'batch_input.jsonl', { type: 'application/jsonl' }),
    purpose: 'batch',
  });

  console.log(file.id);     // "file_abc123"
  console.log(file.status); // "processed"
  ```

  ```csharp C# SDK theme={null}
  using System.Text;
  using MeetKai.MKA1;
  using MeetKai.MKA1.Types.Components;
  using MeetKai.MKA1.Types.Requests;

  var sdk = new SDK(bearerAuth: "Bearer YOUR_API_KEY");

  var file = await sdk.Llm.Files.UploadAsync(new UploadFileRequestBody()
  {
      File = new UploadFileFile()
      {
          FileName = "batch_input.jsonl",
          Content = Encoding.UTF8.GetBytes(jsonlContent),
      },
      Purpose = UploadFilePurpose.Batch,
  });

  Console.WriteLine(file.File!.Id);     // "file_abc123"
  ```

  ```python Python SDK theme={null}
  from mka1 import SDK

  sdk = SDK(bearer_auth="Bearer YOUR_API_KEY")

  file = sdk.llm.files.upload(
      file={"file_name": "batch_input.jsonl", "content": open("batch_input.jsonl", "rb")},
      purpose="batch",
  )

  print(file.id)      # "file_abc123"
  print(file.status)  # "processed"
  ```

  ```bash bash theme={null}
  curl https://apigw.mka1.com/api/v1/llm/files \
    --request POST \
    --header 'Authorization: Bearer <mka1-api-key>' \
    --header 'X-On-Behalf-Of: <end-user-id>' \
    --form 'file=@batch_input.jsonl;type=application/jsonl' \
    --form 'purpose=batch'
  ```
</CodeGroup>

## Passo 3 — Crie o lote

Informe o ID do arquivo enviado, o endpoint de destino e a janela de conclusão.

<CodeGroup>
  ```bash CLI theme={null}
  mka1 llm batches create --body '{
    "input_file_id": "file_abc123",
    "endpoint": "/v1/chat/completions",
    "completion_window": "24h"
  }'
  ```

  ```ts MKA1 SDK theme={null}
  const batch = await mka1.llm.batches.create({
    inputFileId: file.id,
    endpoint: '/v1/chat/completions',
    completionWindow: '24h',
  });

  console.log(batch.id);            // "batch_abc123"
  console.log(batch.status);        // "validating" or "in_progress"
  console.log(batch.requestCounts); // { total: 3, completed: 0, failed: 0 }
  ```

  ```ts OpenAI SDK theme={null}
  const batch = await openai.batches.create({
    input_file_id: file.id,
    endpoint: '/v1/chat/completions',
    completion_window: '24h',
  });

  console.log(batch.id);              // "batch_abc123"
  console.log(batch.status);          // "validating" or "in_progress"
  console.log(batch.request_counts);  // { total: 3, completed: 0, failed: 0 }
  ```

  ```csharp C# SDK theme={null}
  using MeetKai.MKA1;
  using MeetKai.MKA1.Types.Components;

  var sdk = new SDK(bearerAuth: "Bearer YOUR_API_KEY");

  var batch = await sdk.Llm.Batches.CreateAsync(new CreateBatchRequest()
  {
      InputFileId = file.File!.Id,
      Endpoint = BatchEndpoint.RootV1ChatCompletions,
  });

  Console.WriteLine(batch.BatchObject!.Id);            // "batch_abc123"
  Console.WriteLine(batch.BatchObject!.Status);        // "validating" or "in_progress"
  Console.WriteLine(batch.BatchObject!.RequestCounts); // { Total: 3, Completed: 0, Failed: 0 }
  ```

  ```python Python SDK theme={null}
  batch = sdk.llm.batches.create(
      input_file_id=file.id,
      endpoint="/v1/chat/completions",
  )

  print(batch.id)              # "batch_abc123"
  print(batch.status)          # "validating" or "in_progress"
  print(batch.request_counts)  # { total: 3, completed: 0, failed: 0 }
  ```

  ```bash bash theme={null}
  curl https://apigw.mka1.com/api/v1/llm/batches \
    --request POST \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer <mka1-api-key>' \
    --header 'X-On-Behalf-Of: <end-user-id>' \
    --data '{
      "input_file_id": "file_abc123",
      "endpoint": "/v1/chat/completions",
      "completion_window": "24h"
    }'
  ```
</CodeGroup>

Você também pode anexar metadados para seu próprio controle:

<CodeGroup>
  ```bash CLI theme={null}
  mka1 llm batches create --body '{
    "input_file_id": "file_abc123",
    "endpoint": "/v1/chat/completions",
    "completion_window": "24h",
    "metadata": {
      "description": "nightly evaluation run",
      "run_id": "eval-2026-03-31"
    }
  }'
  ```

  ```ts MKA1 SDK theme={null}
  const batch = await mka1.llm.batches.create({
    inputFileId: file.id,
    endpoint: '/v1/chat/completions',
    completionWindow: '24h',
    metadata: {
      description: 'nightly evaluation run',
      run_id: 'eval-2026-03-31',
    },
  });
  ```

  ```ts OpenAI SDK theme={null}
  const batch = await openai.batches.create({
    input_file_id: file.id,
    endpoint: '/v1/chat/completions',
    completion_window: '24h',
    metadata: {
      description: 'nightly evaluation run',
      run_id: 'eval-2026-03-31',
    },
  });
  ```

  ```csharp C# SDK theme={null}
  using MeetKai.MKA1;
  using MeetKai.MKA1.Types.Components;

  var sdk = new SDK(bearerAuth: "Bearer YOUR_API_KEY");

  var batch = await sdk.Llm.Batches.CreateAsync(new CreateBatchRequest()
  {
      InputFileId = file.File!.Id,
      Endpoint = BatchEndpoint.RootV1ChatCompletions,
      Metadata = new Dictionary<string, string>
      {
          { "description", "nightly evaluation run" },
          { "run_id", "eval-2026-03-31" },
      },
  });
  ```

  ```python Python SDK theme={null}
  batch = sdk.llm.batches.create(
      input_file_id=file.id,
      endpoint="/v1/chat/completions",
      metadata={
          "description": "nightly evaluation run",
          "run_id": "eval-2026-03-31",
      },
  )
  ```
</CodeGroup>

## Passo 4 — Verifique o status do lote

Faça polling do lote até que ele atinja um status final.

<CodeGroup>
  ```bash CLI theme={null}
  mka1 llm batches get --batch-id batch_abc123
  ```

  ```ts MKA1 SDK theme={null}
  const batch = await mka1.llm.batches.get({ batchId: 'batch_abc123' });

  console.log(batch.status);                // "completed"
  console.log(batch.requestCounts.completed); // 3
  console.log(batch.requestCounts.failed);    // 0
  console.log(batch.outputFileId);           // "file_xyz789"
  ```

  ```ts OpenAI SDK theme={null}
  const batch = await openai.batches.retrieve('batch_abc123');

  console.log(batch.status);                  // "completed"
  console.log(batch.request_counts.completed); // 3
  console.log(batch.request_counts.failed);    // 0
  console.log(batch.output_file_id);           // "file_xyz789"
  ```

  ```csharp C# SDK theme={null}
  using MeetKai.MKA1;
  using MeetKai.MKA1.Types.Components;

  var sdk = new SDK(bearerAuth: "Bearer YOUR_API_KEY");

  var batch = await sdk.Llm.Batches.GetAsync("batch_abc123");

  Console.WriteLine(batch.BatchObject!.Status);                // "completed"
  Console.WriteLine(batch.BatchObject!.RequestCounts);         // { Total: 3, Completed: 3, Failed: 0 }
  Console.WriteLine(batch.BatchObject!.OutputFileId);          // "file_xyz789"
  ```

  ```python Python SDK theme={null}
  batch = sdk.llm.batches.get(batch_id="batch_abc123")

  print(batch.status)                  # "completed"
  print(batch.request_counts.completed)  # 3
  print(batch.request_counts.failed)     # 0
  print(batch.output_file_id)           # "file_xyz789"
  ```

  ```bash bash theme={null}
  curl https://apigw.mka1.com/api/v1/llm/batches/batch_abc123 \
    --header 'Authorization: Bearer <mka1-api-key>' \
    --header 'X-On-Behalf-Of: <end-user-id>'
  ```
</CodeGroup>

Aqui está um auxiliar de polling que espera o lote finalizar:

<CodeGroup>
  ```bash CLI theme={null}
  # Faça polling de um lote até atingir um status final usando --jq e um loop de shell.
  BATCH_ID=batch_abc123
  while :; do
    STATUS=$(mka1 llm batches get --batch-id "$BATCH_ID" --jq '.status' --output-format json)
    echo "status: $STATUS"
    case "$STATUS" in
      completed|failed|cancelled|expired) break ;;
    esac
    sleep 2
  done
  ```

  ```ts MKA1 SDK theme={null}
  async function waitForBatch(batchId: string, timeoutMs = 120_000) {
    const terminal = ['completed', 'failed', 'cancelled', 'expired'];
    const start = Date.now();

    while (Date.now() - start < timeoutMs) {
      const batch = await mka1.llm.batches.get({ batchId });
      if (terminal.includes(batch.status)) return batch;
      await new Promise((r) => setTimeout(r, 2000));
    }

    throw new Error(`Batch ${batchId} did not complete within ${timeoutMs}ms`);
  }

  const completed = await waitForBatch(batch.id);
  ```

  ```ts OpenAI SDK theme={null}
  async function waitForBatch(batchId: string, timeoutMs = 120_000) {
    const terminal = ['completed', 'failed', 'cancelled', 'expired'];
    const start = Date.now();

    while (Date.now() - start < timeoutMs) {
      const batch = await openai.batches.retrieve(batchId);
      if (terminal.includes(batch.status)) return batch;
      await new Promise((r) => setTimeout(r, 2000));
    }

    throw new Error(`Batch ${batchId} did not complete within ${timeoutMs}ms`);
  }

  const completed = await waitForBatch(batch.id);
  ```

  ```csharp C# SDK theme={null}
  using MeetKai.MKA1;
  using MeetKai.MKA1.Types.Components;

  var sdk = new SDK(bearerAuth: "Bearer YOUR_API_KEY");

  async Task<BatchObject> WaitForBatch(SDK sdk, string batchId, int timeoutMs = 300_000)
  {
      var terminal = new HashSet<BatchObjectStatus>
      {
          BatchObjectStatus.Completed,
          BatchObjectStatus.Failed,
          BatchObjectStatus.Cancelled,
          BatchObjectStatus.Expired,
      };
      var start = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();

      while (DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - start < timeoutMs)
      {
          var batch = await sdk.Llm.Batches.GetAsync(batchId);
          if (terminal.Contains(batch.BatchObject!.Status))
              return batch.BatchObject;
          await Task.Delay(2000);
      }

      throw new TimeoutException($"Batch {batchId} did not complete within {timeoutMs}ms");
  }

  var completed = await WaitForBatch(sdk, batch.BatchObject!.Id);
  Console.WriteLine(completed.Status); // BatchObjectStatus.Completed
  ```

  ```python Python SDK theme={null}
  import time

  def wait_for_batch(sdk, batch_id, timeout_ms=120_000):
      terminal = {"completed", "failed", "cancelled", "expired"}
      start = time.time() * 1000

      while (time.time() * 1000) - start < timeout_ms:
          batch = sdk.llm.batches.get(batch_id=batch_id)
          if batch.status in terminal:
              return batch
          time.sleep(2)

      raise TimeoutError(f"Batch {batch_id} did not complete within {timeout_ms}ms")

  completed = wait_for_batch(sdk, batch.id)
  ```
</CodeGroup>

## Passo 5 — Baixe os resultados

Quando o lote estiver `completed`, baixe o arquivo de saída. Ele é um arquivo JSONL onde cada linha contém o `custom_id` que você forneceu, a resposta e qualquer erro.

<CodeGroup>
  ```bash CLI theme={null}
  # Baixe o arquivo de saída JSONL
  mka1 llm files content \
    --file-id file_xyz789 \
    --output-file ./batch_output.jsonl

  # Inspecione os resultados inline com jq
  mka1 llm files content --file-id file_xyz789 \
    --jq '"\(.custom_id): status=\(.response.status_code)"'
  ```

  ```ts MKA1 SDK theme={null}
  const stream = await mka1.llm.files.content({ fileId: completed.outputFileId! });
  const reader = stream.getReader();
  const chunks: Uint8Array[] = [];
  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    chunks.push(value);
  }
  const text = new TextDecoder().decode(Buffer.concat(chunks));

  const results = text
    .split('\n')
    .filter((line) => line.trim())
    .map((line) => JSON.parse(line));

  for (const result of results) {
    console.log(`${result.custom_id}: status=${result.response.status_code}`);
    console.log(`  body:`, result.response.body);
  }
  ```

  ```ts OpenAI SDK theme={null}
  const content = await openai.files.content(completed.output_file_id!);
  const text = await content.text();

  const results = text
    .split('\n')
    .filter((line) => line.trim())
    .map((line) => JSON.parse(line));

  for (const result of results) {
    console.log(`${result.custom_id}: status=${result.response.status_code}`);
    console.log(`  body:`, result.response.body);
  }
  ```

  ```csharp C# SDK theme={null}
  using System.Text;
  using MeetKai.MKA1;

  var sdk = new SDK(bearerAuth: "Bearer YOUR_API_KEY");

  var content = await sdk.Llm.Files.ContentAsync(completed.OutputFileId!);

  var bytes = content.TwoHundredTextPlainBytes
      ?? content.TwoHundredApplicationJsonlBytes
      ?? content.TwoHundredApplicationJsonBytes;
  var text = Encoding.UTF8.GetString(bytes!);

  Console.WriteLine(text); // JSONL com uma linha por solicitação
  ```

  ```python Python SDK theme={null}
  import json

  content = sdk.llm.files.content(file_id=completed.output_file_id)
  text = content.decode("utf-8")

  results = [json.loads(line) for line in text.strip().split("\n") if line.strip()]

  for result in results:
      print(f"{result['custom_id']}: status={result['response']['status_code']}")
      print(f"  body: {result['response']['body']}")
  ```

  ```bash bash theme={null}
  curl https://apigw.mka1.com/api/v1/llm/files/file_xyz789/content \
    --header 'Authorization: Bearer <mka1-api-key>' \
    --header 'X-On-Behalf-Of: <end-user-id>'
  ```
</CodeGroup>

Cada linha do arquivo de saída tem esta estrutura:

```json theme={null}
{
  "id": "response_abc123",
  "custom_id": "request-1",
  "response": {
    "status_code": 200,
    "request_id": "req_abc123",
    "body": { "...": "same shape as the synchronous endpoint response" }
  },
  "error": null
}
```

Se uma solicitação falhar, `response` será `null` e `error` conterá os detalhes:

```json theme={null}
{
  "id": "response_def456",
  "custom_id": "request-2",
  "response": null,
  "error": {
    "code": "processing_error",
    "message": "The request could not be processed."
  }
}
```

Se houver solicitações com falha, o lote também fornece um `error_file_id` contendo apenas as entradas que falharam.

## Cancelar um lote

Cancele um lote que ainda está em andamento. Solicitações que já foram concluídas permanecem na saída.

<CodeGroup>
  ```bash CLI theme={null}
  mka1 llm batches cancel --batch-id batch_abc123
  ```

  ```ts MKA1 SDK theme={null}
  const cancelled = await mka1.llm.batches.cancel({ batchId: 'batch_abc123' });
  console.log(cancelled.status); // "cancelling"
  ```

  ```ts OpenAI SDK theme={null}
  const cancelled = await openai.batches.cancel('batch_abc123');
  console.log(cancelled.status); // "cancelling"
  ```

  ```csharp C# SDK theme={null}
  using MeetKai.MKA1;

  var sdk = new SDK(bearerAuth: "Bearer YOUR_API_KEY");

  var cancelled = await sdk.Llm.Batches.CancelAsync("batch_abc123");
  Console.WriteLine(cancelled.BatchObject!.Status); // "cancelling"
  ```

  ```python Python SDK theme={null}
  cancelled = sdk.llm.batches.cancel(batch_id="batch_abc123")
  print(cancelled.status)  # "cancelling"
  ```

  ```bash bash theme={null}
  curl https://apigw.mka1.com/api/v1/llm/batches/batch_abc123/cancel \
    --request POST \
    --header 'Authorization: Bearer <mka1-api-key>' \
    --header 'X-On-Behalf-Of: <end-user-id>'
  ```
</CodeGroup>

O lote transita para `cancelling` enquanto as solicitações em andamento são finalizadas, depois para `cancelled`.

## Listar lotes

Recupere todos os lotes da conta atual, do mais recente para o mais antigo. Suporta paginação.

<CodeGroup>
  ```bash CLI theme={null}
  mka1 llm batches list --limit 20
  ```

  ```ts MKA1 SDK theme={null}
  const page = await mka1.llm.batches.list({ limit: 20 });

  for (const batch of page.data) {
    console.log(`${batch.id}: ${batch.status} (${batch.requestCounts?.completed}/${batch.requestCounts?.total})`);
  }
  ```

  ```ts OpenAI SDK theme={null}
  const page = await openai.batches.list({ limit: 20 });

  for (const batch of page.data) {
    console.log(`${batch.id}: ${batch.status} (${batch.request_counts?.completed}/${batch.request_counts?.total})`);
  }
  ```

  ```csharp C# SDK theme={null}
  using MeetKai.MKA1;

  var sdk = new SDK(bearerAuth: "Bearer YOUR_API_KEY");

  var page = await sdk.Llm.Batches.ListAsync(limit: 20);

  foreach (var batch in page.ListBatchesResponseValue!.Data!)
  {
      Console.WriteLine($"{batch.Id}: {batch.Status} ({batch.RequestCounts?.Completed}/{batch.RequestCounts?.Total})");
  }
  ```

  ```python Python SDK theme={null}
  page = sdk.llm.batches.list(limit=20)

  for batch in page.data:
      print(f"{batch.id}: {batch.status} ({batch.request_counts.completed}/{batch.request_counts.total})")
  ```

  ```bash bash theme={null}
  curl 'https://apigw.mka1.com/api/v1/llm/batches?limit=20' \
    --header 'Authorization: Bearer <mka1-api-key>' \
    --header 'X-On-Behalf-Of: <end-user-id>'
  ```
</CodeGroup>

Use o parâmetro `after` com um ID de lote para paginar os resultados.

## Exemplo: embeddings em lote

O mesmo fluxo funciona para embeddings. Altere o `url` em cada linha do JSONL e o `endpoint` ao criar o lote.

```jsonl theme={null}
{"custom_id": "embed-1", "method": "POST", "url": "/v1/embeddings", "body": {"model": "meetkai:functionary-pt", "input": "The quick brown fox"}}
{"custom_id": "embed-2", "method": "POST", "url": "/v1/embeddings", "body": {"model": "meetkai:functionary-pt", "input": "jumps over the lazy dog"}}
```

<CodeGroup>
  ```bash CLI theme={null}
  # Faça upload do arquivo JSONL de embeddings
  FILE_ID=$(mka1 llm files upload \
    --file ./embed_batch.jsonl \
    --purpose batch \
    --jq '.id' --output-format json | tr -d '"')

  # Crie o lote para o endpoint de embeddings
  mka1 llm batches create --body "{
    \"input_file_id\": \"$FILE_ID\",
    \"endpoint\": \"/v1/embeddings\",
    \"completion_window\": \"24h\"
  }"

  # Faça polling e baixe os resultados — veja os Passos 4 e 5
  ```

  ```ts MKA1 SDK theme={null}
  const file = await mka1.llm.files.upload({
    file: new File([jsonlContent], 'embed_batch.jsonl', { type: 'application/jsonl' }),
    purpose: 'batch',
  });

  const batch = await mka1.llm.batches.create({
    inputFileId: file.id,
    endpoint: '/v1/embeddings',
    completionWindow: '24h',
  });

  const completed = await waitForBatch(batch.id);
  const stream = await mka1.llm.files.content({ fileId: completed.outputFileId! });
  // ... leia o stream conforme mostrado no Passo 5
  ```

  ```ts OpenAI SDK theme={null}
  const file = await openai.files.create({
    file: new File([jsonlContent], 'embed_batch.jsonl', { type: 'application/jsonl' }),
    purpose: 'batch',
  });

  const batch = await openai.batches.create({
    input_file_id: file.id,
    endpoint: '/v1/embeddings',
    completion_window: '24h',
  });

  const completed = await waitForBatch(batch.id);
  const content = await openai.files.content(completed.output_file_id!);
  const results = (await content.text()).split('\n').filter(Boolean).map(JSON.parse);

  for (const r of results) {
    console.log(`${r.custom_id}: ${r.response.body.data[0].embedding.length} dimensions`);
  }
  ```

  ```csharp C# SDK theme={null}
  using System.Text;
  using MeetKai.MKA1;
  using MeetKai.MKA1.Types.Components;
  using MeetKai.MKA1.Types.Requests;

  var sdk = new SDK(bearerAuth: "Bearer YOUR_API_KEY");

  var file = await sdk.Llm.Files.UploadAsync(new UploadFileRequestBody()
  {
      File = new UploadFileFile()
      {
          FileName = "embed_batch.jsonl",
          Content = Encoding.UTF8.GetBytes(jsonlContent),
      },
      Purpose = UploadFilePurpose.Batch,
  });

  var batch = await sdk.Llm.Batches.CreateAsync(new CreateBatchRequest()
  {
      InputFileId = file.File!.Id,
      Endpoint = BatchEndpoint.RootV1Embeddings,
  });

  var completed = await WaitForBatch(sdk, batch.BatchObject!.Id);
  // Baixe e analise os resultados conforme mostrado no Passo 5
  ```

  ```python Python SDK theme={null}
  file = sdk.llm.files.upload(
      file={"file_name": "embed_batch.jsonl", "content": open("embed_batch.jsonl", "rb")},
      purpose="batch",
  )

  batch = sdk.llm.batches.create(
      input_file_id=file.id,
      endpoint="/v1/embeddings",
  )

  completed = wait_for_batch(sdk, batch.id)
  # Baixe e analise os resultados conforme mostrado no Passo 5
  ```
</CodeGroup>

## Erros de validação

Se o arquivo de entrada tiver problemas de formatação, o lote muda para `failed` imediatamente.
Causas comuns:

* **JSON inválido** — uma linha não é um JSON válido.
* **Campos ausentes** — uma linha está sem `custom_id`, `method`, `url` ou `body`.
* **Método incorreto** — `method` deve ser `"POST"`.
* **URL não corresponde** — o `url` de uma linha não corresponde ao `endpoint` declarado ao criar o lote.
* **`custom_id` duplicado** — cada `custom_id` deve ser único dentro do arquivo.

Verifique `batch.errors.data` para mensagens de erro específicas e números de linha.

<CodeGroup>
  ```bash CLI theme={null}
  mka1 llm batches get --batch-id batch_abc123 \
    --jq '.errors.data[] | "Line \(.line): [\(.code)] \(.message)"'
  ```

  ```ts MKA1 SDK theme={null}
  const batch = await mka1.llm.batches.get({ batchId: 'batch_abc123' });

  if (batch.status === 'failed' && batch.errors) {
    for (const err of batch.errors.data ?? []) {
      console.log(`Line ${err.line}: [${err.code}] ${err.message}`);
    }
  }
  ```

  ```ts OpenAI SDK theme={null}
  const batch = await openai.batches.retrieve('batch_abc123');

  if (batch.status === 'failed' && batch.errors) {
    for (const err of batch.errors.data ?? []) {
      console.log(`Line ${err.line}: [${err.code}] ${err.message}`);
    }
  }
  ```

  ```csharp C# SDK theme={null}
  using MeetKai.MKA1;
  using MeetKai.MKA1.Types.Components;

  var sdk = new SDK(bearerAuth: "Bearer YOUR_API_KEY");

  var batch = await sdk.Llm.Batches.GetAsync("batch_abc123");

  if (batch.BatchObject!.Status == BatchObjectStatus.Failed && batch.BatchObject.Errors != null)
  {
      foreach (var err in batch.BatchObject.Errors.Data ?? new List<BatchObjectErrorsData>())
      {
          Console.WriteLine($"Line {err.Line}: [{err.Code}] {err.Message}");
      }
  }
  ```

  ```python Python SDK theme={null}
  batch = sdk.llm.batches.get(batch_id="batch_abc123")

  if batch.status == "failed" and batch.errors:
      for err in batch.errors.data or []:
          print(f"Line {err.line}: [{err.code}] {err.message}")
  ```
</CodeGroup>

## Veja também

* [Gerar uma resposta](/pt/docs/generate-a-response) para o padrão síncrono de conclusões de chat.
* [Arquivos e vetores](/pt/docs/files-and-vector-stores) para a API de Arquivos usada para enviar entradas em lote.
