Skip to main content
Replay is configured by two independent settings. Send each as a request header for one-off control, or set it as a default on an API key:
  • X-Lumenfall-Replay (the activation) — the outcome: what you get on a hit and on a miss.
  • X-Lumenfall-Replay-Match (the match) — the lookup: how Lumenfall decides whether a recording matches.
They’re orthogonal. The activation fully determines the outcome; the match only changes how a recording is found. Any replay-or-* activation works with any match strategy.

Activation — X-Lumenfall-Replay

The activation decides what happens — both when a recording is found and when one isn’t.
ActivationOn a hitOn a miss
offNormal request (not routed through replay)
record— (always forwards)Forward to provider, store recording
replay-or-mock (default)Serve recordingSynthesize a mock response
replay-or-errorServe recording404 RECORDING_NOT_FOUND
replay-or-liveServe recordingForward to provider (no recording)
replay-or-recordServe recordingForward to provider and record
mock— (never looks)Synthesize a mock response
mock never touches a provider or storage. It synthesizes a well-formed response in the endpoint’s shape — including placeholder media — instantly and for free. Use it to build and demo your app before a real integration exists, to develop offline, or in CI where you just need a valid-shaped response on every call. replay-or-mock is the same synthesis used only as the fallback when a recording isn’t found.

Match — X-Lumenfall-Replay-Match

The match strategy decides how Lumenfall looks for a recording. It is consulted only by the replay-or-* activations — off, record, and mock ignore it.
MatchHow it matchesCompanion header
standard (default)Canonical parameters — tolerant of cosmetic differences
strictByte-exact request body
specificOnly the fields you chooseX-Lumenfall-Replay-Fields: <comma-separated>
pinnedOne explicit recording, by IDX-Lumenfall-Replay-Recording: rec_…
pinned and specific each require their companion header. Omitting it returns 400 (PINNED_MODE_REQUIRES_RECORDING / SPECIFIC_MODE_REQUIRES_FIELDS).
The match and the activation are independent, so pinning composes with any outcome. With X-Lumenfall-Replay-Match: pinned and X-Lumenfall-Replay-Recording: rec_abc123, the activation still decides what happens if that recording is gone: replay-or-error returns a 404, while replay-or-mock returns a mock instead.

How matching works

When you replay, Lumenfall builds a match key from your request and looks for a recording with the same key.
FieldSource
OrganizationThe owner of the API key
ProviderThe provider that handles the request
EndpointThe API endpoint (e.g. image generation)
ModelThe model identifier
Request hashA hash of the request body
The first four fields are always part of the key. The match strategy changes how the request hash is computed:
  • standard hashes the canonical parameters, ignoring fields that don’t change the nature of the request: the prompt, the response/output format, and (for text-to-image and text-to-video) reference media. Changing the prompt still matches; changing something that defines the generation — size, seed, quality — does not.
  • strict hashes the exact request body bytes. Any change — even whitespace — produces a different key and won’t match.
  • specific hashes only the fields you name in X-Lumenfall-Replay-Fields; everything else is ignored.
  • pinned skips hashing entirely and serves the recording named in X-Lumenfall-Replay-Recording.

Cross-provider matches

standard matching isn’t limited to the provider that created the recording. Because Lumenfall can route the same model to different providers, a recording made against one can satisfy a request that routes to another — as long as both resolve to the same model. Same-provider recordings are preferred; a cross-provider match is used only when there’s no same-provider hit. This applies to standard only — strict and pinned stay within a single recording. When a cross-provider recording answers, the response carries X-Lumenfall-Provider-Used (whose recording served it) and, if the body was adapted to the requested provider’s shape, X-Lumenfall-Wire-Provider.

Latency simulation

By default a replay returns instantly. Set X-Lumenfall-Replay-Latency (per request, or as a key default) to make a replayed response take as long as the original did — useful for testing loading states and timeouts.
ValueBehavior
instant (default)Return immediately
realWait for the originally recorded duration before returning
{ttfb},{duration}Split timing in milliseconds — delay before the response starts, then stream the body over the given duration (e.g. 1200,8000)
curl https://api.lumenfall.ai/openai/v1/images/generations \
  -H "Authorization: Bearer $LUMENFALL_API_KEY" \
  -H "Content-Type: application/json" \
  -H "X-Lumenfall-Replay: replay-or-error" \
  -H "X-Lumenfall-Replay-Latency: real" \
  -d '{ ... }'
real is capped at 60 seconds — a safety bound to match typical client timeouts. When the cap applies, the response carries X-Lumenfall-Warning: LATENCY_CLAMPED.

Knowing what happened

Every replay-engaged response carries headers describing what happened, so a test can assert it never silently called the provider.
HeaderValuesMeaning
X-Lumenfall-Replay-Resultreplay · record · live · mock · missWhat the replay layer did. Its presence means the request was handled by replay; its absence means it wasn’t.
X-Lumenfall-Replay-Matchstandard · strict · specific · pinnedWhich match strategy resolved the request
X-Lumenfall-Recording-Idrec_…The recording served or created (absent for mock and live)
X-Lumenfall-Provider-Usedprovider nameThe provider whose recording served the request — differs from the routed provider on a cross-provider match
X-Lumenfall-Wire-Providerprovider namePresent when the recorded body was adapted to the requested provider’s response shape
The result values map 1:1 to the activations, so you can assert exactly what happened: a replay-or-live that hit reports replay; the same request on a miss reports live.

Errors

ScenarioHTTP statusX-Lumenfall-Replay-ResultError code
replay-or-error, nothing matched404missRECORDING_NOT_FOUND
pinned without X-Lumenfall-Replay-Recording400PINNED_MODE_REQUIRES_RECORDING
specific without X-Lumenfall-Replay-Fields400SPECIFIC_MODE_REQUIRES_FIELDS
Invalid X-Lumenfall-Replay-Latency value400INVALID_LATENCY_POLICY
A replay-or-error miss returns HTTP 404 with X-Lumenfall-Replay-Result: miss. Branch on that header, not the bare status — a provider’s own “model not found” 404 won’t carry it. Only replay-or-error (and pinned / specific with a missing companion header) ever errors on a miss. replay-or-mock, replay-or-live, and replay-or-record always produce a response.