API7 Docs

Create Passthrough Route

POST /environments/{env_id}/passthrough_routes

POST /environments/{env_id}/passthrough_routes

Interactive request editor loads with JavaScript.

Authorization

BearerAdminToken
AuthorizationBearer <token>

Organization-scoped admin token. Read operations require a valid token, and write operations require a token with write permission.

In: header

Path Parameters

env_id*string

Environment ID that scopes the request.

Formatuuid

Request Body

application/json

Create an explicit passthrough route. Coupling rules (enforced here and identically in the gateway's resource schema): at least one of path_prefix / hosts; exactly one of target_url / preserve_host: true (the latter only together with hosts); header_keyauth_header_name; anonymousanonymous_key_id + non-empty source_cidrs; injectprovider_key_id, forward_client ⇒ no provider_key_id.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "$AISIX_CP/environments/$ENV_ID/passthrough_routes" \  -H "Authorization: Bearer $AISIX_TOKEN" \  -H "Content-Type: application/json" \  -d '{    "name": "copilot-chat",    "hosts": [      "api.githubcopilot.com",      "*.individual.githubcopilot.com"    ],    "preserve_host": true,    "auth_mode": "header_key",    "auth_header_name": "x-aisix-api-key",    "credential_mode": "forward_client",    "identity_header": "x-aisix-user"  }'

Created

{
  "passthrough_route": {
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "env_id": "3f917d0d-4dff-42f3-97c4-6a5455dfe8c2",
    "name": "string",
    "path_prefix": "string",
    "hosts": [
      "string"
    ],
    "target_url": "string",
    "preserve_host": false,
    "auth_mode": "gateway_key",
    "auth_header_name": "string",
    "anonymous_key_id": "cf032c4c-881f-492e-aa11-fcbf5714649c",
    "source_cidrs": [
      "string"
    ],
    "credential_mode": "inject",
    "provider_key_id": "f265db88-9bcc-4e5b-add5-bfd9a815465c",
    "identity_header": "string",
    "timeout_ms": 1,
    "enabled": true,
    "created_at": "2019-08-24T14:15:22Z",
    "updated_at": "2019-08-24T14:15:22Z"
  },
  "warnings": [
    {
      "code": "field_ignored",
      "field": "string",
      "min_dp_version": "string",
      "affected_dp_count": 0,
      "affected_dp_versions": [
        "string"
      ]
    }
  ]
}
Complete operation details and schema variants

POST /environments/{env_id}/passthrough_routes

Create Passthrough Route

Create an explicit passthrough route: a binding from a gateway entry — a path_prefix on the gateway's own URL space, an inbound hosts allowlist (forward-proxy traffic delivered with its original Host), or both — to one upstream target, forwarded without protocol translation. The route carries its own gateway authentication mode and upstream credential handling; callers additionally need the route's name granted in their API key's allowed_routes patterns. At least one match dimension (path_prefix or hosts) is required. Exactly one target shape is required: target_url, or preserve_host: true (which derives https://<host> from the matched inbound host and is only accepted together with hosts). auth_mode: header_key requires auth_header_name; auth_mode: anonymous requires anonymous_key_id and a non-empty source_cidrs. credential_mode: inject (the default) requires provider_key_id; credential_mode: forward_client forbids it. The route name is unique within the environment and cannot be changed after creation.

Parameters

  • env_id (path, string, required): Environment ID that scopes the request.

Request body

Content type: application/json

  • name (string, required): Route name, unique within the environment. Fixed at creation; referenced by API keys' allowed_routes.

  • path_prefix (string, optional): Gateway path prefix to serve (segment-boundary match; a target_url route strips it before the remainder joins the target, a preserve_host route forwards the complete path). Reserved gateway namespaces (/v1, /mcp, /a2a, /admin, /livez, /readyz, /metrics) are rejected on a route without hosts — the gateway's own endpoints would shadow it. A route that also matches on hosts may claim any prefix: host-matched requests dispatch ahead of the typed endpoints, which is what lets a forward proxy relay an upstream's own namespace.

  • hosts (array, optional): Inbound Host allowlist to serve. *. wildcards match one extra label and need at least two literal labels (*.example.com, never *.com).

  • target_url (string, optional): Explicit upstream base URL.

  • preserve_host (boolean, optional): Derive the target from the matched inbound host instead of target_url. Only accepted together with hosts.

  • auth_mode (object, optional): Gateway authentication mode for this route.

  • allOf variant 1

  • auth_header_name (string, optional): Lowercase gateway-credential header for header_key mode; credential-bearing names are rejected, and so is setting this on any other auth_mode.

  • anonymous_key_id (string, optional): Environment API key anonymous traffic runs as (required for anonymous mode, rejected on any other). The key must exist in this environment.

  • source_cidrs (array, optional): Source CIDRs allowed to use the route. Required for anonymous mode; optional otherwise.

  • credential_mode (object, optional): Upstream credential handling for this route.

  • allOf variant 1

  • provider_key_id (string, optional): Provider key to inject (required for inject mode; must be visible to this environment; forbidden for forward_client).

  • identity_header (string, optional): Lowercase end-user identity header recorded as client_identity; credential-bearing names are rejected.

  • timeout_ms (integer, optional): Upstream exchange bound in milliseconds (response-header phase and non-SSE body reads; never a healthy SSE relay).

  • enabled (boolean, optional): Whether the route is active on creation.

Responses

  • 201: Created
  • passthrough_route (object, required): An explicit passthrough binding from a gateway entry to one upstream target. Callers additionally need the route's name granted by their API key's allowed_routes patterns.

The body envelope (OpenAI-compatible chat / completions / Responses, or opaque) is not configured: the gateway detects it per request from the body's top-level keys, and guardrail extraction, audit capture, and token-usage recording follow the detection. Bodies are always relayed verbatim; SSE upstream responses are always relayed incrementally.

  • passthrough_route.id (string, required): Unique passthrough route ID.

  • passthrough_route.env_id (string, required): Environment the route belongs to.

  • passthrough_route.name (string, required): Route name, unique within the environment and fixed at creation. Referenced by API keys' allowed_routes patterns and recorded on usage events for attribution.

  • passthrough_route.path_prefix (string, optional): Gateway path prefix this route serves (segment-boundary match: /copilot matches /copilot and /copilot/x, never /copilotx). The prefix is stripped before the remainder joins the target URL. Must not claim a reserved gateway namespace (/v1, /mcp, /a2a, /admin, /livez, /readyz, /metrics). At least one of path_prefix / hosts is required; when both are set a request must satisfy both.

  • passthrough_route.hosts (array, optional): Inbound Host values this route serves — the forward-proxy entry, where a TLS-terminating device delivers plaintext traffic with its original Host. Matched case-insensitively, ignoring any :port suffix. A leading *. wildcard matches exactly one extra label and must keep at least two literal labels (*.githubcopilot.com is accepted; *.com and a bare * are rejected). Host-matched requests keep their full path unless path_prefix also matched.

  • passthrough_route.target_url (string, optional): Explicit upstream base URL; the matched remainder path and query are appended (a trailing /v1 on the target and a leading v1/ on the remainder de-duplicate). Exactly one of target_url / preserve_host: true must be configured.

  • passthrough_route.preserve_host (boolean, required): Derive the target from the matched inbound host (https://<host>), for forward-proxy routes fanning one route over several official hosts. Only accepted together with hosts — the allowlist is what bounds the derived target.

  • passthrough_route.auth_mode (object, required): How the gateway authenticates callers of this route. header_key requires auth_header_name; anonymous requires anonymous_key_id and a non-empty source_cidrs.

  • allOf variant 1

  • passthrough_route.auth_header_name (string, optional): Lowercase header carrying the gateway credential when auth_mode is header_key (for example x-aisix-api-key); stripped before forwarding. Rejected on any other auth_mode — the gateway never consults it there. Credential-bearing names (authorization, proxy-authorization, cookie, set-cookie, x-api-key) are rejected.

  • passthrough_route.anonymous_key_id (string, optional): The environment API key this route's traffic runs as when auth_mode is anonymous. Its allowed_routes grant, rate limits, budget, and usage attribution apply unchanged, so anonymous traffic keeps a stable, governable principal. Rejected on any other auth_mode — the gateway never consults it there.

  • passthrough_route.source_cidrs (array, optional): Client source CIDRs allowed to use this route. Required (non-empty) when auth_mode is anonymous; optional hardening for the other modes. Unset means no route-level source restriction.

  • passthrough_route.credential_mode (object, required): How the upstream credential is produced. inject (the default) requires provider_key_id; forward_client forbids it.

  • allOf variant 1

  • passthrough_route.provider_key_id (string, optional): Provider key whose secret is injected upstream when credential_mode is inject; its header-strip list and TLS settings apply to the route's traffic. The provider key must be visible to this environment.

  • passthrough_route.identity_header (string, optional): Optional lowercase header carrying the end-user identity injected by the upstream network device (for example x-aisix-user). Its value is recorded on usage events as client_identity for per-employee audit attribution and stripped before forwarding. Credential-bearing names are rejected.

  • passthrough_route.timeout_ms (integer, optional): Upstream exchange bound in milliseconds. Bounds the response-header phase and any non-SSE body read, never a healthy SSE relay. When omitted, the gateway's default request timeout applies the same way.

  • passthrough_route.enabled (boolean, required): Whether the route is active. A disabled route matches nothing.

  • passthrough_route.created_at (string, required): Creation timestamp.

  • passthrough_route.updated_at (string, required): Last update timestamp.

  • warnings (array, optional): Data-plane compatibility warnings for this save, when any connected data plane predates a configured capability.

  • warnings[].code (string, required): How affected nodes treat the saved resource. field_ignored: the resource stays in service on those nodes but the named field has no effect there — beware when the field is restrictive, since the restriction is silently not enforced. row_rejected: those nodes refuse the whole resource, so it stops serving there entirely (or, if a previously accepted version exists, they keep serving the old values).

  • warnings[].field (string, required): Dot-separated path of the field that triggered the warning, as delivered to gateway nodes.

  • warnings[].min_dp_version (string, required): Oldest gateway version that fully executes the field. The literal value unreleased means no released gateway version executes it yet.

  • warnings[].affected_dp_count (integer, required): Number of currently registered nodes in the environment running an older gateway version than min_dp_version.

  • warnings[].affected_dp_versions (array, required): Distinct gateway versions reported by the affected nodes, capped at five entries. Nodes that report no version appear as unknown.

  • 400: Request body or parameters failed validation.

  • error (object, required): Error details.

  • error.code (string, required): Machine-readable identifier. Examples: UNAUTHENTICATED, INVALID_REQUEST, MASTER_KEY_UNSET, INTERNAL.

  • error.message (string, required): Human-readable explanation; safe to surface to operators.

  • 401: Missing or invalid bearer. Response fields (application/json): identical to POST /environments/{env_id}/passthrough_routes, response 400 above.

  • 403: Authenticated request is not permitted. Response fields (application/json): identical to POST /environments/{env_id}/passthrough_routes, response 400 above.

  • 404: Resource not found. Response fields (application/json): identical to POST /environments/{env_id}/passthrough_routes, response 400 above.

  • 409: Request conflicts with current resource state. Response fields (application/json): identical to POST /environments/{env_id}/passthrough_routes, response 400 above.

cURL

curl -X POST '$AISIX_CP/environments/{env_id}/passthrough_routes' -H 'Authorization: Bearer $AISIX_TOKEN'