# Gateway API

Provon exposes an OpenAI-compatible inference surface plus project-scoped discovery and Provider
Key management endpoints. The configured runtime is the source of truth for endpoint and feature
availability.

## Base URLs

For the local Node runtime:

| Surface                    | Base URL                           |
| -------------------------- | ---------------------------------- |
| Explicit Gateway inference | `http://127.0.0.1:3000/gateway/v1` |
| OpenAI-compatible aliases  | `http://127.0.0.1:3000/v1`         |
| Gateway control API        | `http://127.0.0.1:3000/v1/gateway` |

Prefer `/gateway/v1` as the SDK base URL when Gateway, API, and OTLP share one origin. It keeps
model traffic distinct from Provon's control API and OTLP routes.

Production deployments replace the local origin with the public Gateway origin for that runtime.

## Authentication

Send a Provon project API key as a Bearer token:

```http
Authorization: Bearer <PROVON_API_KEY>
```

Relevant API-key capabilities:

| Capability       | Grants                                                                       |
| ---------------- | ---------------------------------------------------------------------------- |
| `gateway:invoke` | Model inference through `/gateway/v1/*` and supported `/v1/*` aliases        |
| `workspace:read` | Provider catalog, capability matrix, model selection, and Provider Key reads |
| `gateway:manage` | Provider Key and model-binding writes                                        |

Workbench sessions use project permissions instead of these API-key capabilities.

Provider credentials are not valid Gateway client credentials. They remain attached to
project-scoped Provider Keys.

## First Request

```bash
curl "$PROVON_BASE_URL/gateway/v1/chat/completions" \
  -H "Authorization: Bearer $PROVON_API_KEY" \
  -H "Content-Type: application/json" \
  -H "x-otel-gen-ai-conversation-id: conversation-123" \
  -d '{
    "model": "openai/gpt-5-mini",
    "messages": [{"role": "user", "content": "Hello"}]
  }'
```

The request and response follow the selected Gateway endpoint shape. Provider adapters may
translate that shape to a native upstream protocol and translate the result back.

## Model Values

| Shape              | Example             | Behavior                                                   |
| ------------------ | ------------------- | ---------------------------------------------------------- |
| Provider-qualified | `openai/gpt-5-mini` | Pins provider resolution to `openai`                       |
| Plain model        | `gpt-5-mini`        | Applies a matching Model Policy, then registry inference   |
| Auto Router        | `provon/auto`       | Selects an eligible mapped Provider Key model when enabled |

Provider-qualified values are the safest integration default because provider intent is explicit.
Plain names are useful when the project owns a stable logical model name. `provon/auto` is useful
when target selection should consider request fit, health, latency, and estimated cost.

See [Routing and reliability](./gateway-routing.md).

## Request Context

Gateway context headers become OpenTelemetry attributes on the root and attempt spans. They do not
change provider routing unless a separately configured policy uses the same value.

| Header                          | Trace attribute          |
| ------------------------------- | ------------------------ |
| `x-otel-gen-ai-conversation-id` | `gen_ai.conversation.id` |
| `x-otel-user-id`                | `user.id`                |
| `x-otel-user-hash`              | `user.hash`              |
| `x-otel-user-name`              | `user.name`              |
| `x-otel-user-full-name`         | `user.full_name`         |
| `x-otel-user-email`             | `user.email`             |
| `x-otel-session-id`             | `session.id`             |
| `x-otel-gen-ai-agent-id`        | `gen_ai.agent.id`        |
| `x-otel-gen-ai-agent-name`      | `gen_ai.agent.name`      |
| `x-otel-gen-ai-agent-version`   | `gen_ai.agent.version`   |
| `x-otel-gen-ai-workflow-name`   | `gen_ai.workflow.name`   |

Values are trimmed and limited to 512 characters. Use stable pseudonymous user IDs when raw
identity is not required. Never send secrets in context headers.

For multi-turn diagnostics, `x-otel-gen-ai-conversation-id` is the most important field: Provon uses
it to reconstruct a conversation across traces.

## Endpoint Discovery

Gateway recognizes these endpoint families:

```text
chat-completions      responses             messages
embeddings            rerank                ocr
image-generations     image-edits           image-variations
audio-transcriptions  audio-speech          moderations
batches               files                 fine-tuning
vector-stores         realtime              videos
video-extensions      video-edits           search
classify              pipeline              a2a
mcp-tools
```

Recognition does not imply that every provider supports every family. Query the project capability
matrix:

```bash
curl "$PROVON_BASE_URL/v1/gateway/capability-matrix?includeDisabled=false" \
  -H "Authorization: Bearer $PROVON_API_KEY"
```

The response distinguishes:

- `native`: the provider exposes the endpoint shape directly;
- `translated`: Provon adapts the Gateway shape to a provider-native endpoint;
- `bridged`: the public endpoint is implemented through another provider endpoint family;
- `unsupported`: the provider cannot serve that endpoint;
- `available` or `disabled`: project Provider Key availability.

Inspect eligible model targets for one endpoint and feature set:

```bash
curl \
  "$PROVON_BASE_URL/v1/gateway/model-selection?endpoint=chat-completions&features=streaming,tool-calling" \
  -H "Authorization: Bearer $PROVON_API_KEY"
```

Supported feature filters include streaming, tool calling, structured outputs, reasoning, vision,
audio, prompt caching, usage metadata, native passthrough, and custom base URLs.

List the provider catalog:

```bash
curl "$PROVON_BASE_URL/v1/gateway/providers" \
  -H "Authorization: Bearer $PROVON_API_KEY"
```

## Control API

Project API keys with `workspace:read` can inspect Gateway configuration:

| Method | Path                                            | Result                                    |
| ------ | ----------------------------------------------- | ----------------------------------------- |
| `GET`  | `/v1/gateway/providers`                         | Runtime provider catalog                  |
| `GET`  | `/v1/gateway/capability-matrix`                 | Provider and Provider Key capabilities    |
| `GET`  | `/v1/gateway/model-selection`                   | Eligible models for endpoint/features     |
| `GET`  | `/v1/gateway/provider-keys`                     | Project Provider Keys without raw secrets |
| `GET`  | `/v1/gateway/provider-keys/:keyId/capabilities` | One Provider Key and its model mappings   |

Keys with `gateway:manage` can write Provider Keys and mappings:

| Method   | Path                                                          | Operation                                             |
| -------- | ------------------------------------------------------------- | ----------------------------------------------------- |
| `POST`   | `/v1/gateway/provider-keys`                                   | Create a Provider Key and optional initial credential |
| `PATCH`  | `/v1/gateway/provider-keys/:keyId`                            | Update target settings or rotate its primary secret   |
| `DELETE` | `/v1/gateway/provider-keys/:keyId`                            | Delete the target, credentials, and mappings          |
| `POST`   | `/v1/gateway/provider-keys/:keyId/capabilities`               | Create or update a model mapping                      |
| `DELETE` | `/v1/gateway/provider-keys/:keyId/capabilities/:capabilityId` | Delete a model mapping                                |

Signed-in Workbench routes also expose project-qualified variants under
`/v1/projects/:projectId/gateway/*`. Prefer the unqualified paths for project API-key clients
because the project is already derived from the key.

## Common Inference Paths

The explicit Gateway prefix accepts the corresponding path under `/gateway/v1`:

| Operation                                        | Path                                          |
| ------------------------------------------------ | --------------------------------------------- |
| Chat Completions                                 | `/gateway/v1/chat/completions`                |
| Responses                                        | `/gateway/v1/responses`                       |
| Messages, including Anthropic native passthrough | `/gateway/v1/messages`                        |
| Embeddings                                       | `/gateway/v1/embeddings`                      |
| Rerank                                           | `/gateway/v1/rerank`                          |
| Image generation                                 | `/gateway/v1/images/generations`              |
| Audio transcription                              | `/gateway/v1/audio/transcriptions`            |
| Audio speech                                     | `/gateway/v1/audio/speech`                    |
| Realtime client secret                           | `/gateway/v1/realtime/client_secrets`         |
| Realtime WebSocket                               | `/gateway/v1/realtime?model=<provider/model>` |

Use the capability matrix before integrating less common or provider-native paths.

## Streaming

For OpenAI-compatible streaming endpoints, send the normal request field:

```json
{
  "model": "openai/gpt-5-mini",
  "stream": true,
  "messages": [{ "role": "user", "content": "Write one sentence." }]
}
```

The candidate target must declare `streaming`. Provon streams the provider-compatible response
while collecting final attempt, usage, guardrail, and trace evidence where available.

## Request IDs

Successful and failed inference responses include `x-provon-request-id` after request context is
established. Log this value with the application request and use it to correlate:

- the client failure;
- the Gateway root trace ID;
- upstream attempt spans;
- usage-policy and guardrail evidence.

Clients may send `x-provon-request-id`, but generated IDs are safer unless the caller guarantees
uniqueness.

## Error Shape

Gateway-owned errors use a JSON envelope:

```json
{
  "error": {
    "code": "GATEWAY_PAUSED",
    "message": "gateway is paused for this project",
    "details": {}
  }
}
```

Usage-policy rejections return `429` with `Retry-After`, `RateLimit-Limit`,
`RateLimit-Remaining`, and `RateLimit-Reset`. Guardrail blocks return `409` with
`PROVON_GATEWAY_GUARD_TRIGGERED` and guardrail headers.

Provon Cloud managed model requests return `402` with `INSUFFICIENT_GATEWAY_CREDITS` when the
organization cannot reserve the estimated request cost. A paused project Gateway returns `503`
with `GATEWAY_PAUSED`. Model resolution with no eligible target returns `404` with
`UPSTREAM_NOT_CONFIGURED`.

Upstream provider errors remain provider-compatible when possible and gain normalized
classification in the Gateway trace.

## Transport Limits

Runtime defaults are:

- 4 MiB for JSON request bodies;
- 25 MiB for other supported request bodies;
- no compressed Gateway request body;
- a 60-second overall Gateway request deadline;
- 2 MiB maximum response body capture for telemetry.

Deployments can override these limits. A provider may impose stricter limits.

## Related Docs

- [Gateway quickstart](./gateway-quickstart.md)
- [Migration guide](./gateway-migration.md)
- [Integrate SDKs](./gateway-integrations.md)
- [Model providers](./model-providers.md)
- [Routing and reliability](./gateway-routing.md)
- [Gateway governance](./gateway-governance.md)
- [Gateway evidence](./gateway-observability.md)
- [Production guide](./gateway-production.md)
- [Gateway troubleshooting](./gateway-troubleshooting.md)
