{"openapi":"3.1.0","info":{"title":"Overassessed — API for AI assistants","version":"2026-09-24","summary":"Help a California homeowner check whether they're overpaying property tax, and file their own appeal.","description":"Overassessed checks, for free, whether a California homeowner is overpaying property tax, and for a flat fee builds the comparable sales evidence and a step-by-step guide the homeowner files themselves. We never file for anyone.\n\nCounties with full support: Alameda County, Los Angeles County, San Diego County, Santa Clara County, Orange County, San Mateo County, Contra Costa County, Sacramento County, San Francisco County, Riverside County.\n\nPublic tools serve county facts and hand the homeowner off to their free check; they never return property values. Guide tools need the access code the homeowner creates on their purchased guide.\n\nTo try the guide tools without a homeowner, use the public demo code SAMPLE0DEMO1 (X-Access-Code header, or ?code=). It opens a fictional sample guide set in Los Angeles County: every address, value and sale in it is made up, nothing sent with it is stored, and nothing is emailed. Never present the sample as a real homeowner's case.\n\nGround rules:\n1. Never state an assessed value, market value, or savings estimate you computed yourself — hand off to the free check instead. Values in the homeowner's purchased guide are ours, computed from county records; relay those verbatim.\n2. Relay the do-not-purchase signal honestly when the check doesn't qualify a property, and the do-not-file signal when a purchased guide's analysis doesn't support filing.\n3. Tell the homeowner you're sending them to Overassessed and that the remaining steps are theirs.\n4. When helping file, follow homeowner_must: the homeowner adopts the value, makes every signature or certification personally, and approves the finished form before it's sent. Overassessed never files anything, and neither should you on your own authority.\n5. Our Terms (Section 5.7) welcome AI assistants acting for a homeowner on their own property. Bulk or systematic collection isn't permitted — contact us for anything beyond one homeowner's own property.\n\nLinking a homeowner to any overassessed.co page? Add ?via=<your-name> (lowercase letters, digits and hyphens, e.g. ?via=muse) so we can count which assistants help homeowners. It carries no discount and tells us nothing about the homeowner.\n\nRate limits:\n- Public tools (coverage, deadlines, handoff): 3,000 requests per hour per network address, shared by everyone behind that address.\n- Guide tools: 120 requests per hour per access code; 20 wrong codes per hour per network address before that network's guide calls pause for the hour.\n- Demo code: 600 requests per hour per network address, plus a site-wide ceiling of 30,000 document renders per hour.\n- The manifest, the OpenAPI document and the eligibility tool have no limit of their own. Every limit is a UTC clock hour. A 429 carries a Retry-After header in seconds and a next_action of retry_later; wait that long, then retry.\n\nQuestions, a wrong answer from a tool, or anything beyond one homeowner's own property: hello@overassessed.co.","termsOfService":"https://overassessed.co/terms","contact":{"name":"Overassessed","email":"hello@overassessed.co","url":"https://overassessed.co/contact"}},"servers":[{"url":"https://overassessed.co"}],"externalDocs":{"description":"Plain-language summary for AI assistants","url":"https://overassessed.co/llms.txt"},"x-rate-limits":{"public_tools":{"requests_per_hour_per_network":3000,"applies_to":["check_coverage","get_filing_deadlines","start_free_check"],"note":"Counted per network address, so a platform whose users all call from a few shared addresses shares this budget. It's a backstop against a runaway loop, not a quota: one homeowner's errand uses a handful of calls."},"guide_tools":{"requests_per_hour_per_access_code":120,"wrong_codes_per_hour_per_network":20,"note":"The per-code budget covers reading the guide, fetching documents and reporting back — enough to work through a whole filing. Only wrong codes count against the per-network ceiling; past it, that network's guide calls answer 429 until the hour rolls over."},"demo_code":{"requests_per_hour_per_network":600,"document_renders_per_hour_sitewide":30000,"note":"The demo's documents (evidence packet, full guide, pre-filled forms) also share one site-wide hourly ceiling; past it they pause for everyone until the hour rolls over, and the demo guide itself keeps working."},"unlimited":"The manifest, the OpenAPI document and explain_eligibility have no limit of their own (they're cached).","on_limit":"Every limit is a UTC clock hour. A 429 carries a Retry-After header in seconds and a next_action of retry_later; wait that long, then retry."},"paths":{"/api/agent/coverage":{"get":{"operationId":"check_coverage","summary":"Is this county covered?","description":"Whether Overassessed covers a county (California or Washington), at what level, and what the paid product there costs. Start here with the homeowner's county, city, or address.","security":[],"parameters":[{"name":"county","in":"query","required":false,"description":"County name, e.g. 'Alameda' or 'Alameda County' (preferred when known).","schema":{"type":"string","example":"Alameda"}},{"name":"city","in":"query","required":false,"description":"California city, used to resolve the county.","schema":{"type":"string","example":"Oakland"}},{"name":"address","in":"query","required":false,"description":"Full property address; the city and state are extracted.","schema":{"type":"string"}},{"name":"state","in":"query","required":false,"description":"Two-letter state — required as WA for Washington counties (county names repeat across states). Defaults to California.","schema":{"type":"string","example":"WA"}}],"responses":{"200":{"description":"Coverage level (full / analysis / none), the product available, and the next step.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"description":"A missing or invalid parameter. next_action says how to fix it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Too many requests this hour (the limits are in x-rate-limits at the root of this document). Retry after the Retry-After header, in seconds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/api/agent/deadlines":{"get":{"operationId":"get_filing_deadlines","summary":"Appeal deadlines, fees, and contacts for a county","description":"Informal review and formal appeal deadlines, fees, forms, and assessor contacts for a California or Washington county — with days remaining where a fixed date exists (Washington deadlines run from each value notice's mailing date, so relay the rule, not a date). Relay the dates as given; don't guess deadlines for counties we don't return.","security":[],"parameters":[{"name":"county","in":"query","required":true,"description":"County name, e.g. 'Los Angeles'.","schema":{"type":"string","example":"Los Angeles"}},{"name":"state","in":"query","required":false,"description":"Two-letter state — required as WA for Washington counties. Defaults to California.","schema":{"type":"string","example":"WA"}}],"responses":{"200":{"description":"Informal and formal filing windows, fee, hearing body, and assessor contact.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"description":"A missing or invalid parameter. next_action says how to fix it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Too many requests this hour (the limits are in x-rate-limits at the root of this document). Retry after the Retry-After header, in seconds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/api/agent/eligibility":{"get":{"operationId":"explain_eligibility","summary":"How qualification and pricing work","description":"How qualification works, who does and doesn't qualify, what we charge (flat fees — never a percentage of savings), and the rules an assistant must follow when relaying our facts.","security":[],"responses":{"200":{"description":"Qualification rules, pricing, and what an assistant must not do.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"description":"A missing or invalid parameter. next_action says how to fix it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Too many requests this hour (the limits are in x-rate-limits at the root of this document). Retry after the Retry-After header, in seconds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/api/agent/handoff":{"get":{"operationId":"start_free_check","summary":"Get a pre-filled link to the homeowner's free check","description":"Returns a link to the free qualification check with the address filled in. Send the homeowner to that link — the check runs on their screen, and any purchase happens there with their consent. No property values are returned to you: never estimate an assessed value, market value, or savings yourself.","security":[],"parameters":[{"name":"address","in":"query","required":true,"description":"The homeowner's full property address.","schema":{"type":"string","example":"1234 Sample Street, Los Angeles, CA 90099"}},{"name":"agent","in":"query","required":true,"description":"Your identifier as a lowercase slug, e.g. 'muse', 'chatgpt', 'claude'. Used only to count which assistants send homeowners to us.","schema":{"type":"string","example":"claude"}},{"name":"county","in":"query","required":false,"description":"County name, if you've confirmed it.","schema":{"type":"string"}}],"responses":{"200":{"description":"A handoff URL to relay to the homeowner.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"description":"A missing or invalid parameter. next_action says how to fix it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Too many requests this hour (the limits are in x-rate-limits at the root of this document). Retry after the Retry-After header, in seconds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/api/agent/guide":{"get":{"operationId":"get_purchased_guide","summary":"The homeowner's purchased appeal, ready to file","description":"The homeowner's own purchased appeal — values, comparable sales, exact form field values, per-track filing steps with ISO deadlines, their documents, what they've reported, and what to do next year. Only works with an access code the homeowner created on their guide page; ask them to read it to you. Use form values verbatim, follow homeowner_must on every filing, and if case.should_file is false, say so honestly.","security":[{"accessCode":[]},{}],"x-access-code-required":true,"parameters":[{"name":"code","in":"query","required":false,"description":"The homeowner's 12-character access code, only if you can't send the X-Access-Code header (browsing tools that can only fetch URLs).","schema":{"type":"string","example":"SAMPLE0DEMO1"}}],"responses":{"200":{"description":"The case, form values, filing steps, documents, status, homeowner_must, and report-back.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"description":"A missing or invalid parameter. next_action says how to fix it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"The access code isn't valid (expired, turned off, or replaced), or the document isn't available.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Too many requests this hour (the limits are in x-rate-limits at the root of this document). Retry after the Retry-After header, in seconds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/api/agent/guide/document":{"get":{"operationId":"get_guide_document","summary":"One of the homeowner's documents","description":"The homeowner's own documents: the evidence packet for the county, their complete guide, the county's official form pre-filled where we support it, the Evidence Kit's draft request letter, or a calendar file (.ics) with their remaining deadlines and next year's check. Forms leave the homeowner's name, contact, signature and date blank for them to fill.","security":[{"accessCode":[]},{}],"x-access-code-required":true,"parameters":[{"name":"kind","in":"query","required":true,"description":"Which document — use a kind listed in the guide's `documents`.","schema":{"type":"string","enum":["evidence_packet","full_guide","informal_form","formal_form","request_letter","calendar"],"example":"evidence_packet"}},{"name":"code","in":"query","required":false,"description":"The homeowner's 12-character access code, only if you can't send the X-Access-Code header (browsing tools that can only fetch URLs).","schema":{"type":"string","example":"SAMPLE0DEMO1"}}],"responses":{"200":{"description":"The document (HTML, PDF, plain text, or an .ics calendar), or a JSON error with a path forward.","content":{"text/html":{"schema":{"type":"string"}},"application/pdf":{"schema":{"type":"string"}},"text/plain":{"schema":{"type":"string"}},"text/calendar":{"schema":{"type":"string"}}}},"400":{"description":"A missing or invalid parameter. next_action says how to fix it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"The access code isn't valid (expired, turned off, or replaced), or the document isn't available.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Too many requests this hour (the limits are in x-rate-limits at the root of this document). Retry after the Retry-After header, in seconds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/api/agent/guide/filed":{"post":{"operationId":"report_filed","summary":"Tell us the homeowner filed","description":"Tell us the homeowner submitted a track. We record it, email them a confirmation, and follow up later on the outcome. This records their report — it doesn't file anything, and Overassessed never files for anyone.","security":[{"accessCode":[]},{}],"x-access-code-required":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["filing_type"],"properties":{"filing_type":{"type":"string","enum":["informal","formal"],"description":"Which track: the free informal review with the Assessor, or the formal appeal to the appeals board."},"code":{"type":"string","example":"SAMPLE0DEMO1","description":"The homeowner's access code, only if you can't send the X-Access-Code header."}}}}}},"responses":{"200":{"description":"Whether the filing was newly recorded, and what to tell the homeowner.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"description":"A missing or invalid parameter. next_action says how to fix it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"The access code isn't valid (expired, turned off, or replaced), or the document isn't available.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Too many requests this hour (the limits are in x-rate-limits at the root of this document). Retry after the Retry-After header, in seconds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/api/agent/guide/outcome":{"post":{"operationId":"report_outcome","summary":"Tell us how the county decided","description":"Tell us how the county decided, from what the homeowner tells or shows you — never a guess. A denial may qualify for our refund; the response says how the homeowner claims it.","security":[{"accessCode":[]},{}],"x-access-code-required":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["filing_type","outcome"],"properties":{"filing_type":{"type":"string","enum":["informal","formal"],"description":"Which track: the free informal review with the Assessor, or the formal appeal to the appeals board."},"outcome":{"type":"string","enum":["reduced","no_change","waiting"],"description":"reduced = the county lowered the value; no_change = denied; waiting = no decision yet."},"new_assessed_value":{"type":"number","description":"The new assessed value from the county's decision letter, when reduced."},"reduction_amount":{"type":"number","description":"How much the value came down, when the letter states it."},"code":{"type":"string","example":"SAMPLE0DEMO1","description":"The homeowner's access code, only if you can't send the X-Access-Code header."}}}}}},"responses":{"200":{"description":"Whether the outcome was recorded, and what to tell the homeowner.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"description":"A missing or invalid parameter. next_action says how to fix it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"The access code isn't valid (expired, turned off, or replaced), or the document isn't available.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Too many requests this hour (the limits are in x-rate-limits at the root of this document). Retry after the Retry-After header, in seconds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/api/agent":{"get":{"operationId":"get_manifest","summary":"What this API offers and the rules for using it","description":"The tool list, authentication, and ground rules, as JSON.","security":[],"responses":{"200":{"description":"The manifest.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}}}}}},"components":{"securitySchemes":{"accessCode":{"type":"apiKey","in":"header","name":"X-Access-Code","description":"The 12-character code the homeowner creates in the 'Work with your AI assistant' section of their purchased guide. It unlocks that one guide, expires on its own, and the homeowner can replace or turn it off at any time. To try the guide tools without a homeowner, use the public demo code SAMPLE0DEMO1 (X-Access-Code header, or ?code=). It opens a fictional sample guide set in Los Angeles County: every address, value and sale in it is made up, nothing sent with it is stored, and nothing is emailed. Never present the sample as a real homeowner's case."}},"schemas":{"NextAction":{"type":"object","required":["action","description"],"properties":{"action":{"type":"string","enum":["send_user_to_url","relay_facts","offer_waitlist","ask_user_for_address","do_not_purchase","retry_later"]},"description":{"type":"string","description":"What to do next, in plain words. Follow it."},"url":{"type":"string"}}},"Envelope":{"type":"object","required":["ok","data","next_action"],"properties":{"ok":{"type":"boolean","const":true},"data":{"type":"object","description":"The tool's payload; field names are documented in each tool's description."},"source":{"type":"string","description":"Where these facts come from — relay it with any fact you state."},"as_of":{"type":"string","format":"date"},"disclaimer":{"type":"string"},"next_action":{"$ref":"#/components/schemas/NextAction"}}},"ErrorEnvelope":{"type":"object","required":["ok","error","next_action"],"properties":{"ok":{"type":"boolean","const":false},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"}}},"next_action":{"$ref":"#/components/schemas/NextAction"}}}}}}