Core Features

Network Capture

Reliable instruments fetch and XMLHttpRequest to record failed requests. Successful requests can be opted in via captureAllRequests.

How it works#

On init(), Reliable monkey-patches both window.fetch and XMLHttpRequest.prototype.send. Every request flows through a wrapper that times the call, records the outcome, and decides whether to send a POST /requests to the ingest endpoint.

What's captured by default#

With the default captureAllRequests: false, only failures are reported. A failure is any of:

  • A network error (DNS failure, CORS preflight rejection, request aborted by the browser)
  • A 4xx response (400 Bad Request, 401 Unauthorized, 404 Not Found, 429 Rate Limited, etc.)
  • A 5xx response (500 Server Error, 502 Bad Gateway, 503 Unavailable, 504 Timeout)

This default keeps payload volume low while still surfacing the requests that matter for debugging.

Capturing successful requests too#

For full API call visibility — useful while debugging or in low-traffic apps — opt in:

typescript
init({
  publicKey: 'pk_live_rl_...',
  captureAllRequests: true,   // every request, success or fail
});

Cost impact

On a typical SPA this can multiply your event volume by 10-50×. Use sampling (see below) or scope the toggle to non-production environments.

What gets sent#

NameTypeDefaultDescription
methodstringHTTP verb — GET, POST, PUT, DELETE, etc.
urlstringFull request URL with query string. Sensitive query params (token, key, password) are scrubbed.
statusnumberHTTP status code, or 0 for network errors.
duration_msnumberTime from request start to response end, measured by the SDK wrapper.
request_sizenumberBody size in bytes if Content-Length was set on the request.
response_sizenumberBody size in bytes from the response Content-Length, when present.
typeenumfetch or xhr — depending on which API the app used.
is_failurebooleanTrue for status >= 400 or network errors.
pathstringThe current page route when the request was made.

What's NOT captured#

A few requests are excluded by design to prevent feedback loops and noise:

  • Requests to your Reliable ingest endpoint — capturing these would cause infinite loops.
  • Browser-initiated subresource loads (images, scripts, stylesheets) that don't go through fetch/XHR — these aren't trackable from JS.
  • WebSocket frames — only the upgrade request is captured if it fails.

Network errors as crash triggers#

If a JavaScript error fires within 500ms of a failed network request, Reliable classifies the error's trigger as api_response. That gives you a tight signal in the dashboard: "this 500 error broke the page" vs. "this 500 error happened in the background and the user never saw it."

If you wrap fetch yourself#

Reliable's wrapping happens at init() time. If you have your own fetch wrapper (e.g. for auth headers), call init() first, then install your wrapper. Your wrapper will then call into Reliable's wrapped fetch and everything stacks correctly.

Tip

For requests you'd rather not report (telemetry endpoints, polling, analytics), filter them out in beforeSend:
typescript
beforeSend(event) {
  if (event.path === '/requests' && event.url?.includes('/heartbeat')) {
    return null;
  }
  return event;
}