{"openapi":"3.1.0","info":{"title":"HALOWERK laufwerk","version":"1.0.0","description":"HALOWERK laufwerk — bezahlte Endpunkte nach x402. Preise in USDC auf Base Mainnet.","contact":{"url":"https://lauf.halowerk.com/"}},"servers":[{"url":"https://lauf.halowerk.com"}],"paths":{"/v1/browser-task":{"post":{"operationId":"browser_task","summary":"Run a short, bounded browser task on a public page — load it, perform up to eight interaction steps, and get back the step log, the resulting text, links, forms and an optional screenshot.","description":"Loads one https page in a real headless browser and performs up to eight steps on it: click, fill, select, check, uncheck, wait, wait_for_selector. Returns a per-step log saying what was attempted and whether it succeeded, plus the final URL, title, visible text, links, form structure and an optional screenshot as a base64 PNG. Three limits are part of the product, not accidents. robots.txt is fetched and evaluated before the page is loaded, following RFC 9309 precedence, and a disallowed path is refused rather than fetched; an unreadable robots.txt counts as a refusal, not as permission. Login walls, captchas and paywalls are detected and the call is aborted instead of worked around. And a step cannot navigate: the only address loaded is the one in url, so this endpoint cannot be steered somewhere else by a step list. Nothing is charged when a call is refused for any of those reasons. Not suitable for pages that require a session, and not a crawler: one page per call.","tags":["laufwerk"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url"],"additionalProperties":false,"properties":{"url":{"type":"string","format":"uri","description":"The https page to load. Only public addresses; no credentials in the URL."},"steps":{"type":"array","maxItems":8,"description":"At most 8 steps, executed in order. A step cannot navigate to another address.","items":{"type":"object","required":["action"],"additionalProperties":false,"properties":{"action":{"type":"string","enum":["click","fill","select","check","uncheck","wait","wait_for_selector"],"description":"What to do. \"press\" and free typing are deliberately absent — the Enter key is the usual way to submit a form without saying so."},"selector":{"type":"string","maxLength":300,"description":"CSS selector of the element. Required for click, fill, select, check, uncheck and wait_for_selector."},"text":{"type":"string","maxLength":2000,"description":"Text for fill."},"values":{"type":"array","items":{"type":"string"},"maxItems":20,"description":"Option values for select."},"ms":{"type":"integer","minimum":0,"maximum":10000,"description":"Milliseconds for wait."},"wait_after_ms":{"type":"integer","minimum":0,"maximum":10000,"description":"Pause after this step, e.g. to let a page settle."}}}},"collect":{"type":"object","additionalProperties":false,"description":"What to return. text and links are on by default.","properties":{"text":{"type":"boolean","default":true},"links":{"type":"boolean","default":true},"forms":{"type":"boolean","default":false},"screenshot":{"type":"boolean","default":false,"description":"A base64 PNG of the final state."},"console":{"type":"boolean","default":false,"description":"Console messages emitted by the page."}}},"viewport":{"type":"object","additionalProperties":false,"properties":{"width":{"type":"integer","minimum":320,"maximum":2560,"default":1280},"height":{"type":"integer","minimum":320,"maximum":2000,"default":900}}},"wait_until":{"type":"string","enum":["load","domcontentloaded","networkidle"],"default":"load","description":"When the page counts as loaded."}}}}}},"responses":{"200":{"description":"Ergebnis","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Eingabe ungültig, charged=false"},"402":{"description":"Zahlung erforderlich. Die Antwort trägt accepts, description und inputSchema.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentRequired"}}}},"429":{"description":"Zu viele unbezahlte Anfragen, charged=false"},"502":{"description":"Gegenstelle nicht erreichbar, charged=false"},"504":{"description":"Zeitbudget überschritten, charged=false"}}}},"/v1/form-dryrun":{"post":{"operationId":"form_dryrun","summary":"Fill a web form with your values in a real browser, get every field checked against the constraints the page declares, and be sure nothing was ever submitted.","description":"Loads a public https page, finds the requested form, fills your values into it in a real headless browser and reports what a submission would run into — without submitting. Each field is checked against what the page itself declares: whether it is required and empty, whether the value matches the field type for email, url, number, tel, date, time and color, and whether a select value is one of the offered options. Fields you named that the form does not have are reported, as are required fields you left out. The promise not to submit is structural, not a policy: the input schema has no place to put a selector or a click, and the only browser steps this endpoint generates are fill, select and check on fields that exist in the loaded form. It never clicks, and it never presses a key. One thing it cannot prevent and therefore states plainly: a page whose own script submits on input will do so regardless of who typed. What it cannot do is run the page own JavaScript validation — a site that checks values in script may still reject a value this endpoint calls plausible, and that limit is stated rather than papered over. robots.txt is honoured; login walls, captchas and paywalls end the call instead of being worked around, and a refused call is not charged.","tags":["laufwerk"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url","values"],"additionalProperties":false,"properties":{"url":{"type":"string","format":"uri","description":"The https page carrying the form."},"values":{"type":"object","minProperties":1,"maxProperties":40,"description":"Field name to value. Field names are the name attributes of the form controls; use form_index first with an empty probe if you do not know them.","additionalProperties":{"type":["string","number","boolean"]}},"form_index":{"type":"integer","minimum":0,"maximum":20,"default":0,"description":"Which form on the page, in document order. Default is the first."},"form_name":{"type":"string","maxLength":120,"description":"Pick the form by its name or id instead of by position. Wins over form_index when both are given."}}}}}},"responses":{"200":{"description":"Ergebnis","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Eingabe ungültig, charged=false"},"402":{"description":"Zahlung erforderlich. Die Antwort trägt accepts, description und inputSchema.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentRequired"}}}},"429":{"description":"Zu viele unbezahlte Anfragen, charged=false"},"502":{"description":"Gegenstelle nicht erreichbar, charged=false"},"504":{"description":"Zeitbudget überschritten, charged=false"}}}}},"components":{"schemas":{"PaymentRequired":{"type":"object","properties":{"x402Version":{"type":"integer"},"error":{"type":"string"},"description":{"type":"string"},"inputSchema":{"type":"object"},"accepts":{"type":"array","items":{"type":"object"}}}}},"securitySchemes":{"x402":{"type":"apiKey","in":"header","name":"PAYMENT-SIGNATURE","description":"x402 Zahlungsnachweis"}}}}