{"openapi":"3.1.0","info":{"title":"whoisbrowsing agent API","version":"1.0.0","summary":"Create a whoisbrowsing site with no sign-up, from a coding agent.","description":"whoisbrowsing shows who is on a website right now: every current visitor's cursor drawn live on the owner's real page. A coding agent creates a site here with no account, puts the returned snippet on every page, and hands the human a watch link and a claim link. The full guide for agents: https://whoisbrowsing.com/SKILL.md","contact":{"name":"Sandeep Arneja LLC","email":"sandeep.arneja.llc@gmail.com","url":"https://whoisbrowsing.com"}},"servers":[{"url":"https://whoisbrowsing.com"}],"externalDocs":{"description":"SKILL.md: the one-file guide for coding agents","url":"https://whoisbrowsing.com/SKILL.md"},"paths":{"/api/agent/sites":{"post":{"operationId":"createSite","summary":"Create a site with no sign-up","description":"Creates an anonymous site (no account yet) and returns its snippet, one watch link per website, and a one-time claim link. No auth. Limits: 10 creations per network per hour, and 5 unclaimed sites per wib_claim cookie. Create one site per project.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSiteRequest"},"example":{"domains":["localhost:3000","example.com"]}}}},"responses":{"201":{"description":"The site was created.","headers":{"Set-Cookie":{"description":"wib_claim, when the request sent none: the browser-side tie to this site until it is claimed. Clients without a cookie jar can ignore it and use claimUrl.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatedSite"},"example":{"siteId":"a1b2c3d4e5f6","snippet":"<script src=\"https://live.whoisbrowsing.com/s.js\" data-site=\"a1b2c3d4e5f6\" defer></script>","watchUrls":{"localhost:3000":"http://localhost:3000/#wib=<owner key>","example.com":"https://example.com/#wib=<owner key>"},"claimUrl":"https://whoisbrowsing.com/claim?t=<one-time token>","installDocs":"https://whoisbrowsing.com/install","next":["Put the snippet on every page, unchanged: in the file all pages share…","Give the human the watch link right away…"]}}}},"400":{"description":"invalid_json: the body is not JSON, or Content-Type is not application/json. invalid_body: a field is missing or of the wrong type. invalid_domains: no usable domain, more than 20, or one that is not host[:port] or *.host. The hint says how to fix it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"cross_site_request: the request came from another website's page in a browser (Sec-Fetch-Site: cross-site or same-site). Call the API from a terminal, a server or an agent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"A creation limit was hit. The hint says what to do.","headers":{"Retry-After":{"description":"Seconds to wait (the per-network limit only; absent when waiting does not help).","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimited"}}}},"500":{"description":"Something failed on our side. Try again in a minute.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"CreateSiteRequest":{"type":"object","properties":{"domains":{"minItems":1,"maxItems":20,"type":"array","items":{"type":"string","maxLength":253},"description":"The websites the tag will run on: host[:port] (e.g. localhost:3000, example.com), or *.host for every subdomain (e.g. *.vercel.app). A scheme or path is stripped; a host is letters, digits, hyphens and dots (a non-ASCII domain in its xn-- form); www. is the same website as the bare domain; each website is watched separately."},"name":{"description":"A label for the site. Defaults to the first domain.","type":"string","maxLength":100}},"required":["domains"]},"CreatedSite":{"type":"object","properties":{"siteId":{"type":"string","pattern":"^[a-z0-9]{12}$","description":"The site ID: the data-site value in the snippet. Public, fine to commit."},"snippet":{"type":"string","description":"The script tag to put on every page, unchanged."},"watchUrls":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","format":"uri"},"description":"One watch link per website: the human's own site, opened with a private owner key in the #fragment. Give it to the human right away; never write it into a file, commit or log. Treat it like a password."},"claimUrl":{"type":"string","format":"uri","description":"The one-time link that keeps the site in the human's account after signing in with Google. Expires after 30 days. Give it to the human right away; never write it into a file, commit or log."},"installDocs":{"type":"string","format":"uri","description":"Where the tag goes for each platform."},"next":{"type":"array","items":{"type":"string"},"description":"What to do next, in order, in plain words."}},"required":["siteId","snippet","watchUrls","claimUrl","installDocs","next"],"additionalProperties":false},"Error":{"type":"object","properties":{"error":{"type":"string","enum":["invalid_json","invalid_body","invalid_domains","cross_site_request","internal_error"]},"hint":{"type":"string","description":"How to fix the request."}},"required":["error","hint"],"additionalProperties":false},"RateLimited":{"type":"object","properties":{"error":{"type":"string","const":"rate_limited"},"reason":{"type":"string","enum":["cookie","ip"],"description":"ip: 10 sites from this network in the last hour. cookie: this client's wib_claim cookie already holds 5 unclaimed sites."},"retryAfterSec":{"anyOf":[{"type":"integer","minimum":1,"maximum":9007199254740991},{"type":"null"}],"description":"Seconds until the next creation is allowed; null when waiting does not help (claim a site instead)."},"hint":{"type":"string"}},"required":["error","reason","retryAfterSec","hint"],"additionalProperties":false}}}}