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 doesn't wrap directly: account details, Primitive Memories reads and writes, or semantic search. primitive.api is generated from the same OpenAPI spec 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 and Receiving and Parsing Inbound Email. Use primitive.api for everything else.
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.
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 thesyncvariant for a blocking call (anasynciovariant exists alongside it for async code):from primitive.api.api.account.get_account import sync as get_account - 2
Call it with the client#
account = get_account(client=client) print(account)The
syncvariant returns the parsed response model for the operation, orNonewhen the response could not be parsed into a model. Reach forsync_detailedwhen 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.modelsand construct it before passing it asbody: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 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.
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.
memory = get_memory(
client=client,
key="state",
scope_type="function",
scope_id="3fa85f64-5717-4562-b3fc-2c963f66afa6",
)
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:
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.
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.
Next steps#
Configure timeouts, dual-host base URLs, and per-call overrides on the high-level PrimitiveClient.
Python SDK Error ReferenceLook up every PrimitiveAPIError, webhook error code, and x402 error condition the SDK can raise.
Registering Payout Addresses and Spend PolicyUse the dedicated X402Client instead of the generated API module for payment operations.
Monorepo Structure and Release ProcessSee how the shared OpenAPI spec propagates into the generated primitive.api module.
Was this page helpful?