Skip to main content

Documentation Index

Fetch the complete documentation index at: https://tyk.io/docs/llms.txt

Use this file to discover all available pages before exploring further.

Internal routing redirects a matched request to a different endpoint or API hosted on the same Tyk Gateway instance, without making an outbound network call. Tyk dispatches the request directly to the target API’s middleware chain in memory, so the request is processed a second time without any network overhead. Internal routing is configured through the URL rewrite middleware. See Path Modification for how to configure rewrite rules.

How It Works

When the URL rewrite middleware produces a target beginning with tyk://, Tyk resolves the target to an API definition and dispatches the request directly to that API’s middleware chain. Listen path matching is bypassed entirely - the request does not re-enter the HTTP router. What is re-evaluated on each loop:
  • The target API’s full middleware chain, including endpoint-level middleware for the matched path.
What is not re-evaluated:
  • Listen path matching is bypassed; the target API is resolved by identifier, not by URL.
  • Original query parameters are dropped; only query parameters explicitly included in the rewrite target survive into the loop.
  • Authentication depends on the auth method in use and the method used to address the target. See Authentication on Looped Requests.
  • Rate limits and quotas are skipped by default. See Rate Limits and Quotas.

Addressing the Target

A tyk:// URL takes one of two forms depending on whether the destination is within the same API or on a different API.

Same API

tyk://self/<path>
The hostname self resolves to the same API definition handling the current request. Use this when the routing logic and the destination endpoint are in the same API definition. For example, a rewrite target of tyk://self/internal/transform routes to the /internal/transform endpoint on the same API, running it through that endpoint’s configured middleware.

Different API

tyk://<identifier>/<path>
Tyk resolves the identifier against each registered API in the following order:
  1. The API ID (info.id) - exact match
  2. The API’s database ID (info.dbId) - exact match
  3. The API’s display name (info.name), slugified: non-alphanumeric characters are replaced with -, match is case-insensitive
For example, an API named "Books Backend" can be addressed as tyk://books-backend/endpoint or tyk://Books-Backend/endpoint. Using the API ID directly, such as tyk://4e3c8b9f2a1d4f67b8e3c1a2f5d9e0c7/endpoint, is more robust in automated environments where the API name may change.
The listen path is not a valid identifier. If the identifier does not match any registered API, Tyk returns HTTP 500 with the error "Can't detect loop target".
If using Tyk Classic, the API ID is api_id, the database ID is id, and the display name is name, all in the root of the API definition. In Tyk Classic, API names can include category tags in the form #tag; these are stripped before name matching, so an API named "Books Backend #catalog" can be addressed as tyk://books-backend/endpoint.

Loop Behavior

Authentication on Looped Requests

Authentication behavior on a looped request depends on the auth method in use and whether the loop targets the same API or a different one. This should be considered carefully when designing an internal routing chain. Same API (tyk://self/...) When looping to an endpoint in the same API, the behavior depends on the API’s auth method as follows:
  • Auth Token: the auth check is only performed on the original request.
  • Basic Auth and Certificate Auth: the auth check is run on each loop, but succeeds because Tyk forwards the original request headers into the loop, so the credential is still present and unchanged.
  • JWT, OAuth 2.0, HMAC: the auth check is run on every loop and must succeed.
For example, an API using JWT authentication that rewrites to tyk://self/internal-endpoint will validate the JWT again on the looped request. The token must still be present and valid. Different API (tyk://<identifier>/...) Each API definition is an independent security boundary. Tyk runs the target API’s full authentication middleware chain as it would for any other incoming request, validating the request fresh against the target API’s own credentials. The request must carry credentials that are valid for the target API. If those credentials differ from the ones used on the first hop, for example when the target API uses a different API key or a different header, add the required credential to the request with a request header transformation before the rewrite target is reached.
APIs secured with Certificate Auth cannot be used as targets for internal looping. The internal transport used for different-API routing does not carry TLS connection state, so when the request is presented to the target API there is no client certificate to validate and Tyk will reject the request with HTTP 403.

Rate Limits and Quotas

The Gateway’s Session contains details of access and usage permissions, such as rate limits and quotas, for the requesting client. Tyk’s standard rate limiting middleware increments the counters for each API request and applies limits to prevent overuse. A loop represents an internal leg of a single external client request: if Tyk incremented the counters and applied limits at each hop, a single request would be double-counted and clients could be charged multiple times for one request. By default, rate limit and quota increments and checks are performed only on the original API, not in the looped requests. Same API (tyk://self/...) Authentication is not re-run on a self-loop, so the originating Session is used throughout the entire chain. There is one set of rate limit and quota counters, decremented once on the original request. All subsequent loop legs within the same API skip rate limit and quota checks by default. Different API (tyk://<identifier>/...) If the target API performs authentication it loads its own Session from Redis during authentication. That Session may carry rate limit and quota counters independent of the originating API. These are skipped by default for looped requests. Checking Rate Limits on Looped APIs An optional control can be configured when looping that will run the rate limiting middleware in the target API. If this is enabled for a loop to the same API, this will lead to double counting and is not recommended. If it is enabled for a loop to a different API, the counters in the target API’s Session will be incremented and checked against the limits configured for that API. Rate limit and quota deductions happen in memory during middleware processing. The updated Session is written back to Redis only after the full request chain - including all loop legs - has completed.

Loop Depth

To guard against infinite loops, Tyk enforces a configurable maximum of five loops per request. When this limit is exceeded, Tyk returns HTTP 500:
Loop level too deep. Found more than 5 loops in single request

Loop Controls

The behavior of a looped request can be modified by appending control parameters to the tyk:// URL. These parameters are consumed by Tyk and stripped before the looped request is dispatched, so they do not reach the target upstream.
ParameterDescription
check_limits=trueEnforce rate limits and quotas on the looped request. For same API loops, this double-counts the request against the client’s allowance and is not recommended. For different API loops, limits are enforced against the target API’s own session.
method=<VERB>Override the HTTP method of the looped request, for example method=POST.
loop_limit=<n>Set the maximum number of loops permitted in this request chain. Default is 5. Can only be set in the original loop - subsequent loops in the same request chain cannot change it.
For example, to loop to the Books Backend API enforcing its rate limits, use the rewrite target tyk://books-backend/fiction/9780?check_limits=true.

Internal-Only APIs

An API or an individual endpoint can be restricted so it is only accessible via internal routing, not from external HTTP requests.

API-Level

Mark an entire API as internal to exclude it from the HTTP router. External requests return HTTP 404. The API is only reachable via tyk://. Tyk OAS - set internal: true in the info.state section of the Tyk Vendor Extension:
"x-tyk-api-gateway": {
  "info": {
    "state": {
      "active": true,
      "internal": true
    }
  }
}
If using Tyk Classic, set "internal": true at the root of the API definition.

Endpoint-Level

Mark individual endpoints as internal to allow the rest of the API to remain externally accessible while restricting specific paths to loop context only. External requests to a marked endpoint are rejected with HTTP 403. Tyk OAS - add internal to the operation in the middleware.operations section:
"operations": {
  "getContract": {
    "internal": {
      "enabled": true
    }
  }
}
If using Tyk Classic, add entries to extended_paths.internal:
"extended_paths": {
  "internal": [
    {
      "path": "/contract",
      "method": "GET"
    }
  ]
}

Worked Example

This example demonstrates three internal routing capabilities together: authentication on a looped API, rate limit enforcement via loop controls, and routing to a different upstream service. Acme Publishing’s Books API serves free previews to all clients without authentication. Clients with a download subscription can retrieve the full book by adding ?download=true and providing a valid access token. Download requests are routed internally to a separate Download API that validates the subscriber’s token, enforces their download allowance, and proxies to a dedicated download service. The setup uses two APIs:
  • Books API (external, keyless, listen path /books, upstream http://books-service): Receives all client requests. Default requests are rewritten to the upstream’s preview path. Requests with ?download=true are looped internally to the Download API with rate limit enforcement enabled.
  • Download API (internal, auth token required, upstream http://download-service): Validates the subscriber’s access token, enforces their download allowance, and proxies to the download service. Unreachable directly from outside Tyk Gateway.
Tyk OAS Configuration Books API - the GET /{category}/{id} endpoint with URL rewrite:
"operations": {
  "getBook": {
    "urlRewrite": {
      "enabled": true,
      "pattern": "/([^/]+)/([^/]+)",
      "rewriteTo": "preview/$1/$2",
      "triggers": [
        {
          "condition": "any",
          "rewriteTo": "tyk://download-api/$1/$2?check_limits=true",
          "rules": [
            { "in": "query", "name": "download", "pattern": "true", "negate": false }
          ]
        }
      ]
    }
  }
}
Download API - marked internal at the API level, with auth token authentication and a separate upstream:
"x-tyk-api-gateway": {
  "info": {
    "name": "Download API",
    "state": { "active": true, "internal": true }
  },
  "server": {
    "authentication": {
      "enabled": true,
      "securitySchemes": {
        "authToken": {
          "enabled": true
        }
      }
    }
  },
  "upstream": { "url": "http://download-service" }
}
The securitySchemes key authToken must match a scheme defined in the OpenAPI components.securitySchemes section of the Download API’s OAS document. See Auth Token for full authentication configuration detail. If using Tyk Classic, mark the Download API internal with "internal": true at the root of its API definition. The URL rewrite on the Books API is configured in extended_paths.url_rewrites using the same trigger structure described in Path Modification. Outcomes
RequestProcessed byResponse
GET /books/fiction/9780Books API → books-service/preview/fiction/9780Book preview
GET /books/fiction/9780?download=true with valid tokenBooks API → Download API → download-service/fiction/9780Full book
GET /books/fiction/9780?download=true with missing or invalid tokenBooks API → Download API → rejectedHTTP 401
For the default request, no advanced trigger fires. The basic trigger captures fiction as $1 and 9780 as $2, and the request is proxied to books-service/preview/fiction/9780. For the download request with a valid token, the advanced trigger fires on download=true and rewrites to tyk://download-api/fiction/9780?check_limits=true. The ?download=true query parameter is dropped at the loop boundary. It is not included in the rewrite target and does not reach the Download API. The loop control parameter check_limits=true is consumed by Tyk and stripped before dispatch. The Download API validates the token, decrements the subscriber’s download allowance against their Session, and proxies to download-service/fiction/9780. For the download request with a missing or invalid token, the Download API’s authentication middleware rejects the request with HTTP 401 before it reaches the upstream. A direct external request to the Download API’s listen path returns HTTP 404. It is excluded from the HTTP router entirely.