# Response envelope

> 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

```json
{
  "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](./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 |
