{"openapi":"3.1.0","info":{"title":"FetchDelta","version":"0.1.0","summary":"Paid page freshness API for agents that monitor docs, release notes, pricing, and policy pages","description":"FetchDelta is a paid HTTP API for autonomous agents. It resolves public webpages into clean markdown and computes diffs against prior snapshots. Protected endpoints return HTTP 402 until paid over x402.","contact":{"name":"FetchDelta support","url":"https://github.com/henrihallik/fetchdelta-client/issues"}},"servers":[{"url":"https://fetchdelta.com"}],"tags":[{"name":"meta","description":"Free capability and health endpoints"},{"name":"paid","description":"x402-protected paid endpoints"}],"components":{"schemas":{"LinkSummary":{"type":"object","description":"A normalized link discovered on the target page.","properties":{"href":{"type":"string","format":"uri","description":"Absolute URL after resolving relative links against the fetched page."},"text":{"type":"string","description":"Visible link text or URL fallback."}}},"PreviewResponse":{"type":"object","description":"Free preview of a public page before paying for a full resolve or diff.","properties":{"url":{"type":"string","format":"uri","description":"Original requested URL."},"finalUrl":{"type":"string","format":"uri","description":"Final URL after redirects."},"fetchedAt":{"type":"string","format":"date-time","description":"Fetch timestamp."},"title":{"type":"string","description":"Extracted page title."},"excerpt":{"type":["string","null"],"description":"Meta description or short excerpt when available."},"headings":{"type":"array","description":"Top extracted headings, useful for deciding whether the page is relevant.","items":{"type":"string"}},"links":{"type":"array","description":"Top normalized links from the public page.","items":{"$ref":"#/components/schemas/LinkSummary"}},"previewMarkdown":{"type":"string","description":"Truncated markdown sample from the public page."},"truncated":{"type":"boolean","description":"Whether the markdown sample was shortened."},"upgrade":{"type":"object","description":"Paid upgrade URLs and prices for full resolve or diff calls.","additionalProperties":true}}},"ResolveResponse":{"type":"object","description":"Full cleaned markdown and metadata for a public page.","properties":{"url":{"type":"string","format":"uri","description":"Original requested URL."},"finalUrl":{"type":"string","format":"uri","description":"Final URL after redirects."},"fetchedAt":{"type":"string","format":"date-time","description":"Fetch timestamp."},"title":{"type":"string","description":"Extracted page title."},"excerpt":{"type":["string","null"],"description":"Meta description or short excerpt when available."},"markdown":{"type":"string","description":"Normalized markdown representation of the fetched public page."},"headings":{"type":"array","description":"Extracted headings from the page.","items":{"type":"string"}},"monitoringUpgrade":{"$ref":"#/components/schemas/PageWatchUpgrade"}}},"PageWatchUpgrade":{"type":"object","description":"Machine-readable x402 offer to turn this one-off result into a 30-day daily page watch.","properties":{"product":{"type":"string","const":"page-watch-30d"},"protocol":{"type":"string","const":"x402"},"method":{"type":"string","const":"GET"},"price":{"type":"string","example":"$0.50"},"currency":{"type":"string","const":"USDC"},"durationDays":{"type":"integer","const":30},"maxUrls":{"type":"integer","const":5},"checkoutUrl":{"type":"string","format":"uri"},"description":{"type":"string"}},"required":["product","protocol","method","price","currency","durationDays","maxUrls","checkoutUrl"]},"PricingSnapshotResponse":{"type":"object","description":"Structured pricing evidence extracted from a public competitor pricing page.","properties":{"ok":{"type":"boolean"},"product":{"type":"string","const":"pricing-snapshot"},"source":{"type":"object","additionalProperties":true},"requestedSources":{"type":"integer","minimum":1,"maximum":5},"maxSources":{"type":"integer","const":5},"sources":{"type":"array","items":{"type":"object","additionalProperties":true}},"priceMentions":{"type":"array","items":{"type":"string"}},"commercialSignals":{"type":"array","items":{"type":"string"}},"excerpt":{"type":["string","null"]},"headings":{"type":"array","items":{"type":"string"}},"markdown":{"type":"string"}}},"DiffPreviewItem":{"type":"object","properties":{"type":{"type":"string","enum":["added","removed","unchanged"],"description":"Change classification for this preview line."},"text":{"type":"string","description":"Changed line text."}}},"DiffResponse":{"type":"object","description":"Structured comparison against the previous snapshot for the target page.","properties":{"url":{"type":"string","format":"uri","description":"Original requested URL."},"finalUrl":{"type":"string","format":"uri","description":"Final URL after redirects."},"fetchedAt":{"type":"string","format":"date-time","description":"Fetch timestamp."},"baselineCreated":{"type":"boolean","description":"True when this is the first snapshot and no prior diff exists yet."},"hasChanges":{"type":"boolean","description":"Whether the latest fetch differs from the previous stored snapshot."},"addedLines":{"type":"integer","description":"Number of added markdown lines."},"removedLines":{"type":"integer","description":"Number of removed markdown lines."},"preview":{"type":"array","description":"Short structured preview of changed lines.","items":{"$ref":"#/components/schemas/DiffPreviewItem"}},"monitoringUpgrade":{"$ref":"#/components/schemas/PageWatchUpgrade"}}},"PageWatchPurchaseResponse":{"type":"object","description":"One-time activation response for an account-free 30-day page watch. The bearer token is only returned here.","properties":{"ok":{"type":"boolean"},"product":{"type":"string","const":"page-watch-30d"},"watch":{"type":"object","additionalProperties":true},"access":{"type":"object","additionalProperties":true},"initialCheck":{"type":"object","additionalProperties":true},"initialResults":{"type":"array","items":{"type":"object","additionalProperties":true}}}},"PageWatchStatusResponse":{"type":"object","description":"Current state, latest checks, and change events for a paid 30-day page watch.","properties":{"ok":{"type":"boolean"},"product":{"type":"string","const":"page-watch-30d"},"watch":{"type":"object","additionalProperties":true}}},"ErrorResponse":{"type":"object","properties":{"error":{"type":"string","description":"Human-readable error message."}}}}},"paths":{"/health":{"get":{"tags":["meta"],"summary":"Health check","operationId":"health","responses":{"200":{"description":"Service is healthy"}}}},"/manifest":{"get":{"tags":["meta"],"summary":"Machine-readable service manifest","operationId":"manifest","responses":{"200":{"description":"Service manifest"}}}},"/.well-known/agent-card.json":{"get":{"tags":["meta"],"summary":"Machine-readable agent/service card with skills and endpoint examples.","operationId":"agentCard","responses":{"200":{"description":"Agent card"}}}},"/api/resolve/preview":{"description":"Free public preview for deciding whether a full paid resolve or diff is worth calling. This route does not require x402 payment.","get":{"tags":["meta"],"summary":"Fetch a public page preview with title, excerpt, headings, links, and a truncated markdown sample.","description":"Use this free endpoint first when an agent needs to inspect a docs, changelog, release-note, pricing, or policy page before spending on the full page freshness result.","operationId":"previewResolvePage","parameters":[{"name":"url","in":"query","required":true,"description":"Absolute URL of a public HTTP(S) page to fetch. Use docs, changelogs, release notes, pricing pages, policy pages, or other public pages. Private, localhost, credentialed, and non-HTTP(S) URLs are rejected.","schema":{"type":"string","format":"uri"},"example":"https://example.com/"}],"responses":{"200":{"description":"Free preview response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewResponse"},"examples":{"preview":{"summary":"Preview of a public page","value":{"url":"https://example.com/","finalUrl":"https://example.com/","title":"Example Domain","excerpt":null,"headings":["Example Domain"],"links":[{"href":"https://www.iana.org/domains/example","text":"More information..."}],"previewMarkdown":"# Example Domain\n\nThis domain is for use in illustrative examples.","truncated":false}}}}}},"400":{"description":"Invalid, private, credentialed, or missing URL.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"The upstream public page could not be fetched or parsed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/resolve":{"description":"Paid x402 endpoint for turning a public web page into clean markdown plus metadata for an AI agent.","get":{"tags":["paid"],"summary":"Fetch a public page and return clean markdown plus metadata for agent use.","description":"Use this when the agent needs the current full body of a public docs, changelog, release-note, pricing, or policy page as normalized markdown. For a free preflight, call /api/resolve/preview first.","operationId":"resolvePage","x-payment-info":{"protocols":["x402"],"price":{"mode":"fixed","currency":"USD","amount":"0.002"}},"parameters":[{"name":"url","in":"query","required":true,"description":"Absolute URL of a public HTTP(S) page to fetch. Use docs, changelogs, release notes, pricing pages, policy pages, or other public pages. Private, localhost, credentialed, and non-HTTP(S) URLs are rejected.","schema":{"type":"string","format":"uri"},"example":"https://example.com/"}],"responses":{"200":{"description":"Resolved page content","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResolveResponse"},"examples":{"resolved":{"summary":"Full markdown for a public page","value":{"url":"https://example.com/","title":"Example title","excerpt":"Short summary.","markdown":"# Example title","headings":["Example title"],"monitoringUpgrade":{"product":"page-watch-30d","price":"$0.50","checkoutUrl":"https://fetchdelta.com/api/page-watch-30d?url=https%3A%2F%2Fexample.com%2F"}}}}}}},"400":{"description":"Invalid, private, credentialed, or missing URL.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"Payment required. Retry this same URL with an x402 payment for $0.002 on eip155:8453 using USDC.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"examples":{"paymentRequired":{"summary":"x402 payment requirements","value":{}}}}}},"502":{"description":"The upstream public page could not be fetched or parsed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-x402-payment":{"network":"eip155:8453","price":"$0.002","settlementAsset":"USDC"}}},"/api/diff":{"description":"Paid x402 endpoint for comparing a public page against the previous stored snapshot.","get":{"tags":["paid"],"summary":"Fetch a public page, compare it to the previous snapshot, and return structured changes.","description":"Use this for repeated monitoring of public docs, release notes, changelogs, pricing, or policy pages. The first paid call creates a baseline; later calls return structured additions and removals.","operationId":"diffPage","x-payment-info":{"protocols":["x402"],"price":{"mode":"fixed","currency":"USD","amount":"0.004"}},"parameters":[{"name":"url","in":"query","required":true,"description":"Absolute URL of a public HTTP(S) page to fetch. Use docs, changelogs, release notes, pricing pages, policy pages, or other public pages. Private, localhost, credentialed, and non-HTTP(S) URLs are rejected.","schema":{"type":"string","format":"uri"},"example":"https://example.com/"}],"responses":{"200":{"description":"Structured diff response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiffResponse"},"examples":{"diff":{"summary":"Structured change result","value":{"url":"https://example.com/","baselineCreated":false,"hasChanges":true,"addedLines":3,"removedLines":1,"preview":[{"type":"added","text":"New paragraph"}],"monitoringUpgrade":{"product":"page-watch-30d","price":"$0.50","checkoutUrl":"https://fetchdelta.com/api/page-watch-30d?url=https%3A%2F%2Fexample.com%2F"}}}}}}},"400":{"description":"Invalid, private, credentialed, or missing URL.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"Payment required. Retry this same URL with an x402 payment for $0.004 on eip155:8453 using USDC.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"examples":{"paymentRequired":{"summary":"x402 payment requirements","value":{}}}}}},"502":{"description":"The upstream public page could not be fetched or parsed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-x402-payment":{"network":"eip155:8453","price":"$0.004","settlementAsset":"USDC"}}},"/api/pricing-snapshot":{"description":"Paid x402 endpoint for extracting structured pricing evidence from up to five public competitor pricing pages.","get":{"tags":["paid"],"summary":"Extract a paid pricing snapshot pack from up to five public pages.","description":"Use this when an agent needs competitor pricing mentions and commercial terms from one to five pages immediately. Repeat the url query parameter for a multi-source pack; one x402 payment returns structured signals and normalized markdown for every source.","operationId":"pricingSnapshot","x-payment-info":{"protocols":["x402"],"price":{"mode":"fixed","currency":"USD","amount":"0.02"}},"parameters":[{"name":"url","in":"query","required":true,"description":"Absolute URL of a public HTTP(S) page to fetch. Use docs, changelogs, release notes, pricing pages, policy pages, or other public pages. Private, localhost, credentialed, and non-HTTP(S) URLs are rejected.","schema":{"type":"string","format":"uri"},"example":"https://example.com/"}],"responses":{"200":{"description":"Structured pricing evidence","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PricingSnapshotResponse"},"examples":{"pricingSnapshot":{"summary":"Pricing snapshot for a public page","value":{"ok":true,"product":"pricing-snapshot","source":{"url":"https://example.com/","finalUrl":"https://example.com/","title":"Example pricing","fetchedAt":"2026-08-25T00:00:00.000Z"},"priceMentions":["$99/month"],"commercialSignals":["per month"],"requestedSources":1,"maxSources":5,"sources":[{"markdown":"# Example pricing"}]}}}}}},"400":{"description":"Invalid, private, credentialed, or missing URL.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"Payment required. Retry this same URL with an x402 payment for $0.02 on eip155:8453 using USDC.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"examples":{"paymentRequired":{"summary":"x402 payment requirements","value":{}}}}}},"502":{"description":"The upstream public page could not be fetched or parsed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-x402-payment":{"network":"eip155:8453","price":"$0.02","settlementAsset":"USDC"}}},"/api/page-watch-30d":{"description":"Paid x402 endpoint that creates an account-free daily watch for one to five public pages for 30 days.","get":{"tags":["paid"],"summary":"Create a 30-day daily page-change watch.","description":"Repeat the url query parameter for up to five pages. The paid response includes an immediate baseline check, a private bearer token, and a status URL that can be polled without another payment until expiry.","operationId":"createPageWatch30d","x-payment-info":{"protocols":["x402"],"price":{"mode":"fixed","currency":"USD","amount":"0.5"}},"parameters":[{"name":"url","in":"query","required":true,"description":"One to five public HTTP(S) URLs. Repeat this query parameter for each watched page.","style":"form","explode":true,"schema":{"type":"array","minItems":1,"maxItems":5,"items":{"type":"string","format":"uri"}},"example":["https://example.com/"]}],"responses":{"200":{"description":"Activated page watch, one-time access token, and first check","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageWatchPurchaseResponse"}}}},"400":{"description":"Invalid, private, credentialed, or missing URL.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"Payment required. Retry this same URL with an x402 payment for $0.50 on eip155:8453 using USDC.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"examples":{"paymentRequired":{"summary":"x402 payment requirements","value":{}}}}}},"502":{"description":"A watched public page could not be fetched for the initial baseline.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"x-x402-payment":{"network":"eip155:8453","price":"$0.50","settlementAsset":"USDC"}}},"/api/page-watch-30d/{id}":{"get":{"tags":["meta"],"summary":"Poll a paid 30-day page watch with its bearer token.","operationId":"getPageWatch30d","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Authorization","in":"header","required":true,"description":"Bearer token returned once by the paid activation response.","schema":{"type":"string","pattern":"^Bearer [A-Fa-f0-9]{64}$"}}],"responses":{"200":{"description":"Current watch status, latest checks, and recent change events","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PageWatchStatusResponse"}}}},"401":{"description":"Bearer token is missing."},"404":{"description":"Watch id or bearer token is not valid."}}}}}}