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

# Start Run

> Open a run that you own and close yourself.

## Returns

Returns an `ActiveRun`: a handle on the open [Run](https://docs.galtea.ai/concepts/product/run.md) that also works as a context manager.

Use it in a `with` block. Every session and evaluation the SDK creates inside the block joins the run,
and leaving the block closes the run. A failure inside the block closes it too, so a run never stays open
after an error.

Outside a `with` block the handle stays open until you call `close()` on it, or
[`runs.close(run_id)`](https://docs.galtea.ai/sdk/api/run/close).

> [!WARNING]
>
> Keep the block around the work of one product and one version. Every write inside it joins the
> run, with no product or version check of its own, so an unrelated call inside a long block is
> refused by the API with a 400 naming a run the caller never passed. There is no per-call opt-out:
> `run_id=None` means "use the block". Close the block before you work on something else.

> [!WARNING]
>
> A thread started inside the block does not join the run. The open run travels on a context
> variable, which an `asyncio` task inherits and a thread does not, so a session or evaluation
> created in a worker thread lands outside the run and reports no error. Pass `run_id=run.id`
> explicitly in the worker, or hand it the current context with `contextvars.copy_context()`.

> [!WARNING]
>
> [`evaluations.run()`](https://docs.galtea.ai/sdk/api/evaluation/run) without an agent does not join the block. That call
> queues a launch, and the platform opens the run that holds it. Read that run from the `runId` of
> the returned result.

> [!NOTE]
>
> A production session cannot belong to a run, and `sessions.create()` treats a session with no
> `test_case_id` as production. So a plain `galtea.sessions.create(version_id=...)` inside the
> block joins no run; pass `is_production=False` or a `test_case_id` to join it.

`ActiveRun` reads like the run itself: `run.id`, `run.ordinal`, `run.custom_id` and `run.status` all
come from the wrapped [Run](https://docs.galtea.ai/concepts/product/run.md). It adds two methods of its own, `close()` and
`delete()`, both taking no arguments.

## Example

```python theme={"system"}
with galtea.runs.start(product_id=product_id, custom_id="ci-build-42") as run:
    print(f"Opened run #{run.ordinal} ({run.id})")

    # Every session and evaluation created inside the block joins the run.
    session = galtea.sessions.create(version_id=version_id, is_production=False)
    galtea.traces.create_batch(
        session_id=session.id,
        conversation_turns=[
            {"role": "user", "content": "What is the capital of France?"},
            {"role": "assistant", "content": "The capital of France is Paris."},
        ],
    )
    galtea.evaluations.create(session_id=session.id, metrics=[{"name": "Conversation Relevancy"}])
# Leaving the block closes the run, whether the block finished or raised.
```

## Parameters

**product\_id** `string` *required*

The ID of the product this run belongs to. A run always names exactly one product.

**version\_id** `string`

The ID of the version under test. A run that names a version accepts only work naming that version.
Omit it to let the run span several versions of the product.

**custom\_id** `string`

Your own label for the run, for example a build number. It must be unique within the product among
runs that are not deleted. Use it to find the run again with [Get Run By Custom ID](https://docs.galtea.ai/sdk/api/run/get-by-custom-id.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.