{
  "schema_version": "1",
  "generated_at": "2026-10-20T00:00:00Z",
  "language": "en",
  "title": "Agent trust checklist",
  "description": "How agentpaywire.com commits to being dependable for agents. Status is met or partial. Nothing here is paid.",
  "html_url": "https://agentpaywire.com/trust/",
  "markdown_url": "https://agentpaywire.com/trust.md",
  "worker_redeploy_required": true,
  "worker_redeploy_note": "Redeploy the agentpaywire-api worker if it is older than this commit. This commit serves /.well-known/l402-services, returns 400 for a missing since before spending a credit, adds price_sats, credits, ttl_days, and authorization on the API-host L402 document, and lists the error codes on /v1/openapi.json.",
  "deprecation": "A published path is not removed without a changelog record and a redirect from the old path. Renaming a query parameter or a JSON field follows the same rule. Adding a field is not a removal.",
  "authorization": "Authorization: L402 <macaroon>:<preimage>",
  "credits": {
    "price_sats": 100,
    "credits": 100,
    "ttl_days": 30,
    "unit": "One credit is one paid request."
  },
  "rate_limits": {
    "client": null,
    "http_429": false,
    "wallet": "No client rate limit. HTTP 429 is not used. A Lightning wallet rate limit becomes HTTP 503, error rate_limited, and Retry-After. The default wait is 10 seconds."
  },
  "error_body": {
    "minimum": "{ \"error\": \"<code>\" }",
    "l402": "protocol and payment are added on L402 failures.",
    "exceptions": [
      "OPTIONS is 204 with no body.",
      "GET /v1/health?deep=1 during a wallet rate limit is 503 with the health document (ok false) and Retry-After, not only the error object."
    ]
  },
  "urls": {
    "site": [
      "https://agentpaywire.com/api/index.json",
      "https://agentpaywire.com/openapi.json",
      "https://agentpaywire.com/llms.txt",
      "https://agentpaywire.com/llms-full.txt",
      "https://agentpaywire.com/changelog.json",
      "https://agentpaywire.com/sitemap.xml",
      "https://agentpaywire.com/trust.json",
      "https://agentpaywire.com/trust.md",
      "https://agentpaywire.com/support.json",
      "https://agentpaywire.com/api/library.json",
      "https://agentpaywire.com/datasets/index.json",
      "https://agentpaywire.com/bots.json"
    ],
    "api": [
      "https://api.agentpaywire.com/v1",
      "https://api.agentpaywire.com/v1/health",
      "https://api.agentpaywire.com/v1/openapi.json",
      "https://api.agentpaywire.com/v1/search",
      "https://api.agentpaywire.com/v1/updates",
      "https://api.agentpaywire.com/v1/digest"
    ],
    "mcp": [
      "https://mcp.agentpaywire.com/mcp"
    ],
    "well_known": [
      "https://agentpaywire.com/.well-known/api-catalog",
      "https://agentpaywire.com/.well-known/ai-catalog.json",
      "https://agentpaywire.com/.well-known/l402",
      "https://agentpaywire.com/.well-known/l402-services",
      "https://agentpaywire.com/.well-known/support.json",
      "https://api.agentpaywire.com/.well-known/l402",
      "https://api.agentpaywire.com/.well-known/l402-services"
    ]
  },
  "errors": [
    {
      "status": 400,
      "code": "since_required",
      "body": "{ error }",
      "when": "GET /v1/updates without a since value that Date.parse accepts. Returned before a credit is spent."
    },
    {
      "status": 401,
      "code": "invalid_macaroon",
      "body": "{ error, protocol, payment }",
      "when": "Authorization uses L402 but the macaroon signature or body is invalid."
    },
    {
      "status": 402,
      "code": "payment_required",
      "body": "{ error, protocol, payment, price, invoice, macaroon, how_to_pay, free_data }",
      "when": "A paid route has no Authorization header, or the header is not L402. WWW-Authenticate carries the macaroon and BOLT11 invoice."
    },
    {
      "status": 402,
      "code": "token_expired",
      "body": "{ error, protocol, payment }",
      "when": "The macaroon exp has passed, or the stored bundle is past its expiry."
    },
    {
      "status": 402,
      "code": "payment_not_settled",
      "body": "{ error, protocol, payment, macaroon, how_to_pay }",
      "when": "The preimage is missing or its sha256 does not match the payment hash, and the verify-URL lookup is not settled."
    },
    {
      "status": 402,
      "code": "token_spent",
      "body": "{ error, protocol, payment, credits_remaining, credits_total, how_to_pay }",
      "when": "The bundle has no credits left."
    },
    {
      "status": 404,
      "code": "not_found",
      "body": "{ error }",
      "when": "The path is not a free or paid route. Trailing slashes are stripped before the check."
    },
    {
      "status": 405,
      "code": "method_not_allowed",
      "body": "{ error }",
      "when": "The method is not GET. OPTIONS returns 204 with an empty body."
    },
    {
      "status": 500,
      "code": "token_store",
      "body": "{ error }",
      "when": "The credit row could not be written or read."
    },
    {
      "status": 500,
      "code": "misconfigured",
      "body": "{ error }",
      "when": "The worker threw before it could handle the request."
    },
    {
      "status": 502,
      "code": "upstream_unavailable",
      "body": "{ error }",
      "when": "The paid route could not read the public site files."
    },
    {
      "status": 503,
      "code": "signing_key_missing",
      "body": "{ error }",
      "when": "L402_SIGNING_KEY is empty."
    },
    {
      "status": 503,
      "code": "rate_limited",
      "body": "{ error, protocol, payment } plus Retry-After",
      "when": "The Lightning wallet rate-limits invoice creation or lookup. Default Retry-After is 10 seconds when the wallet omits it. A deep health probe instead returns the health document with ok false."
    }
  ],
  "wallet_error_codes": [
    "invoice_unavailable",
    "invalid_lightning_address",
    "lightning_address_missing",
    "nwc_invalid_relay",
    "nwc_invalid_secret",
    "nwc_missing",
    "nwc_wrong_scheme",
    "rate_limited",
    "wallet_api_key_missing",
    "wallet_api_url_missing",
    "wallet_backend_unimplemented",
    "wallet_backend_unknown",
    "wallet_unreachable"
  ],
  "tools": [
    "changes_since",
    "get_article",
    "get_dataset",
    "get_source",
    "get_support_info",
    "get_trust_checklist",
    "latest_sources",
    "list_articles",
    "list_bots",
    "list_categories",
    "list_datasets",
    "protocol_facts",
    "search",
    "search_library"
  ],
  "count": 3,
  "items": [
    {
      "id": "stable-urls",
      "title": "Stable endpoint URLs",
      "status": "met",
      "statement": "Site files are unversioned and listed in https://agentpaywire.com/api/index.json. The paid API is only under https://api.agentpaywire.com/v1. The MCP server is only at https://mcp.agentpaywire.com/mcp. A published path is not removed without a changelog record and a redirect from the old path. Renaming a query parameter or a JSON field follows the same rule. Adding a field is not a removal.",
      "evidence": [
        {
          "url": "https://agentpaywire.com/api/index.json",
          "note": "Every site machine path."
        },
        {
          "url": "https://agentpaywire.com/openapi.json",
          "note": "Site OpenAPI, including the paid routes."
        },
        {
          "url": "https://api.agentpaywire.com/v1/openapi.json",
          "note": "API-host OpenAPI. Redeploy the API worker for this host to match the worker source."
        },
        {
          "url": "https://agentpaywire.com/changelog.json",
          "note": "Removal notices go here."
        },
        {
          "url": "https://agentpaywire.com/sitemap.xml",
          "note": "HTML and machine URLs."
        }
      ]
    },
    {
      "id": "errors-and-limits",
      "title": "Explicit limits and errors",
      "status": "met",
      "statement": "100 sats buys 100 credits for 30 days. One credit is one paid request. The API does not rate-limit clients and does not return HTTP 429. A wallet rate limit is HTTP 503 with Retry-After. Error bodies are JSON with a string error field, except OPTIONS (204, empty) and a rate-limited deep health probe (the health document, ok false).",
      "evidence": [
        {
          "url": "https://agentpaywire.com/.well-known/l402",
          "note": "Site L402 discovery: price_sats, credits, ttl_days, authorization."
        },
        {
          "url": "https://agentpaywire.com/support.json",
          "note": "paid_api block with the same numbers."
        },
        {
          "url": "https://api.agentpaywire.com/v1/openapi.json",
          "note": "Worker OpenAPI. The source lists these codes. The live host matches after redeploy."
        },
        {
          "url": "https://agentpaywire.com/trust.json",
          "note": "The error table in this file."
        }
      ]
    },
    {
      "id": "consistent-naming",
      "title": "Consistent naming",
      "status": "partial",
      "statement": "Paid requests use Authorization: L402 <macaroon>:<preimage>. price_sats, credits, and ttl_days are the names on the site discovery, support.json, and the site OpenAPI x-payment object. The static changelog cursor is exclusive: verified_at greater than the cursor, parameter updated_since. Paid GET /v1/updates is inclusive: verified_at >= since, parameter since. The site L402 file and the API-host L402 file share protocol, payment, price_sats, credits, ttl_days, and authorization. The API host also nests pricing.amount_sats. The documents are not identical.",
      "evidence": [
        {
          "url": "https://agentpaywire.com/llms.txt",
          "note": "Authorization line and the 100 sat price."
        },
        {
          "url": "https://agentpaywire.com/.well-known/l402",
          "note": "Site field names."
        },
        {
          "url": "https://api.agentpaywire.com/.well-known/l402",
          "note": "API-host field names. pricing.amount_sats remains."
        },
        {
          "url": "https://agentpaywire.com/changelog.json",
          "note": "Exclusive cursor."
        },
        {
          "url": "https://api.agentpaywire.com/v1/updates",
          "note": "Inclusive since parameter."
        },
        {
          "url": "https://mcp.agentpaywire.com/mcp",
          "note": "MCP tools: changes_since, get_article, get_dataset, get_source, get_support_info, get_trust_checklist, latest_sources, list_articles, list_bots, list_categories, list_datasets, protocol_facts, search, search_library."
        }
      ]
    }
  ],
  "site": "https://agentpaywire.com"
}
