Client
Reference for vorq.Client, its constructors, submit, job, models and the request and retry behavior.
vorq.Client is async-only: every network method is a coroutine. The one exception is
client.job(), which makes no request. For synchronous code, see
OpenAI transport.
Constructor
client = vorq.Client(
*,
base_url: str = "https://api.vorq.co",
timeout: float = 30.0,
max_retries: int = 3,
signer: Signer | None = None,
cipher: Cipher | None = None,
transport: httpx.AsyncBaseTransport | None = None,
verifier: Verifier | None = None,
gateway: str | None = None,
)With VORQ_WALLET_KEY set, vorq.Client() builds a WalletSigner from it, mints the
vorq_sess_… session token from a wallet signature, re-mints it 60 seconds before it expires,
and derives the result cipher from the wallet. With no signer= and no VORQ_WALLET_KEY, it
raises ValueError.
| Parameter | Meaning |
|---|---|
base_url | The coordinator's origin. Pass your coordinator's URL. |
timeout | Connect and connection-pool timeout per request, in seconds. Read and write timeouts are fixed at 900 s so large uploads can finish. It doesn't bound how long a job takes; use handle.result(timeout=...). |
max_retries | Cap on automatic retries per request. See Retry policy. |
signer | Overrides the wallet signer, for example with a KMS-backed signer. See Signer. |
cipher | Overrides the result cipher. An explicit cipher always wins. Otherwise a WalletSigner derives one, and any other client uses VORQ_CIPHER_KEY if it is set. |
transport | Replaces the underlying httpx transport: a proxy, a custom pool or a test double. |
verifier | A vorq.Verifier. Required to post an open bid, including every line of a batch without providers, and for confidential=True. |
gateway | The storage gateway result bytes are read from. See Reading results. |
The client is an async context manager (async with vorq.Client(...) as client:); otherwise
call await client.aclose().
from_session_token()
client = vorq.Client.from_session_token(token: str, *, <same keyword arguments>) -> ClientBuilds a client on a pre-minted vorq_sess_… token. The token is never rotated ahead of expiry.
With a signer=, a 401 re-mints it once; without one, the token is used as-is, and the client
can read jobs but raises ValidationError on submit and cancel. Without cipher=, the
client uses VORQ_CIPHER_KEY if it is set.
mint_session_token()
token = vorq.mint_session_token(
*,
signer: Signer | None = None,
base_url: str = "https://api.vorq.co",
timeout: float = 30.0,
transport: httpx.BaseTransport | None = None,
) -> strRuns the /auth/nonce → sign → /auth/session handshake once, synchronously, with signer or
VORQ_WALLET_KEY, and returns the token. Raises ValueError without a wallet and
httpx.HTTPStatusError when the coordinator refuses. Use it to call routes that carry no prompt
from your own HTTP code; prompts must go through submit or the sealing transport.
submit()
handle = await client.submit(
model: str,
input: str | dict,
sla: str = "batch",
rate_in: int | str | None = None,
rate_out: int | str | None = None,
provider: int | None = None,
validate_params: bool = True,
*,
confidential: bool = False,
units_out: int | None = None,
custom_id: str | None = None,
) -> JobHandleSeals, signs, pays for and posts one job to POST /v1/jobs, for any modality. The flow is
described in Bids and matching.
| Parameter | Default | Meaning |
|---|---|---|
model | — | A model id as listed by models.list(). The order signs the catalog's numeric model_id, so an unlisted id raises ValidationError. |
input | — | A str is sent as {"input": str}. A dict is the model's own input object and is sent as-is. |
sla | "batch" | "async" ("1h") or "batch" ("24h"). Other <n>h, <n>m or <n>s strings are passed through for the network to validate. |
rate_in | None | Your bid for the input side: atomic token units per 1,000,000 input units, as an int or a string of digits. With both rates None, the order takes the market: the first provider the coordinator ranks, at its own ask. With only one None, that side bids zero. A decimal raises ValidationError. |
rate_out | None | Your bid for the output side, same scaling. Both rates are uint128. |
provider | None | Pins a provider by registry id and seals to its registered key. A provider that publishes no key raises VerificationError. With no rates named, the bid is this provider's ask, and ValidationError is raised when it is not live for the model. |
validate_params | True | Check a dict input against the model's published schema first. See Local param validation. |
confidential | False | Seal only to a provider whose attestation verifies. Requires verifier=. See Verifier. |
units_out | None | Overrides the declared output units, zero included. Must be a non-negative int. See Units. |
custom_id | None | Your own label. It travels sealed and comes back as .custom_id on the result. |
submit requires both a signer and a cipher and raises ValidationError before any request
without them. Sealed containers up to 15,679,488 bytes are posted inline as base64; larger ones
are first uploaded with POST /v1/files and referenced by content id.
Returns a JobHandle.
Local param validation
When the model's entry in GET /v1/models carries a vorq.params_schema (JSON Schema), a
dict input is checked against it before anything is sealed:
- A key the schema marks
false, or a value that fails its subschema, raisesValidationError. reasoning_max_tokensmust be below the output cap, andmin_tokensmust not exceed it.- A key the schema doesn't list triggers a
UserWarningand is sent unchanged.
When the model publishes no schema, or the model list can't be fetched, validation is skipped.
job()
handle = client.job(job_id: str) -> JobHandleRe-attaches to an existing job. Makes no network call and never creates a job.
models
models.list()
await client.models.list() -> list[dict]Returns the data array of GET /v1/models. Each entry is an OpenAI-style model object (id,
object, owned_by) plus a vorq block carrying model_id (the numeric id an order signs)
and enabled. Pass the id as submit(model=...).
models.params_schema()
await client.models.params_schema(model: str) -> dict | NoneThe model's vorq.params_schema, or None when the model isn't listed or publishes none. The
model list behind it is cached for 5 minutes.
batches
client.batches.submit(...) and client.batches.get(batch_id). See Batches.
chain_context()
ctx = await client.chain_context() -> ChainContextThe deployment every signature belongs to, read once from GET /evm/chain and cached for the
client's life. See ChainContext.
fetch_blob()
data = await client.fetch_blob(cid: str) -> bytesReads content-addressed bytes from the configured gateway. See Reading results.
Reading results
A settled job names its result by result_cid. The client reads it with
GET {gateway}/ipfs/{cid}, without authorization, and opens it with its cipher. The coordinator
serves no result bytes.
The gateway is, in order: the gateway= argument, then VORQ_PIN_GATEWAY, then the built-in
public gateway, https://ipfs.filebase.io. An empty string at either of the first two levels disables it, and reads then
raise VorqError.
A fresh result can take a few seconds to become readable, so a 404, a 5xx or a dropped
connection is retried: 8 attempts, 1.5 s apart. Any other error status raises on the first
answer. Every failure raises VorqError.
Retry policy
- A request is retried only when the response carries
X-Vorq-Retryable: true, with exponential backoff and jitter, up tomax_retriestimes. Other errors raise immediately. - A
401re-mints the session token once, when the client holds a signer, and repeats the request. - Submissions (
POST /v1/jobs,POST /v1/files,POST /v1/batches) are never retried on an error status. If the connection drops while posting a job, the client reads the job back by its precomputed id and re-sends only if it doesn't exist. - If the gas fee changes during a submission, the coordinator returns a new quote and the client re-signs the payment, up to 3 attempts in total.