{"openapi":"3.1.0","info":{"title":"Stumble API","version":"1.0.0","description":"Watch-and-notify service for AI agents. Pay per watch via x402 (requirements arrive in the PAYMENT-REQUIRED header AND the 402 JSON body). Free endpoints are rate limited per IP with X-RateLimit-* headers; 429s carry Retry-After. Full reference: https://stumble.vimabrosta.com/llms-full.txt","contact":{"email":"contact@vimabrosta.com"}},"servers":[{"url":"https://stumble.vimabrosta.com"}],"components":{"securitySchemes":{"watchSecret":{"type":"http","scheme":"bearer","description":"The one-time secret returned at watch creation. Alternative: ?secret= query parameter."}}},"paths":{"/v1/validate":{"post":{"summary":"Free pre-flight: is a URL watchable under the URL policy, is a condition well-formed","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"},"condition":{"type":"object","description":"Exactly one condition. See /llms-full.txt for all six types with examples.","oneOf":[{"properties":{"type":{"const":"keyword"},"keyword":{"type":"string"},"when":{"enum":["appears","disappears"]}},"required":["type","keyword"]},{"properties":{"type":{"const":"selector"},"selector":{"type":"string"},"op":{"enum":["contains","not_contains","equals","matches","changes"]},"value":{"type":"string"}},"required":["type","selector","op"]},{"properties":{"type":{"const":"json_path"},"path":{"type":"string"},"op":{"enum":["eq","ne","gt","lt","gte","lte","exists","not_exists","contains","changes"]},"value":{}},"required":["type","path","op"]},{"properties":{"type":{"const":"price"},"op":{"enum":["below","above"]},"value":{"type":"number"},"selector":{"type":"string"}},"required":["type","op","value"]},{"properties":{"type":{"const":"content_change"},"selector":{"type":"string"}},"required":["type"]},{"properties":{"type":{"const":"status"},"op":{"enum":["eq","ne","gte","lt"]},"value":{"type":"integer"}},"required":["type","op","value"]}]}},"required":["url"]}}}},"responses":{"200":{"description":"watchable true/false with the failing policy rule; no page fetch is performed"},"429":{"description":"rate limited (30/min/IP)"}}}},"/v1/checks":{"post":{"summary":"One immediate fetch + condition evaluation ($0.01)","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"},"condition":{"type":"object","description":"Exactly one condition. See /llms-full.txt for all six types with examples.","oneOf":[{"properties":{"type":{"const":"keyword"},"keyword":{"type":"string"},"when":{"enum":["appears","disappears"]}},"required":["type","keyword"]},{"properties":{"type":{"const":"selector"},"selector":{"type":"string"},"op":{"enum":["contains","not_contains","equals","matches","changes"]},"value":{"type":"string"}},"required":["type","selector","op"]},{"properties":{"type":{"const":"json_path"},"path":{"type":"string"},"op":{"enum":["eq","ne","gt","lt","gte","lte","exists","not_exists","contains","changes"]},"value":{}},"required":["type","path","op"]},{"properties":{"type":{"const":"price"},"op":{"enum":["below","above"]},"value":{"type":"number"},"selector":{"type":"string"}},"required":["type","op","value"]},{"properties":{"type":{"const":"content_change"},"selector":{"type":"string"}},"required":["type"]},{"properties":{"type":{"const":"status"},"op":{"enum":["eq","ne","gte","lt"]},"value":{"type":"integer"}},"required":["type","op","value"]}]}},"required":["url","condition"]}}}},"responses":{"200":{"description":"matched, value, evidence, receipt"},"402":{"description":"Payment required ($0.01, x402). Body lists exact requirements; retry with X-PAYMENT header."},"422":{"description":"invalid request or unreachable target (not charged)"}}}},"/v1/watches/standard":{"post":{"summary":"Create standard watch: poll every 900s, up to 14 days ($0.10)","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"condition":{"type":"object","description":"Exactly one condition. See /llms-full.txt for all six types with examples.","oneOf":[{"properties":{"type":{"const":"keyword"},"keyword":{"type":"string"},"when":{"enum":["appears","disappears"]}},"required":["type","keyword"]},{"properties":{"type":{"const":"selector"},"selector":{"type":"string"},"op":{"enum":["contains","not_contains","equals","matches","changes"]},"value":{"type":"string"}},"required":["type","selector","op"]},{"properties":{"type":{"const":"json_path"},"path":{"type":"string"},"op":{"enum":["eq","ne","gt","lt","gte","lte","exists","not_exists","contains","changes"]},"value":{}},"required":["type","path","op"]},{"properties":{"type":{"const":"price"},"op":{"enum":["below","above"]},"value":{"type":"number"},"selector":{"type":"string"}},"required":["type","op","value"]},{"properties":{"type":{"const":"content_change"},"selector":{"type":"string"}},"required":["type"]},{"properties":{"type":{"const":"status"},"op":{"enum":["eq","ne","gte","lt"]},"value":{"type":"integer"}},"required":["type","op","value"]}]},"notify":{"type":"object","properties":{"mode":{"enum":["webhook","poll"]},"url":{"type":"string","format":"uri"},"format":{"enum":["json","slack","discord"],"default":"json"}},"required":["mode"]},"duration_days":{"type":"number"}},"required":["url","condition"]}}}},"responses":{"201":{"description":"watch created; response includes one-time secret, links, receipt, resume_hint"},"402":{"description":"Payment required ($0.10, x402). Body lists exact requirements; retry with X-PAYMENT header."},"409":{"description":"condition already true right now - not charged; use /v1/checks"},"422":{"description":"invalid request / unreachable target / unevaluable condition - not charged"}}}},"/v1/watches/fast":{"post":{"summary":"Create fast watch: poll every 60s, up to 7 days ($0.50)","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"condition":{"type":"object","description":"Exactly one condition. See /llms-full.txt for all six types with examples.","oneOf":[{"properties":{"type":{"const":"keyword"},"keyword":{"type":"string"},"when":{"enum":["appears","disappears"]}},"required":["type","keyword"]},{"properties":{"type":{"const":"selector"},"selector":{"type":"string"},"op":{"enum":["contains","not_contains","equals","matches","changes"]},"value":{"type":"string"}},"required":["type","selector","op"]},{"properties":{"type":{"const":"json_path"},"path":{"type":"string"},"op":{"enum":["eq","ne","gt","lt","gte","lte","exists","not_exists","contains","changes"]},"value":{}},"required":["type","path","op"]},{"properties":{"type":{"const":"price"},"op":{"enum":["below","above"]},"value":{"type":"number"},"selector":{"type":"string"}},"required":["type","op","value"]},{"properties":{"type":{"const":"content_change"},"selector":{"type":"string"}},"required":["type"]},{"properties":{"type":{"const":"status"},"op":{"enum":["eq","ne","gte","lt"]},"value":{"type":"integer"}},"required":["type","op","value"]}]},"notify":{"type":"object","properties":{"mode":{"enum":["webhook","poll"]},"url":{"type":"string","format":"uri"},"format":{"enum":["json","slack","discord"],"default":"json"}},"required":["mode"]},"duration_days":{"type":"number"}},"required":["url","condition"]}}}},"responses":{"201":{"description":"watch created; response includes one-time secret, links, receipt, resume_hint"},"402":{"description":"Payment required ($0.50, x402). Body lists exact requirements; retry with X-PAYMENT header."},"409":{"description":"condition already true right now - not charged; use /v1/checks"},"422":{"description":"invalid request / unreachable target / unevaluable condition - not charged"}}}},"/v1/watches/sniper":{"post":{"summary":"Create sniper watch: poll every 10s, up to 2 days ($2.00)","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"condition":{"type":"object","description":"Exactly one condition. See /llms-full.txt for all six types with examples.","oneOf":[{"properties":{"type":{"const":"keyword"},"keyword":{"type":"string"},"when":{"enum":["appears","disappears"]}},"required":["type","keyword"]},{"properties":{"type":{"const":"selector"},"selector":{"type":"string"},"op":{"enum":["contains","not_contains","equals","matches","changes"]},"value":{"type":"string"}},"required":["type","selector","op"]},{"properties":{"type":{"const":"json_path"},"path":{"type":"string"},"op":{"enum":["eq","ne","gt","lt","gte","lte","exists","not_exists","contains","changes"]},"value":{}},"required":["type","path","op"]},{"properties":{"type":{"const":"price"},"op":{"enum":["below","above"]},"value":{"type":"number"},"selector":{"type":"string"}},"required":["type","op","value"]},{"properties":{"type":{"const":"content_change"},"selector":{"type":"string"}},"required":["type"]},{"properties":{"type":{"const":"status"},"op":{"enum":["eq","ne","gte","lt"]},"value":{"type":"integer"}},"required":["type","op","value"]}]},"notify":{"type":"object","properties":{"mode":{"enum":["webhook","poll"]},"url":{"type":"string","format":"uri"},"format":{"enum":["json","slack","discord"],"default":"json"}},"required":["mode"]},"duration_days":{"type":"number"}},"required":["url","condition"]}}}},"responses":{"201":{"description":"watch created; response includes one-time secret, links, receipt, resume_hint"},"402":{"description":"Payment required ($2.00, x402). Body lists exact requirements; retry with X-PAYMENT header."},"409":{"description":"condition already true right now - not charged; use /v1/checks"},"422":{"description":"invalid request / unreachable target / unevaluable condition - not charged"}}}},"/v1/watches/{id}":{"get":{"summary":"Watch status & result (free)","security":[{"watchSecret":[]}],"responses":{"200":{"description":"watch state incl. result and resume_hint"},"404":{"description":"unknown id or wrong secret (uniform)"},"429":{"description":"rate limited (120/min/IP)"}}},"delete":{"summary":"Cancel watch (free; separate 120/min bucket so polling never blocks cancellation)","security":[{"watchSecret":[]}],"responses":{"200":{"description":"cancelled (idempotent)"},"404":{"description":"unknown id or wrong secret"}}}},"/v1/find":{"get":{"summary":"Recover watch ids by exact url + webhook match (free)","responses":{"200":{"description":"matching ids, never secrets"}}}},"/v1/quote":{"get":{"summary":"Machine-readable pricing (free)","responses":{"200":{"description":"products, prices, notes"}}}},"/healthz":{"get":{"summary":"Service health","responses":{"200":{"description":"ok"},"503":{"description":"degraded"}}}}}}