Skip to content

Menu

Understand a Scraipe request receipt

Read compile and network charges, recognise idempotent replays, and diagnose missing or inconsistent receipt fields with a tested offline checker.

By Scraipe editorial. Checked 2026-10-10.

Read the charge and the work separately

A request receipt answers two different questions: what work happened, and what credits were reported for that work. An extractor can be reused with zero LLM tokens while a residential network still incurs a charge. An idempotent retry can return a positive total from the original receipt without creating a second charge. Reading only the tier or one header misses those distinctions.

This guide explains the JSON API receipt and supplies an offline checker for a captured response. Use it when a result costs more than expected, when headers disagree with your dashboard, or when a retry appears twice in your own logs. It checks reported arithmetic and selected fields; it does not query your account, settle an invoice or verify the extracted data's accuracy.

Start with the explicit credit breakdown

The API contract defines three values under meta.credits:

FieldWhat to read from it
compileCredits for learning or repairing extraction logic; an aggregate can include several pages.
egressNetwork credits reported for fetching pages.
totalThe combined compile and network charge for the original operation.

Use the explicit breakdown before drawing conclusions from tier. A compiled result means a reusable extractor answered; it does not mean every network path was free. A demo receipt can describe compilation work while reporting zero actual credits. Tokens describe model work, not the account's credit balance.

There is a naming trap in the current contract. The JSON value meta.creditsCharged equals the combined total. The legacy HTTP header X-Scraipe-Credits-Charged contains whole compile credits only. For the combined amount in headers, use X-Scraipe-Credits-Total, which is formatted with three decimal places.

For example, compile: 0, egress: 0.05 and total: 0.05 should have a legacy charged header of 0 and a total header of 0.050. Those values agree. Comparing the legacy header directly with the combined total would create a false alarm.

Keep amounts in credit units for this comparison. Purchase prices, currencies and account transactions are a separate concern; the fixture below is not a current price quote. A missing receipt must remain unknown instead of becoming a zero charge through a default such as Number(value) || 0.

Run a receipt check locally

Download these three files into one directory:

Use Node 22 or later. The example was tested on Node 22.23.2 on 6 October 2026 and needs no npm installation or API key. The Node test runner documentation describes the built-in runner used here.

bash

node --test inspect-request-receipt.test.mjs
node inspect-request-receipt.mjs request-receipt.fixture.json

The first command passes 18 tests. The second exits with code 0 and includes this report:

json

{
  "status": "consistent",
  "receiptRequestId": "req_example_original",
  "responseRequestId": "req_example_original",
  "replay": null,
  "credits": {
    "compile": "0.000",
    "egress": "0.050",
    "total": "0.050"
  },
  "observations": {
    "tier": "compiled",
    "latencyMs": 1200,
    "tokens": 0,
    "originRequests": 2,
    "network": "residential",
    "attempts": 2
  },
  "issues": []
}

Every ID, record, amount and timing in the fixture is invented for a deterministic test. It is not a customer receipt, an extraction run or a speed benchmark. The fixture models a failed direct fetch followed by a successful residential fetch. Its two network attempts still belong to one operation.

Inspect your own captured response

The inspector accepts a small JSON file with the response body under body and, optionally, saved HTTP response headers under headers. These wrapper keys are the example's file format, not additional keys required by the Scraipe API.

json

{
  "headers": {
    "X-Scraipe-Credits-Charged": "0",
    "X-Scraipe-Credits-Total": "0.050"
  },
  "body": {
    "meta": {
      "credits": { "compile": 0, "egress": 0.05, "total": 0.05 }
    }
  }
}

Save response headers as strings. The example matches their names without regard to case and flags duplicate names with different casing. Save only the response fields needed for diagnosis; do not copy Authorization headers, API keys, cookies or private records into a shared debugging file. The inspector does not echo the extracted data field, but the capture itself can still contain sensitive information.

The CLI returns 0 for a consistent credit breakdown, 1 for missing or inconsistent receipt information, and 2 for an unreadable file, invalid JSON or invalid command arguments. The exported inspectReceipt(capture) function returns the same report for a Node application. It never changes the input, makes a network request or spends API credits.

consistent means the available fields checked by this example agree. It is not a full API-schema validation or confirmation that the balance was debited. Optional observations that are missing or unusable remain null. The tool reads the whole file into memory, so keep captures small and add your own resource controls before integrating it into a large ingestion job.

Diagnose disagreement without guessing

The checker requires numeric, finite, nonnegative JSON credit amounts at the contract's thousandth-credit precision. Strings such as "0.05" are rejected in the JSON breakdown; HTTP header strings are parsed separately. Fractional compile counts, unsupported precision and amounts outside the example's safe range are also rejected.

It converts decimal credit values into integer thousandths before adding them, avoiding ordinary floating-point addition for the comparison. It rejects values beyond JavaScript's safe integer range in those units. See the ECMAScript number specification for the underlying integer constraint. This is a diagnostic convention for the current receipt format, not a general currency library.

ReportNext check
unavailable with missing credit fieldsPreserve the capture and inspect the response version or error; do not infer a free request.
sum_mismatchCompare the original compile, network and total fields before any application transformation.
Header or alias mismatchCheck that body and headers came from the same response and that the correct header was used.
positive_total_on_uncharged_errorKeep the request IDs and reconcile the contradictory capture against the request log.

An error containing charged: false can omit meta entirely. The checker then reports an unavailable numeric breakdown while leaving that error claim in the original capture. A timeout or HTML infrastructure error may give you no Scraipe receipt at all. Neither condition justifies inventing a total or repeatedly resubmitting a request.

Keep replays out of charge totals

For the JSON POST /v1/scrape flow, a stored idempotent success returns the original body and X-Scraipe-Idempotent-Replay: true. That body can still contain a positive original charge. The replay does not represent another debit.

The inspector reports replay: true when that header was captured; it does not replace the original receipt amount with zero. When the header is absent, it returns null, because a saved body alone cannot establish whether it was replayed. Keep the original body/receipt ID separately from the response-header ID: a replay can carry a new HTTP request ID alongside the original body.

Do not sum every downloaded response as a new charge. Reconcile distinct original operations against your account's request records and preserve replay context. The example deliberately does not produce an account total. Batch and crawl summaries also need their own handling: adding both a parent summary and its per-page receipts can double-count the same work.

The contract scopes idempotency to the caller and key, requires an unchanged request body, and currently retains successes for ten minutes. Reusing a key with different input conflicts; failures are not stored as successful replays. Do not assume an arbitrary later retry is free merely because you kept the same key.

Use the remaining fields to explain the work

After checking credits, inspect tier, tokens, originRequests and the egress.attempts trace. The trace helps distinguish a single fetch from retries or network escalation. An attempt's status or block classification explains that attempt; it is not by itself the final operation outcome or another charge.

latencyMs is reported server time, not a measurement of your client's complete round trip. Attempt durations also omit work outside those attempts, so do not expect them to add up to the full duration. One receipt is insufficient evidence for throughput, extraction accuracy or a latency guarantee.

For a confusing operation, retain the time, endpoint, sanitized response, original receipt ID and response-header ID. Check the authenticated request detail before starting another extraction. For a new workflow, first choose Read or Extract, then use the playground to inspect a small permitted source and its receipt.

Sources and verification

Try the next step

Try the playground

Continue building