API7 Docs
AISIX AI GatewayOpen-Source AISIX Gateway Admin APIList Passthrough Routes

List Passthrough Routes

GET /admin/v1/passthrough_routes

GET /admin/v1/passthrough_routes

Interactive request editor loads with JavaScript.

Authorization

AdminBearer
AuthorizationBearer <token>

Admin key from config.admin.admin_keys.

In: header

Response Body

application/json

application/json

application/json

curl -X GET "http://127.0.0.1:3001/admin/v1/passthrough_routes"

OK

[
  {
    "id": "string",
    "revision": 0,
    "value": {
      "display_name": "string",
      "enabled": true,
      "forward_client_headers": [
        "string"
      ],
      "name": "string",
      "provider_key_id": "string",
      "timeout_ms": 1,
      "hosts": [
        "string"
      ],
      "path_prefix": null,
      "preserve_host": true,
      "target_url": "string",
      "identity_header": null,
      "auth_header_name": "string",
      "auth_mode": "anonymous",
      "anonymous_key_id": "string",
      "source_cidrs": [
        "string"
      ],
      "credential_mode": "forward_client"
    }
  }
]
Complete operation details and schema variants

GET /admin/v1/passthrough_routes

List Passthrough Routes

List explicit passthrough route resources.

Parameters

Responses

  • 200: OK
  • [].id (string, required): Resource ID, as assigned by the active resource source.
  • [].revision (integer, required): Monotonic resource revision: the etcd mod_revision of the entry, or the load generation in file mode.
  • [].value (object, required): Stored passthrough route configuration.
  • allOf variant 1
  • [].value.anonymous_key_id (string,null, optional): The API key this route's traffic runs as when auth_mode is anonymous: its allowed_routes, rate limits, budget and usage attribution all apply, so anonymous traffic keeps a stable, governable principal. Required for anonymous; ignored otherwise.
  • [].value.auth_header_name (string,null, optional): Header carrying the gateway credential (API key or JWT) when auth_mode is header_key, e.g. x-aisix-api-key. Lets Authorization carry the caller's own upstream credential. The header is stripped before forwarding. Lowercase-only so the forbidden credential-slot list in the coupling is exhaustive (matching is case-insensitive on the wire regardless). Required for header_key; ignored otherwise.
  • [].value.auth_mode (object, optional): How the gateway authenticates the caller on this route.
  • allOf variant 1
  • oneOf variant 1: Standard gateway credential
  • oneOf variant 2: Gateway credential in a dedicated header
  • oneOf variant 3: Anonymous (bound principal)
  • [].value.credential_mode (object, optional): How the upstream credential is produced.
  • allOf variant 1
  • oneOf variant 1: Inject the ProviderKey secret
  • oneOf variant 2: Forward the caller's own credential
  • [].value.display_name (string, optional): Accepted as an alternative spelling of name. Provide the label under exactly one of the two names.
  • [].value.enabled (boolean, optional): Whether this route is active. A disabled route matches nothing.
  • [].value.forward_client_headers (array, optional): Inbound client headers forwarded to the upstream even when this route would otherwise strip them, as single-* glob patterns matched case-insensitively against the header name ("authorization", "x-trace-*"). Empty — the default — overrides no stripping.

A header the caller sends more than once is forwarded with every value preserved.

A route forwards the caller's headers by default, so this field only matters for the ones it removes: the ProviderKey's strip_headers under credential_mode: inject, and the slot the gateway consumed to authenticate the caller. Naming authorization under auth_mode: gateway_key therefore puts the caller's own credential back on the upstream request in place of the one this route would inject, never both — which is what lets an internal service that already authorizes on the end user's Authorization keep doing so unchanged.

A credential slot — authorization, proxy-authorization, x-api-key, api-key, x-goog-api-key, cookie, and the AWS SigV4 trio x-amz-security-token / x-amz-date / x-amz-content-sha256 — and traceparent / tracestate are forwarded only when a pattern names them exactly. A glob such as "*" or "x-*" is a statement about the operator's own headers, not consent to hand a third party the caller's credential or to graft the caller's trace onto that party's telemetry, so a broad pattern overrides the rest of the strip set and leaves those alone.

This route's own auth_header_name and identity_header are read the same way. Both are slots this route chose rather than ones the gateway owns — under auth_mode: header_key the first carries the gateway credential the caller authenticated with, and the second carries an end-user identity this route records and strips — so a glob does not sweep either, and a pattern that names one in full forwards it.

Headers whose forwarding would break the exchange rather than change who it comes from are stripped whatever the patterns say: host, content-length, the hop-by-hop headers that describe the caller's own connection, and the gateway's x-aisix-* namespace.

  • [].value.hosts (array,null, optional): Inbound Host values this route serves (the forward-proxy entry: a TLS-terminating device delivers plaintext traffic with the original host, e.g. api.githubcopilot.com). Matched case-insensitively, ignoring any :port suffix; a leading *. wildcard matches exactly one extra label (*.githubcopilot.com matches proxy.githubcopilot.com). Host-matched requests keep their full path (no prefix stripping unless path_prefix also matched).
  • [].value.identity_header (string,null, optional): Optional header carrying the end-user identity injected by the upstream network device (e.g. x-aisix-user). Its value is recorded on the usage event for per-employee audit attribution and stripped before forwarding. Lowercase-only so the forbidden credential-slot list in the coupling is exhaustive; credential-bearing names (authorization, cookie, …) are rejected outright — their value on the usage event would be credential retention, not identity.
  • [].value.name (string, optional): Operator-facing label, unique within the gateway. Referenced by API keys' allowed_routes globs and used for usage attribution.
  • [].value.path_prefix (string,null, optional): Gateway path prefix this route serves, e.g. /passthrough/openai. Must start with /.

How the prefix is treated depends on the target shape: a target_url route MOUNTS at the prefix, so it is stripped before the remainder is joined to the target base; a preserve_host route MIRRORS an upstream that owns its own path space, so the prefix only selects which requests the route claims and the complete path is forwarded unchanged.

A route WITHOUT hosts must not claim a reserved gateway namespace (/v1, /mcp, /a2a, health probes) — the typed routes would shadow it. A route WITH hosts may use any prefix: host-matched requests dispatch ahead of the typed routes, which is what lets a forward proxy relay an upstream's own namespace (e.g. Copilot's /mcp/... on its chat host). At least one of path_prefix / hosts is required; when both are set the request must satisfy both.

  • [].value.preserve_host (boolean, optional): Derive the target from the request's own Host header (https://<host>), for forward-proxy routes that fan one route out over several official hosts. Only legal when hosts is set — the matched allowlist is what makes the derived target non-attacker- controlled (SSRF guard).
  • [].value.provider_key_id (string,null, optional): ProviderKey whose secret is injected upstream when credential_mode is inject (per-provider auth shape: x-api-key + anthropic-version for Anthropic, Authorization: Bearer otherwise; its strip_headers and TLS settings apply). Required for inject; forbidden for forward_client.
  • [].value.source_cidrs (array,null, optional): Client source CIDRs allowed to use this route. Required (non-empty) when auth_mode is anonymous — network reachability is the only gate left in front of the anonymous principal. Optional hardening for the other modes; unset means no route-level restriction.
  • [].value.target_url (string,null, optional): Explicit upstream base URL, e.g. https://api.openai.com. The matched request's remainder path and query are appended. Exactly one of target_url / preserve_host must be configured.
  • [].value.timeout_ms (integer,null, optional): Maximum time, in milliseconds, for the upstream exchange. Bounds the response-header phase and any non-SSE body read, but never a healthy SSE relay (which ends with the upstream stream or the client hanging up). When omitted, the gateway default request timeout applies the same way.
  • allOf variant 1
  • anyOf variant 1: Path-prefix match
  • anyOf variant 2: Host match
  • allOf variant 2
  • allOf variant 3
  • allOf variant 4
  • allOf variant 5
  • oneOf variant 1: Explicit target URL
  • oneOf variant 2: Preserve inbound host
  • [].value.preserve_host (object, required): Set when the route derives its target from the inbound Host instead of target_url.
  • allOf variant 6
  • allOf variant 7
  • allOf variant 8
  • allOf variant 9
  • allOf variant 10
  • allOf variant 11
  • allOf variant 12: auth_header_name only in header_key mode
  • allOf variant 13: anonymous_key_id only in anonymous mode
  • allOf variant 14
  • allOf variant 15
  • anyOf variant 1: name
  • anyOf variant 2: display_name
  • 401: Missing or invalid admin key
  • error_msg (string, required): Human-readable error message.
  • 500: Configuration store operation failed Response fields (application/json): identical to GET /admin/v1/passthrough_routes, response 401 above.

cURL

curl -X GET 'http://127.0.0.1:3001/admin/v1/passthrough_routes'