> For the complete documentation index, see [llms.txt](https://docs.tumbler.app/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.tumbler.app/subscription-contract/fetcher-http-contract.md).

# Fetcher HTTP contract

## Who this is for

Provider teams that serve the `subscription` URL and want to account for fetcher-agent restrictions in advance.

## What you can do

* Verify that the origin responds according to strict HTTP/HTTPS rules.
* Configure redirects and size limits so the fetcher does not return errors.
* Make sure encodings and content types are compatible.

## Examples

* Request: `GET https://provider.example.com/public/subscription` with `User-Agent: tumbler-backend-fetcher/1.0` and `Accept-Encoding: identity`.
* 302 redirect to the final `https://cdn.provider.example.com/subscription` (allowed scheme/host/port).
* `304 Not Modified` response when `If-None-Match` or `If-Modified-Since` matches.

## See also

* [subscription/fetch-url.md](/getting-started/fetch-url.md)
* [operations/caching-and-304.md](/after-first-launch/caching-and-304.md)
* [security/fetcher-restrictions.md](/after-first-launch/fetcher-restrictions.md)

## Method and headers

* Method: `GET` only.
* `User-Agent`: `tumbler-backend-fetcher/1.0` (may become `1.x` in future releases, but the prefix is preserved).
* `Accept-Encoding: identity` - the provider **must not require** gzip/br/deflate; return an uncompressed response.
* Additional provider headers are allowed, but the fetcher forcibly sets `User-Agent` and `Accept-Encoding` on every redirect hop.

## Redirect policy

* 301, 302, 307, and 308 are supported.
* Redirect chain limit: up to 10 hops per request; exceeding it returns `REDIRECT_LIMIT`.
* Every hop goes through SSRF validation: only `http`/`https` are allowed, ports must be on the allowlist (80/443 by default), localhost/internal addresses and userinfo are forbidden. Details: [fetcher-restrictions.md](/after-first-launch/fetcher-restrictions.md).
* Prefer redirecting directly to the final HTTPS endpoint without multi-step chains.

## Response size

* Hard body limit: **up to 2 MB**. A larger body returns `BODY_TOO_LARGE` and is not used.
* Recommended size: **< 200 KB** for faster delivery and caching.
* If a CDN adds padding, make sure the final size stays below the limit.

## Encoding and lines

* The body must be UTF-8 without BOM.
* Recommended line endings are `\n` (LF); `\r\n` is allowed, but do not mix endings.
* Empty lines and final newline are preserved as is; avoid accidental trailing spaces and tabs.

## Status codes

* `200 OK` - successful response with a body.
* `304 Not Modified` - recommended through `If-None-Match`/`If-Modified-Since`; no body.
* Any `4xx`/`5xx` is treated as a fetch error and leads to retries/fallback; use precise codes, for example `429` with `Retry-After`.

## Content-Type

* Allowed types: `text/plain` or `application/json`.
* Include `charset=utf-8` to avoid ambiguous interpretation.
* Other types may be ignored or treated as compatibility errors.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.tumbler.app/subscription-contract/fetcher-http-contract.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
