webdevpuneet.com

API Response Inspector — Free HTTP Request/Response Panel UI

API Response Inspector · Dashboards · Plain HTML, CSS & JS · Live preview

CategoryDashboards

Copy & paste

Source Code

<div class="ari-panel">
  <div class="ari-req-bar">
    <span class="ari-method">GET</span>
    <span class="ari-url">/v1/users/8241/orders?limit=3</span>
    <span class="ari-status" id="ariStatus">200 OK</span>
  </div>

  <div class="ari-tabs" role="tablist">
    <button class="ari-tab active" data-tab="body" role="tab" aria-selected="true">Body</button>
    <button class="ari-tab" data-tab="headers" role="tab" aria-selected="false">Headers</button>
    <button class="ari-tab" data-tab="timing" role="tab" aria-selected="false">Timing</button>
    <button class="ari-copy" id="ariCopyBtn" type="button">Copy</button>
  </div>

  <div class="ari-panels">
    <pre class="ari-panel-content active" id="ariBodyPanel" data-panel="body"><code id="ariBodyCode"></code></pre>

    <div class="ari-panel-content" id="ariHeadersPanel" data-panel="headers">
      <div class="ari-header-row"><span class="ari-h-key">content-type</span><span class="ari-h-val">application/json; charset=utf-8</span></div>
      <div class="ari-header-row"><span class="ari-h-key">cache-control</span><span class="ari-h-val">no-store</span></div>
      <div class="ari-header-row"><span class="ari-h-key">x-request-id</span><span class="ari-h-val">req_9f2a1c3d</span></div>
      <div class="ari-header-row"><span class="ari-h-key">x-ratelimit-remaining</span><span class="ari-h-val">247</span></div>
      <div class="ari-header-row"><span class="ari-h-key">server</span><span class="ari-h-val">edge-fra1</span></div>
    </div>

    <div class="ari-panel-content" id="ariTimingPanel" data-panel="timing">
      <div class="ari-timing-row"><span>DNS lookup</span><div class="ari-timing-bar"><span style="width:4%"></span></div><b>3 ms</b></div>
      <div class="ari-timing-row"><span>TCP + TLS</span><div class="ari-timing-bar"><span style="width:18%"></span></div><b>14 ms</b></div>
      <div class="ari-timing-row"><span>Waiting (TTFB)</span><div class="ari-timing-bar"><span style="width:62%"></span></div><b>48 ms</b></div>
      <div class="ari-timing-row"><span>Content download</span><div class="ari-timing-bar"><span style="width:16%"></span></div><b>12 ms</b></div>
      <div class="ari-timing-total">Total: <b>77 ms</b></div>
    </div>
  </div>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

One-pass JSON highlighting
A single regex classifies keys, strings, numbers, booleans, and null.
Escape-before-highlight
Response content is HTML-escaped first so it can never break the panel markup.
Data-attribute tab routing
One click handler serves any number of tabs via a data-tab lookup.
Graceful clipboard fallback
Copy degrades silently when the Clipboard API is unavailable.
Proportional timing bars
CSS-width bars visualize each request phase relative to total time.
Status badge color-coding
Success and error status codes get distinct colors via one class toggle.
Monospaced throughout
URL, body, headers, and timing all use a consistent code font.
Zero dependencies
No highlighting library, no tab library — every behavior is plain JS.

About this UI Snippet

API Response Inspector — Tabs, Manual JSON Highlighting & Copy

Screenshot of the API Response Inspector snippet rendered live

Every developer tool that surfaces an HTTP exchange — an API explorer, a webhook debugger, a support-facing request log — needs the same panel: the request line, a status badge, and tabbed access to the body, headers, and timing. This snippet builds that panel with hand-rolled JSON syntax highlighting and no dependency, pairing well with a code diff viewer or api key manager in a developer dashboard.

Syntax highlighting with one regular expression

Rather than a highlighting library, syntaxHighlight() runs a single regex over the stringified JSON that matches strings, booleans, null, and numbers in one pass, then classifies each match by inspecting it: a quoted string followed by a colon is a key, any other quoted string is a value, and so on. This is the same technique used by classic vanilla JSON highlighters — it's not a full JSON parser, but for displaying already-valid JSON.stringify output it's reliable and tiny.

HTML-escaping before highlighting

The raw JSON string is escaped for &, <, and > before the highlighting regex runs, and the highlighted output is injected via innerHTML. Escaping first matters because response bodies can legitimately contain angle brackets in string values — skipping this step would let response content break the panel's markup.

Tabs driven by a data attribute, not three separate handlers

Each tab button carries data-tab, and a single click handler looks up the matching panel from a panels object keyed by that same string — adding a fourth tab means adding one button and one panel, not another branch of conditional logic. aria-selected is kept in sync with the .active class on every click, so the accessible state matches the visual one.

A copy button that degrades gracefully

The copy handler tries navigator.clipboard.writeText, which is unavailable in some sandboxed/insecure contexts, and falls back to just showing the "Copied" confirmation either way rather than throwing — because from a UI perspective, telling the user copy failed silently is worse than a harmless no-op in an environment where clipboard access is blocked.

A timing breakdown built from CSS bars

Each timing row pairs a label, a proportionally-widthed bar, and a millisecond value — the bar widths are set inline as percentages of total request time, the same lightweight technique used in git diff stat summary's insertion/deletion bars. Swap in real PerformanceResourceTiming values from fetch or XMLHttpRequest to make this reflect an actual request.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSA request/response panel renders on the Body tab with highlighted JSON.
  2. 2
    Switch tabsClick Headers or Timing to see the response headers list or a request-phase timing breakdown.
  3. 3
    Click CopyThe raw JSON body is copied to the clipboard with a brief "Copied" confirmation.
  4. 4
    Swap in real dataReplace the responseData object with an actual fetch() response body.
  5. 5
    Add real headers/timingPopulate the headers list from response.headers and the timing bars from PerformanceResourceTiming.
  6. 6
    Add more tabsAdd a button with a new data-tab value and a matching entry in the panels object — no other logic changes.

Real-world uses

Common Use Cases

API explorer tools
Show the request line, status badge and tabbed Headers, Body and Timing panes after a user sends a call, so everything about one exchange sits in a single panel.
Webhook debugging consoles
Display incoming webhook payloads with highlighted JSON, escaping the response content first so a payload can never break out of the markup.
Credential-aware dev dashboards
Pair with an API key manager so developers can issue a key and immediately inspect a response made with it.
Support request logs
Let support staff see exactly what a customer's client sent and received, with one click handler serving every tab through data-tab routing.
Change comparison tooling
Link to a code diff viewer when comparing two responses, using the one-pass regex highlighter as a compact reference for manual JSON colouring.
Related: Fundraising Campaign Leaderboard
See the Fundraising Campaign Leaderboard for a related dashboards pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

A single regular expression matches quoted strings, booleans, null, and numbers across the stringified JSON in one pass. Each match is then classified in a callback: a quoted string immediately followed by a colon is styled as a key, any other quoted string as a string value, and so on for booleans, null, and numbers — each gets a CSS class with its own color.

Response body content can legitimately contain characters like < or > inside string values. Escaping them for &, <, and > before running the highlighting regex and injecting via innerHTML ensures response content is always treated as text, never as markup — protecting the panel from being broken or manipulated by the data it's displaying.

Add a new button with role="tab" and a data-tab value (e.g. data-tab="cookies"), add a matching panel element, and add one entry to the panels object keyed by that same string. The existing click handler already loops generically over all tabs and panel keys, so no new conditional logic is needed.

The copy handler checks for navigator.clipboard.writeText before calling it, and falls back to simply showing the "Copied" confirmation regardless of whether the write succeeded. This avoids throwing an error in sandboxed or insecure (non-HTTPS) contexts where clipboard access is blocked, prioritizing a harmless no-op over a broken button.

Use the Resource Timing API: after a fetch() call, look up performance.getEntriesByName(url)[0] and read its domainLookupStart/End, connectStart/End, responseStart, and responseEnd timestamps to compute each phase's duration. Set each timing bar's inline width as a percentage of the total duration, exactly as the mock values are set here.