{"openapi":"3.1.0","info":{"title":"AgentWeb.live API","description":"AI-agent-optimized business directory","version":"1.0.0"},"paths":{"/v1/agent/history":{"get":{"summary":"Agent History","description":"Return this agent's interaction history — businesses it searched for, viewed, contributed to.","operationId":"agent_history_v1_agent_history_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/agent/favorites":{"get":{"summary":"Agent Favorites","description":"Return businesses this agent interacts with most (implicit favorites).","operationId":"agent_favorites_v1_agent_favorites_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/agent/profile":{"get":{"summary":"Agent Profile","description":"Return this agent's profile: usage stats, contribution tier, memory summary.","operationId":"agent_profile_v1_agent_profile_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/register":{"post":{"summary":"Register","operationId":"register_v1_register_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/health":{"get":{"summary":"Health","operationId":"health_v1_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/search":{"get":{"summary":"Search","operationId":"search_v1_search_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Text search query","title":"Q"},"description":"Text search query"},{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Business category, e.g. 'restaurant'","title":"Category"},"description":"Business category, e.g. 'restaurant'"},{"name":"city","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"City name (case-insensitive prefix match)","title":"City"},"description":"City name (case-insensitive prefix match)"},{"name":"country","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO 3166-1 alpha-2 country code, e.g. 'US'","title":"Country"},"description":"ISO 3166-1 alpha-2 country code, e.g. 'US'"},{"name":"lat","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lat"}},{"name":"lng","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lng"}},{"name":"radius_km","in":"query","required":false,"schema":{"type":"number","maximum":500.0,"minimum":0.1,"default":10,"title":"Radius Km"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Opaque pagination cursor (offset as base10 string)","title":"Cursor"},"description":"Opaque pagination cursor (offset as base10 string)"},{"name":"format","in":"query","required":false,"schema":{"type":"string","pattern":"^(json|text|md|markdown)$","description":"Response format: 'json' (default) or 'text'/'md'/'markdown' for agent-native prose (~60% fewer tokens)","default":"json","title":"Format"},"description":"Response format: 'json' (default) or 'text'/'md'/'markdown' for agent-native prose (~60% fewer tokens)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/business/{business_id}":{"get":{"summary":"Get Business","description":"Return a single business by ID (legacy authenticated endpoint).\n\nFor new agent-native consumers, prefer the public substrate endpoints:\n    GET /v1/biz/{id}            — public, no auth, supports ?format=short|full\n    GET /v1/biz/{id}/agent.json — public alias, always returns shorthand","operationId":"get_business_v1_business__business_id__get","parameters":[{"name":"business_id","in":"path","required":true,"schema":{"type":"string","title":"Business Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/schema/short":{"get":{"summary":"Schema Short","description":"The shorthand format spec, as JSON.","operationId":"schema_short_v1_schema_short_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/r/{record_id}":{"get":{"summary":"Get Record Substrate","description":"Agent-native endpoint for fetching a single business record.\n\nRequires a free API key (X-API-Key header, Authorization: Bearer, or ?api_key=).\nGet one instantly at https://agentweb.live/#signup — no credit card, no verification.\n\nFree tier: 1,000 reads/day, 120 req/min burst. Pro tier available for higher volume.\n\nResponse format (`?format=`):\n    full     JSON — complete entity (default)\n    short    JSON — ~320-byte shorthand with single-letter keys (~80% fewer tokens)\n    text     markdown/prose — agent-native, ~60% fewer tokens than JSON\n    md       alias for text\n    markdown alias for text\n\nAccept: text/markdown header also triggers the prose format.\nThe legacy `/v1/biz/{id}` path is kept as an alias forever.","operationId":"get_record_substrate_v1_r__record_id__get","parameters":[{"name":"record_id","in":"path","required":true,"schema":{"type":"string","title":"Record Id"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","pattern":"^(full|short|text|md|markdown)$","default":"full","title":"Format"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/r/{record_id}/agent.json":{"get":{"summary":"Get Record Agent Json","description":"Canonical agent.json for a business — always compact shorthand.\n\nRequires a free API key. ~320 bytes, sub-50ms.\nFor the markdown/prose format (recommended for most agents), use\n`/v1/r/{id}/agent.md` or pass `Accept: text/markdown`.\n\nFree tier: 1,000 reads/day. Instant signup at https://agentweb.live/#signup.","operationId":"get_record_agent_json_v1_r__record_id__agent_json_get","parameters":[{"name":"record_id","in":"path","required":true,"schema":{"type":"string","title":"Record Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/r/{record_id}/agent.md":{"get":{"summary":"Get Record Agent Md","description":"Canonical agent.md for a business — markdown/prose format.\n\nThis is the RECOMMENDED endpoint for most AI agents. LLMs parse prose\nmore accurately than JSON and consume ~60% fewer tokens for the same data.\n\nThe response is a single markdown document with labeled key:value lines:\n\n    # Noma\n    - Category: restaurant\n    - Phone: +45 32 96 32 97\n    - Email: noma@noma.dk\n    - Website: https://noma.dk\n    - Hours: Tue-Thu 17:00-23:00, Fri 12:30-17:30 & 18:00-23:30\n    - Address: Refshalevej 96, 1432 Copenhagen, DK\n    - Geo: 55.683, 12.611\n    - Trust: 92%, verified 2026-02-26\n    - ID: 07eb3c7b-...\n\nRequires a free API key. Free tier: 1,000 reads/day.","operationId":"get_record_agent_md_v1_r__record_id__agent_md_get","parameters":[{"name":"record_id","in":"path","required":true,"schema":{"type":"string","title":"Record Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/b/{identifier}":{"get":{"summary":"Get Business By Slug Json","description":"Fetch a business by slug (e.g. `noma-copenhagen`) OR UUID.\n\nThis is the recommended canonical URL — the slug is human-readable,\nshareable, and SEO-friendly. UUIDs still work as a fallback for rows\nthat haven't been backfilled yet.\n\nResponse format (`?format=`):\n    full     JSON — complete entity (default)\n    short    JSON — ~320-byte shorthand with single-letter keys\n    text/md  markdown prose — ~60% fewer tokens than JSON\n\nAccept: text/markdown header also triggers the prose format.","operationId":"get_business_by_slug_json_v1_b__identifier__get","parameters":[{"name":"identifier","in":"path","required":true,"schema":{"type":"string","title":"Identifier"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","pattern":"^(full|short|text|md|markdown)$","default":"full","title":"Format"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/b/{identifier}/agent.md":{"get":{"summary":"Get Business By Slug Md","description":"Markdown/prose representation of a business — the RECOMMENDED format\nfor AI agents. Accepts slug OR UUID.\n\nLLMs parse markdown more accurately than JSON and consume ~60% fewer\ntokens for the same data. Hand the response directly to the model.","operationId":"get_business_by_slug_md_v1_b__identifier__agent_md_get","parameters":[{"name":"identifier","in":"path","required":true,"schema":{"type":"string","title":"Identifier"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/b/{identifier}/agent.json":{"get":{"summary":"Get Business By Slug Agent Json","description":"Compact shorthand JSON for a business — single-letter keys, ~320 bytes.\nAccepts slug OR UUID.\n\nFor most LLM-facing use cases, prefer /v1/b/{slug}/agent.md which returns\nthe prose format (better parsing, ~60% fewer tokens). Use agent.json\nwhen you specifically need structured data in minimum bytes.","operationId":"get_business_by_slug_agent_json_v1_b__identifier__agent_json_get","parameters":[{"name":"identifier","in":"path","required":true,"schema":{"type":"string","title":"Identifier"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/r/{business_id}":{"get":{"summary":"Get Record Profile Page","description":"Human-readable public profile page for any business.\n\nCanonical URL: `/b/{slug}` (e.g. `/b/noma-copenhagen`)\nLegacy URLs:   `/r/{uuid}` and `/biz/{uuid}` — redirect to `/b/{slug}` when a slug is present\n\nServer-side rendered HTML with embedded JSON-LD (schema.org/LocalBusiness)\nso that search engines AND AI crawlers can index it without executing JS.\nAlso includes a <link rel=\"alternate\" type=\"application/json\"> pointing at\nthe agent.json endpoint, so MCP-aware clients can discover the structured\nrecord from the human page.","operationId":"get_record_profile_page_r__business_id__get","parameters":[{"name":"business_id","in":"path","required":true,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Business Id"}},{"name":"identifier","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Identifier"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/b/{identifier}":{"get":{"summary":"Get Record Profile Page","description":"Human-readable public profile page for any business.\n\nCanonical URL: `/b/{slug}` (e.g. `/b/noma-copenhagen`)\nLegacy URLs:   `/r/{uuid}` and `/biz/{uuid}` — redirect to `/b/{slug}` when a slug is present\n\nServer-side rendered HTML with embedded JSON-LD (schema.org/LocalBusiness)\nso that search engines AND AI crawlers can index it without executing JS.\nAlso includes a <link rel=\"alternate\" type=\"application/json\"> pointing at\nthe agent.json endpoint, so MCP-aware clients can discover the structured\nrecord from the human page.","operationId":"get_record_profile_page_b__identifier__get","parameters":[{"name":"identifier","in":"path","required":true,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Identifier"}},{"name":"business_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Business Id"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/claim/submit":{"post":{"summary":"Claim Submit","description":"Submit a new claim for a business.\n\nCreates an API key for the claimer if they don't have one yet, creates a\npending claim, sends a verification email. Public endpoint — no API key\nrequired to call (because the user might not have one yet).","operationId":"claim_submit_v1_claim_submit_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimSubmitRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/claim/verify":{"get":{"summary":"Claim Verify Get","description":"Confirm a claim via the link sent to the claimer's email.\n\nReachable at TWO paths:\n  /claim/verify     — short, public, used in email links\n  /v1/claim/verify  — full API path, kept for parity\n\nThe /claim/verify route is registered BEFORE /claim/{business_id} (which\ncatches everything else under /claim/) so route order resolves correctly.\n\nGET so the user can click the link directly. Marks the claim as 'claimed'\n(or 'owner_verified' if signals already pushed it past the threshold) and\nupdates the businesses table denormalised columns.","operationId":"claim_verify_get_v1_claim_verify_get","parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/claim/edit":{"post":{"summary":"Claim Edit","description":"Edit a business profile. Requires a verified claim by the same API key.","operationId":"claim_edit_v1_claim_edit_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BusinessEditRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/claim/upgrade":{"post":{"summary":"Claim Upgrade","description":"Strong verification — send a code to an address at the business's own domain.\n\nThe user has an existing 'claimed' claim. We send a fresh verification\ntoken to an email address that lives at the same domain as the business's\nwebsite. Whoever can receive email at that domain proves they control the\ndomain → therefore controls the business → we promote the claim to\nowner_verified on confirmation.","operationId":"claim_upgrade_v1_claim_upgrade_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimUpgradeRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/claim/dispute":{"post":{"summary":"Claim Dispute","description":"File a dispute against a business or its claim. Public, no auth.","operationId":"claim_dispute_v1_claim_dispute_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DisputeRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/sitemap.xml":{"get":{"summary":"Sitemap Xml","description":"Dynamic sitemap.xml.\n\nIncludes all static pages + every /directory/category/{slug} +\n/directory/country/{cc} + every owner-claimed /r/{id}. Cached in Redis\nfor 1 hour. Each URL is its own SEO entry point.","operationId":"sitemap_xml_sitemap_xml_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/directory":{"get":{"summary":"Directory Page","description":"Public browse-the-directory page.\n\nServer-rendered HTML, no auth, cached aggressively at the edge.\nUses business_by_category + business_by_country materialized views\nso the page loads in <50ms even under load.","operationId":"directory_page_directory_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/directory/category/{slug}":{"get":{"summary":"Directory Category","description":"Per-category landing page. Each category is its own SEO surface.","operationId":"directory_category_directory_category__slug__get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","maximum":10000,"minimum":1,"default":1,"title":"Page"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/directory/country/{cc}":{"get":{"summary":"Directory Country","description":"Per-country landing page.","operationId":"directory_country_directory_country__cc__get","parameters":[{"name":"cc","in":"path","required":true,"schema":{"type":"string","title":"Cc"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","maximum":10000,"minimum":1,"default":1,"title":"Page"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/claim":{"get":{"summary":"Claim Landing","description":"Public landing for the claim flow.\n\nWith ?q=... performs a search and returns matching businesses.","operationId":"claim_landing_claim_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string","default":"","title":"Q"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/claim/new":{"post":{"summary":"Claim New","description":"Create a brand-new business record AND immediately claim it.\n\nNo prior API key required — we create one for the claimer if needed,\njust like /v1/claim/submit. The new business is created with a\ndeterministic ID; if a record with the same LOWER(name) at the same\nrounded coords already exists, the unique index merges the data and we\nredirect the claimer to claim that one instead.","operationId":"claim_new_v1_claim_new_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimNewRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/claim/new":{"get":{"summary":"Claim New Form","description":"Public form to add a brand-new business and claim it in one step.\n\nThe substrate moment: a business owner can put their bakery on the agent\nweb in 30 seconds, with no website, no domain, no hosting.","operationId":"claim_new_form_claim_new_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/claim/{business_id}":{"get":{"summary":"Claim Form","description":"Per-business claim form.","operationId":"claim_form_claim__business_id__get","parameters":[{"name":"business_id","in":"path","required":true,"schema":{"type":"string","title":"Business Id"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/dispute/{business_id}":{"get":{"summary":"Dispute Page","description":"Public page for filing a dispute against a business or its claim.\n\nAnyone can flag a profile as fraudulent / wrong / closed / etc.\nPOSTs to the existing /v1/claim/dispute endpoint.","operationId":"dispute_page_dispute__business_id__get","parameters":[{"name":"business_id","in":"path","required":true,"schema":{"type":"string","title":"Business Id"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/r/{business_id}/edit":{"get":{"summary":"Record Edit Page","description":"Edit form for a record profile (canonical: /r/{id}/edit).\n\nRenders the form. Authorization happens server-side on POST /v1/claim/edit.\nThe legacy /biz/{id}/edit path remains as an alias forever.","operationId":"record_edit_page_r__business_id__edit_get","parameters":[{"name":"business_id","in":"path","required":true,"schema":{"type":"string","title":"Business Id"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/site-config":{"get":{"summary":"Site Config","description":"Public endpoint for landing page dynamic content.","operationId":"site_config_v1_site_config_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/contribute":{"post":{"summary":"Contribute Business","description":"Contribute a new business or enrich an existing one.\n\nWhen agents can't find a business in AgentWeb but find the data elsewhere,\nthey can POST it here to grow the directory. Crowdsourced by AI agents.","operationId":"contribute_business_v1_contribute_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContributeRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/report":{"post":{"summary":"Report Business","description":"Report a business as closed, incorrect, or spam. Crowdsource data quality.","operationId":"report_business_v1_report_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/agents/seen":{"get":{"summary":"Agents Seen","description":"Recently observed user-agents that called /v1/health.\nPublic — used for outbound discovery mining (so you can see who's scanning you).\nReturns top N user-agents by hit count over the last 30 days.","operationId":"agents_seen_v1_agents_seen_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/capabilities":{"get":{"summary":"Capabilities","description":"Machine-readable description of what AgentWeb can do.\n\nDesigned for AI agents that land on this domain and want to introspect\ncapabilities in one call. Combines OpenAPI metadata with an extended\n`x-mcp` block describing the MCP tools that wrap this API.\n\nNo authentication required.","operationId":"capabilities_v1_capabilities_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/suggest":{"get":{"summary":"Suggest","description":"Autocomplete suggestions for business names, cities, or categories.","operationId":"suggest_v1_suggest_get","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":2,"maxLength":100,"description":"Search prefix (min 2 chars)","title":"Q"},"description":"Search prefix (min 2 chars)"},{"name":"type","in":"query","required":false,"schema":{"type":"string","pattern":"^(business|city|category)$","description":"What to autocomplete: business, city, or category","default":"business","title":"Type"},"description":"What to autocomplete: business, city, or category"},{"name":"country","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO country code to filter results","title":"Country"},"description":"ISO country code to filter results"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":20,"minimum":1,"default":10,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/batch":{"get":{"summary":"Batch Businesses","description":"Fetch multiple businesses in one call. Accepts UUIDs or slugs, comma-separated.","operationId":"batch_businesses_v1_batch_get","parameters":[{"name":"ids","in":"query","required":true,"schema":{"type":"string","description":"Comma-separated business IDs or slugs (max 50)","title":"Ids"},"description":"Comma-separated business IDs or slugs (max 50)"},{"name":"format","in":"query","required":false,"schema":{"type":"string","pattern":"^(json|text|md|markdown|short)$","default":"json","title":"Format"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/trending":{"get":{"summary":"Trending Businesses","description":"Most-searched businesses by demand. Powered by real agent query data.","operationId":"trending_businesses_v1_trending_get","parameters":[{"name":"period","in":"query","required":false,"schema":{"type":"string","pattern":"^(24h|alltime)$","description":"Time period: '24h' or 'alltime'","default":"24h","title":"Period"},"description":"Time period: '24h' or 'alltime'"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/leaderboard/contributors":{"get":{"summary":"Leaderboard Contributors","description":"Top agent contributors by number of contributions.\n\nReads from the durable aw_events table (Postgres) so the counter\nsurvives any Redis flush. Cached in Redis for 5 minutes for speed.\nEmails are anonymised to protect privacy.","operationId":"leaderboard_contributors_v1_leaderboard_contributors_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"default":10,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/business/{business_id}/freshness":{"get":{"summary":"Business Freshness","description":"Check how fresh/reliable a business listing is.","operationId":"business_freshness_v1_business__business_id__freshness_get","parameters":[{"name":"business_id","in":"path","required":true,"schema":{"type":"string","title":"Business Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/site/{domain}":{"get":{"summary":"Get Site Map","description":"Get the pre-processed interaction map for a website.\n\nInstead of agents slowly screenshotting and clicking through websites,\nthey query this endpoint for the site's interaction structure and navigate\ndirectly. 60x faster. 75x cheaper in tokens.\n\nOptional ?section= to get just one part: forms, api, nav, auth, actions, search","operationId":"get_site_map_v1_site__domain__get","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","title":"Domain"}},{"name":"section","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional section: forms, api, nav, auth, actions, search","title":"Section"},"description":"Optional section: forms, api, nav, auth, actions, search"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/sites":{"get":{"summary":"List Mapped Sites","description":"List all websites that have been pre-processed with interaction maps.","operationId":"list_mapped_sites_v1_sites_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/recipes":{"get":{"summary":"List Recipes","description":"List all available recipes for interacting with external websites.","operationId":"list_recipes_v1_recipes_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/execute/{domain}/{recipe_name}":{"get":{"summary":"Execute Recipe","description":"Execute a recipe against a real website. Returns structured data.\n\nExample: /v1/execute/booking.com/search_hotels?destination=Rome&checkin=2026-04-15&checkout=2026-04-17\n\nThis calls booking.com's internal API directly (no browser, no Playwright)\nand returns hotel results in ~1.5 seconds. Results are cached for 30 minutes.","operationId":"execute_recipe_v1_execute__domain___recipe_name__get","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","title":"Domain"}},{"name":"recipe_name","in":"path","required":true,"schema":{"type":"string","title":"Recipe Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/go/{code}":{"get":{"summary":"Booking Redirect","description":"Redirect to a booking page. Short links created by the recipe engine.\nStores flight/hotel details in Redis, serves a clean redirect page.","operationId":"booking_redirect_go__code__get","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string","title":"Code"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"BusinessEditRequest":{"properties":{"business_id":{"type":"string","title":"Business Id"},"api_key":{"type":"string","title":"Api Key"},"edits":{"type":"object","title":"Edits"}},"type":"object","required":["business_id","api_key","edits"],"title":"BusinessEditRequest"},"ClaimNewRequest":{"properties":{"name":{"type":"string","title":"Name"},"category":{"type":"string","title":"Category","default":""},"description":{"type":"string","title":"Description","default":""},"street":{"type":"string","title":"Street","default":""},"city":{"type":"string","title":"City","default":""},"postal_code":{"type":"string","title":"Postal Code","default":""},"country":{"type":"string","title":"Country","default":""},"lat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lat"},"lng":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lng"},"phone":{"type":"string","title":"Phone","default":""},"email_biz":{"type":"string","title":"Email Biz","default":""},"website":{"type":"string","title":"Website","default":""},"email":{"type":"string","title":"Email"},"role":{"type":"string","title":"Role","default":"owner"},"attestation_accepted":{"type":"boolean","title":"Attestation Accepted"},"honeypot":{"type":"string","title":"Honeypot","default":""},"form_loaded_at":{"type":"integer","title":"Form Loaded At","default":0}},"type":"object","required":["name","email","attestation_accepted"],"title":"ClaimNewRequest"},"ClaimSubmitRequest":{"properties":{"business_id":{"type":"string","title":"Business Id"},"email":{"type":"string","title":"Email"},"role":{"type":"string","title":"Role","default":"owner"},"attestation_accepted":{"type":"boolean","title":"Attestation Accepted"},"honeypot":{"type":"string","title":"Honeypot","default":""},"form_loaded_at":{"type":"integer","title":"Form Loaded At","default":0}},"type":"object","required":["business_id","email","attestation_accepted"],"title":"ClaimSubmitRequest"},"ClaimUpgradeRequest":{"properties":{"business_id":{"type":"string","title":"Business Id"},"api_key":{"type":"string","title":"Api Key"},"target_email":{"type":"string","title":"Target Email"}},"type":"object","required":["business_id","api_key","target_email"],"title":"ClaimUpgradeRequest"},"ContributeRequest":{"properties":{"name":{"type":"string","title":"Name"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"website":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Website"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"address":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Address"},"country_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country Code"},"hours":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Hours"},"lat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lat"},"lng":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lng"}},"type":"object","required":["name"],"title":"ContributeRequest"},"DisputeRequest":{"properties":{"business_id":{"type":"string","title":"Business Id"},"reason":{"type":"string","title":"Reason"},"details":{"type":"string","title":"Details","default":""},"reporter_email":{"type":"string","title":"Reporter Email","default":""}},"type":"object","required":["business_id","reason"],"title":"DisputeRequest"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"RegisterRequest":{"properties":{"email":{"type":"string","title":"Email"},"name":{"type":"string","title":"Name","default":""}},"type":"object","required":["email"],"title":"RegisterRequest"},"ReportRequest":{"properties":{"business_id":{"type":"string","title":"Business Id"},"report_type":{"type":"string","title":"Report Type"},"details":{"type":"string","title":"Details","default":""}},"type":"object","required":["business_id","report_type"],"title":"ReportRequest"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}}}