Skip to content

SDK Reference (auto-generated)

This page is auto-generated from source docstrings via mkdocstrings. For narrative documentation with examples, see the SDK Guide.

Client

unitysvc.Client

Client(api_key: str, *, base_url: str | None = None, api_base_url: str | None = None, s3_base_url: str | None = None, smtp_base_url: str | None = None, timeout: float | Timeout | None = 30.0, verify_ssl: bool = True)

Synchronous customer SDK client.

Parameters:

Name Type Description Default
api_key str

A customer API key (svcpass_...). Encodes the customer context, so no separate customer_id is required.

required
base_url str | None

Override the default control-plane URL. Falls back to UNITYSVC_API_URL, then to :data:DEFAULT_API_URL.

None
api_base_url str | None

HTTP API gateway base URL. Falls back to UNITYSVC_API_BASE_URL. Exposed for downstream SDK use.

None
s3_base_url str | None

S3 gateway base URL. Falls back to UNITYSVC_S3_BASE_URL.

None
smtp_base_url str | None

SMTP gateway base URL. Falls back to UNITYSVC_SMTP_BASE_URL.

None
timeout float | Timeout | None

Per-request timeout in seconds. Default 30s.

30.0
verify_ssl bool

Whether to verify TLS certificates. Default True.

True

Attributes

groups property

groups: Groups

services property

services: Services

enrollments property

enrollments: Enrollments

secrets property

secrets: Secrets

aliases property

aliases: Aliases

recurrent_requests property

recurrent_requests: RecurrentRequests

request_logs property

request_logs: RequestLogs

Functions

from_env classmethod

from_env(**kwargs: object) -> Client

Construct a client from environment variables.

Reads :data:ENV_API_KEY (required) and :data:ENV_API_URL (optional). Any extra keyword arguments are forwarded to the :class:Client constructor.

resolve

resolve(*, path: str, routing_key: dict | None = None, gateway: str = 'api', strategy: str | None = None) -> ResolveResponse

Dry-run resolve a gateway path + routing key.

Mirrors the gateway's selection decision without executing the upstream call — useful for debugging routing or picking a specific service/interface ahead of dispatch. See :mod:unitysvc.resolve for details.

AsyncClient

unitysvc.AsyncClient

AsyncClient(api_key: str, *, base_url: str | None = None, api_base_url: str | None = None, s3_base_url: str | None = None, smtp_base_url: str | None = None, timeout: float | Timeout | None = 30.0, verify_ssl: bool = True)

Asynchronous customer SDK client.

Parameters:

Name Type Description Default
api_key str

A customer API key (svcpass_...).

required
base_url str | None

Override the control-plane URL. Falls back to UNITYSVC_API_URL, then to :data:DEFAULT_API_URL.

None
api_base_url, s3_base_url, smtp_base_url

Optional gateway base URLs, matching the sync :class:Client.

required
timeout float | Timeout | None

Per-request timeout in seconds. Default 30s.

30.0
verify_ssl bool

Whether to verify TLS certificates. Default True.

True

Attributes

groups property

groups: AsyncGroups

services property

services: AsyncServices

enrollments property

enrollments: AsyncEnrollments

secrets property

secrets: AsyncSecrets

aliases property

aliases: AsyncAliases

recurrent_requests property

recurrent_requests: AsyncRecurrentRequests

request_logs property

request_logs: AsyncRequestLogs

Functions

from_env classmethod

from_env(**kwargs: object) -> AsyncClient

Construct an :class:AsyncClient from environment variables.

resolve async

resolve(*, path: str, routing_key: dict | None = None, gateway: str = 'api', strategy: str | None = None) -> ResolveResponse

Async dry-run resolve. See :func:unitysvc.resolve.resolve.

Resources

Groups

unitysvc.groups.Groups

Groups(client: AuthenticatedClient, *, parent: Client)

Operations on customer-visible service groups (/v1/customer/groups).

Example::

llm = client.groups.get("llm")              # by name
page = llm.services()                       # active-record nav
resp = llm.dispatch(json={"messages": [...]})

The same operations are also available on the manager directly (client.groups.services("llm")); :class:Group is just a convenience that pre-binds the slug.

Functions

list

list(*, owner: str = 'all', name: str | None = None) -> GroupListPage

List service groups and collections visible to the customer.

Returns platform groups plus the customer's own editable collections. The visible set is small and bounded — the endpoint is not paginated and returns a {data, count} envelope.

owner narrows the server-side result set: "all" (platform + own, default), "system" (platform only), or "own" (the customer's own collections only).

name is a client-side substring filter applied on top of the returned rows (kept for back-compat with scripts that passed name=). Items are :class:Group wrappers with bound methods.

get

get(name: str) -> Group

Get a single group by its slug name.

create

create(*, name: str, display_name: str | None = None, description: str | None = None) -> Group

Create a customer-owned service collection.

Collections are editable, customer-curated catalogs addressable at /g/<name>. Returns the created group as a :class:Group.

update

update(group_id: str | UUID, *, display_name: Any = _UNSET, description: Any = _UNSET, enabled: Any = _UNSET) -> Group

Update a customer-owned collection's metadata.

Only the fields you pass are changed; omitted fields are left untouched server-side. Returns the updated group.

delete

delete(group_id: str | UUID) -> None

Delete a customer-owned collection.

add_member

add_member(group_id: str | UUID, *, service_id: str | UUID, routing_key: Any = None, sort_order: int = 0) -> ServiceCollectionMemberPublic

Add a member service to a customer-owned collection.

Returns the created member record (raw generated :class:ServiceCollectionMemberPublic).

members

members(group_id: str | UUID) -> builtins.list[ServiceCollectionMemberPublic]

List the member services of a collection (raw member records).

remove_member

remove_member(group_id: str | UUID, service_id: str | UUID) -> None

Remove a member service from a customer-owned collection.

services

services(name: str, *, cursor: str | None = None, limit: int = 50, search: str | None = None) -> ServiceListPage

List services that belong to a group.

Cursor-paginated newest-first. Pass the response's next_cursor back as cursor= to fetch the next page.

This is the canonical service-discovery path — there is no flat /customer/services list endpoint. Items are :class:~unitysvc.services.Service wrappers.

dispatch

dispatch(name: str, *, path: str = '', method: str = 'POST', json: Any = None, data: Any = None, headers: dict[str, str] | None = None, timeout: float | None = None) -> httpx.Response

Send an HTTP request through the group's gateway interface.

Resolves group.interface.base_url (the one group-level interface declared on the group's user_access_interfaces) and makes a single HTTP request. The gateway's routing_policy picks a member service via weighted / content-dependent / price-based selection. No interface= parameter is needed because groups have at most one user-facing interface.

For wrapper primitives, use the fluent API on the active-record :class:Group: grp.cached(ttl="1h").dispatch(json=body).

Parameters:

Name Type Description Default
name str

Group slug.

required
path str

Optional sub-path appended to interface.base_url (e.g. "completions" for an LLM gateway that already has /v1 in its base).

''
method str

HTTP method. Defaults to POST.

'POST'
json Any

Request body as JSON-serializable dict.

None
data Any

Raw request body (bytes / str / form).

None
headers dict[str, str] | None

Extra headers merged on top of the auth header.

None
timeout float | None

Per-request timeout in seconds.

None

Returns:

Type Description
Response

The raw httpx.Response from the gateway. Upstream

Response

errors (4xx/5xx) are not raised — the caller can inspect

Response

.status_code / .json() directly.

Raises:

Type Description
ValueError

If the group has no group-level interface configured (group.interface is None).

stream

stream(name: str, *, path: str = '', method: str = 'POST', json: Any = None, data: Any = None, headers: dict[str, str] | None = None, timeout: float | None = None) -> StreamingResponse

Open a streaming HTTP request through the group-level interface.

Same interface-resolution and URL composition as :meth:dispatch, but returns a context-managed :class:StreamingResponse so the caller can iterate the body lazily (SSE / NDJSON / chunks) via iter_events() / iter_bytes() / iter_lines().

Setting the upstream-protocol stream flag in the request body (e.g. json={"stream": True} for OpenAI-style APIs) is the caller's job — orthogonal to whether the SDK iterates lazily.

Example::

with client.groups.stream(name, json={..., "stream": True}) as r:
    for event in r.iter_events():
        if event.kind == "done":
            break
        handle(event.parsed)

Services

unitysvc.services.Services

Services(client: AuthenticatedClient, *, parent: Client)

Operations on customer-visible services (/v1/customer/services).

Example::

svc = client.services.get(service_id)
ifaces = svc.interfaces()                   # active-record nav
resp = svc.dispatch(json={"messages": [...]})

The same operations are also available on the manager directly (client.services.dispatch(service_id, …)); :class:Service is just a convenience that pre-binds the id.

Functions

get

get(service_id: str | UUID) -> Service

Get a single service by UUID (or partial UUID prefix).

Returns 404 for inactive or non-public services — the customer-visible set matches what client.groups.services(name) returns.

interfaces

interfaces(service_id: str | UUID) -> list[AccessInterface]

List access interfaces dispatchable by this customer.

Returns shared interfaces plus any enrollment-bound interfaces owned by the calling customer. Each entry carries an optional enrollment_idNone for shared, set for BYOK/BYOE.

dispatch

dispatch(service_id: str | UUID, *, interface: str | UUID | None = None, enrollment: str | UUID | None = None, path: str = '', method: str = 'POST', json: Any = None, data: Any = None, headers: dict[str, str] | None = None, timeout: float | None = None) -> httpx.Response

Send an HTTP request to the service through its gateway interface.

Resolves the target interface using :meth:_pick_interface and POSTs to its base_url using the client's svcpass API key. Upstream 4xx/5xx responses are returned as-is; the caller is responsible for inspecting .status_code.

For wrapper primitives (log, cache, failover, tee), use the fluent API on the active-record :class:Service instead: svc.cached(ttl="1h").logged().dispatch(json=body). The fluent API doesn't carry the interface / enrollment selection logic this method does — use this when you need that specifically, the fluent API when you don't.

Parameters:

Name Type Description Default
service_id str | UUID

Service UUID.

required
interface str | UUID | None

Optional interface selector — name or UUID. Required if the service has more than one interface and no enrollment= hint picks one uniquely.

None
enrollment str | UUID | None

Optional enrollment hint. If set, picks the interface whose enrollment_id matches. Silently ignored when there is exactly one interface.

None
path str

Optional sub-path appended to the interface base URL.

''
method str

HTTP method. Defaults to POST.

'POST'
json / data

Request body (mutually exclusive).

required
headers dict[str, str] | None

Extra headers merged on top of the auth header.

None
timeout float | None

Per-request timeout in seconds.

None

stream

stream(service_id: str | UUID, *, interface: str | UUID | None = None, enrollment: str | UUID | None = None, path: str = '', method: str = 'POST', json: Any = None, data: Any = None, headers: dict[str, str] | None = None, timeout: float | None = None) -> StreamingResponse

Open a streaming HTTP request through the resolved service interface.

Sibling to :meth:dispatch — same interface resolution, auth, and URL composition; the difference is that the response body is consumed lazily via :class:StreamingResponse. Use for SSE / NDJSON / chunked LLM responses where buffering the full body before yielding chunks would defeat the streaming UX.

The upstream-protocol stream flag (e.g. json={"stream": True} for OpenAI-compatible APIs) is orthogonal — set it in the body if the upstream requires it. stream() controls only how the SDK consumes the response.

Example::

with client.services.stream(svc_id, json={..., "stream": True}) as r:
    print(r.status_code)
    for event in r.iter_events():
        if event.kind == "done":
            break
        handle(event.parsed)

Args: same as :meth:dispatch.

Returns:

Name Type Description
A StreamingResponse

class:StreamingResponse context manager.

schedule

schedule(service_id: str | UUID, *, recurrence: dict[str, Any], interface: str | UUID | None = None, enrollment: str | UUID | None = None, path: str = '', method: str = 'POST', json: Any = None, headers: dict[str, str] | None = None, name: str | None = None) -> RecurrentRequestPublic

Schedule a recurring dispatch.

Same interface-resolution rule as :meth:dispatch. Creates a :class:~unitysvc._generated.models.recurrent_request_public.RecurrentRequestPublic via POST /customer/recurrent-requests. The server then fires the request on the given schedule (cron or fixed interval) against the resolved interface's gateway path.

Parameters:

Name Type Description Default
service_id str | UUID

Service UUID.

required
recurrence dict[str, Any]

Schedule spec. One of::

{"schedule_type": "interval", "interval_seconds": 300} {"schedule_type": "cron", "cron_expression": "/5 * * * ", "timezone": "UTC"}

required
interface / enrollment / path / method / json / headers

Same as :meth:dispatch — resolve the target interface and compose the gateway URL.

required
name str | None

Optional human label for the recurrent request.

None

Enrollments

unitysvc.enrollments.Enrollments

Enrollments(client: AuthenticatedClient, *, parent: Client)

Operations on the customer's enrollments (/v1/customer/enrollments).

Example::

enr = client.enrollments.create(
    service_id=svc.id,
    parameters={"endpoint": "https://my-host", "api_key": "..."},
)
# Poll for activation:
while enr.status == "pending":
    time.sleep(1)
    enr = enr.refresh()

Or via the :class:~unitysvc.services.Service shortcut:

enr = svc.enroll(parameters={...})

Functions

list

list(*, skip: int = 0, limit: int = 100, include_service_details: bool = True) -> EnrollmentList

List enrollments owned by the calling customer.

get

get(enrollment_id: str | UUID, *, include_service_details: bool = True) -> Enrollment

Get one enrollment by UUID.

create

create(*, service_id: str | UUID, parameters: dict[str, Any] | None = None) -> Enrollment

Enroll in a service (async — poll status via :meth:Enrollment.refresh).

Returns immediately with status="pending"; the server activates the enrollment in a background worker once required parameters / secrets are satisfied.

Parameters:

Name Type Description Default
service_id str | UUID

Service UUID.

required
parameters dict[str, Any] | None

Optional user parameters (BYOK/BYOE values, model selection, etc.). Secret-shaped keys (api_key, password, ...) are masked on reads.

None

cancel

cancel(enrollment_id: str | UUID) -> CustomerEnrollmentCancelResponse

Cancel (unenroll) — sets status to cancelled.

Access interfaces and parameters are preserved so the customer can re-enroll later with the same parameters to reactivate.

Secrets

unitysvc.secrets.Secrets

Secrets(client: AuthenticatedClient)

Operations on the customer's secret store (/v1/customer/secrets).

Functions

list

list(*, skip: int = 0, limit: int = 100) -> SecretsPublic

List all secrets owned by the authenticated customer.

get

get(name: str) -> SecretPublic

Get a single secret by name (metadata only — value is never returned).

set

set(name: str, value: str) -> SecretPublic

Set name to value (idempotent — creates or replaces).

Maps to PUT /v1/customer/secrets/{name}. Returns the secret's public metadata; the value itself is never echoed back. The encryption is handled server-side.

Parameters:

Name Type Description Default
name str

Secret name (must match ^[A-Z_][A-Z0-9_]*$).

required
value str

Secret value. May be empty.

required

Returns:

Type Description
SecretPublic

SecretPublic metadata for the stored secret.

delete

delete(name: str) -> Message

Delete a secret by name. This action cannot be undone.

Aliases

unitysvc.aliases.Aliases

Aliases(client: AuthenticatedClient)

Operations on the customer's service aliases (/v1/customer/aliases).

Functions

list

list(*, skip: int = 0, limit: int = 100, name: str | None = None, include_deactivated: bool = False) -> Any

List aliases owned by the authenticated customer.

get

get(alias_id: str | UUID) -> Any

Get a single alias by id.

create

create(body: ServiceAliasCreate | dict[str, Any]) -> Any

Create a new alias.

update

update(alias_id: str | UUID, body: ServiceAliasUpdate | dict[str, Any]) -> Any

Update an existing alias.

switch_routing

switch_routing(alias_id: str | UUID, *, on: bool = True) -> Any

Switch routing on or off for an alias.

When on is True, any sibling alias currently routing the same (name, routing_key) combo is atomically demoted. When False the alias simply stops routing.

delete

delete(alias_id: str | UUID) -> Any

Delete an alias by id.

RecurrentRequests

unitysvc.recurrent_requests.RecurrentRequests

RecurrentRequests(client: AuthenticatedClient)

Operations on the customer's recurrent requests (/v1/customer/recurrent-requests).

Functions

list

list(*, service_id: str | UUID | None = None, enrollment_id: str | UUID | None = None, status: RecurrentRequestStatusEnum | str | None = None, skip: int = 0, limit: int = 100) -> RecurrentRequestsPublic

List recurrent requests owned by the authenticated customer.

get

get(request_id: str | UUID) -> RecurrentRequestPublic

Get a single recurrent request by id.

create

create(body: RecurrentRequestCreate | dict[str, Any]) -> RecurrentRequestPublic

Create a new recurrent request.

update

update(request_id: str | UUID, body: RecurrentRequestUpdate | dict[str, Any]) -> RecurrentRequestPublic

Update an existing recurrent request.

trigger

trigger(request_id: str | UUID) -> Any

Force an immediate run of a recurrent request.

delete

delete(request_id: str | UUID) -> Any

Delete a recurrent request by id.

RequestLogs

unitysvc.request_logs.RequestLogs

RequestLogs(client: AuthenticatedClient)

Operations on the customer's request log (/v1/customer/request-logs).

Functions

start

start(*, truncate_long_message: bool | None = None) -> LoggingStatusResponse

Enable request logging for the authenticated user.

Subsequent gateway dispatches will be persisted and visible via :meth:list / :meth:get. Idempotent — safe to call when logging is already on.

Parameters:

Name Type Description Default
truncate_long_message bool | None

Picks the storage mode.

  • Truetruncated: 8 KB inline preview is stored, no S3 upload. The listing endpoint serves the preview; :meth:get returns the same preview (full body is not preserved).
  • Falsecomplete: full request / response bodies are uploaded to S3 so :meth:get can return the full payload. The listing endpoint still returns only the preview to keep paging cheap.
  • None (default) → preserve the user's existing preference.logging mode if it's already truncated or complete; otherwise fall back to truncated. Use this when the frontend has already set the preference via PATCH /users/me and you just want to flip the gateway on. SDK scripts that don't manage preferences should pass True or False explicitly.
None

stop

stop() -> LoggingStatusResponse

Disable request logging for the authenticated user.

Already-persisted rows remain visible via :meth:list / :meth:get; only future dispatches are skipped. Idempotent.

list

list(*, skip: int = 0, limit: int = 50, service_id: UUID | None = None, service_enrollment_id: UUID | None = None, status_min: int | None = None, status_max: int | None = None, start_time: datetime | None = None, end_time: datetime | None = None, user_request_path: str | None = None, error_source: str | None = None, error_type: str | None = None, gateway_source: str | None = None) -> RequestLogListResponse

List request logs for the authenticated customer.

Returns lightweight columns (no body / header fields) for fast pagination. Default time range is the last 24 hours when both start_time and end_time are omitted.

Parameters:

Name Type Description Default
skip int

Pagination offset.

0
limit int

Page size (1–200).

50
service_id UUID | None

Filter by service listing.

None
service_enrollment_id UUID | None

Filter by enrollment.

None
status_min int | None

Min upstream status code (100–599).

None
status_max int | None

Max upstream status code (100–599).

None
start_time datetime | None

Inclusive lower bound on event_timestamp.

None
end_time datetime | None

Inclusive upper bound on event_timestamp.

None
user_request_path str | None

Path-prefix filter.

None
error_source str | None

"gateway" or "upstream".

None
error_type str | None

Filter by error type.

None
gateway_source str | None

"apisix" or "backend".

None

get

get(log_id: UUID | str) -> RequestLogDetail

Get full detail of a single request log row.

Includes request and response bodies (subject to the backend's redaction rules — upstream identity and credentials are stripped server-side).

Streaming responses

Services.stream() / Groups.stream() (and async siblings) return these context-managed wrappers. See the Streaming section of the SDK guide for usage.

Streaming-response primitives for Services.stream / Groups.stream.

Provides lazy iteration over HTTP response bodies — SSE, NDJSON, plain lines, or raw bytes — selected by Content-Type. Sibling to the buffered :meth:dispatch path; same auth and interface resolution, but httpx.Client.stream() instead of request() so the caller sees chunks as they arrive.

The dominant use case is LLM SSE streaming (data: {...}\n\n frames terminated by data: [DONE]); the same surface handles NDJSON and arbitrary binary streams.

Classes

StreamEvent dataclass

StreamEvent(kind: str, parsed: Any = None, raw: bytes = b'', text: str | None = None)

One frame from a streaming response body.

Attributes:

Name Type Description
kind str

"sse" | "ndjson" | "line" | "bytes" | "done". See :meth:StreamingResponse.iter_events for the taxonomy.

parsed Any

JSON-decoded payload for "sse" / "ndjson", else None.

raw bytes

The raw bytes of this frame (the full SSE frame for "sse", the line including delimiter-stripped bytes for "ndjson" / "line", or the chunk for "bytes").

text str | None

Decoded UTF-8 text for "line" events; None otherwise.

StreamingResponse

StreamingResponse(httpx_client: Client, method: str, url: str, kwargs: dict[str, Any])

Sync context-managed wrapper around an httpx.Response stream.

Created by :meth:Services.stream / :meth:Groups.stream. Opens the underlying httpx.Client.stream() on __enter__ and closes it on __exit__. Status/headers are available before iteration; the body is consumed lazily by iter_events / iter_bytes / iter_lines.

Attributes

response property
response: Response

The underlying httpx.Response. Only valid inside the with block.

Functions

iter_bytes
iter_bytes(chunk_size: int | None = None) -> Iterator[bytes]

Yield raw body chunks as they arrive.

iter_lines
iter_lines() -> Iterator[str]

Yield \n-delimited decoded text lines.

iter_events
iter_events() -> Iterator[StreamEvent]

Yield :class:StreamEvent objects, discriminated by Content-Type.

  • text/event-stream"sse" per frame, "done" on data: [DONE]. Frames split across TCP chunks are reassembled before yielding.
  • application/x-ndjson / application/jsonl"ndjson" per line.
  • text/*"line" per line (text in event.text).
  • anything else → "bytes" per chunk.

AsyncStreamingResponse

AsyncStreamingResponse(httpx_client: AsyncClient, method: str, url: str, kwargs: dict[str, Any])

Async sibling of :class:StreamingResponse. async with to enter.

Functions

iter_events async
iter_events() -> AsyncIterator[StreamEvent]

Async sibling of :meth:StreamingResponse.iter_events.

Resolve (dry-run primitive)

unitysvc.resolve

client.resolve — dry-run gateway route resolution.

Wraps POST /v1/customer/resolve from the generated low-level client. Answers "what would the gateway do for this path + routing key?" without executing the upstream call — useful for debugging, simulating selection, or picking an interface when the caller only knows gateway semantics.

Functions

resolve

resolve(client: AuthenticatedClient, *, path: str, routing_key: dict[str, Any] | None = None, gateway: str = 'api', strategy: str | None = None) -> ResolveResponse

Dry-run resolve a gateway path + routing key to its candidates.

Parameters:

Name Type Description Default
client AuthenticatedClient

Low-level authenticated client (injected by :class:~unitysvc.Client).

required
path str

Gateway request path (same shape as service.dispatch(path=...)), e.g. v1/chat/completions.

required
routing_key dict[str, Any] | None

Optional routing key the gateway would match against interface rules (e.g. {"model": "gpt-4"}).

None
gateway str

"api" (default), "s3", or "smtp". Picks which gateway prefix the path belongs to.

'api'
strategy str | None

Override the group's configured routing strategy (e.g. "by_price", "lowest_latency").

None

Returns:

Name Type Description
A ResolveResponse

class:~unitysvc._generated.models.resolve_response.ResolveResponse

ResolveResponse

with the candidate list, the effective strategy, and an

ResolveResponse

optional pre-selected candidate.

Exceptions

unitysvc.exceptions

Exception hierarchy for the customer SDK.

All errors raised by unitysvc are subclasses of :class:UnitysvcSDKError, which in turn is a subclass of Exception. This lets callers choose the granularity that fits their use case::

try:
    client.secrets.list()
except NotFoundError:
    ...
except UnitysvcSDKError:
    ...

Classes

UnitysvcSDKError

Bases: Exception

Base class for all errors raised by unitysvc.

APIError

APIError(message: str, *, status_code: int, detail: Any = None, response_body: bytes | None = None)

Bases: UnitysvcSDKError

The server returned a non-success status code.

Attributes:

Name Type Description
status_code

HTTP status code.

detail

Parsed error payload from the server (usually a dict matching ErrorResponse), or the raw text if not JSON.

response_body

Raw response bytes, useful for debugging.

AuthenticationError

AuthenticationError(message: str, *, status_code: int, detail: Any = None, response_body: bytes | None = None)

Bases: APIError

401 Unauthorized. The API key is missing, invalid, or expired.

PermissionError

PermissionError(message: str, *, status_code: int, detail: Any = None, response_body: bytes | None = None)

Bases: APIError

403 Forbidden. The authenticated customer cannot perform this action.

NotFoundError

NotFoundError(message: str, *, status_code: int, detail: Any = None, response_body: bytes | None = None)

Bases: APIError

404 Not Found. The requested resource does not exist for this customer.

ValidationError

ValidationError(message: str, *, status_code: int, detail: Any = None, response_body: bytes | None = None)

Bases: APIError

400/422. The request body failed server-side validation.

detail typically contains a list of per-field errors.

ConflictError

ConflictError(message: str, *, status_code: int, detail: Any = None, response_body: bytes | None = None)

Bases: APIError

409 Conflict. The request conflicts with server state (e.g. duplicate name).

RateLimitError

RateLimitError(message: str, *, status_code: int, detail: Any = None, response_body: bytes | None = None)

Bases: APIError

429 Too Many Requests. Retry after the backoff window.

ServerError

ServerError(message: str, *, status_code: int, detail: Any = None, response_body: bytes | None = None)

Bases: APIError

5xx. The server encountered an error. Safe to retry idempotent requests.