# Receipts

Every result carries a receipt. It records what Skryp did, so an agent or a person can judge the result instead of trusting a status code.

| Field | Meaning |
| --- | --- |
| `request_id` | The request in your Activity history. |
| `credits` | What this result cost. Failed and blocked pages cost 0. |
| `route` | The route that produced the result, for example `http:direct`, `http:res:za`, `browser:res:us`, `real:res:us`, `unlocker:brightdata`, `archive:wayback`. |
| `egress` | The exit IP the request left from, and how it was checked: see below. |
| `attempts` | Every route tried, in order, with its outcome, HTTP status, bytes, duration and exit. |
| `cache` | `hit` (an earlier live fetch), `miss` (fetched now) or `bypass` (a fresh fetch was required). |
| `fetched_at` | When the request started. For archive copies, the capture date. |
| `ms` | Total time. |

## The exit IP: `egress`

| Field | Meaning |
| --- | --- |
| `country` | The exit's country, as an ISO code. |
| `city` | The exit's city, when the geolocation service gives one. |
| `asn` | The exit's network: its AS number and the operator's name. |
| `ip` | The exit IP. |
| `verified` | `true` when a geolocation service, asked through this same exit, placed it in `country`. |
| `source` | Which service answered: `ipinfo.io` first, then `ipapi.co`, `ifconfig.co` or `api.country.is` if it did not. |
| `checked_at` | When the check ran (UTC). A route keeps its check for a few minutes, so several pages can share one. |

On a strict-country request (`strict_country: true`) the check runs before the page loads, and an IP placed in another country is skipped rather than used. The unblocker's exit is reported by Bright Data rather than checked by Skryp, so it shows `verified: false` and is never used for strict requests.

## A real response

A strict request for a store page from Germany, run on 1 October 2026 (the IP is masked here):

```json
{
  "status": "ok",
  "title": "Sparen Sie 80 % bei Portal 2 auf Steam",
  "receipt": {
    "credits": 5,
    "route": "http:res:de",
    "cache": "bypass",
    "fetched_at": "2026-10-01T21:17:01+00:00",
    "egress": {
      "country": "de",
      "city": "Lingen",
      "asn": "AS8881 1&1 Versatel GmbH",
      "ip": "88.130.x.x",
      "verified": true,
      "source": "ipinfo.io",
      "checked_at": "2026-10-01T21:17:04Z"
    },
    "attempts": [
      {
        "route": "http:res:de",
        "outcome": "ok",
        "status_code": 200,
        "bytes": 187855,
        "ms": 3821
      }
    ]
  }
}
```

The page came through a residential IP in Germany (5 credits), checked by ipinfo.io three seconds after the request started and before the page loaded.

The Firecrawl-compatible endpoints put the same object in `metadata.egress`, next to `creditsUsed`. The same page through `POST /v2/scrape` with `"location": {"country": "DE"}`:

```json
{
  "success": true,
  "data": {
    "metadata": {
      "title": "Sparen Sie 80 % bei Portal 2 auf Steam",
      "sourceURL": "https://store.steampowered.com/app/620/Portal_2/",
      "statusCode": 200,
      "creditsUsed": 5,
      "egress": {
        "country": "de",
        "city": "Deidesheim",
        "asn": "AS42652 inexio Informationstechnologie und Telekommunikation Gmbh",
        "ip": "128.0.x.x",
        "verified": true,
        "source": "ipinfo.io",
        "checked_at": "2026-10-01T21:17:24Z"
      }
    }
  }
}
```

## Reading it well

- A verified exit proves where the request left from. It does not prove that every field on the page is correct for that market: sites also price by account, cookie or delivery address.
- HTTP 200 is not the same as usable. The outcome (`ok`, `partial`, `blocked`…) is the judgement; the status code is evidence.
- An archive copy always says so, with its capture date, in both the route and the warnings.
- The dashboard shows the same receipt, plus what was held while the request ran and what was released.

Source: https://skryp.dev/docs/receipts
