{
  "ok": true,
  "catalog": {
    "catalog_version": 1,
    "service": "x402-catalog-history",
    "what_this_is": "The machine-readable catalogue of every product served by this Worker: what each one is, its input and output, its price, payment terms, a purchase example and notes for catalogue listing. GET / returns this same object as `catalog`, and product.json is that object on disk; both come from this one function, so they cannot drift apart.",
    "how_to_read": "purchase_examples[] is the machine-readable purchase example for each product (call, input, output shape, price), in the same order as products[]. products[] holds one entry per product; product_id identifies it. Each price is for one delivery.",
    "purchase_examples": [
      {
        "product_id": "x402-catalog-history",
        "call": {
          "method": "GET",
          "url_template": "https://<worker-host>/history",
          "path": "/history",
          "params": "none",
          "body": "none",
          "headers": {
            "PAYMENT-SIGNATURE": "<base64 payment payload> — required only for the paid delivery; the first call without it returns 402 with the price"
          }
        },
        "input": {
          "method": "GET",
          "path": "/history",
          "params": "none",
          "body": "none",
          "note": "Payment is proven by the payment header, not by a request body."
        },
        "output": {
          "content_type": "application/json",
          "encoding": "UTF-8",
          "shape": {
            "product_id": "string",
            "schema_version": "number",
            "generated_at": "ISO-8601 UTC, when this snapshot was built",
            "period": "{ first_observed_at, last_observed_at, cycles, series_events }",
            "coverage": "{ targets[], total_observations, total_misses, miss_events[], missing_meaning }",
            "changes": "[{ observed_at, observed_at_jst, target_id, change_status, changes[] }] sorted oldest first",
            "latest": "{ target_id: { observed_at, facts } } — full facts of the newest observation per target",
            "delivery": "{ delivered_at, payer, payment: { transaction, network, scheme, amount_atomic, asset } }"
          }
        },
        "price": {
          "amount_atomic": "10000",
          "amount_usd": 0.01,
          "asset_symbol": "USDC",
          "network": "eip155:8453",
          "scheme": "exact",
          "per": "one GET /history response"
        },
        "steps": [
          "curl -i https://<worker-host>/history  -> 402, read the PAYMENT-REQUIRED header",
          "decode the header, sign an exact eip3009 USDC transfer for accepts[0] with your x402 client",
          "repeat the call with the PAYMENT-SIGNATURE header  -> 200 with the x402-catalog-history response"
        ],
        "note": "The 402 challenge is the authority on the current price and payTo. This example is generated from the same CONFIG and the same io/price fields as the product entry above."
      },
      {
        "product_id": "x402-json-compat-check",
        "call": {
          "method": "POST",
          "url_template": "https://<worker-host>/compat",
          "path": "/compat",
          "params": null,
          "body": {
            "schema": "JSON Schema fragment (supported keywords only)",
            "actual": "the JSON value to check"
          },
          "headers": {
            "PAYMENT-SIGNATURE": "<base64 payment payload> — required only for the paid delivery; the first call without it returns 402 with the price"
          }
        },
        "input": {
          "content_type": "application/json",
          "method": "POST",
          "path": "/compat",
          "body": {
            "schema": "JSON Schema fragment (supported keywords only)",
            "actual": "the JSON value to check"
          },
          "note": "The request body is validated (size, JSON shape, depth, node count) and rejected with 400/413 before any payment is requested."
        },
        "output": {
          "content_type": "application/json",
          "encoding": "UTF-8",
          "shape": {
            "status": "no_mismatch | mismatch | unsupported_input",
            "issues": "[{ path (RFC 6901 JSON Pointer), schemaPath, keyword, expected, actual }]",
            "checker": "{ name, version, supported_keywords }",
            "input": "{ schema_sha256, actual_sha256, schema_canonical_bytes, actual_canonical_bytes }"
          }
        },
        "price": {
          "amount_atomic": "10000",
          "amount_usd": 0.01,
          "asset_symbol": "USDC",
          "network": "eip155:8453",
          "scheme": "exact",
          "per": "one POST /compat response"
        },
        "steps": [
          "curl -i -X POST https://<worker-host>/compat  -> 402, read the PAYMENT-REQUIRED header",
          "decode the header, sign an exact eip3009 USDC transfer for accepts[0] with your x402 client",
          "repeat the call with the PAYMENT-SIGNATURE header  -> 200 with the x402-json-compat-check response"
        ],
        "note": "The 402 challenge is the authority on the current price and payTo. This example is generated from the same CONFIG and the same io/price fields as the product entry above."
      },
      {
        "product_id": "x402-catalog-change-log",
        "call": {
          "method": "GET",
          "url_template": "https://<worker-host>/changes",
          "path": "/changes",
          "params": {
            "from": "optional ISO-8601 timestamp or date (YYYY-MM-DD); default: the first observed cycle",
            "to": "optional ISO-8601 timestamp or date (YYYY-MM-DD); default: the last observed cycle"
          },
          "body": "none",
          "headers": {
            "PAYMENT-SIGNATURE": "<base64 payment payload> — required only for the paid delivery; the first call without it returns 402 with the price"
          }
        },
        "input": {
          "method": "GET",
          "path": "/changes",
          "params": {
            "from": "optional ISO-8601 timestamp or date (YYYY-MM-DD); default: the first observed cycle",
            "to": "optional ISO-8601 timestamp or date (YYYY-MM-DD); default: the last observed cycle"
          },
          "body": "none",
          "note": "An unparsable or reversed from/to is rejected with 400 before any payment is requested. Payment is proven by the payment header, not by a request body."
        },
        "output": {
          "content_type": "application/json",
          "encoding": "UTF-8",
          "shape": {
            "product_id": "string",
            "schema_version": "number",
            "generated_at": "ISO-8601 UTC, when this change log was built",
            "snapshot_id": "string (snap-<16 hex>)",
            "first_observed_at": "ISO-8601 UTC, first observation inside the selected period",
            "last_observed_at": "ISO-8601 UTC, last observation inside the selected period",
            "cycles": "number of collector cycles inside the selected period",
            "period": "{ requested, default_period, cycles, observation_records, available, filter_rule }",
            "changes": "{ total, by_target, by_field, first_change_at, last_change_at, events[] } where each event is { observed_at, observed_at_jst, cycle, target_id, field, kind (changed|added|removed), from, to }",
            "targets": "[{ target_id, url, purpose, observations_in_period, cycles_present, cycles_missing, first/last_observed_at, last_success_at, last_failure_at, consecutive_failures, state }]",
            "outages": "{ total, intervals[{ target_id, started_at, ended_at, ongoing, failed_attempts, http_statuses, errors }] }",
            "missing": "{ total, intervals[{ target_id, from, to, missing_cycles, cycle_numbers, after, before }], cycle_gaps }",
            "first_seen": "[{ target_id, observed_at, cycle }] — targets first observed inside the period",
            "snapshot": "{ id, kind, generated_at, cycles, observation_records }",
            "delivery": "{ delivered_at, payer, payment: { transaction, network, scheme, amount_atomic, asset } }"
          }
        },
        "price": {
          "amount_atomic": "10000",
          "amount_usd": 0.01,
          "asset_symbol": "USDC",
          "network": "eip155:8453",
          "scheme": "exact",
          "per": "one GET /changes response"
        },
        "steps": [
          "curl -i https://<worker-host>/changes  -> 402, read the PAYMENT-REQUIRED header",
          "decode the header, sign an exact eip3009 USDC transfer for accepts[0] with your x402 client",
          "repeat the call with the PAYMENT-SIGNATURE header  -> 200 with the x402-catalog-change-log response"
        ],
        "note": "The 402 challenge is the authority on the current price and payTo. This example is generated from the same CONFIG and the same io/price fields as the product entry above."
      },
      {
        "product_id": "x402-catalog-change-bundle",
        "call": {
          "method": "GET",
          "url_template": "https://<worker-host>/changes/bundle",
          "path": "/changes/bundle",
          "params": {
            "units": "optional integer 1..100; default 100. A larger value is refused with 400, not truncated.",
            "from": "optional ISO-8601 timestamp or date (YYYY-MM-DD); default: the first observed cycle",
            "to": "optional ISO-8601 timestamp or date (YYYY-MM-DD); default: the last observed cycle",
            "order": "optional oldest (default) | newest — the order the units are delivered in"
          },
          "body": "none",
          "headers": {
            "PAYMENT-SIGNATURE": "<base64 payment payload> — required only for the paid delivery; the first call without it returns 402 with the price"
          }
        },
        "input": {
          "method": "GET",
          "path": "/changes/bundle",
          "params": {
            "units": "optional integer 1..100; default 100. A larger value is refused with 400, not truncated.",
            "from": "optional ISO-8601 timestamp or date (YYYY-MM-DD); default: the first observed cycle",
            "to": "optional ISO-8601 timestamp or date (YYYY-MM-DD); default: the last observed cycle",
            "order": "optional oldest (default) | newest — the order the units are delivered in"
          },
          "body": "none",
          "note": "Every parameter is checked before any payment: a bad period, a bad order, a missing or non-integer units value and a units value above the limit are answered with 400 and no PAYMENT-REQUIRED header. A period that contains no observation cycle at all is also refused with 400 (period_not_observed) instead of charging for nothing."
        },
        "output": {
          "content_type": "application/json",
          "encoding": "UTF-8",
          "shape": {
            "product_id": "string",
            "units_requested": "number — what the request asked for (default 100)",
            "units_delivered": "number — how many units are in units[]",
            "units_unavailable": "number — units_requested - units_delivered",
            "unit_definition": "object — the definition every delivered unit follows",
            "units": "[{ unit_index, target_id, field, kind (changed|added|removed), from, to, observed_at, observed_at_jst, cycle }]",
            "shortfall": "{ units, unit_slots: { detected_change, observed_without_change, missing_observation, total }, reasons: [{ code, count, meaning }], note }",
            "order": "string — the delivery order that was applied",
            "period": "same as GET /changes",
            "targets": "same as GET /changes (per-target status, missing cycles)",
            "outages": "same as GET /changes",
            "missing": "same as GET /changes",
            "snapshot_id": "string (snap-<16 hex>)",
            "delivery": "{ delivered_at, payer, payment: { transaction, network, scheme, amount_atomic, asset } }"
          }
        },
        "price": {
          "amount_atomic": "500000",
          "amount_usd": 0.5,
          "asset_symbol": "USDC",
          "network": "eip155:8453",
          "scheme": "exact",
          "per": "one GET /changes/bundle response (up to 100 units)"
        },
        "steps": [
          "curl -i https://<worker-host>/changes/bundle  -> 402, read the PAYMENT-REQUIRED header",
          "decode the header, sign an exact eip3009 USDC transfer for accepts[0] with your x402 client",
          "repeat the call with the PAYMENT-SIGNATURE header  -> 200 with the x402-catalog-change-bundle response"
        ],
        "note": "The 402 challenge is the authority on the current price and payTo. This example is generated from the same CONFIG and the same io/price fields as the product entry above."
      }
    ],
    "products": [
      {
        "product_id": "x402-catalog-history",
        "schema_version": 1,
        "title": "x402 catalog observation history",
        "what_it_is": "The observed change history of the public x402 facilitator catalog: which listed resources appeared, disappeared, changed price, changed network/asset, or changed terms, cycle by cycle, with raw facts.",
        "when_to_buy": "Buy one delivery when you need a dated record of how the public x402 catalogue changed — resource totals, the composition of one discovery page, facilitator pricing and a tracked set of resources — instead of a single live reading. Typical case: a listing, an integration or a report depends on a resource count, a price band or an accepted network, and you want the exact period covered, the raw facts and the misses behind those numbers.",
        "subject": {
          "what_is_observed": [
            "facilitator discovery catalog: total resource count, per-page window composition (hosts, networks, price bands, schemes, assets, max timeouts)",
            "facilitator supported networks/schemes (network x scheme rows, feePayer, gas sponsored, extensions, signer networks)",
            "facilitator pricing (credit price, published margin, per network x scheme x transferMethod rates, published rate changes)",
            "a tracked set of individual resources (listed/not listed, last_updated, accepts: network, scheme, asset, amount, payTo, maxTimeoutSeconds)"
          ],
          "not_included": [
            "no response bodies of third-party APIs, no private keys, no buyer or payer identities",
            "no observations of resources outside the configured watch list"
          ],
          "source": "public facilitator endpoints (discovery/resources, supported, pricing)",
          "observation_interval_minutes": 15,
          "collector_location": "local host (not in this Worker); this Worker only serves the stored snapshot"
        },
        "period": {
          "first_observed_at": "2026-10-11T12:31:51.688Z",
          "last_observed_at": "2026-10-11T14:45:39.239Z",
          "cycles_recorded": 56,
          "note": "The delivery contains the snapshot built from all cycles recorded so far. The exact window is reported in the response period field.",
          "timezone": "UTC (observed_at); observed_at_jst is UTC+09:00"
        },
        "version": {
          "product_schema_version": 1,
          "history_schema_version": 1,
          "snapshot_generated_at": "2026-10-11T15:00:11.423Z",
          "kind": "fixed_snapshot",
          "update_policy": "This delivery is a fixed snapshot. Continued local observation does NOT change it. A newer snapshot is published as a separate deployment with a different snapshot_id, and this URL then serves that newer snapshot; the period fields always state exactly what is included.",
          "how_to_tell_which_snapshot": "Read snapshot.id, snapshot.generated_at and period in this response before paying.",
          "static_catalogue_file": "The same values are published in product.json (built from this code, checked by selftest)."
        },
        "missing_data": {
          "meaning": "A missing cycle means the observation attempt for that target failed (HTTP error or timeout). It does not mean the observed value was absent, zero, or removed.",
          "how_to_read": "coverage.miss_events lists failed cycles with target_id, http_status and error. coverage.total_misses is their count.",
          "coverage_caveat": "Observations are 15-minute samples, not a continuous record. A change that appeared and reverted between two cycles is not visible. Zero misses does not mean zero blind spots."
        },
        "io": {
          "input": {
            "method": "GET",
            "path": "/history",
            "params": "none",
            "body": "none",
            "note": "Payment is proven by the payment header, not by a request body."
          },
          "output": {
            "content_type": "application/json",
            "encoding": "UTF-8",
            "shape": {
              "product_id": "string",
              "schema_version": "number",
              "generated_at": "ISO-8601 UTC, when this snapshot was built",
              "period": "{ first_observed_at, last_observed_at, cycles, series_events }",
              "coverage": "{ targets[], total_observations, total_misses, miss_events[], missing_meaning }",
              "changes": "[{ observed_at, observed_at_jst, target_id, change_status, changes[] }] sorted oldest first",
              "latest": "{ target_id: { observed_at, facts } } — full facts of the newest observation per target",
              "delivery": "{ delivered_at, payer, payment: { transaction, network, scheme, amount_atomic, asset } }"
            }
          },
          "free_sample": {
            "method": "GET",
            "path": "/",
            "returns": "this product description plus the newest change events"
          },
          "health": {
            "method": "GET",
            "path": "/health",
            "returns": "{ status, service, time, snapshot_generated_at }"
          }
        },
        "price": {
          "amount_atomic": "10000",
          "asset_decimals": 6,
          "amount_usd": 0.01,
          "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
          "asset_symbol": "USDC",
          "network": "eip155:8453",
          "scheme": "exact",
          "per": "one GET /history response",
          "note": "One payment buys one delivery of the current snapshot. Price is set by the operator and may change; the 402 response always carries the current amount."
        },
        "payment": {
          "protocol": "x402",
          "x402_version": 2,
          "asset_transfer_method": "eip3009",
          "pay_to": "0x6f60659390aDA1D02B14024d8c9d0C889f2F89c3",
          "network": "eip155:8453",
          "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
          "max_timeout_seconds": 60,
          "payment_header": "PAYMENT-SIGNATURE",
          "challenge_header": "PAYMENT-REQUIRED (base64 JSON: x402Version, error, resource{url,description,mimeType}, accepts[])",
          "settlement_receipt_header": "PAYMENT-RESPONSE (base64 SettlementResponse)",
          "version_note": "V2 only. The version field, the CAIP-2 network id, the header names and the payment requirement shape are the V2 forms and are consistent with each other. A V1 client (x402Version 1, network \"base\", X-PAYMENT) is answered with 400 and an explicit message rather than being silently misread.",
          "verification": "The Worker POSTs the payment payload and the payment requirements to the facilitator /verify, then /settle. Signature verification is delegated to the facilitator; no keys are handled here.",
          "facilitator": "https://facilitator.payai.network",
          "refunds": "Payments are settled on-chain and are not refunded automatically. If a paid request fails to return data, the transaction is the record of the claim.",
          "terms_of_use": "Data is provided as observed, without warranty of completeness or fitness for a particular purpose."
        },
        "purchase_example": {
          "step_1": "curl -i https://<worker-host>/history   -> 402, read the PAYMENT-REQUIRED header",
          "step_2": "decode the header, sign an exact eip3009 USDC transfer for accepts[0] with your x402 client",
          "step_3": "curl -i -H 'PAYMENT-SIGNATURE: <base64 payload>' https://<worker-host>/history   -> 200 with the history JSON",
          "note": "An x402 client library performs steps 2 and 3 automatically."
        },
        "listing_notes": {
          "resource_type": "Plain GET. A catalogue can confirm the payment terms by calling the resource and reading the 402 PAYMENT-REQUIRED header; no request body is needed, so listing it does not require preparing an input.",
          "price": "The 402 response always carries the current amount. product.json and this catalogue are generated from the same CONFIG, so a price change must be re-generated and re-deployed for both at once.",
          "snapshot": "List it as a fixed snapshot sold one delivery at a time, not as a live or streaming feed. snapshot.id, snapshot.generated_at and period in each response state exactly what is included.",
          "claims": "Do not advertise completeness or real-time coverage. Observation is a 15-minute sample, and a delivery does not change when local observation continues."
        }
      },
      {
        "product_id": "x402-json-compat-check",
        "schema_version": 1,
        "title": "x402 JSON Schema compatibility check",
        "what_it_is": "A bounded compatibility check of one JSON value against one JSON Schema fragment. Supported keywords: type, required, properties, additionalProperties, items, enum, const. It returns pass/fail, the kind and location of each mismatch, expected vs actual, the checker version and the sha256 of the canonicalized inputs. It is not a full JSON Schema validator and runs no input code.",
        "when_to_buy": "Buy one check when you have one JSON value and one JSON Schema fragment and want a yes/no answer plus the failing paths, before you wire that pair into your own validator, test suite or paid pipeline. It fits a pre-flight step: confirm the payload shape a seller expects without shipping a full validator.",
        "subject": {
          "what_is_checked": "one JSON Schema fragment against one JSON value, in one request (the fields schema and actual)",
          "supported_keywords": [
            "type",
            "required",
            "properties",
            "additionalProperties",
            "items",
            "enum",
            "const"
          ],
          "checker": {
            "name": "x402-compat-check",
            "version": "1.0.0",
            "format_version": 1
          },
          "not_included": [
            "no full JSON Schema conformance: $ref, boolean schemas, format, numeric/string length constraints and oneOf/anyOf/allOf are reported as unsupported, never silently ignored",
            "no input retention: only the sha256 of the canonicalized inputs is returned",
            "no code execution: the checker reads JSON data only (no eval, no regular expressions, no property getters)"
          ]
        },
        "io": {
          "input": {
            "content_type": "application/json",
            "method": "POST",
            "path": "/compat",
            "body": {
              "schema": "JSON Schema fragment (supported keywords only)",
              "actual": "the JSON value to check"
            },
            "note": "The request body is validated (size, JSON shape, depth, node count) and rejected with 400/413 before any payment is requested."
          },
          "output": {
            "content_type": "application/json",
            "encoding": "UTF-8",
            "shape": {
              "status": "no_mismatch | mismatch | unsupported_input",
              "issues": "[{ path (RFC 6901 JSON Pointer), schemaPath, keyword, expected, actual }]",
              "checker": "{ name, version, supported_keywords }",
              "input": "{ schema_sha256, actual_sha256, schema_canonical_bytes, actual_canonical_bytes }"
            }
          },
          "health": {
            "method": "GET",
            "path": "/health",
            "returns": "{ status, service, time, snapshot_generated_at }"
          },
          "free_sample": {
            "method": "GET",
            "path": "/",
            "returns": "this catalogue plus the newest change events of product 1"
          }
        },
        "limits": {
          "maxBodyBytes": 65536,
          "maxDepth": 16,
          "maxNodes": 10000,
          "maxIssues": 100
        },
        "price": {
          "amount_atomic": "10000",
          "asset_decimals": 6,
          "amount_usd": 0.01,
          "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
          "asset_symbol": "USDC",
          "network": "eip155:8453",
          "scheme": "exact",
          "per": "one POST /compat response",
          "note": "One payment buys one checked pair. This is a separate constant from product 1, so either price can change alone; the 402 response always carries the current amount."
        },
        "payment": {
          "protocol": "x402",
          "x402_version": 2,
          "asset_transfer_method": "eip3009",
          "pay_to": "0x6f60659390aDA1D02B14024d8c9d0C889f2F89c3",
          "network": "eip155:8453",
          "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
          "max_timeout_seconds": 60,
          "payment_header": "PAYMENT-SIGNATURE",
          "challenge_header": "PAYMENT-REQUIRED (base64 JSON: x402Version, error, resource{url,description,mimeType}, accepts[])",
          "settlement_receipt_header": "PAYMENT-RESPONSE (base64 SettlementResponse)",
          "version_note": "V2 only, the same forms as product 1 (x402Version 2, CAIP-2 network id, PAYMENT-SIGNATURE). A V1 client (x402Version 1, network \"base\", X-PAYMENT) is answered with 400 and an explicit message.",
          "verification": "The Worker POSTs the payment payload and the payment requirements to the facilitator /verify, then /settle. Signature verification is delegated to the facilitator; no keys are handled here.",
          "facilitator": "https://facilitator.payai.network",
          "refunds": "Payments are settled on-chain and are not refunded automatically. If a paid request fails to return a report, the transaction is the record of the claim.",
          "terms_of_use": "The check is provided as-is, without warranty. no_mismatch only means no mismatch within the six supported keywords."
        },
        "purchase_example": {
          "step_1": "curl -i -X POST https://<worker-host>/compat -H 'content-type: application/json' -d '{\"schema\":{\"type\":\"object\"},\"actual\":{}}'   -> 402, read the PAYMENT-REQUIRED header",
          "step_2": "decode the header, sign an exact eip3009 USDC transfer for accepts[0] with your x402 client",
          "step_3": "curl -i -X POST -H 'content-type: application/json' -H 'PAYMENT-SIGNATURE: <base64 payload>' https://<worker-host>/compat -d '{...}'   -> 200 with the compatibility report",
          "note": "The body must be exactly {schema, actual}. An x402 client library performs steps 2 and 3 automatically."
        },
        "listing_notes": {
          "resource_type": "POST resource. A catalogue that confirms payment terms by calling the resource may need a request body and a payment to complete the listing, which is not possible for a GET-only listing flow.",
          "no_get_alias": "GET /compat stays 405 on purpose. A GET window that returns a description or an empty report would put a resource in the catalogue that does not behave as listed and would break a buyer's 402 check.",
          "first_listing_unverified": "The exact listing procedure (a one-off listing payment, manual registration, a facilitator-side setting) is UNVERIFIED. Do not claim it is listable until it has been done once with a real payment.",
          "price": "The 402 response always carries COMPAT_PRICE_ATOMIC. product.json and this catalogue come from the same CONFIG."
        },
        "spec": "compat-spec.md (published with this code; not served as a GET route)"
      },
      {
        "product_id": "x402-catalog-change-log",
        "schema_version": 1,
        "title": "x402 catalog change log (period diff)",
        "what_it_is": "The diff of the stored observation history of the public x402 facilitator catalog, for a period you choose with from/to: every detected change with the field name and its before/after values and the observation time, the last success and last failure per target with the intervals where observation failed, and the observation cycles that are missing. It is built only by processing observation records that were already collected; it makes no new observation and no upstream call. It is not a live feed.",
        "when_to_buy": "Buy one delivery before you rely on a number from the catalog, or before you pay someone else: confirm what changed in a period (which tracked resource repriced, which host left the page window, which capability appeared), where observation stopped and where it resumed, and how many cycles are missing — so you know whether a value you are about to trust is stable, moving, or simply unobserved. Use /history when you need the current snapshot of the facts; use /changes when you need the difference over a period.",
        "subject": {
          "what_is_diffed": [
            "field-level changes of every observation target (target_id, field, before value, after value, observation time, cycle number)",
            "the status of each target over the period (last success, last failure, consecutive failures, cycles present and missing)",
            "intervals where observation failed (start, end, ongoing, failed attempts, http status, error)",
            "missing observation cycles per target: the interval, how many cycles, and the cycles before and after",
            "cycle-level gaps in the observation record itself (a gap longer than 25 minutes is flagged)"
          ],
          "not_included": [
            "no third-party response bodies, no private keys, no buyer or payer identities",
            "no interpolated values: a missing cycle is reported as missing, never filled in",
            "no new collection: the data is the stored observation record only"
          ],
          "source": "the same local observation store as GET /history (facilitator discovery/resources, supported, pricing and a tracked resource set)",
          "observation_interval_minutes": 15,
          "collector_location": "local host (not in this Worker); this Worker only serves the stored record"
        },
        "period": {
          "default": "all observed cycles",
          "selectable": "?from=<ISO-8601>&to=<ISO-8601>; a bare date (YYYY-MM-DD) means the whole day in UTC",
          "available": {
            "first_observed_at": "2026-10-11T12:31:51.688Z",
            "last_observed_at": "2026-10-12T12:00:41.050Z",
            "cycles": 100,
            "observation_records": 396
          },
          "how_cycles_are_counted": "One cycle is one run of the collector, which observes every target within a few seconds. A cycle counts when the observation time of at least one target falls inside the period. Note that the cycles field of the bundled GET /history snapshot counts stored observation records (one per target per cycle), not runs, so compare it with observation_records here, not with cycles.",
          "timezone": "UTC (observed_at); observed_at_jst is UTC+09:00"
        },
        "version": {
          "product_schema_version": 1,
          "change_schema_version": 1,
          "change_log_generated_at": "2026-10-12T12:08:14.380Z",
          "kind": "fixed_snapshot",
          "update_policy": "This delivery is a fixed snapshot of the stored change log. Continued local observation does NOT change it. A newer change log is published as a separate deployment with a different snapshot_id, and this URL then serves that newer one; the period fields always state exactly what is included.",
          "how_to_tell_which_snapshot": "Read snapshot_id, generated_at and period in this response before paying.",
          "static_catalogue_file": "The same values are published in product.json (built from this code, checked by selftest)."
        },
        "missing_data": {
          "meaning": "A missing cycle means the observation of that target in that cycle left no record. The collector writes a failed attempt to misses.jsonl instead of records.jsonl, so a failure and an absent run both appear here as a missing cycle. It does not mean the observed value was absent, zero or removed.",
          "how_to_read": "missing.intervals lists, per target, the interval, the number of missing cycles and the cycles immediately before and after. outages.intervals lists recorded failed attempts with their http status and error.",
          "coverage_caveat": "Observations are 15-minute samples, not a continuous record. A change that appeared and reverted between two cycles is not visible. Zero missing cycles does not mean zero blind spots."
        },
        "io": {
          "input": {
            "method": "GET",
            "path": "/changes",
            "params": {
              "from": "optional ISO-8601 timestamp or date (YYYY-MM-DD); default: the first observed cycle",
              "to": "optional ISO-8601 timestamp or date (YYYY-MM-DD); default: the last observed cycle"
            },
            "body": "none",
            "note": "An unparsable or reversed from/to is rejected with 400 before any payment is requested. Payment is proven by the payment header, not by a request body."
          },
          "output": {
            "content_type": "application/json",
            "encoding": "UTF-8",
            "shape": {
              "product_id": "string",
              "schema_version": "number",
              "generated_at": "ISO-8601 UTC, when this change log was built",
              "snapshot_id": "string (snap-<16 hex>)",
              "first_observed_at": "ISO-8601 UTC, first observation inside the selected period",
              "last_observed_at": "ISO-8601 UTC, last observation inside the selected period",
              "cycles": "number of collector cycles inside the selected period",
              "period": "{ requested, default_period, cycles, observation_records, available, filter_rule }",
              "changes": "{ total, by_target, by_field, first_change_at, last_change_at, events[] } where each event is { observed_at, observed_at_jst, cycle, target_id, field, kind (changed|added|removed), from, to }",
              "targets": "[{ target_id, url, purpose, observations_in_period, cycles_present, cycles_missing, first/last_observed_at, last_success_at, last_failure_at, consecutive_failures, state }]",
              "outages": "{ total, intervals[{ target_id, started_at, ended_at, ongoing, failed_attempts, http_statuses, errors }] }",
              "missing": "{ total, intervals[{ target_id, from, to, missing_cycles, cycle_numbers, after, before }], cycle_gaps }",
              "first_seen": "[{ target_id, observed_at, cycle }] — targets first observed inside the period",
              "snapshot": "{ id, kind, generated_at, cycles, observation_records }",
              "delivery": "{ delivered_at, payer, payment: { transaction, network, scheme, amount_atomic, asset } }"
            }
          },
          "free_sample": {
            "method": "GET",
            "path": "/",
            "returns": "this product description plus the newest change events"
          },
          "health": {
            "method": "GET",
            "path": "/health",
            "returns": "{ status, service, time, snapshot_generated_at }"
          }
        },
        "price": {
          "amount_atomic": "10000",
          "asset_decimals": 6,
          "amount_usd": 0.01,
          "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
          "asset_symbol": "USDC",
          "network": "eip155:8453",
          "scheme": "exact",
          "per": "one GET /changes response",
          "note": "The price is per deliverable period and does not depend on the size of the period. This is a separate constant from the other products, so either price can change alone; the 402 response always carries the current amount."
        },
        "payment": {
          "protocol": "x402",
          "x402_version": 2,
          "asset_transfer_method": "eip3009",
          "pay_to": "0x6f60659390aDA1D02B14024d8c9d0C889f2F89c3",
          "network": "eip155:8453",
          "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
          "max_timeout_seconds": 60,
          "payment_header": "PAYMENT-SIGNATURE",
          "challenge_header": "PAYMENT-REQUIRED (base64 JSON: x402Version, error, resource{url,description,mimeType}, accepts[], extensions.bazaar)",
          "settlement_receipt_header": "PAYMENT-RESPONSE (base64 SettlementResponse)",
          "version_note": "V2 only, the same forms as the other products (x402Version 2, CAIP-2 network id, PAYMENT-SIGNATURE). A V1 client (x402Version 1, network \"base\", X-PAYMENT) is answered with 400 and an explicit message.",
          "verification": "The Worker POSTs the payment payload and the payment requirements to the facilitator /verify, then /settle. Signature verification is delegated to the facilitator; no keys are handled here.",
          "facilitator": "https://facilitator.payai.network",
          "refunds": "Payments are settled on-chain and are not refunded automatically. If a paid request fails to return data, the transaction is the record of the claim.",
          "terms_of_use": "Data is provided as observed, without warranty of completeness or fitness for a particular purpose."
        },
        "purchase_example": {
          "step_1": "curl -i 'https://<worker-host>/changes?from=2026-10-12T00:00:00Z&to=2026-10-12T12:00:00Z'   -> 402, read the PAYMENT-REQUIRED header",
          "step_2": "decode the header, sign an exact eip3009 USDC transfer for accepts[0] with your x402 client",
          "step_3": "curl -i -H 'PAYMENT-SIGNATURE: <base64 payload>' 'https://<worker-host>/changes?from=...&to=...'   -> 200 with the change log JSON",
          "note": "The same payment header works with or without from/to; the period only selects what is reported. An x402 client library performs steps 2 and 3 automatically."
        },
        "listing_notes": {
          "resource_type": "Plain GET with optional query parameters. A catalogue can confirm the payment terms by calling the resource and reading the 402 PAYMENT-REQUIRED header; the parameters are optional, so listing it does not require preparing an input.",
          "query_params": "from/to are optional and default to the full observed period. They select the reported period only; they do not change the price or the snapshot.",
          "snapshot": "List it as a fixed snapshot sold one delivery at a time, not as a live or streaming feed. snapshot_id, generated_at and period in each response state exactly what is included.",
          "distinct_from_history": "/history serves the current facts per target; /changes serves the period diff. They are separate products with separate prices and must not be listed as duplicates of each other.",
          "claims": "Do not advertise completeness or real-time coverage. Observation is a 15-minute sample, a delivery does not change when local observation continues, and a missing cycle is reported as missing rather than filled in."
        }
      },
      {
        "product_id": "x402-catalog-change-bundle",
        "schema_version": 1,
        "title": "x402 catalog change bundle — up to 100 units in one delivery",
        "unit_definition": {
          "one_unit": "one observation target x one checked field x one detected change inside the selected period (the values before and after, at one observation time). One field change = one unit.",
          "triple": {
            "target": "one of the tracked observation targets (target_id)",
            "field": "one checked field of that target (field)",
            "period": "the from/to you pass; every unit is bound to exactly that period, so the same period always yields the same units"
          },
          "what_a_unit_contains": [
            "target_id",
            "field",
            "kind: changed | added (no previous value) | removed (no new value)",
            "from and to: the stored before/after values",
            "observed_at, observed_at_jst and the cycle number"
          ],
          "not_a_unit": [
            "a field that was observed across the period and did not change is not a delivered unit — it is counted in shortfall.unit_slots.observed_without_change (code no_change)",
            "a field whose target left no record in some cycle of the period is not a delivered unit — it is counted in shortfall.unit_slots.missing_observation (code missing_observation)",
            "no aggregation and no splitting: one compound change (a host map, a payment terms object) is one unit"
          ],
          "selection_order": "oldest first by observation time; order=newest reverses it. The same request returns the same units for the same snapshot.",
          "units_per_delivery": 100,
          "max_units_per_delivery": 100,
          "over_limit_behavior": "a request for more than 100 units is refused with HTTP 400 (units_limit_exceeded) before any payment; the answer is never silently truncated to the limit",
          "no_data_behavior": "a period that yields no change at all is still a delivery: units_delivered is 0 and shortfall.reasons says whether the fields were observed without a change or were not observed"
        },
        "what_it_is": "One delivery of up to 100 units counted against the definition below, taken from the same period diff as GET /changes and built by the same processing of the stored observation record. Each unit is one detected change of one field of one target inside the period you select. The response states units_requested, units_delivered, the unit definition and, when the period yields fewer units than asked, why — separating 'observed and did not change' from 'not observed at all'. No new collection and no upstream call.",
        "when_to_buy": "Buy the bundle when you want the period diff split into countable, labelled units in a single response — for unit-level accounting, for a fixed-size answer instead of an unbounded diff, or when you need each finding carried with its own field, before/after values, observation time and a per-unit statement of what could not be checked. Use the cheaper 0.01 GET /changes when you only want the whole period diff as one document; the bundle costs more per delivery because the units are counted, capped and individually labelled.",
        "subject": {
          "what_is_delivered": [
            "units[]: one entry per delivered unit (target_id, field, kind, from, to, observed_at, observed_at_jst, cycle, unit_index)",
            "units_requested / units_delivered / units_unavailable: the exact count, never a silent truncation",
            "unit_slots: how many unit slots the period holds — detected changes, fields observed without a change, and fields whose target is missing cycles",
            "shortfall.reasons[]: per-code counts and meaning, with no_change and missing_observation kept apart",
            "the same period context as GET /changes: period, targets, outages, missing, snapshot_id"
          ],
          "not_included": [
            "no new observation and no upstream call: the stored record only",
            "no aggregation: one field change is one unit, and a compound change (a host map, a payment terms object) is also one unit",
            "no filling in: a missing cycle is reported as missing, never interpolated",
            "no third-party response bodies, no private keys, no buyer or payer identities"
          ],
          "source": "the same local observation store as GET /history and GET /changes",
          "unit_supply_in_this_snapshot": {
            "change_events": 688,
            "target_field_pairs": 29,
            "observation_cycles": 100,
            "note": "change_events is the number of units this snapshot can deliver for the full period (one per detected field change). target_field_pairs is the number of (target, field) pairs the bundled snapshot knows; the rest of the unit slots are those pairs observed without a change."
          }
        },
        "io": {
          "input": {
            "method": "GET",
            "path": "/changes/bundle",
            "params": {
              "units": "optional integer 1..100; default 100. A larger value is refused with 400, not truncated.",
              "from": "optional ISO-8601 timestamp or date (YYYY-MM-DD); default: the first observed cycle",
              "to": "optional ISO-8601 timestamp or date (YYYY-MM-DD); default: the last observed cycle",
              "order": "optional oldest (default) | newest — the order the units are delivered in"
            },
            "body": "none",
            "note": "Every parameter is checked before any payment: a bad period, a bad order, a missing or non-integer units value and a units value above the limit are answered with 400 and no PAYMENT-REQUIRED header. A period that contains no observation cycle at all is also refused with 400 (period_not_observed) instead of charging for nothing."
          },
          "output": {
            "content_type": "application/json",
            "encoding": "UTF-8",
            "shape": {
              "product_id": "string",
              "units_requested": "number — what the request asked for (default 100)",
              "units_delivered": "number — how many units are in units[]",
              "units_unavailable": "number — units_requested - units_delivered",
              "unit_definition": "object — the definition every delivered unit follows",
              "units": "[{ unit_index, target_id, field, kind (changed|added|removed), from, to, observed_at, observed_at_jst, cycle }]",
              "shortfall": "{ units, unit_slots: { detected_change, observed_without_change, missing_observation, total }, reasons: [{ code, count, meaning }], note }",
              "order": "string — the delivery order that was applied",
              "period": "same as GET /changes",
              "targets": "same as GET /changes (per-target status, missing cycles)",
              "outages": "same as GET /changes",
              "missing": "same as GET /changes",
              "snapshot_id": "string (snap-<16 hex>)",
              "delivery": "{ delivered_at, payer, payment: { transaction, network, scheme, amount_atomic, asset } }"
            }
          },
          "free_sample": {
            "method": "GET",
            "path": "/",
            "returns": "this product description (including the unit definition) plus the newest change events"
          },
          "health": {
            "method": "GET",
            "path": "/health",
            "returns": "{ status, service, time, snapshot_generated_at }"
          }
        },
        "limits": {
          "max_units_per_delivery": 100,
          "default_units": 100,
          "over_limit": "400 units_limit_exceeded before payment — the response is never silently truncated to the limit",
          "empty_period": "400 period_not_observed before payment when the selected period contains no observation cycle"
        },
        "price": {
          "amount_atomic": "500000",
          "asset_decimals": 6,
          "amount_usd": 0.5,
          "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
          "asset_symbol": "USDC",
          "network": "eip155:8453",
          "scheme": "exact",
          "per": "one GET /changes/bundle response (up to 100 units)",
          "price_hypothesis": {
            "unit_price_usd": 0.01,
            "bundle_units": 100,
            "bundle_price_usd": 0.5,
            "note": "The per-unit price and the bundle price are a pricing hypothesis, not a measured willingness to pay."
          },
          "note": "The price is per response, not a function of units_delivered. A period with fewer detected changes than requested delivers fewer units and says so in shortfall; the count is always reported before the buyer reuses the data. This is a separate constant from the other products, so either price can change alone; the 402 response always carries the current amount."
        },
        "payment": {
          "protocol": "x402",
          "x402_version": 2,
          "asset_transfer_method": "eip3009",
          "pay_to": "0x6f60659390aDA1D02B14024d8c9d0C889f2F89c3",
          "network": "eip155:8453",
          "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
          "max_timeout_seconds": 60,
          "payment_header": "PAYMENT-SIGNATURE",
          "challenge_header": "PAYMENT-REQUIRED (base64 JSON: x402Version, error, resource{url,description,mimeType}, accepts[], extensions.bazaar)",
          "settlement_receipt_header": "PAYMENT-RESPONSE (base64 SettlementResponse)",
          "version_note": "V2 only, the same forms as the other products (x402Version 2, CAIP-2 network id, PAYMENT-SIGNATURE). A V1 client (x402Version 1, network \"base\", X-PAYMENT) is answered with 400 and an explicit message.",
          "verification": "The Worker POSTs the payment payload and the payment requirements to the facilitator /verify, then /settle. Signature verification is delegated to the facilitator; no keys are handled here.",
          "facilitator": "https://facilitator.payai.network",
          "refunds": "Payments are settled on-chain and are not refunded automatically. If a paid request fails to return data, the transaction is the record of the claim.",
          "terms_of_use": "Data is provided as observed, without warranty of completeness or fitness for a particular purpose."
        },
        "purchase_example": {
          "call": {
            "method": "GET",
            "url_template": "https://<worker-host>/changes/bundle?units=100",
            "headers": {
              "PAYMENT-SIGNATURE": "<base64 payment payload> (the first call without it returns 402)"
            }
          },
          "input": {
            "units": 100,
            "from": null,
            "to": null,
            "order": "oldest"
          },
          "output": {
            "status": 200,
            "content_type": "application/json",
            "shape": {
              "units_requested": 100,
              "units_delivered": "number (<= units_requested)",
              "units_unavailable": "units_requested - units_delivered",
              "unit_definition": "{ one_unit, triple, selection_order, max_units_per_delivery }",
              "units": "[{ unit_index, target_id, field, kind, from, to, observed_at, cycle }]",
              "shortfall": "{ units, unit_slots, reasons: [{ code, count, meaning }] }"
            }
          },
          "price": {
            "amount_atomic": "500000",
            "amount_usd": 0.5,
            "asset_symbol": "USDC",
            "network": "eip155:8453",
            "per": "one delivery of up to 100 units"
          },
          "steps": [
            "curl -i 'https://<worker-host>/changes/bundle?units=100'   -> 402, read the PAYMENT-REQUIRED header",
            "decode the header, sign an exact eip3009 USDC transfer for accepts[0] with your x402 client",
            "curl -i -H 'PAYMENT-SIGNATURE: <base64 payload>' 'https://<worker-host>/changes/bundle?units=100'   -> 200 with the units JSON"
          ],
          "note": "All parameters are optional; units defaults to 100. An x402 client library performs the signing and the retry automatically. Read units_delivered and shortfall before treating the delivery as complete."
        },
        "listing_notes": {
          "resource_type": "Plain GET with optional query parameters. A catalogue can confirm the payment terms by calling the resource and reading the 402 PAYMENT-REQUIRED header; the parameters are optional, so listing it does not require preparing an input.",
          "distinct_from_changes": "The 0.01 GET /changes and this 0.50 bundle use the same data, but they are not the same delivery: /changes returns the whole period diff as one unbounded document, the bundle returns counted and individually labelled units capped at 100 with an explicit shortfall account. Do not list them as duplicates.",
          "price": "The 402 response always carries BUNDLE_PRICE_ATOMIC. product.json and this catalogue come from the same CONFIG. The bundle price is a hypothesis: 1 unit = 0.01 USD, 100 units = 0.50 USD.",
          "claims": "Do not advertise completeness or real-time coverage, and do not promise a fixed number of units: the number delivered depends on how many field changes the period actually contains, and the response states it."
        }
      }
    ]
  },
  "snapshot": {
    "id": "snap-d4ab8aea65ad49f8",
    "kind": "fixed_snapshot",
    "generated_at": "2026-10-11T15:00:11.423Z",
    "first_observed_at": "2026-10-11T12:31:51.688Z",
    "last_observed_at": "2026-10-11T14:45:39.239Z",
    "cycles": 56,
    "missing_cycles": 0,
    "note": "This Worker serves exactly this snapshot. Local observation continues, but this delivery does not change until a new snapshot is deployed. Compare id/generated_at/period before paying."
  },
  "data_period": {
    "first_observed_at": "2026-10-11T12:31:51.688Z",
    "last_observed_at": "2026-10-11T14:45:39.239Z",
    "cycles": 56,
    "series_events": 56
  },
  "data_summary": {
    "targets": 4,
    "cycles": 56,
    "change_events": 18,
    "total_misses": 0
  },
  "sample": {
    "note": "Newest change events, free. The full history including all events, the target list and the latest facts per target is at GET /history. Field-level before/after values, the intervals where observation stopped and the missing cycles are at GET /changes (a period diff over the same store).",
    "events": [
      {
        "observed_at": "2026-10-11T14:45:39.239Z",
        "observed_at_jst": "2026-10-11T23:45:39.239+09:00",
        "target_id": "facilitator.supported",
        "change_status": "unchanged",
        "changes": []
      },
      {
        "observed_at": "2026-10-11T14:45:39.239Z",
        "observed_at_jst": "2026-10-11T23:45:39.239+09:00",
        "target_id": "facilitator.pricing",
        "change_status": "unchanged",
        "changes": []
      },
      {
        "observed_at": "2026-10-11T14:45:39.239Z",
        "observed_at_jst": "2026-10-11T23:45:39.239+09:00",
        "target_id": "tracked.resources",
        "change_status": "changed",
        "changes": []
      }
    ],
    "change_log_preview": {
      "note": "Newest field-level changes, free. GET /changes returns the same shape for a period you choose, plus the outages and the missing cycles.",
      "newest": [
        {
          "cycle": 100,
          "observed_at": "2026-10-12T12:00:41.050Z",
          "observed_at_jst": "2026-10-12T21:00:41.050+09:00",
          "target_id": "catalog.resources",
          "field": "pageDistinctHosts",
          "kind": "changed",
          "from": 17,
          "to": 19
        },
        {
          "cycle": 100,
          "observed_at": "2026-10-12T12:00:41.050Z",
          "observed_at_jst": "2026-10-12T21:00:41.050+09:00",
          "target_id": "catalog.resources",
          "field": "pageNetworkCounts",
          "kind": "changed",
          "from": {
            "eip155:137": 2,
            "eip155:8453": 96,
            "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp": 2
          },
          "to": {
            "eip155:137": 1,
            "eip155:8453": 97,
            "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp": 2
          }
        },
        {
          "cycle": 100,
          "observed_at": "2026-10-12T12:00:41.050Z",
          "observed_at_jst": "2026-10-12T21:00:41.050+09:00",
          "target_id": "catalog.resources",
          "field": "pageAssetCounts",
          "kind": "changed",
          "from": {
            "0x3c499c542c": 2,
            "0x833589fCD6": 95,
            "0x833589fcd6": 1,
            "EPjFWdd5Aufq": 2
          },
          "to": {
            "0x3c499c542c": 1,
            "0x833589fCD6": 96,
            "0x833589fcd6": 1,
            "EPjFWdd5Aufq": 2
          }
        },
        {
          "cycle": 100,
          "observed_at": "2026-10-12T12:00:41.050Z",
          "observed_at_jst": "2026-10-12T21:00:41.050+09:00",
          "target_id": "catalog.resources",
          "field": "pageHosts",
          "kind": "changed",
          "from": {
            "dns.intel.rallylive.ca": {
              "resources": 25,
              "priceBands": {
                "0.01-0.05": 25
              },
              "networks": [
                "eip155:8453"
              ]
            },
            "intel.rallylive.ca": {
              "resources": 24,
              "priceBands": {
                "0.01-0.05": 24
              },
              "networks": [
                "eip155:8453"
              ]
            },
            "email.intel.rallylive.ca": {
              "resources": 17,
              "priceBands": {
                "0.01-0.05": 17
              },
              "networks": [
                "eip155:8453"
              ]
            },
            "data.intel.rallylive.ca": {
              "resources": 9,
              "priceBands": {
                "0.01-0.05": 9
              },
              "networks": [
                "eip155:8453"
              ]
            },
            "chain.intel.rallylive.ca": {
              "resources": 7,
              "priceBands": {
                "0.01-0.05": 7
              },
              "networks": [
                "eip155:8453"
              ]
            },
            "dev.intel.rallylive.ca": {
              "resources": 5,
              "priceBands": {
                "0.01-0.05": 5
              },
              "networks": [
                "eip155:8453"
              ]
            },
            "agentsvc.io": {
              "resources": 2,
              "priceBands": {
                "0.005-0.01": 1,
                "0.01-0.05": 1
              },
              "networks": [
                "eip155:137"
              ]
            },
            "ip.intel.rallylive.ca": {
              "resources": 2,
              "priceBands": {
                "0.01-0.05": 2
              },
              "networks": [
                "eip155:8453"
              ]
            },
            "api.dev.hypercli.com": {
              "resources": 1,
              "priceBands": {
                "0.01-0.05": 1
              },
              "networks": [
                "eip155:8453"
              ]
            },
            "apiv2.laevitas.ch": {
              "resources": 1,
              "priceBands": {
                "0.1-1": 1
              },
              "networks": [
                "eip155:8453"
              ]
            },
            "flow-kg4x.vercel.app": {
              "resources": 1,
              "priceBands": {
                "0.01-0.05": 1
              },
              "networks": [
                "eip155:8453"
              ]
            },
            "lax.kognai.ai": {
              "resources": 1,
              "priceBands": {
                "unknown": 1
              },
              "networks": [
                "eip155:8453"
              ]
            },
            "mpp.hyreagent.fun": {
              "resources": 1,
              "priceBands": {
                "unknown": 1
              },
              "networks": [
                "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"
              ]
            },
            "mystudios.fun": {
              "resources": 1,
              "priceBands": {
                ">=1": 1
              },
              "networks": [
                "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"
              ]
            },
            "www.kognai.ai": {
              "resources": 1,
              "priceBands": {
                "0.1-1": 1
              },
              "networks": [
                "eip155:8453"
              ]
            },
            "www.voxight.online": {
              "resources": 1,
              "priceBands": {
                "unknown": 1
              },
              "networks": [
                "eip155:8453"
              ]
            },
            "x402-catalog-history.ai-business-surface.workers.dev": {
              "resources": 1,
              "priceBands": {
                "0.01-0.05": 1
              },
              "networks": [
                "eip155:8453"
              ]
            }
          },
          "to": {
            "dns.intel.rallylive.ca": {
              "resources": 24,
              "priceBands": {
                "0.01-0.05": 24
              },
              "networks": [
                "eip155:8453"
              ]
            },
            "intel.rallylive.ca": {
              "resources": 24,
              "priceBands": {
                "0.01-0.05": 24
              },
              "networks": [
                "eip155:8453"
              ]
            },
            "email.intel.rallylive.ca": {
              "resources": 18,
              "priceBands": {
                "0.01-0.05": 18
              },
              "networks": [
                "eip155:8453"
              ]
            },
            "data.intel.rallylive.ca": {
              "resources": 8,
              "priceBands": {
                "0.01-0.05": 8
              },
              "networks": [
                "eip155:8453"
              ]
            },
            "chain.intel.rallylive.ca": {
              "resources": 7,
              "priceBands": {
                "0.01-0.05": 7
              },
              "networks": [
                "eip155:8453"
              ]
            },
            "dev.intel.rallylive.ca": {
              "resources": 5,
              "priceBands": {
                "0.01-0.05": 5
              },
              "networks": [
                "eip155:8453"
              ]
            },
            "ip.intel.rallylive.ca": {
              "resources": 2,
              "priceBands": {
                "0.01-0.05": 2
              },
              "networks": [
                "eip155:8453"
              ]
            },
            "agentsvc.io": {
              "resources": 1,
              "priceBands": {
                "0.005-0.01": 1
              },
              "networks": [
                "eip155:137"
              ]
            },
            "api.dev.hypercli.com": {
              "resources": 1,
              "priceBands": {
                "0.01-0.05": 1
              },
              "networks": [
                "eip155:8453"
              ]
            },
            "apiv2.laevitas.ch": {
              "resources": 1,
              "priceBands": {
                "0.1-1": 1
              },
              "networks": [
                "eip155:8453"
              ]
            },
            "enrich.node01.org": {
              "resources": 1,
              "priceBands": {
                "0.01-0.05": 1
              },
              "networks": [
                "eip155:8453"
              ]
            },
            "flow-kg4x.vercel.app": {
              "resources": 1,
              "priceBands": {
                "0.01-0.05": 1
              },
              "networks": [
                "eip155:8453"
              ]
            },
            "lax.kognai.ai": {
              "resources": 1,
              "priceBands": {
                "unknown": 1
              },
              "networks": [
                "eip155:8453"
              ]
            },
            "library.intel.rallylive.ca": {
              "resources": 1,
              "priceBands": {
                "0.01-0.05": 1
              },
              "networks": [
                "eip155:8453"
              ]
            },
            "mpp.hyreagent.fun": {
              "resources": 1,
              "priceBands": {
                "unknown": 1
              },
              "networks": [
                "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"
              ]
            },
            "mystudios.fun": {
              "resources": 1,
              "priceBands": {
                ">=1": 1
              },
              "networks": [
                "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"
              ]
            },
            "www.kognai.ai": {
              "resources": 1,
              "priceBands": {
                "0.1-1": 1
              },
              "networks": [
                "eip155:8453"
              ]
            },
            "www.voxight.online": {
              "resources": 1,
              "priceBands": {
                "unknown": 1
              },
              "networks": [
                "eip155:8453"
              ]
            },
            "x402-catalog-history.ai-business-surface.workers.dev": {
              "resources": 1,
              "priceBands": {
                "0.01-0.05": 1
              },
              "networks": [
                "eip155:8453"
              ]
            }
          }
        },
        {
          "cycle": 100,
          "observed_at": "2026-10-12T12:00:41.050Z",
          "observed_at_jst": "2026-10-12T21:00:41.050+09:00",
          "target_id": "tracked.resources",
          "field": "scan",
          "kind": "changed",
          "from": {
            "pages_scanned": 16,
            "items_scanned": 1600,
            "catalog_total": 19460
          },
          "to": {
            "pages_scanned": 16,
            "items_scanned": 1600,
            "catalog_total": 19461
          }
        }
      ]
    }
  },
  "paid_endpoint": {
    "path": "/history",
    "price": {
      "amount_atomic": "10000",
      "amount_usd": 0.01,
      "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "network": "eip155:8453"
    },
    "pay_to": "0x6f60659390aDA1D02B14024d8c9d0C889f2F89c3"
  },
  "paid_endpoints": [
    {
      "product_id": "x402-catalog-history",
      "path": "/history",
      "method": "GET",
      "price_atomic": "10000"
    },
    {
      "product_id": "x402-json-compat-check",
      "path": "/compat",
      "method": "POST",
      "price_atomic": "10000"
    },
    {
      "product_id": "x402-catalog-change-log",
      "path": "/changes",
      "method": "GET",
      "price_atomic": "10000",
      "params": [
        "from",
        "to"
      ]
    },
    {
      "product_id": "x402-catalog-change-bundle",
      "path": "/changes/bundle",
      "method": "GET",
      "price_atomic": "500000",
      "params": [
        "units",
        "from",
        "to",
        "order"
      ],
      "units_per_delivery": 100,
      "max_units": 100
    }
  ]
}
