# Response Headers

- Canonical URL: https://docs.fairvisor.com/docs/reference/headers/
- Section: docs
- Last updated: n/a
> Headers that Fairvisor Edge may set on decision responses.


Header presence depends on decision path and limiter result. Not every response contains all headers.

## Rate-limit headers

| Header | Present when | Notes |
|---|---|---|
| `RateLimit-Limit` | Limiter returns `limit` | Algorithm-dependent |
| `RateLimit-Remaining` | Limiter returns `remaining` | Algorithm-dependent |
| `RateLimit-Reset` | Limiter returns `reset` or `retry_after` | Fallback `1` in some limiter paths |
| `RateLimit` | A limiter result exists | Structured: `"<policy_or_rule>";r=<remaining>;t=<reset>` |

Fairvisor follows the standard `RateLimit*` header model from:

- https://datatracker.ietf.org/doc/draft-ietf-httpapi-ratelimit-headers/
- https://datatracker.ietf.org/doc/draft-polli-ratelimit-headers/

## Reject headers

| Header | Present when |
|---|---|
| `Retry-After` | Reject decisions |

`Retry-After` includes deterministic per-identity jitter and is not runtime-configurable.

`X-Fairvisor-Policy`, `X-Fairvisor-Rule`, and the reject reason are emitted in debug-session headers only (as `X-Fairvisor-Debug-Policy`, `X-Fairvisor-Debug-Rule`, `X-Fairvisor-Debug-Reason`). See [Debug Session](/docs/reference/debug-session/).

## Advisory headers

| Header | Present when |
|---|---|
| `X-Fairvisor-Warning` | Non-blocking warning paths (`budget_warn`, `budget_throttle`, `loop_warn`) |
| `X-Fairvisor-Loop-Count` | Loop detector emits loop metadata |

## Debug headers

Debug headers are available only on requests that carry a valid signed debug cookie. Set `FAIRVISOR_DEBUG_SESSION_SECRET` and call `POST /v1/debug/session` to obtain one.

| Header | Notes |
|---|---|
| `X-Fairvisor-Decision` | Effective decision action |
| `X-Fairvisor-Mode` | `enforce` or `shadow` |
| `X-Fairvisor-Latency-Us` | Decision latency in microseconds |
| `X-Fairvisor-Debug-Decision` | Same as above (verbose form) |
| `X-Fairvisor-Debug-Mode` | Same as above (verbose form) |
| `X-Fairvisor-Debug-Reason` | Internal reject reason |
| `X-Fairvisor-Debug-Policy` | Policy ID that triggered the decision |
| `X-Fairvisor-Debug-Rule` | Rule name that triggered the decision |
| `X-Fairvisor-Debug-Latency-Us` | Same as above (verbose form) |
| `X-Fairvisor-Debug-Matched-Policies` | Number of policies evaluated |
| `X-Fairvisor-Debug-Descriptor-*` | Per-descriptor key/value pairs (up to 16) |

See [Debug Session](/docs/reference/debug-session/).

## Notes on token headers

Some docs/examples may show additional token-specific headers such as `X-Fairvisor-TPD-Remaining`. Treat those as implementation-dependent unless explicitly documented by your running version.

## Shadow mode

In shadow mode, would-reject decisions are converted to allow. Reject-specific response headers are suppressed for the client path.

Top-level runtime overrides (`global_shadow`, `kill_switch_override`) also do not add client-visible response headers. Use logs and metrics to verify override state.

## `decision_service` vs `reverse_proxy`

- In `decision_service`, headers are returned on `/v1/decision` and must be forwarded by the gateway.
- In `reverse_proxy`, headers are attached on proxied responses in nginx filter phases.

