---
title: "Generated API Client (Python)"
canonical: "https://test.abhinandan.one/python-generated-api-client"
markdown_url: "https://test.abhinandan.one/python-generated-api-client.md"
publisher: "Primitive SDKs"
kind: "guide"
content_type: "reference"
category: "Python SDK"
description: "Call primitive.api's generated operation functions directly to reach account, memories, and semantic-search endpoints not covered by the high-level Python client."
keywords: ["primitive.api", "create_client", "primitive.api.models", "sync detailed", "semantic_search", "Primitive Memories Python"]
last_modified: "2026-08-21T18:22:43.359885+00:00"
published_at: "2026-08-11T18:55:07.224377+00:00"
source_files:
  - "sdk-python/src/primitive/client.py"
  - "sdk-python/README.md"
  - "sdk-go/README.md"
sections:
  - {anchor: "construct-a-client", title: "Construct a client"}
  - {anchor: "call-a-generated-operation", title: "Call a generated operation"}
  - {anchor: "step-import-the-operation-function", title: "Import the operation function"}
  - {anchor: "step-call-it-with-the-client", title: "Call it with the client"}
  - {anchor: "step-handle-request-bodies-with-typed-model-classes", title: "Handle request bodies with typed model classes"}
  - {anchor: "primitive-memories", title: "Primitive Memories"}
  - {anchor: "semantic-search", title: "Semantic search"}
  - {anchor: "errors", title: "Errors"}
  - {anchor: "next-steps", title: "Next steps"}
---

> Documentation index: https://test.abhinandan.one/llms.txt

# Generated API Client (Python)

Call any Primitive REST operation directly through primitive.api, the generated HTTP client, for account, memories, and semantic-search operations that the high-level PrimitiveClient doesn't wrap.

Reach for the generated API module, `primitive.api`, when you need an operation the high-level [`PrimitiveClient`](https://test.abhinandan.one/python-sdk-quickstart.md) doesn't wrap directly: account details, Primitive Memories reads and writes, or semantic search. `primitive.api` is generated from the same [OpenAPI spec](https://test.abhinandan.one/monorepo-and-releases.md) that produces the Node and Go clients, so every operation the API exposes has a matching Python function.

The high-level client (`client.send`, `client.reply`, `client.forward`) stays the default for outbound/inbound mail, see [Sending Email](https://test.abhinandan.one/python-send-email.md) and [Receiving and Parsing Inbound Email](https://test.abhinandan.one/python-receive-email.md). Use `primitive.api` for everything else.

> **Note:** `primitive.api` is generated by `sdk-python/scripts/generate_api_client.py`, which runs `openapi-python-client` against the normalized `openapi/primitive-api.codegen.json` spec and copies the output into `src/primitive/api/`. You never hand-edit files under this path.

## Construct a client

Every generated operation function takes a `client` keyword argument built with `create_client`.

```python
from primitive.api import create_client

client = create_client("prim_test")
```

`create_client` accepts the same API key format as the high-level `primitive.client(...)` (`prim_test` in examples, or `os.environ["PRIMITIVE_API_KEY"]` in real code). It targets the primary API host; the generated client does not need the dual-host split the high-level client uses internally for `/send-mail` and `/emails/{id}/reply`, because those two endpoints have dedicated high-level methods.

## Call a generated operation

### 1. Import the operation function

Each OpenAPI operation lives at a predictable import path: `primitive.api.api.<tag>.<operation_name>`. Import the `sync` variant for a blocking call (an `asyncio` variant exists alongside it for async code):

```python
from primitive.api.api.account.get_account import sync as get_account
```

### 2. Call it with the client

```python
account = get_account(client=client)
print(account)
```

The `sync` variant returns the parsed response model for the operation, or `None` when the response could not be parsed into a model. Reach for `sync_detailed` when you need the status code and headers as well.

### 3. Handle request bodies with typed model classes

Operations that take a body import a matching model from `primitive.api.models` and construct it before passing it as `body`:

```python
from primitive.api.api.memories.set_memory import sync as set_memory
from primitive.api.models.set_memory_input import SetMemoryInput

saved = set_memory(
    client=client,
    body=SetMemoryInput(key="greeting", value="hello"),
)
```

## Primitive Memories

[Primitive Memories](https://test.abhinandan.one/node-sdk-api-client.md) are durable JSON key-value records, available here as the generated `set_memory` / `get_memory` / `search_memories` / `delete_memory` operations. Calls default to org scope.

```python
from primitive.api import create_client
from primitive.api.api.memories.get_memory import sync as get_memory
from primitive.api.api.memories.set_memory import sync as set_memory
from primitive.api.models.set_memory_input import SetMemoryInput

client = create_client("prim_test")

saved = set_memory(
    client=client,
    body=SetMemoryInput(key="greeting", value="hello"),
)
memory = get_memory(client=client, key="greeting")
```

Function scope is available on the generated memory operations with `scope_type="function"` and `scope_id=<function-id>`; the id is the function's UUID, not the function name.

```python
memory = get_memory(
    client=client,
    key="state",
    scope_type="function",
    scope_id="3fa85f64-5717-4562-b3fc-2c963f66afa6",
)
```

> **Tip:** `search_memories` lists records by key prefix, it is not free-text or semantic search. For ranked search across mail, use the generated `semantic_search` operation shown below (or `primitive semantic-search` from the CLI).

## Semantic search

The generated `semantic_search` operation runs ranked semantic, hybrid, or keyword search across received and sent mail:

```python
from primitive.api.api.search.semantic_search import sync as semantic_search
from primitive.api.models.semantic_search_input import SemanticSearchInput

results = semantic_search(
    client=client,
    body=SemanticSearchInput(query="invoice from Acme", mode="hybrid", limit=10),
)
```

Semantic search requires the Pro plan and the `semantic_search_enabled` entitlement; callers without them receive a 403 error.

## Errors

The generated functions do not raise `PrimitiveAPIError`; that mapping lives in the high-level client. A `sync` call returns the parsed model for the status the spec declares, so an error status parses into the generated `ErrorResponse` model rather than throwing. Import the `sync_detailed` variant (`from primitive.api.api.account.get_account import sync_detailed`) when you need the status code, headers, and raw content to build your own error handling. For the error shapes the high-level SDK raises, see the [Python SDK Error Reference](https://test.abhinandan.one/python-errors-reference.md).

> **Warning:** Every file under `src/primitive/api/` is regenerated wholesale on the next `make python-generate`. Any local edit there is silently discarded; put customizations in your own module that imports from `primitive.api` instead.
