{"openapi":"3.1.0","info":{"title":"RoastWeb agent API","version":"1.0.0","description":"Roast a website for an AI agent: scores for speed, SEO, accessibility, best practices, mobile and AI search readiness, every problem with its fix, and a fix brief for a coding agent. Every roast an agent starts costs $1 (1 credit). Nothing is free for agents. MCP server: https://roastweb.com/mcp (Streamable HTTP). Docs: https://roastweb.com/developers"},"servers":[{"url":"https://roastweb.com"}],"paths":{"/api/v1/roasts":{"post":{"summary":"Start a paid roast on the key's credits (1 credit = $1)","security":[{"apiKey":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Send the same key again to get the first roast back without paying twice.","schema":{"type":"string","pattern":"^[A-Za-z0-9_.:-]{1,100}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}}}}},"responses":{"200":{"description":"The same Idempotency-Key again: the first roast, nothing charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoastAnswer"}}}},"201":{"description":"Paid and queued. Poll statusUrl until status is done.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoastAnswer"}}}},"400":{"description":"Bad URL, bad body, an X profile, or a bad Idempotency-Key. Nothing charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"No credits left. Nothing charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key can only read.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"That Idempotency-Key was used for another URL. Nothing charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The site didn't answer, or isn't a web page. Nothing charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Two roasts already running, or 100 in the last 24 hours. Nothing charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Couldn't start the roast. The credit is back.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"summary":"This key's agent roasts, newest first","security":[{"apiKey":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":50}}],"responses":{"200":{"description":"Recent roasts","content":{"application/json":{"schema":{"type":"object","properties":{"roasts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"status":{"$ref":"#/components/schemas/Status"},"score":{"type":["number","null"]},"createdAt":{"type":"string","format":"date-time"},"finishedAt":{"type":["string","null"]}}}}}}}}},"401":{"description":"Missing or unknown API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/roasts/{id}":{"get":{"summary":"One roast: its status, and the full roast once done","security":[{"apiKey":[]},{"roastToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The roast","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoastAnswer"}}}},"404":{"description":"No agent roast with that id for these credentials.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/roasts/{id}/compare/{otherId}":{"get":{"summary":"What changed between two of your roasts (free: no scan runs)","security":[{"apiKey":[]},{"roastToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"otherId","in":"path","required":true,"schema":{"type":"string"}},{"name":"otherToken","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"The change","content":{"application/json":{"schema":{"type":"object","properties":{"change":{"$ref":"#/components/schemas/AgentChange"}}}}}},"404":{"description":"Not found for these credentials.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Both roasts have to be done.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/roasts/{id}/publish":{"post":{"summary":"Make your roast a public page (roasts are private until you do)","security":[{"apiKey":[]},{"roastToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Published","content":{"application/json":{"schema":{"type":"object","properties":{"published":{"type":"object","properties":{"url":{"type":"string"}}}}}}}},"403":{"description":"Adult site, or a read-only key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found for these credentials.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The roast has to be done first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/credits":{"get":{"summary":"The key's credit balance","security":[{"apiKey":[]}],"responses":{"200":{"description":"Balance","content":{"application/json":{"schema":{"type":"object","properties":{"balance":{"type":"integer"}}}}}},"401":{"description":"Missing or unknown API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"summary":"Top up this key's account: pay with sharedPaymentToken, or get a Stripe link for the person","security":[{"apiKey":[]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"pack":{"type":"string","enum":["5","10","20","50","100"]},"sharedPaymentToken":{"type":"string","pattern":"^spt_","description":"Pay the pack by card now; the credits land at once."}}}}}},"responses":{"200":{"description":"The link","content":{"application/json":{"schema":{"type":"object","properties":{"checkoutUrl":{"type":"string"},"expiresAt":{"type":"string"},"message":{"type":"string"}}}}}},"201":{"description":"Paid by the token","content":{"application/json":{"schema":{"type":"object","properties":{"credits":{"type":"integer"},"balance":{"type":["integer","null"]},"paymentIntent":{"type":"string"},"message":{"type":"string"}}}}}},"401":{"description":"Missing or unknown API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Stripe couldn't make a link. Nothing charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/prices":{"get":{"summary":"The price and the ways to pay (information only)","responses":{"200":{"description":"Prices","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/roasts/card":{"post":{"summary":"Pay a pack by card: with sharedPaymentToken the agent pays itself; without it, a Stripe link for the person","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"},"pack":{"type":"string","enum":["5","10","20","50","100"],"description":"The pack in dollars. Default \"5\" (5 roasts)."},"sharedPaymentToken":{"type":"string","pattern":"^spt_","description":"A Stripe shared payment token granted for RoastWeb's seller profile (in /api/v1/prices). Charged once for the pack; the same token is never charged twice."},"email":{"type":"string","format":"email","description":"Optional: where the receipt goes."}}}}}},"responses":{"201":{"description":"Paid by the token: the roast, and without an API key a new key holding the pack's other credits.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/RoastAnswer"},{"type":"object","properties":{"apiKey":{"type":"string"},"credits":{"type":"integer"},"paymentIntent":{"type":"string"}}}]}}}},"400":{"description":"Bad URL, bad pack, or an X profile. Nothing charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Payment needed: give checkoutUrl to the person, then poll statusUrl for the roast and the new API key. With a token: token_refused (the token does not cover the pack), card_declined, or card_needs_person (3-D Secure: give checkoutUrl to the person). Nothing charged.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"$ref":"#/components/schemas/Error/properties/error"},"roastId":{"type":"string"},"token":{"type":"string"},"checkoutUrl":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"},"statusUrl":{"type":"string"}}}}}},"409":{"description":"This token already paid for something else. Nothing more charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The site didn't answer, or isn't a web page. Nothing charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many payment links from here. Try again in an hour.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Stripe couldn't make a link. Nothing charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{},{"apiKey":[]}]}},"/api/v1/roasts/x402":{"post":{"summary":"Pay $1 in USDC on Base with x402, no account. The USDC moves only when the roast is done.","parameters":[{"name":"PAYMENT-SIGNATURE","in":"header","required":false,"description":"The signed x402 payment (base64 JSON, version 2). Without it the answer is a 402 with the terms in PAYMENT-REQUIRED.","schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}}}}},"responses":{"202":{"description":"Payment checked and the roast queued. The USDC moves only when the roast is done; poll statusUrl.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoastAnswer"}}}},"400":{"description":"No URL, a bad URL, or an X profile. Nothing charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Payment required: exactly $1 (1000000 units) of USDC on Base (eip155:8453), signed for 600 seconds. The terms are in the PAYMENT-REQUIRED header.","headers":{"PAYMENT-REQUIRED":{"description":"x402 version 2 terms, base64 JSON.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"That payment was already used for a roast. Nothing more charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The site didn't answer, or isn't a web page. Nothing charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Two roasts from this wallet are running, or it started 100 in 24 hours. Nothing charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"x402 is off, or the payment service didn't answer. Nothing charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"An API key (rw_live_...) from the dashboard. Each roast spends 1 credit."},"roastToken":{"type":"apiKey","in":"query","name":"token","description":"The token returned with a roast. Opens that roast only."}},"schemas":{"Status":{"type":"string","enum":["awaiting_payment","expired","queued","running","done","failed","refunded","payment_failed","refund_due"]},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"}}}}},"RoastAnswer":{"type":"object","properties":{"roast":{"$ref":"#/components/schemas/AgentRoast"},"token":{"type":"string","description":"Opens this roast: ?token= on the API, ?k= on the report page."},"statusUrl":{"type":"string"}}},"AgentScores":{"type":"object","properties":{"overall":{"type":"number"},"speed":{"type":["number","null"]},"seo":{"type":["number","null"]},"accessibility":{"type":["number","null"]},"bestPractices":{"type":["number","null"]},"mobile":{"type":["number","null"]},"aiSearch":{"type":"object","properties":{"geo":{"type":["number","null"]},"aeo":{"type":["number","null"]},"llmo":{"type":["number","null"]},"sxo":{"type":["number","null"]}}}}},"AgentProblem":{"type":"object","properties":{"id":{"type":"string","description":"Stable across roasts of the same site."},"category":{"type":"string"},"severity":{"type":["string","null"],"enum":["critical","warning","info",null]},"title":{"type":"string"},"where":{"type":["array","null"],"items":{"type":"string"}},"why":{"type":["string","null"]},"fix":{"type":["string","null"]},"snippet":{"type":["string","null"]}}},"AgentChange":{"type":"object","properties":{"previousId":{"type":"string"},"previousAt":{"type":"string","format":"date-time"},"scoreChange":{"type":"number"},"fixed":{"type":"array","items":{"type":"string"}},"new":{"type":"array","items":{"type":"string"}}}},"AgentRoast":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"status":{"$ref":"#/components/schemas/Status"},"message":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"finishedAt":{"type":["string","null"]},"scores":{"oneOf":[{"$ref":"#/components/schemas/AgentScores"},{"type":"null"}]},"problems":{"type":["array","null"],"items":{"$ref":"#/components/schemas/AgentProblem"}},"fixPrompt":{"type":["string","null"]},"reportUrl":{"type":["string","null"]},"change":{"oneOf":[{"$ref":"#/components/schemas/AgentChange"},{"type":"null"}]},"published":{"type":["object","null"],"properties":{"url":{"type":"string"}}}}}}},"x-ways-to-pay":{"apiKey":true,"checkout":true,"x402":true,"cardToken":true,"mcp":true}}