Docs
Envelope
data, meta, cost vs price.
Callers speak Switchboard at the edge; the payload they care about is still the provider’s. JSON ops and proxy return
{ data, meta, error? }. Streams and OpenAI-compat are raw +SB-*headers.
Shape
{
"data": { },
"meta": {
"schema": "v1",
"request_id": "req_…",
"outcome": "sent",
"cache": "miss",
"provider_account": "house-primary",
"units": { "tokens": 168 },
"cost": { "amount": 0.002, "currency": "USD" },
"price": { "amount": 0.005, "currency": "USD" },
"latency_ms": { "hub": 1.2, "provider": 180 }
}
}
| Field | Owner | Meaning |
|---|---|---|
data |
Third party | Stripe PaymentIntent, chat completion, GraphQL payload, … |
meta |
Switchboard | request id, outcome, who paid the provider key, units, cost/price, latency, resolved model for tiers |
error |
Switchboard | Hub/policy failure. On errors data is present and null |
error fields: code, message, retryable, request_id, and optionally retry_after_ms (also mirrored as HTTP Retry-After in seconds). See errors.md.
JSON Schema: platform/schemas/envelope.schema.json.
Outcomes
meta.outcome: sent | failed | unknown | pending
Do not treat “object has data and meta” as success — check error / outcome.
Cost vs price
Quoted from the cell price book after metering:
- cost — what the provider charges you (
pricebook://…cost) - price — what you charge the caller (
pricebook://…price)
Connector ops declare meter.cost_ref (e.g. pricebook://twilio/sms/{to_country}). Thinking tiers bill list price from pricebook://switchboard/chat/{tier} and may also record resolved-provider cost.
SDK unwrap
createProxyFetch from @switchboard/sdk returns provider-native JSON to vendor SDKs on success, and preserves { error, data: null, meta } on failure (never stringifies null as the body).
Non-envelope responses
| Surface | Body | Hub facts |
|---|---|---|
| SSE / streams | Raw provider stream | SB-* response headers |
OpenAI-compat /v1/chat/completions |
Raw OpenAI JSON | SB-* headers |