Sandbox API

Gateway

Catalog, health, usage

Catalog, health, usage

Every request needs a credential — see Authentication.

MethodPathSummary
GET/sandbox/healthzGateway aggregated health
GET/sandbox/v1/catalogExecution catalog (languages, agents, profiles)
GET/sandbox/v1/providersModel providers this caller has a key for
GET/sandbox/v1/quotaEffective concurrency quota and current project usage
GET/sandbox/v1/usage/summaryProject-scoped latency percentiles (p50/p95/p99)

Common headers

Accepted on every endpoint on this page.

NameInTypeRequiredDescription
x-correlation-idheaderstringnoEnd-to-end correlation id for this eval run. When set, the gateway and downstream services honor it verbatim in logs, Cloud Trace span attributes, async job payloads, and Langfuse trace.id. When omitted, the gateway generates a ULID and echoes it on the response.

Endpoints

Gateway aggregated health

GET /sandbox/healthz

Responses

StatusDescriptionBody
200Successful Responseobject

Execution catalog (languages, agents, profiles)

GET /sandbox/v1/catalog

Parameters

NameInTypeRequiredDescription
kindquerystring | nullno

Responses

StatusDescriptionBody
200Execution catalog entriesany
422Validation ErrorHTTPValidationError

Example response:

{
  "items": [
    {
      "id": "oracle",
      "kind": "agent",
      "tier": 1
    },
    {
      "id": "opencode",
      "kind": "agent",
      "tier": 1
    }
  ],
  "count": 2
}

Model providers this caller has a key for

GET /sandbox/v1/providers

Which providers the caller can actually run a model from.

The platform has no model catalog and deliberately does not gain one here: it accepts any provider/model and leases a key for the provider at run time, so the set of runnable models is whatever the provider serves and not something we can enumerate without inventing a list to maintain by hand.

What is knowable, and what callers were actually missing, is the provider half. Without it a UI could only offer a free-text box, and a model naming a provider with no key was accepted and then failed inside the trial — roughly eighty seconds of cluster time to learn that no key could be leased. That is now answerable before submitting.

Answers for exactly the namespace a run by this caller would lease from: the caller's own tenant:project. There is no shared fallback pool — a missing key for that pair is a provisioning gap for that tenant, not a cue to bill another namespace. source is always tenant when present.

Tenancy comes from :func:resolve_scope, the same check the job routes use, so a credential cannot read a namespace it does not hold: this answer names which providers a tenant has provisioned, and a forged tenant header must not be able to ask on their behalf.

Responses

StatusDescriptionBody
200Successful Responseany

Effective concurrency quota and current project usage

GET /sandbox/v1/quota

Responses

StatusDescriptionBody
200Successful Responseany

Project-scoped latency percentiles (p50/p95/p99)

GET /sandbox/v1/usage/summary

Responses

StatusDescriptionBody
200Successful Responseobject

Schemas

The object shapes referenced above.

HTTPValidationError

FieldTypeRequiredDescription
detailValidationError[]no

ValidationError

FieldTypeRequiredDescription
locstring | integer[]yes
msgstringyes
typestringyes
inputanyno
ctxobjectno

Machine-readable spec: OpenAPI YAML.