Request Ledger
The request ledger is a core feature, not a debug afterthought. Every provider request an emulator handles is recorded so humans, tests, and agents can validate exactly how an application called a service. Control-plane traffic under /_emulate is not recorded.
# Recent records, newest first, sensitive fields redacted
curl -s http://localhost:4001/_emulate/ledger
# Webhook deliveries plus the most recent requests in one payload
curl -s http://localhost:4001/_emulate/logs
# Clear the ledger
curl -s -X DELETE http://localhost:4001/_emulate/ledgerRecorded fields
Each ledger entry records:
| Field | Description |
|---|---|
id | Stable entry id, e.g. req_42 |
correlationId | Honored from the incoming X-Correlation-Id or X-Request-Id header, otherwise generated, and echoed back on the X-Correlation-Id response header |
timestamp | ISO 8601 time the request completed |
method, host, path, query | The request line as received |
route | Matched route pattern, e.g. /repos/:owner/:repo/issues |
operationId | Provider operation id when the handler advertises one |
faulted, faultId | Set when a response was injected by /_emulate/faults, so tests can prove the fault fired |
request | Sanitized request headers and body, with bodyTruncated set when the body was clipped |
identity | Authenticated identity resolved for the request: the user (login, id, scopes) or app (app id, slug, name) |
response | Response status, sanitized headers, and body |
summary | One-line human and agent readable summary, e.g. POST /repos/:owner/:repo -> 201 |
sideEffects | State changes the request caused: create, update, delete, or custom, with the affected collection and id |
webhookDeliveries | Webhook deliveries this request fired, correlated by delivery id, event, action, status code, and success |
durationMs | How long the request took to handle |
Redaction
Sensitive headers such as authorization, cookie, set-cookie, x-api-key, x-github-token, and stripe-signature are replaced with [redacted]. Request and response bodies are redacted by key, so any field whose name matches token, secret, password, authorization, api_key, client_secret, or private_key is masked. Form-encoded bodies are redacted by the same rules. Bodies larger than the limit are clipped and flagged with bodyTruncated.
Correlation ids
Set X-Correlation-Id (or X-Request-Id) on a request and the emulator stores it on the ledger entry and echoes it back on the X-Correlation-Id response header, so you can stitch an entry to a specific call in your test. When no id is supplied the emulator generates one.
Faulted requests
POST /_emulate/faults arms a one-shot or counted response for matching provider requests. Match criteria are combined: operationId when the emulator can resolve one from the service manifest, method, and pathPattern. pathPattern is a glob where * matches any characters in the request path. A matched request short-circuits with the configured response, decrements the fault's remaining count, and is recorded here with faulted: true and faultId.
Persistence
On the hosted Cloudflare surface the ledger is persistent. Each instance is backed by a Durable Object that snapshots state and the ledger to storage, so records survive eviction. Locally and in process the ledger is in memory and is cleared on reset. See Deployment for the instance model.
Example entry
{
"id": "req_42",
"correlationId": "cor_8f1c0a2b4d6e",
"timestamp": "2026-06-08T17:04:22.118Z",
"method": "POST",
"host": "github.my-run.emulators.dev",
"path": "/repos/acme/web/issues",
"query": "",
"route": "/repos/:owner/:repo/issues",
"operationId": "issues/create",
"request": {
"headers": {
"authorization": "[redacted]",
"content-type": "application/json"
},
"body": { "title": "Bug report", "body": "It broke" }
},
"identity": {
"user": { "login": "octocat", "id": 1, "scopes": ["repo"] }
},
"response": {
"status": 201,
"headers": { "content-type": "application/json" },
"body": { "number": 7, "state": "open" }
},
"summary": "POST /repos/:owner/:repo/issues -> 201",
"sideEffects": [{ "type": "create", "collection": "issues", "id": 7 }],
"webhookDeliveries": [
{ "id": 3, "hook_id": 1, "event": "issues", "action": "opened", "status_code": 200, "success": true }
],
"durationMs": 4
}The Service Manifest advertises ledger capabilities under its ledger block, including the recorded fields, whether redaction and correlation ids are supported, and whether the ledger is persistent on this host.