Every request.Every retry.Every payload.

inspector.rest shows every HTTP call your backend makes to other services, live: all retry attempts, headers, bodies and labels, in one place.

Early access is by invitation.

Your logs keep the last line of the story.

When a call to another service fails, you log how it ended. The retries, the headers and the payloads that led there are gone by the time you look.

What your logs say
14:02:31 WARN  sms send failed, giving up
14:02:31 ERROR Request failed with status code 502

Which attempt failed, what was sent, and what came back are all missing.

What inspector.rest keeps
#1429180 ms
#2502340 ms
#3502410 ms
Request
POST sms.example/v1/messages
Waited
250 ms, then 500 ms
Changed
x-retry-count 0, 1, 2
Bodies
request and response, per attempt
Labels
service=notifications, op=send-otp

Everything about a request, in one place.

From the first attempt to the last byte: what your backend sent, what came back, and what happened in between.

See every attempt on a timeline

Each retry is its own bar, and the wait before it is drawn as a hatched gap. Select an attempt to see which headers changed since the one before.

  • Failures are named by status code or error
  • Backoff shows up as a gap, so slow retries stand out
  • The final attempt is selected by default
POST sms.example/v1/messages 1.28 s, 3 attempts

Headers, attempt 1

acceptapplication/json
content-typeapplication/json
user-agentnotifier/2.4.1
x-retry-count0
authorizationBearer …a41c

Headers, attempt 2 compared with 1

-x-retry-count0
+x-retry-count1
4 unchanged headers

Headers, attempt 3 compared with 2

-x-retry-count1
+x-retry-count2
-authorizationBearer …a41c
+authorizationBearer …e90b
3 unchanged headers

Read the bodies, copy the request

Request and response bodies are kept for every attempt. Open JSON as a collapsible tree or as raw text, and copy any request as cURL to replay it in your terminal.

  • Raw and parsed views, switchable per body
  • Copy a node's path or value straight from the tree
  • Headers stay folded, bodies stay open
200 POST api.payments.example/v1/charges

Request 4 headers

{4}
amount: 4200
currency: "eur"
customer: "cus_8d2"
metadata: {1}
order: "A-1043"
}
}

Response 6 headers

{6}
id: "ch_3Qx9"
status: "succeeded"
amount: 4200
paid: true
receipt: {2}
email: "ada@acme.example"
url: null
}
items: [1]
"order A-1043"
]
}
{"id":"ch_3Qx9","status":"succeeded","amount":4200,"paid":true,"receipt":{"email":"ada@acme.example","url":null},"items":["order A-1043"]}

Tag requests, then slice by tag

Add labels in your code: a service name, an operation, a customer id. Every label key becomes a filter with live counts. The SDK also adds server_host, app_package and app_commit for you.

  • One value per key, combined across keys
  • Labels can be set per client, per call or per scope
  • Automatic labels are marked, so they never blur into yours
In your code
axios.post(url, body, {
  inspector_labels: {
    op: 'charge',
    customer: 'cus_8d2',
  },
});

Labels on the request

service=billingop=chargecustomer=cus_8d2server_host=api-3autoapp_package=@acme/billingautoapp_commit=9f2c1ab04d77auto

Filters, with counts

service

billing366
search94

op

charge188
list141
refund37

Watch requests arrive, one tab per investigation

Requests stream in as they settle. Keep a tab for each thing you are chasing: every tab holds its own filters and shows a counter when matching requests arrive while you are looking at another one.

  • Tabs keep their filters and survive a reload
  • Drag tabs to reorder them, double-click to rename
  • Keyboard first: j k to move, t for a new tab
Try it
14:02:3320091 msGET/v1/customers/cus_8d2api.payments.example
14:02:3220058 msGET/v2/lookupgeo.example
14:02:31503920 msPOST/v1/chargesapi.payments.example
14:02:3020077 msGET/v1/customers/cus_1faapi.payments.example

Failures say what kind they are

Every error is classified, so you can filter for network trouble without wading through business-logic failures. Network and parse errors are recorded on the attempt that hit them; domain errors belong to the request.

Network

No usable response arrived: the connection was reset, a lookup failed or the request timed out.

ECONNRESETattempt 1 of 3

Parse

A response arrived, but its body could not be read, for example JSON that is not valid.

SyntaxErrorattempt 2 of 2

Domain

The call itself worked, but your code reported a failure afterwards. The HTTP status stays as received, such as 200, and the request is marked as an error.

SendRejectedstatus 200

Projects and environments

Group requests by project, then by environment. local and production never mix: each environment has its own ingest key and its own storage.

acme
└─ billing
   ├─ local       irk_Ab12…
   └─ production  irk_Zk90…

Teams

Invite teammates into your organization. Everyone can read; owners and admins can also clear an environment's requests.

Owner
Everything, including deleting the organization
Admin
Members, projects, environments and keys
Member
Browse projects and open the app

Retention per environment

Choose how long each environment keeps requests, from 1 to 30 days, and cap how many it stores. Older data is pruned automatically.

Let your AI agent read your requests.

Create a personal access token in the console and connect any MCP client. Agents get read-only access to the environments you can open: they can list them, filter requests and read full details and bodies. They cannot change or delete anything.

  • One token covers every organization you belong to
  • Each call reads a single environment, such as acme/billing/production
  • Revoke a token in the console at any time
Connect Claude Code
claude mcp add --transport http inspector \
  https://mcp.inspector.rest/mcp \
  --header "Authorization: Bearer irt_…"
Tools
list_environments
The environments your token can reach
list_filters
Available filters and the label keys in use
list_filter_values
Values and counts for one filter
list_requests
Filtered requests, newest first
get_request
One request with all of its attempts
get_attempt_body
The raw body of one attempt, by byte range

Every tool except list_environments takes an environment argument.

Add it where your HTTP client lives.

The SDKs wrap the client you already use. Give them your environment's ingest key and requests start to appear in the app. Ready-to-paste snippets with your key are shown in the console.

const axios = require('axios');
const { create_inspector } = require('@inspector-rest/sdk');
const instrument_axios = require('@inspector-rest/sdk/axios');

const inspector = create_inspector({
  server_key: process.env.INSPECTOR_SERVER_KEY, // ingest key
  service: 'billing',
  labels: { env: 'production' },
});

instrument_axios(axios, inspector);

axios.post(url, body, { inspector_labels: { op: 'charge' } });
  • Your clients, wrapped

    axios and @sqaft/reverse-client on Node, Guzzle on PHP. Requests go out exactly as before.

  • Node, Workers and browsers

    The Node package runs on Node 20 and later, on Cloudflare Workers and in the browser, with the same code.

  • Delivery never gets in the way

    Events are batched and sent in the background. If they cannot be delivered, your own requests are not affected.

  • You decide what leaves

    Turn body capture off, or truncate bodies to a size you choose.

From zero to your first request in three steps.

  1. Create a project

    In the console, create a project. It starts with local and production environments, each with its own ingest key.

    billingproduction
    ingest keyirk_Zk90••••••••••••••••••••••••••••

    The full key is shown once, when you create it.

  2. Add the SDK with your key

    Wrap your HTTP client with the SDK and pass the key. Nothing else about your requests changes.

    const inspector = create_inspector({
      server_key: process.env.INSPECTOR_SERVER_KEY,
    });
    instrument_axios(axios, inspector);
  3. Open it in the app

    Press Open next to an environment in the console. Requests show up live as your backend makes them.

    app.inspector.rest/acme/billing/productionLive

Get early access.

inspector.rest is invite-only while it is in early access. Join the waitlist and we will email you an invitation when it is your turn.

We use your details only to contact you about access. Your IP address is stored as a salted hash to limit abuse, never as is.