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

# Python SDK

> Use synchronous and asynchronous Python clients with Pydantic models, safe retries, and cursor pages.

# Python, sync and async

The Python package mirrors the public `/v1` namespaces with Pydantic models,
safe retries, cursor pages, and synchronous or asynchronous clients.

<Info>
  The Python client requires Python 3.12 or newer and currently ships as verified
  wheel and source-distribution artifacts with each GitHub release, not from
  PyPI. Install `synapse-spec` and `synapse-client` from the same version bundle.
</Info>

## Install

```bash theme={null}
# Download both matching artifacts from the release.
python -m pip install ./synapse_spec-0.1.0-py3-none-any.whl \
  ./synapse_client-0.1.0-py3-none-any.whl
```

## Start a subject journey

```python theme={null}
import os
import uuid
from synapse_client import SynapseClient

request_id = str(uuid.uuid4())  # persist this with the workflow

with SynapseClient(
    os.environ["SYNAPSE_API_URL"],
    api_key=os.environ["SYNAPSE_ENVIRONMENT_KEY"],
) as synapse:
    subject, _created = synapse.subjects.upsert(
        organization_id,
        app_id,
        environment_id,
        external_id=authenticated_user_id,
        profile={"locale": "en"},
        idempotency_key=f"{request_id}:subject",
    )
    synapse.programs.enroll(
        organization_id,
        app_id,
        environment_id,
        subject_id=subject.id,
        program_id=program_id,
        idempotency_key=f"{request_id}:enrollment",
    )
    session = synapse.participant_sessions.create(
        organization_id,
        app_id,
        environment_id,
        program_id=program_id,
        subject_id=subject.id,
        expires_in_seconds=3600,
        idempotency_key=f"{request_id}:session",
    )
    print(session.hosted_url)
```

## Async applications

```python theme={null}
from synapse_client import AsyncSynapseClient

async with AsyncSynapseClient(base_url, api_key=environment_key) as synapse:
    page = await synapse.evaluations.list(
        organization_id,
        app_id,
        environment_id,
        limit=50,
    )
    for evaluation in page.items:
        print(evaluation.id, evaluation.status)
```

## Contract notes

* `SynapseClient` and `AsyncSynapseClient` expose matching namespaces and
  models.
* `ApiError` exposes `status`, `detail`, `request_id`, `retry_after`,
  and response headers.
* Use `list_all_*` helpers when you explicitly want to consume every cursor
  page.
* Pass a persisted opaque `idempotency_key` for every mutation.
