> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://onepin.ai/docs/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://onepin.ai/docs/_mcp/server.

# SDK reference

The `onepin` Python SDK ships with `pip install onepin`. For task walkthroughs see the [Guides](/docs/guides/run-a-workflow); this page is the method index.

## Construction

```python
from onepin import OnepinClient

client = OnepinClient()                       # key from `onepin login`, then ONEPIN_API_KEY
client = OnepinClient(api_key="op_live_...")   # explicit
client = OnepinClient(base_url="https://api.onepin.ai", timeout=120.0)
```

Use `AsyncOnepinClient` for the async client (same methods, `await` them). Build once and reuse; it is **not** a context manager. Every method also takes `request_options={"timeout_in_seconds": ..., "max_retries": ..., "additional_headers": {...}}`.

**Return shape:** list methods return a counted envelope (`.data` holds the page); single-object methods return an envelope with the object at `.data`. Page with `offset` / `limit`.

```python
for wf in client.workflows.list(limit=50).data:
    print(wf.id)

wf = client.workflows.get(workflow_id="...").data
```

## workflows

`client.workflows.<method>`

| Method                                                                                  | Purpose                                                                                                                                                                                                                                 |
| --------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `list(limit=, offset=, status=, search=, sort=, order=, include_definition=)`           | List workflows                                                                                                                                                                                                                          |
| `get(workflow_id=)`                                                                     | Get one (with definition)                                                                                                                                                                                                               |
| `create_workflow(name=, description=, definition=)`                                     | Create from a definition — `name` is optional at the API level; omit it and the workflow gets a placeholder name, then is auto-named later. `name_source` on the returned object tells you which (`placeholder` / `generated` / `user`) |
| `update_workflow(workflow_id, ...)` / `patch_workflow(workflow_id, definition=)`        | Update (definition is full-replace)                                                                                                                                                                                                     |
| `duplicate_workflow(workflow_id)`                                                       | Copy a workflow                                                                                                                                                                                                                         |
| `delete_workflow(workflow_id)`                                                          | Delete                                                                                                                                                                                                                                  |
| `list_workflow_uploads(workflow_id)`                                                    | Uploads bound to a workflow                                                                                                                                                                                                             |
| `estimate_workflow(workflow_id)` / `preview_run(workflow_id)`                           | Estimate run cost                                                                                                                                                                                                                       |
| `download_run(workflow_id, run_id)` / `download_run_node(workflow_id, run_id, node_id)` | Get a 15-min pre-signed download URL                                                                                                                                                                                                    |
| `runs_summary`, `get_run_steps`, `get_run_overview`, `get_run_data`                     | Run detail views                                                                                                                                                                                                                        |
| `pause_run(workflow_id, run_id)` / `resume_run(...)`                                    | Pause / resume a run — see [Runs can pause](/docs/guides/run-a-workflow#runs-can-pause); runs also pause **automatically** on a provider outage, rate limit, billing problem, or node timeout                                           |

### workflows.runs

`client.workflows.runs.<method>`

| Method                                               | Purpose                                  |
| ---------------------------------------------------- | ---------------------------------------- |
| `start(workflow_id, script_text=, source_language=)` | Start a run (optional run-scoped script) |
| `status(workflow_id, run_id)`                        | Lightweight status + step progress       |
| `get(workflow_id, run_id)`                           | Full run object                          |
| `list(workflow_id, ...)`                             | Run history                              |
| `cancel(workflow_id, run_id)`                        | Cancel a run                             |

## voices

`client.voices.<method>`

| Method                                                                  | Purpose                                                 |
| ----------------------------------------------------------------------- | ------------------------------------------------------- |
| `list(language=, provider=, gender=, favorites_only=, search=, limit=)` | List voices                                             |
| `get(voice_id=)`                                                        | Get one                                                 |
| `similar(voice_id=)`                                                    | Similar voices                                          |
| `preview(voice_id=, language=, model=)`                                 | Ready-to-play preview audio for one voice in one locale |
| `get_voice_facets()`                                                    | Available filter facets                                 |
| `favorite_voice(voice_id)` / `unfavorite_voice(voice_id)`               | Manage favorites                                        |

> **Note**
>
> `voices.preview` is new and lands in the next SDK release. Until then call `GET /api/v1/voices/{voice_id}/preview?language=<locale>` over HTTP — see [Browse voices](/docs/guides/browse-voices#hear-it-before-you-commit).

## templates

`client.templates.<method>`

| Method                                                                   | Purpose                |
| ------------------------------------------------------------------------ | ---------------------- |
| `list(category=, search=, sort=, favorites_only=, limit=)`               | List gallery templates |
| `get(template_id=)`                                                      | Get one                |
| `clone(template_id, name=)`                                              | Clone into a workflow  |
| `create_template(...)` / `update_template(...)` / `delete_template(...)` | Manage templates       |
| `estimate_template(template_id)`                                         | Estimate cost          |
| `favorite_template(...)` / `unfavorite_template(...)`                    | Manage favorites       |

## uploads

`client.uploads.<method>` — three-step presigned flow (see [Upload a file](/docs/guides/upload-a-file)).

| Method                                           | Purpose                                 |
| ------------------------------------------------ | --------------------------------------- |
| `create(filename=, category=)`                   | Create the record + get a presigned URL |
| `confirm(upload_id, context_type=, context_id=)` | Bind a confirmed upload to a workflow   |
| `delete(upload_id)`                              | Delete an upload                        |

## providers

`client.providers.<method>` — the catalog for `voice_map` identifiers (see [Generator](/docs/workflow/generator)).

| Method                                                        | Purpose                                                      |
| ------------------------------------------------------------- | ------------------------------------------------------------ |
| `list_catalog_providers()` / `get_catalog_provider(provider)` | Providers                                                    |
| `list_catalog_provider_models(provider)`                      | Models for a provider (`.model` is what `voice_map` accepts) |
| `list_catalog_provider_model_voices(provider, model, limit=)` | Provider-native voices for a model                           |
| `get_catalog_provider_model(provider, model)`                 | One model                                                    |

## dictionary

`client.dictionary.<method>` — custom pronunciations (`dictionary:read` / `dictionary:write`).

| Method                                                                                                                      | Purpose                           |
| --------------------------------------------------------------------------------------------------------------------------- | --------------------------------- |
| `list_dictionary_entries(language=)` / `search_dictionary_entries(search=)`                                                 | Read entries                      |
| `create_dictionary_entry(word=, method=, language=, ...)` / `update_dictionary_entry(...)` / `delete_dictionary_entry(...)` | Manage entries                    |
| `list_dictionary_languages()`                                                                                               | Supported languages               |
| `suggest_pronunciation(word=, language=)`                                                                                   | Ask for a suggested pronunciation |

## usage

`client.usage.<method>` — see [Check usage](/docs/guides/check-usage).

| Method                                                                           | Purpose                                |
| -------------------------------------------------------------------------------- | -------------------------------------- |
| `usage_summary(range=)` / `usage_by_language(range=)` / `usage_activity(range=)` | Consumption over `30d` / `60d` / `90d` |

## nodes

`client.nodes.<method>`

| Method                       | Purpose                              |
| ---------------------------- | ------------------------------------ |
| `list_nodes()`               | Node types with their ports          |
| `get_node_detail(node_type)` | Full config schema for one node type |

## Errors

All methods raise typed exceptions on non-2xx — see [Handle errors](/docs/guides/handle-errors).