# `Gemini.APIs.Batches`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/apis/batches.ex#L1)

Batches API for batch processing of content generation and embedding requests.

Batch processing allows you to submit large numbers of requests at once,
with 50% cost savings compared to interactive API calls.

## Use Cases

- Processing large document collections for embeddings
- Bulk content generation for content pipelines
- Overnight processing of accumulated requests
- Cost optimization for high-volume workloads

## Batch Sources

**Gemini API:**
- `file_name` - Reference to an uploaded file (JSONL format)
- `inlined_requests` - Direct inline requests (limited size)

**Vertex AI:**
- `gcs_uri` - Google Cloud Storage URIs (JSONL files)
- `bigquery_uri` - BigQuery table URI

## Batch Destinations

**Gemini API:**
- Results returned in `inlined_responses`
- Or written to a file

**Vertex AI:**
- `gcs_uri` - GCS output prefix
- `bigquery_uri` - BigQuery output table

## Example Workflow

    # 1. Prepare input file (JSONL format)
    #    Each line: {"contents": [{"parts": [{"text": "..."}]}]}

    # 2. Upload the input file
    {:ok, input_file} = Gemini.APIs.Files.upload("input.jsonl")

    # 3. Create batch job
    {:ok, batch} = Gemini.APIs.Batches.create("gemini-2.5-flash",
      file_name: input_file.name,
      display_name: "My Batch Job"
    )

    # 4. Wait for completion
    {:ok, completed} = Gemini.APIs.Batches.wait(batch.name,
      poll_interval: 30_000,
      timeout: 3_600_000  # 1 hour
    )

    # 5. Process results
    if BatchJob.succeeded?(completed) do
      IO.puts("Completed #{completed.completion_stats.success_count} requests")
    end

# `batch_opts`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/apis/batches.ex#L79)

```elixir
@type batch_opts() :: [{:auth, :gemini | :vertex_ai}]
```

# `create_opts`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/apis/batches.ex#L68)

```elixir
@type create_opts() :: [
  display_name: String.t(),
  file_name: String.t(),
  inlined_requests: [map()],
  gcs_uri: [String.t()],
  bigquery_uri: String.t(),
  generation_config: map(),
  system_instruction: map(),
  auth: :gemini | :vertex_ai
]
```

# `list_opts`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/apis/batches.ex#L81)

```elixir
@type list_opts() :: [
  page_size: pos_integer(),
  page_token: String.t(),
  filter: String.t(),
  auth: :gemini | :vertex_ai
]
```

# `wait_opts`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/apis/batches.ex#L88)

```elixir
@type wait_opts() :: [
  poll_interval: pos_integer(),
  timeout: pos_integer(),
  on_progress: (Gemini.Types.BatchJob.t() -&gt; any()),
  auth: :gemini | :vertex_ai
]
```

# `cancel`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/apis/batches.ex#L291)

```elixir
@spec cancel(String.t(), batch_opts()) :: :ok | {:error, term()}
```

Cancel a running batch job.

Can only cancel jobs that are in `queued` or `running` state.

## Parameters

- `name` - Batch job name
- `opts` - Options

## Examples

    :ok = Gemini.APIs.Batches.cancel("batches/abc123")

# `create`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/apis/batches.ex#L148)

```elixir
@spec create(String.t(), create_opts()) ::
  {:ok, Gemini.Types.BatchJob.t()} | {:error, term()}
```

Create a new batch generation job.

## Parameters

- `model` - Model to use for generation (e.g., "gemini-2.5-flash")
- `opts` - Batch creation options

## Options

- `:display_name` - Human-readable name for the batch
- `:file_name` - Input file name (for Gemini API)
- `:inlined_requests` - Inline requests (for small batches)
- `:gcs_uri` - GCS input URIs (for Vertex AI)
- `:bigquery_uri` - BigQuery input URI (for Vertex AI)
- `:generation_config` - Generation configuration for all requests
- `:system_instruction` - System instruction for all requests
- `:auth` - Authentication strategy

## Input File Format (JSONL)

For file-based input, each line should be a JSON object:

    {"contents": [{"parts": [{"text": "First request"}]}]}
    {"contents": [{"parts": [{"text": "Second request"}]}]}

## Examples

    # Using uploaded file
    {:ok, batch} = Gemini.APIs.Batches.create("gemini-2.5-flash",
      file_name: "files/abc123",
      display_name: "My Batch"
    )

    # Using inline requests (small batches only)
    {:ok, batch} = Gemini.APIs.Batches.create("gemini-2.5-flash",
      inlined_requests: [
        %{contents: [%{parts: [%{text: "Request 1"}]}]},
        %{contents: [%{parts: [%{text: "Request 2"}]}]}
      ],
      display_name: "Small Batch"
    )

    # With generation config
    {:ok, batch} = Gemini.APIs.Batches.create("gemini-2.5-flash",
      file_name: "files/abc123",
      generation_config: %{
        temperature: 0.7,
        maxOutputTokens: 1000
      }
    )

# `create_embeddings`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/apis/batches.ex#L184)

```elixir
@spec create_embeddings(String.t(), create_opts()) ::
  {:ok, Gemini.Types.BatchJob.t()} | {:error, term()}
```

Create a new batch embedding job.

Similar to `create/2` but for embedding requests.

## Parameters

- `model` - Embedding model to use
- `opts` - Batch creation options

## Input File Format (JSONL)

For embeddings, each line should contain text to embed:

    {"content": {"parts": [{"text": "Text to embed"}]}}
    {"content": {"parts": [{"text": "Another text"}]}}

## Examples

    {:ok, batch} = Gemini.APIs.Batches.create_embeddings("text-embedding-004",
      file_name: "files/embeddings-input",
      display_name: "Embedding Batch"
    )

# `delete`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/apis/batches.ex#L315)

```elixir
@spec delete(String.t(), batch_opts()) :: :ok | {:error, term()}
```

Delete a batch job.

Typically used to clean up completed jobs.

## Parameters

- `name` - Batch job name
- `opts` - Options

## Examples

    :ok = Gemini.APIs.Batches.delete("batches/abc123")

# `get`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/apis/batches.ex#L214)

```elixir
@spec get(String.t(), batch_opts()) ::
  {:ok, Gemini.Types.BatchJob.t()} | {:error, term()}
```

Get the status of a batch job.

## Parameters

- `name` - Batch job name (e.g., "batches/abc123")
- `opts` - Options

## Examples

    {:ok, batch} = Gemini.APIs.Batches.get("batches/abc123")
    IO.puts("State: #{batch.state}")

    if batch.completion_stats do
      IO.puts("Progress: #{batch.completion_stats.success_count}/#{batch.completion_stats.total_count}")
    end

# `get_responses`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/apis/batches.ex#L390)

```elixir
@spec get_responses(Gemini.Types.BatchJob.t()) :: {:ok, [map()]} | {:error, term()}
```

Get inlined responses from a completed batch job.

Only works for batches with inline response output.

## Parameters

- `batch` - Completed BatchJob with inlined responses
- `opts` - Options

## Examples

    {:ok, batch} = Gemini.APIs.Batches.get("batches/abc123")
    if BatchJob.succeeded?(batch) do
      {:ok, responses} = Gemini.APIs.Batches.get_responses(batch)
      Enum.each(responses, &process_response/1)
    end

# `list`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/apis/batches.ex#L252)

```elixir
@spec list(list_opts()) ::
  {:ok, Gemini.Types.ListBatchJobsResponse.t()} | {:error, term()}
```

List batch jobs.

## Parameters

- `opts` - List options

## Options

- `:page_size` - Number of jobs per page (default: 100)
- `:page_token` - Token from previous response for pagination
- `:filter` - Filter string
- `:auth` - Authentication strategy

## Examples

    {:ok, response} = Gemini.APIs.Batches.list()

    Enum.each(response.batch_jobs, fn job ->
      IO.puts("#{job.name}: #{job.state}")
    end)

    # With pagination
    {:ok, response} = Gemini.APIs.Batches.list(page_size: 10)
    if ListBatchJobsResponse.has_more_pages?(response) do
      {:ok, page2} = Gemini.APIs.Batches.list(page_token: response.next_page_token)
    end

# `list_all`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/apis/batches.ex#L272)

```elixir
@spec list_all(list_opts()) :: {:ok, [Gemini.Types.BatchJob.t()]} | {:error, term()}
```

List all batch jobs across all pages.

Automatically handles pagination.

## Examples

    {:ok, all_jobs} = Gemini.APIs.Batches.list_all()
    running = Enum.filter(all_jobs, &BatchJob.running?/1)

# `wait`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/apis/batches.ex#L361)

```elixir
@spec wait(String.t(), wait_opts()) ::
  {:ok, Gemini.Types.BatchJob.t()} | {:error, term()}
```

Wait for a batch job to complete.

Polls the batch status until it reaches a terminal state (succeeded, failed, etc.)
or the timeout is reached.

## Parameters

- `name` - Batch job name
- `opts` - Wait options

## Options

- `:poll_interval` - Milliseconds between status checks (default: 30000)
- `:timeout` - Maximum wait time in milliseconds (default: 3600000 = 1 hour)
- `:on_progress` - Callback for status updates `fn(BatchJob.t()) -> any()`

## Examples

    {:ok, completed} = Gemini.APIs.Batches.wait("batches/abc123",
      poll_interval: 60_000,   # Check every minute
      timeout: 7_200_000,      # Wait up to 2 hours
      on_progress: fn batch ->
        if progress = BatchJob.get_progress(batch) do
          IO.puts("Progress: #{Float.round(progress, 1)}%")
        end
      end
    )

    cond do
      BatchJob.succeeded?(completed) ->
        IO.puts("Success!")
      BatchJob.failed?(completed) ->
        IO.puts("Failed: #{completed.error.message}")
    end

---

*Consult [api-reference.md](api-reference.md) for complete listing*
