AuraClient
Async client for the Strangeworks Aura public /api/v1 surface.
AuraClient(*, api_key: str, base_url: str | None = None, region: Region | None = None, timeout: float = 30.0, transport: httpx.AsyncBaseTransport | None = None, websocket_factory: WebSocketFactory = default_websocket_factory)Authenticates with a company API key (sk-aura-…). Every method is a coroutine;
there is no synchronous variant. chat follows a turn live over the project
WebSocket and falls back to polling when the socket cannot be held open, hiding both
behind a single await.
Owns HTTP connections, so use it as an async context manager, or call aclose:
async with AuraClient(api_key=key) as aura: project = await aura.create_project(name="demo", from_deployment="acme/vrp")All arguments are keyword-only.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
api_key |
str |
— | A company API key, minted under Settings → API Keys. A key belongs to the region whose app you minted it in. |
base_url |
str | None |
None |
Root of the Aura deployment, for a host no region names. Wins over region. |
region |
Region | None |
None |
Which deployment to reach, as a shorthand for its base_url. Defaults to "eu". |
timeout |
float |
DEFAULT_TIMEOUT |
Per-request HTTP timeout in seconds. This bounds one call, not a whole agent turn — see chat’s own timeout. Elapsing raises httpx’s timeout error, not an AuraError. |
transport |
httpx.AsyncBaseTransport | None |
None |
Optional httpx transport — an httpx.MockTransport in tests, or a wrapper that logs or retries. Byte uploads to storage go through it too. |
websocket_factory |
WebSocketFactory |
default_websocket_factory |
Opens the project event socket; tests pass a scripted fake. |
Properties
Section titled “Properties”| Property | Type | Default | Description |
|---|---|---|---|
base_url (read-only) |
str |
— | The Aura origin this client talks to, without a trailing slash. |
Methods
Section titled “Methods”Lifecycle
Section titled “Lifecycle”aclose()
Section titled “aclose()”async def aclose() -> NoneClose the underlying HTTP connections.
Deployments
Section titled “Deployments”create_deployment()
Section titled “create_deployment()”async def create_deployment(name: str) -> DeploymentResponseCreate an empty deployment for your company.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
name |
str |
— | Deployment name, unique within the company. |
Returns
Section titled “Returns”The created deployment.
Throws
Section titled “Throws”| Exception | When |
|---|---|
AuraApiError |
The name is invalid or already taken. |
list_deployments()
Section titled “list_deployments()”async def list_deployments() -> list[DeploymentResponse]List every deployment your company owns, following pagination.
Returns
Section titled “Returns”All deployments, in server order.
get_deployment()
Section titled “get_deployment()”async def get_deployment(name: str) -> DeploymentResponseFetch one deployment by name.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
name |
str |
— | The deployment’s name. |
Returns
Section titled “Returns”The deployment.
Throws
Section titled “Throws”| Exception | When |
|---|---|
AuraApiError |
No such deployment. |
delete_deployment()
Section titled “delete_deployment()”async def delete_deployment(name: str) -> DeploymentDeleteResponseDelete a deployment: purge its files and free its name for reuse.
Irreversible — there is no undelete, and a new deployment claiming the same name starts empty. Projects already seeded from this deployment keep their own copy of the workspace and are left alone.
Requires an admin, which every API key satisfies.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
name |
str |
— | The deployment’s name. |
Returns
Section titled “Returns”The handle, how many files were purged, and how many projects had been seeded from it.
Throws
Section titled “Throws”| Exception | When |
|---|---|
AuraApiError |
No such deployment. |
check_deployment()
Section titled “check_deployment()”async def check_deployment(name: str) -> DeploymentCheckResponseAsk the server whether a deployment satisfies the run contract.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
name |
str |
— | The deployment’s name. |
Returns
Section titled “Returns”ok, plus the missing paths and warnings behind that verdict.
Agent instructions and skills
Section titled “Agent instructions and skills”get_deployment_instructions()
Section titled “get_deployment_instructions()”async def get_deployment_instructions(name: str) -> DeploymentAgentInstructionsResponseFetch the operating instructions a deployment ships.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
name |
str |
— | The deployment’s name. |
Returns
Section titled “Returns”The instruction text, with content set to None when the deployment ships none — distinct from the 404 below, which means no such deployment.
Throws
Section titled “Throws”| Exception | When |
|---|---|
AuraApiError |
No such deployment. |
set_deployment_instructions()
Section titled “set_deployment_instructions()”async def set_deployment_instructions(name: str, content: str) -> AgentInstructionsResponseReplace the operating instructions a deployment ships.
Projects already seeded from this deployment keep the copy they were created with; only projects created afterwards get the new text at seed time.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
name |
str |
— | The deployment’s name. |
content |
str |
— | The instruction text. |
Returns
Section titled “Returns”What was stored.
Throws
Section titled “Throws”| Exception | When |
|---|---|
AuraApiError |
No such deployment, or the content is empty or over 64 KiB. |
delete_deployment_instructions()
Section titled “delete_deployment_instructions()”async def delete_deployment_instructions(name: str) -> NoneRemove a deployment’s operating instructions. Idempotent.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
name |
str |
— | The deployment’s name. |
list_deployment_skills()
Section titled “list_deployment_skills()”async def list_deployment_skills(name: str) -> list[SkillSummary]List the customer skills a deployment ships.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
name |
str |
— | The deployment’s name. |
Returns
Section titled “Returns”One summary per skill, each with its description and file list.
Throws
Section titled “Throws”| Exception | When |
|---|---|
AuraApiError |
No such deployment. |
set_deployment_skill()
Section titled “set_deployment_skill()”async def set_deployment_skill(name: str, skill: str, files: Mapping[str, str]) -> SkillSummaryCreate or replace one customer skill.
Replaces the skill’s whole file set rather than merging, so a file dropped locally does not linger server-side.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
name |
str |
— | The deployment’s name. |
skill |
str |
— | The skill’s directory name, which is what the model invokes. Aura’s own skill names are reserved. |
files |
Mapping[str, str] |
— | Bodies keyed by path relative to the skill’s directory. Must include SKILL.md, whose frontmatter needs a name matching skill and a non-empty description. At most 128 KiB per file and 256 KiB per skill. |
Returns
Section titled “Returns”The stored skill’s summary.
Throws
Section titled “Throws”| Exception | When |
|---|---|
AuraApiError |
No such deployment, or the skill failed validation. |
get_deployment_skill()
Section titled “get_deployment_skill()”async def get_deployment_skill(name: str, skill: str) -> SkillDetailFetch one skill in full, file bodies included.
Separate from list_deployment_skills, which carries filenames only —
describing twenty skills should not ship every byte of all of them.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
name |
str |
— | The deployment’s name. |
skill |
str |
— | The skill’s directory name. |
Returns
Section titled “Returns”The skill’s name, description, and every file’s contents.
Throws
Section titled “Throws”| Exception | When |
|---|---|
AuraApiError |
No such deployment, or it ships no such skill. |
delete_deployment_skill()
Section titled “delete_deployment_skill()”async def delete_deployment_skill(name: str, skill: str) -> NoneRemove one customer skill and all its files. Idempotent.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
name |
str |
— | The deployment’s name. |
skill |
str |
— | The skill’s directory name. |
get_project_instructions()
Section titled “get_project_instructions()”async def get_project_instructions(project_id: str) -> ProjectAgentInstructionsResponseFetch both instruction blocks in force for a project.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
project_id |
str |
— | The project’s id. |
Returns
Section titled “Returns”The deployment block and the project block, either of which may be None, and pulled_from, the deployment the former came from.
set_project_instructions()
Section titled “set_project_instructions()”async def set_project_instructions(project_id: str, content: str) -> AgentInstructionsResponseSet a project’s own instructions, layered onto anything pulled from its deployment.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
project_id |
str |
— | The project’s id. |
content |
str |
— | The instruction text. |
Returns
Section titled “Returns”What was stored.
Throws
Section titled “Throws”| Exception | When |
|---|---|
AuraApiError |
No such project, or the content is empty or over 64 KiB. |
delete_project_instructions()
Section titled “delete_project_instructions()”async def delete_project_instructions(project_id: str) -> NoneRemove every instruction block a project holds. Idempotent.
Both scopes, since both are the project’s — never the deployment’s original.
Siblings are unaffected, and the project gets the rules back with
pull_agent_config.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
project_id |
str |
— | The project’s id. |
list_project_skills()
Section titled “list_project_skills()”async def list_project_skills(project_id: str) -> ProjectSkillListResponseList the customer skills in force for a project.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
project_id |
str |
— | The project’s id. |
Returns
Section titled “Returns”The skills in the deployment scope and the project scope, and pulled_from, the deployment the former came from. A project skill sharing a deployment skill’s name shadows it.
get_project_skill()
Section titled “get_project_skill()”async def get_project_skill(project_id: str, skill: str) -> ProjectSkillDetailFetch one of a project’s skills in full, with the scope in force for it.
The project’s own copy when it has one, since that is the copy a turn mounts — the shadowed deployment one would describe rules that do not apply.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
project_id |
str |
— | The project’s id. |
skill |
str |
— | The skill’s directory name. |
Returns
Section titled “Returns”The skill’s contents plus scope ("deployment" or "project").
Throws
Section titled “Throws”| Exception | When |
|---|---|
AuraApiError |
No such project, or no such skill is in force for it. |
set_project_skill()
Section titled “set_project_skill()”async def set_project_skill(project_id: str, skill: str, files: Mapping[str, str]) -> SkillSummaryCreate or replace one of a project’s own skills.
Naming it after one of the deployment’s skills shadows it for this project alone, leaving the deployment untouched. Replaces the skill’s whole file set rather than merging, so a file dropped locally does not linger server-side.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
project_id |
str |
— | The project’s id. |
skill |
str |
— | The skill’s directory name, which is what the model invokes. Aura’s own skill names are reserved. |
files |
Mapping[str, str] |
— | Bodies keyed by path relative to the skill’s directory. Must include SKILL.md, whose frontmatter needs a name matching skill and a non-empty description. At most 128 KiB per file and 256 KiB per skill. |
Returns
Section titled “Returns”The stored skill’s summary.
Throws
Section titled “Throws”| Exception | When |
|---|---|
AuraApiError |
No such project, or the skill failed validation. |
delete_project_skill()
Section titled “delete_project_skill()”async def delete_project_skill(project_id: str, skill: str) -> NoneRemove a skill from a project, whichever scope holds it. Idempotent.
Never the deployment’s copy, so siblings are unaffected and the project gets
the skill back with pull_agent_config.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
project_id |
str |
— | The project’s id. |
skill |
str |
— | The skill’s directory name. |
pull_agent_config()
Section titled “pull_agent_config()”async def pull_agent_config(project_id: str, from_deployment: str, *, instructions: bool = True, skills: bool = True) -> PullConfigResponsePull a deployment’s instructions and/or skills into a project.
The non-destructive half of a checkout: the project takes the operator’s
current rules without checkout overwriting work in flight. Replaces the
project’s deployment scope rather than merging into it, so a rule the
deployment retired stops applying; the project’s own scope is untouched.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
project_id |
str |
— | The project’s id. |
from_deployment |
str |
— | The deployment to pull from, as a bare name (vrp) or a <company>/<name> handle (acme/vrp). |
instructions |
bool |
True |
Pull the deployment’s AGENTS.md. |
skills |
bool |
True |
Pull the deployment’s skills. |
Returns
Section titled “Returns”The deployment handle pulled from, and how many objects landed.
Throws
Section titled “Throws”| Exception | When |
|---|---|
AuraApiError |
No such project or deployment. |
upload_file()
Section titled “upload_file()”async def upload_file(container: FileContainer, path: str, body: bytes | str, content_type: str, conversation_id: str | None = None) -> FileEntryUpload one file to a container.
Three steps behind one await: plan the upload, PUT the bytes to the URL the plan names, then complete it. The byte PUT carries only the plan’s own headers, never your API key.
One request, one file, up to 100 MiB. Between 100 and 250 MiB the server plans a multipart upload, which this SDK does not implement, so the call raises instead; above 250 MiB the server refuses the plan outright.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
container |
FileContainer |
— | Which files to write to. A SnapshotFiles is rejected server-side; a snapshot is immutable by design. |
path |
str |
— | Destination path within the container, e.g. run/solve.py. A WorkspaceFiles destination must name a directory (data/orders.csv, not orders.csv). |
body |
bytes | str |
— | File contents. A str is encoded as UTF-8. |
content_type |
str |
— | MIME type recorded for the file. |
conversation_id |
str | None |
None |
Announce the write on this conversation, so the project’s agent re-reads the file on its next turn instead of trusting what it read earlier. Workspace only. Refused with a 409 while a turn is in flight, since a notice written mid-turn would never be seen; omit it to write silently. |
Returns
Section titled “Returns”The stored file’s entry.
Throws
Section titled “Throws”| Exception | When |
|---|---|
AuraError |
path is at the workspace root — raised before any request. |
AuraApiError |
The plan, the byte upload, or the completion failed, or the file is over 100 MiB (501, raised before any bytes move) or over 250 MiB (413). |
list_files()
Section titled “list_files()”async def list_files(container: FileContainer, path_prefix: str | None = None) -> list[FileEntry]List a container’s files, following pagination.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
container |
FileContainer |
— | Which files to list. |
path_prefix |
str | None |
None |
Restrict the listing to paths under this prefix. |
Returns
Section titled “Returns”All matching file entries.
read_file()
Section titled “read_file()”async def read_file(container: FileContainer, path: str) -> FileContentResponseRead one file from a container.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
container |
FileContainer |
— | Which files to read from. SnapshotFiles reads a run’s frozen copy, which later runs cannot have overwritten. |
path |
str |
— | The file’s path, e.g. solutions/out.json for a run’s solution. |
Returns
Section titled “Returns”The file’s contents: text for text files, base64 for binary ones.
Throws
Section titled “Throws”| Exception | When |
|---|---|
AuraApiError |
No such file in that container. |
delete_file()
Section titled “delete_file()”async def delete_file(container: FileContainer, path: str, conversation_id: str | None = None) -> DeleteResponseDelete one file from a container.
Not recursive — pass a file path, not a directory.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
container |
FileContainer |
— | Which files to delete from. A SnapshotFiles is rejected server-side; a snapshot is immutable by design. |
path |
str |
— | The file’s path within the container. |
conversation_id |
str | None |
None |
Announce the deletion on this conversation; see upload_file. |
Returns
Section titled “Returns”What the server deleted.
zip_url()
Section titled “zip_url()”async def zip_url(container: FileContainer, path: str | None = None) -> strA URL serving a container as a zip.
Returns the URL rather than the bytes because that is what the API hands
back — always the tokenized /raw leg, since a zip is assembled on demand
and cannot be presigned. The token is single-use and is the credential,
so fetch it without your API key, and only once.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
container |
FileContainer |
— | Which files to zip. |
path |
str | None |
None |
Restrict the zip to this subtree; the whole container by default. |
Returns
Section titled “Returns”An absolute URL to fetch the zip from.
Projects
Section titled “Projects”create_project()
Section titled “create_project()”async def create_project(name: str, *, from_deployment: str | None = None, short_description: str | None = None, description: str | None = None) -> ProjectResponseCreate a project, optionally seeded from a published deployment.
A project seeded from a deployment lands directly in run mode, so the run agent is usable on it immediately.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
name |
str |
— | Human-readable project name. |
from_deployment |
str | None |
None |
A deployment handle, "<company>/<name>". The wire field is from, which is a reserved word in Python. |
short_description |
str | None |
None |
One-line summary. |
description |
str | None |
None |
Longer description. |
Returns
Section titled “Returns”The created project.
Throws
Section titled “Throws”| Exception | When |
|---|---|
AuraApiError |
The deployment handle is unknown or fails its run contract. |
list_projects()
Section titled “list_projects()”async def list_projects() -> list[ProjectSummary]List your projects, following pagination.
Returns
Section titled “Returns”A summary of every project you can see.
get_project()
Section titled “get_project()”async def get_project(project_id: str) -> ProjectResponseFetch one project.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
project_id |
str |
— | The project’s id. |
Returns
Section titled “Returns”The project.
Throws
Section titled “Throws”| Exception | When |
|---|---|
AuraApiError |
No such project, or it is not yours. |
delete_project()
Section titled “delete_project()”async def delete_project(project_id: str) -> NoneDelete a project and everything in it.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
project_id |
str |
— | The project’s id. |
Throws
Section titled “Throws”| Exception | When |
|---|---|
AuraApiError |
No such project, or it is not yours. |
Conversations
Section titled “Conversations”list_conversations()
Section titled “list_conversations()”async def list_conversations(project_id: str) -> list[ConversationResponse]List a project’s conversations, following pagination.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
project_id |
str |
— | The project’s id. |
Returns
Section titled “Returns”All conversations in the project.
create_conversation()
Section titled “create_conversation()”async def create_conversation(project_id: str, title: str | None = None) -> ConversationResponseStart a new conversation in a project.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
project_id |
str |
— | The project’s id. |
title |
str | None |
None |
Optional title; the server names it otherwise. |
Returns
Section titled “Returns”The created conversation.
delete_conversation()
Section titled “delete_conversation()”async def delete_conversation(project_id: str, conversation_id: str) -> NoneDelete one conversation.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
project_id |
str |
— | The project’s id. |
conversation_id |
str |
— | The conversation’s id. |
Throws
Section titled “Throws”| Exception | When |
|---|---|
AuraApiError |
No such conversation in that project. |
Chat turns
Section titled “Chat turns”send_message()
Section titled “send_message()”async def send_message(project_id: str, content: str, *, conversation_id: str | None = None, client_msg_id: str | None = None) -> ChatResponseDispatch a message without waiting for the agent’s reply.
Use this when you want to poll get_conversation_state yourself; chat is
the one-await version.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
project_id |
str |
— | The project’s id. |
content |
str |
— | The message text. |
conversation_id |
str | None |
None |
Target conversation. Defaults to the project’s active one. |
client_msg_id |
str | None |
None |
Your own idempotency key for the dispatch. Resending one with the same content returns the stored message with turn_id None and starts nothing; with different content the server answers 409. |
Returns
Section titled “Returns”The dispatch result, including the stored user message and its sequence.
get_conversation_state()
Section titled “get_conversation_state()”async def get_conversation_state(project_id: str, conversation_id: str | None = None) -> ConversationSyncResponseRead an atomic snapshot of a conversation: its messages plus turn state.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
project_id |
str |
— | The project’s id. |
conversation_id |
str | None |
None |
Which conversation. Defaults to the project’s active one at the time of the call. |
Returns
Section titled “Returns”The messages the server has stored and whether a turn is in flight.
chat()
Section titled “chat()”async def chat(project_id: str, content: str, *, conversation_id: str | None = None, client_msg_id: str | None = None, poll_interval: float = 1.0, timeout: float = 900.0, quiet_probe: float = 30.0, on_delta: Callable[[str], None] | None = None, on_tool_activity: Callable[[ToolActivityData], None] | None = None) -> ChatMessageResponseSend a message and wait for the agent’s reply, following the turn live.
The turn is followed over the project WebSocket, so the wait is event-driven —
turn-end comes from the authoritative stream_end rather than from polling — and
on_delta / on_tool_activity see the turn as it happens. When the socket cannot
be opened, or dies mid-turn, this degrades silently to polling /chat/sync: the
reply is unaffected, only the callbacks stop.
The returned message always comes from a /chat/sync reconcile, never from the
accumulated deltas. Deltas carry no sequence numbers, so a dropped frame is
undetectable; the stream is liveness and the stored row is truth.
On the polling path the reply is the first assistant message whose sequence
exceeds the dispatched one, accepted only once the turn reads idle and the message
is unchanged across two reads. Comparing sequences rather than counting messages
is what makes the wait attributable to this caller, and immune to the newest-N
window /chat/sync returns.
The wait is pinned to the conversation the dispatch resolved to, so creating or activating another conversation mid-turn cannot redirect it.
A socket that dies announces itself, but one that goes half-open does not; it
simply stops delivering, and a turn’s terminal event with it. So the wait never
concludes anything from silence: whenever the stream has been quiet for
quiet_probe, and again before the deadline is allowed to expire, the turn’s
state is read back from the server. A turn that has finished is returned, however
its stream_end was lost.
Cancelling the task awaiting this coroutine raises asyncio.CancelledError as
usual and stops only the waiting — the turn keeps running server-side. Call
cancel to stop the turn itself.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
project_id |
str |
— | The project’s id. |
content |
str |
— | The message text. |
conversation_id |
str | None |
None |
Target conversation. Defaults to the project’s active one. |
client_msg_id |
str | None |
None |
Your own idempotency key for the dispatch; see send_message. |
poll_interval |
float |
1.0 |
Seconds between polls, on the fallback path. |
timeout |
float |
900.0 |
Seconds to wait before giving up. |
quiet_probe |
float |
30.0 |
Seconds the stream may go quiet before the turn’s state is read back from the server rather than waited on, floored at 1.0s. Lower it to notice a half-open socket sooner, at the cost of a /chat/sync read per interval during a long tool call. |
on_delta |
Callable[[str], None] | None |
None |
Called with each chunk of assistant text, in order. |
on_tool_activity |
Callable[[ToolActivityData], None] | None |
None |
Called for each tool start, completion, or failure. |
Returns
Section titled “Returns”The agent’s completed reply.
Throws
Section titled “Throws”| Exception | When |
|---|---|
AuraTurnCancelledError |
The turn stopped before finishing, so the reply is partial. partial_content carries what the agent managed. |
AuraTurnTimeoutError |
timeout elapsed. The turn is still running server-side; conversation_id is what to pass to cancel. |
AuraApiError |
A call failed, or the turn died before streaming. |
AuraResponseError |
The turn finished but its reply was not in the sync window. |
cancel()
Section titled “cancel()”async def cancel(project_id: str, conversation_id: str | None = None) -> boolStop a running agent turn.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
project_id |
str |
— | The project’s id. |
conversation_id |
str | None |
None |
Restrict cancellation to this conversation. Without it, any running turn in the project is cancelled. |
Returns
Section titled “Returns”Whether anything was actually cancelled.
get_agent_status()
Section titled “get_agent_status()”async def get_agent_status(project_id: str) -> AgentStatusResponseReport whether a turn is in flight, without inferring it from messages.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
project_id |
str |
— | The project’s id. |
Returns
Section titled “Returns”The project’s current agent status.
Run dashboard
Section titled “Run dashboard”create_dashboard_ticket()
Section titled “create_dashboard_ticket()”async def create_dashboard_ticket(project_id: str) -> DashboardTicketResponseMint a short-lived view ticket for the project’s run dashboard.
The dashboard is a live web app in the project’s sandbox. The ticket
stands in for your API key in a place a key must never go — a URL a
browser opens, or an <iframe src>. It is scoped to this one
project’s dashboard, is read-only, and expires after 12 hours; mint
another when it does.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
project_id |
str |
— | The project’s id. Its workspace must be in run mode. |
Returns
Section titled “Returns”The ticket, when it expires, and the path to open. The absolute URL is f"{aura.base_url}{ticket.path}" — the path is returned relative so the response never has to guess which hostname you reached.
Throws
Section titled “Throws”| Exception | When |
|---|---|
AuraApiError |
409 if the project has no run dashboard yet. |
dashboard_url()
Section titled “dashboard_url()”async def dashboard_url(project_id: str) -> strThe absolute URL of the project’s run dashboard, ticket included.
A one-call shorthand for create_dashboard_ticket when all you want is
somewhere to point a browser. Use the ticket itself when you need to
know when it expires.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
project_id |
str |
— | The project’s id. Its workspace must be in run mode. |
Returns
Section titled “Returns”A URL that opens the dashboard until the ticket expires.
Solve executions
Section titled “Solve executions”list_executions()
Section titled “list_executions()”async def list_executions(project_id: str) -> list[ExecutionResponse]List the project’s solve executions, most recent first.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
project_id |
str |
— | The project’s id. |
Returns
Section titled “Returns”Every execution, following pagination.
get_execution()
Section titled “get_execution()”async def get_execution(project_id: str, execution_id: str) -> ExecutionResponseFetch one solve execution.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
project_id |
str |
— | The project’s id. |
execution_id |
str |
— | The execution’s id. |
Returns
Section titled “Returns”The execution, including its status and timing.
Snapshots and tags
Section titled “Snapshots and tags”list_snapshots()
Section titled “list_snapshots()”async def list_snapshots(project_id: str, *, kind: SnapshotKind | None = None, conversation_id: str | None = None, has_solution: bool | None = None, has_label: bool | None = None) -> list[SnapshotResponse]List a project’s snapshots, newest first, following pagination.
Filters are applied server-side and combine (AND); the booleans are
tri-state, where None does not filter and False asks for the rows
whose column is unset. kind=SnapshotKind.SOLVE, has_solution=True is
the “give me the solutions” query.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
project_id |
str |
— | The project’s id. |
kind |
SnapshotKind | None |
None |
Only snapshots of this kind — a completed solve or a manual capture. |
conversation_id |
str | None |
None |
Only snapshots captured from this conversation thread. |
has_solution |
bool | None |
None |
Only snapshots that froze a solution. |
has_label |
bool | None |
None |
Only labeled snapshots. A label also pins retention. |
Returns
Section titled “Returns”Every matching snapshot in the project.
get_snapshot()
Section titled “get_snapshot()”async def get_snapshot(project_id: str, ref: str) -> SnapshotDetailResponseFetch one snapshot, including its file list.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
project_id |
str |
— | The project’s id. |
ref |
str |
— | A snapshot id or a tag name. |
Returns
Section titled “Returns”The snapshot and its files.
rename_snapshot()
Section titled “rename_snapshot()”async def rename_snapshot(project_id: str, snapshot_id: str, label: str | None) -> SnapshotResponseSet, change, or clear a snapshot’s label.
A label is a snapshot’s display title — free text, non-unique. It is not a ref;
to fetch a snapshot by name, tag it (set_tag) instead.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
project_id |
str |
— | The project’s id. |
snapshot_id |
str |
— | The snapshot’s id. |
label |
str | None |
— | The new label, or None to clear it (which also unpins the snapshot from retention pruning, unless it also carries a tag). |
Returns
Section titled “Returns”The snapshot as stored.
list_tags()
Section titled “list_tags()”async def list_tags(project_id: str) -> list[SnapshotTagResponse]List a project’s snapshot tags, following pagination.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
project_id |
str |
— | The project’s id. |
Returns
Section titled “Returns”Every tag and the snapshot it points at.
set_tag()
Section titled “set_tag()”async def set_tag(project_id: str, name: str, snapshot_id: str) -> SnapshotTagResponsePoint a tag at a snapshot, creating or moving it.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
project_id |
str |
— | The project’s id. |
name |
str |
— | The tag name. |
snapshot_id |
str |
— | The snapshot the tag should name. |
Returns
Section titled “Returns”The tag as stored.
Workspace
Section titled “Workspace”get_workspace()
Section titled “get_workspace()”async def get_workspace(project_id: str) -> WorkspaceStateResponseRead what the workspace is on, and whether a checkout is rewriting it.
checkout_in_flight comes from the lock a running checkout holds, so it
is a level to poll rather than an event to have received — worth reading
before issuing a checkout of your own, which the server refuses with a
409 while another one holds the workspace.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
project_id |
str |
— | The project’s id. |
Returns
Section titled “Returns”The workspace’s basis and whether a checkout is in flight.
Throws
Section titled “Throws”| Exception | When |
|---|---|
AuraApiError |
The project has no run workspace yet. |
checkout()
Section titled “checkout()”async def checkout(project_id: str, source: str, conversation_id: str | None = None) -> WorkspaceBasisResponseReset the project’s workspace to a deployment or snapshot.
The server dispatches on source’s segment count: one segment is a snapshot
id or tag name, two is a <group>/<name> deployment handle, three is a
<group>/<project>/<name> in-project snapshot tag.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
project_id |
str |
— | The project’s id. |
source |
str |
— | What to check out, as described above. |
conversation_id |
str | None |
None |
Conversation to attribute the checkout to. |
Returns
Section titled “Returns”The workspace’s new basis.
Throws
Section titled “Throws”| Exception | When |
|---|---|
AuraApiError |
source does not resolve to anything checkout-able, a turn is in flight, or another checkout or snapshot already holds the workspace (409) — a checkout clears the tree before it copies, so two of them interleaved would mix both sources. |
get_usage()
Section titled “get_usage()”async def get_usage(*, since: datetime | None = None, until: datetime | None = None) -> CompanyUsageResponseCompany-wide usage in credits.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
since |
datetime | None |
None |
Include events at or after this moment. A naive datetime is read as UTC. |
until |
datetime | None |
None |
Include events strictly before this moment. A naive datetime is read as UTC. |
Returns
Section titled “Returns”The totals, with the slice attributable to no user or key broken out as unattributed.
Throws
Section titled “Throws”| Exception | When |
|---|---|
AuraApiError |
until is not after since. |
list_user_usage()
Section titled “list_user_usage()”async def list_user_usage(*, since: datetime | None = None, until: datetime | None = None) -> list[UserUsageResponse]Usage grouped per user, spend-descending, following pagination.
Key-driven spend never appears here — see list_api_key_usage.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
since |
datetime | None |
None |
Include events at or after this moment. A naive datetime is read as UTC. |
until |
datetime | None |
None |
Include events strictly before this moment. A naive datetime is read as UTC. |
Returns
Section titled “Returns”One row per user with recorded spend in the window.
list_api_key_usage()
Section titled “list_api_key_usage()”async def list_api_key_usage(*, since: datetime | None = None, until: datetime | None = None) -> list[ApiKeyUsageResponse]Usage grouped per API key, spend-descending, following pagination.
Revoked keys keep their history and come back flagged revoked.
Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
since |
datetime | None |
None |
Include events at or after this moment. A naive datetime is read as UTC. |
until |
datetime | None |
None |
Include events strictly before this moment. A naive datetime is read as UTC. |
Returns
Section titled “Returns”One row per key with recorded spend in the window.