{"openapi":"3.1.0","info":{"title":"AI Law Tracker — Public Laws API","version":"v1","description":"Read-only, versioned JSON API over the audited AI-regulation dataset (US state + federal, EU, and global). FREE beta. Data is CC BY 4.0 — attribution required. Informational only, not legal advice.","license":{"name":"CC BY 4.0","url":"https://creativecommons.org/licenses/by/4.0/"}},"servers":[{"url":"https://ai-law-tracker.com/api/v1"}],"security":[{},{"ApiKeyAuth":[]},{"BearerAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key"},"BearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Record":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Stable primary key (the /v1/laws/{id} path key)."},"scope":{"type":"string","enum":["state","federal","eu","global"]},"jurisdiction":{"type":"object","properties":{"slug":{"type":"string","example":"colorado"},"name":{"type":["string","null"],"example":"Colorado"},"abbr":{"type":["string","null"],"example":"CO"}}},"identifier":{"type":["string","null"],"example":"HB 251212"},"title":{"type":["string","null"]},"record_type":{"type":["string","null"],"example":"bill"},"status":{"type":["string","null"],"description":"Rich free-text status verbatim from the source."},"in_force":{"type":["boolean","null"],"description":"Set only where the source states it explicitly; else null."},"record_date":{"type":["string","null"],"format":"date-time"},"summary":{"type":["string","null"]},"source":{"type":["string","null"],"example":"openstates.org"},"official_url":{"type":["string","null"],"description":"Primary/official (.gov) link where available."},"updated_at":{"type":["string","null"],"format":"date-time","description":"Last CHANGED — advanced only on a real content diff."},"checked_at":{"type":["string","null"],"format":"date-time","description":"Last VERIFIED — bumped every time the source was successfully re-checked, even when unchanged."},"attribution":{"type":"string","example":"Data by AI Law Tracker (CC BY 4.0) — https://ai-law-tracker.com"}}},"UsLawRecord":{"type":"object","description":"A US-law record at title/chapter/part granularity. Carries the citation, status, dates, the official source URL and the classification — NOT the statutory text, which is linked via full_text_url.","properties":{"record_uid":{"type":"string"},"jurisdiction_level":{"type":"string","enum":["federal","state"]},"jurisdiction_slug":{"type":"string"},"jurisdiction_name":{"type":"string"},"instrument_type":{"type":"string"},"instrument_label":{"type":"string"},"is_binding":{"type":"boolean"},"citation":{"type":"string","description":"Never withheld at any tier."},"identifier":{"type":["string","null"]},"title":{"type":"string"},"short_title":{"type":["string","null"]},"summary":{"type":["string","null"],"description":"Withheld in the trimmed (basic) envelope."},"status":{"type":"string"},"is_in_force":{"type":"boolean"},"enacted_date":{"type":["string","null"],"format":"date"},"effective_date":{"type":["string","null"],"format":"date"},"repealed_date":{"type":["string","null"],"format":"date"},"official_url":{"type":"string","description":"The official government source. Never withheld at any tier."},"full_text_url":{"type":["string","null"],"description":"Where the text lives. We link it; we do not reproduce it."},"source_authority":{"type":["string","null"]},"retrieved_at":{"type":["string","null"],"format":"date-time"},"last_verified_at":{"type":["string","null"],"format":"date-time"},"primary_branch_id":{"type":["string","null"]},"primary_branch_label":{"type":["string","null"]},"primary_domain_id":{"type":["string","null"],"description":"`other_unclassified` when not yet substantively classified."},"primary_domain_label":{"type":["string","null"]},"domains":{"type":"array","items":{"type":"object"},"description":"ALL assigned domains, primary and secondary — the many-to-many classification."},"edition_year":{"type":["integer","null"]},"edition_label":{"type":["string","null"]},"executive_order_number":{"type":["integer","null"]},"proclamation_number":{"type":["integer","null"]},"presidential_document_number":{"type":["string","null"]}}},"CourtOpinion":{"type":"object","description":"One published court opinion, IDENTIFIED but not reproduced. The record carries the case name, court, filing date, docket number, reporter citation and how many later opinions cite it; the decision itself lives at absolute_url. There is no opinion text and no holding in this corpus.","properties":{"cluster_id":{"type":"integer","description":"CourtListener cluster id — the stable identifier, and the path parameter of the detail endpoint."},"case_name":{"type":"string","description":"The caption. This is the ONLY field `q` searches. Never withheld at any tier."},"court_id":{"type":"string","description":"Court slug, e.g. scotus, iowa, nyappdiv. See /us-law/courts for the full list."},"court_name":{"type":"string","description":"Never withheld at any tier."},"court_citation_string":{"type":["string","null"],"description":"The court’s reporter abbreviation, e.g. \"Iowa\". Withheld in the trimmed (basic) envelope."},"court_jurisdiction":{"type":"string","enum":["F","S","SA"],"description":"The indexed jurisdiction code the court_level / jurisdiction_level filters resolve onto."},"court_level":{"type":"string","enum":["federal_appellate","state_supreme","state_appellate"]},"date_filed":{"type":"string","format":"date","description":"ALWAYS read alongside date_filed_is_approximate."},"date_filed_is_approximate":{"type":"boolean","description":"True when the filing date is our source’s approximation rather than a stated date — 58,828 of 988,554 records. NEVER withheld at any tier, including the keyless envelope: shipping date_filed without this flag would present a guess as a fact to people who compute deadlines from it."},"precedential_status":{"type":"string","description":"Every record currently held is \"Published\"."},"docket_id":{"type":["integer","null"],"description":"Withheld in the trimmed (basic) envelope."},"docket_number":{"type":["string","null"],"description":"Withheld in the trimmed (basic) envelope. NOT a filter — see the endpoint description."},"primary_citation":{"type":["string","null"],"description":"Reporter citation, e.g. \"2022 OK 38\". 541,629 of 988,554 records carry one. Never withheld at any tier."},"citation_count":{"type":"integer","description":"How many later opinions cite this one. Withheld in the trimmed (basic) envelope."},"absolute_url":{"type":"string","description":"Where the decision itself is. Never withheld at any tier — it is how you check our work."},"slug":{"type":["string","null"],"description":"Withheld in the trimmed (basic) envelope."},"source_authority":{"type":"string","description":"courtlistener. Withheld in the trimmed (basic) envelope."},"bulk_edition":{"type":["string","null"],"format":"date","description":"Which source bulk edition this row came from. Withheld in the trimmed (basic) envelope."},"retrieved_at":{"type":"string","format":"date-time","description":"When WE fetched it — not when the court decided it. Withheld in the trimmed (basic) envelope."}}},"EnforcementMatter":{"type":"object","description":"One enforcement or litigation MATTER: a dispute with an identity that persists as it moves. An agency action with a complaint, a settlement and a final order is one matter here, not three rows.","properties":{"matter_uid":{"type":"string","description":"Stable key for fetching this matter again. AN OPAQUE KEY, NOT A DESCRIPTION — do not render it as a name. It is generated from whatever the ingest could parse and is demonstrably unreliable (one uid names RealPage for what is in fact the DOJ/LivCor consent decree). Read `caption`."},"caption":{"type":"string","description":"The matter as a human should read it. This is its name."},"jurisdiction_level":{"type":"string"},"jurisdiction_slug":{"type":"string"},"jurisdiction_name":{"type":["string","null"]},"forum_type":{"type":"string","description":"See /enforcement/categories."},"forum_name":{"type":["string","null"]},"matter_type":{"type":"string","description":"enforcement_action | civil_litigation | guidance_document | investigation | inquiry_6b. See /enforcement/categories."},"matter_status":{"type":"string"},"docket_number":{"type":["string","null"]},"agency_code":{"type":["string","null"],"description":"FTC, DOJ, SEC, CFPB, EEOC, a state AG… Free text, not a closed vocabulary."},"ai_roles":{"type":"array","items":{"type":"string"},"description":"How AI figures in the matter. See the ai_role vocabulary."},"filed_date":{"type":["string","null"],"format":"date","description":"The date the SOURCE states the action was filed or opened, verbatim. NEVER our scrape date — that is `first_seen_at`, and confusing the two is the defect this field was rebuilt to remove. Null means the source did not state one; it is never inferred, and `date_source` below names where a non-null value came from."},"decided_date":{"type":["string","null"],"format":"date","description":"The date the SOURCE states the matter resolved — settlement announced, consent order entered, final order, judgment. Null when unresolved or unstated."},"date_source":{"type":["string","null"],"description":"Which source field `filed_date` was lifted from, e.g. `ftc_case_timeline_oldest_entry`, `cfpb_listing_date_filed`, `tx_ag_listing_meta`, `doj_release_published_meta`. Published so a date can be traced rather than trusted. Always present when filed_date is."},"closed_date":{"type":["string","null"],"format":"date"},"summary":{"type":["string","null"],"description":"Null on 42 of 91 matters."},"source_authority":{"type":"string"},"source_url":{"type":"string","description":"Where the claim came from. Never withheld at any tier — it is how you check our work."},"verification":{"type":"string","description":"Corroboration level. MEASURED 2026-08-22: every matter currently held is `single_source`, i.e. recorded from ONE official source with no second confirmation. Never withheld at any tier; read it before relying on any claim here."},"first_seen_at":{"type":"string","format":"date-time"},"last_verified_at":{"type":["string","null"],"format":"date-time"},"primary_domain_id":{"type":"string"},"primary_domain_label":{"type":"string"},"primary_branch_id":{"type":"string"},"primary_branch_label":{"type":"string"},"domains":{"type":"array","items":{"type":"object"},"description":"All assigned subject domains, primary and secondary."},"is_canonical":{"type":"boolean","description":"False when another matter_uid already publishes this same source document."},"duplicate_of":{"type":["string","null"],"description":"The matter_uid to read instead. Present only on a non-canonical row."},"publish_ready":{"type":"boolean","description":"Canonical AND its CAPTION is in English. Rows where this is false are served only to a caller licensed for the raw registry."},"unavailable_fields":{"type":"array","items":{"type":"string"},"description":"Present only when a DESCRIPTIVE field (forum_name, agency_code or summary) was nulled because it still carries untranslated internal working language. The matter itself is published; only these fields are not. A null WITHOUT this list means the source simply did not state a value."},"unavailable_reason":{"type":"string","description":"Why the fields above are null. Present only alongside unavailable_fields."},"enforcement_tier":{"type":["string","null"],"description":"A = an enforcement DECISION (complaint filed, consent order, settlement, civil penalty, judgment, cease-and-desist). B = an enforcement-adjacent SIGNAL (opened investigation, sweep, CID, enforcement advisory, 6(b) study order). NULL means the tier was never assessed — true of every matter recorded before 2026-08-22 — and does NOT mean B. Filter `tier=A` when the question is how many real enforcement decisions exist."},"ai_basis":{"type":"object","description":"WHY this matter is in an AI dataset. `matches` lists each term that fired, the field it fired in, the ai_role it implies, and a VERBATIM excerpt of the source text around it; `method` says whether the agency's own classification was used (e.g. the FTC industry tag \"Technology > Artificial Intelligence\") or only keywords. Published deliberately: it is the citation for the inclusion decision, so the corpus can be audited without re-reading every source."},"source_absent_fields":{"type":"array","items":{"type":"string"},"description":"Fields the ingest LOOKED FOR and the source did not state. NOT the same as `unavailable_fields`, which is what WE withheld. This one is the agency's gap; that one is ours."},"industry_labels":{"type":"array","items":{"type":"string"},"description":"Sector labels the SOURCE applied, verbatim (FTC industry/topic tags, DOJ ATR \"Industry Code(s)\"). Never inferred from the respondent's name."},"violation_labels":{"type":"array","items":{"type":"string"},"description":"Violation types the SOURCE stated, verbatim (FTC \"Enforcement Type\"/\"Type of Action\", DOJ ATR \"Case Violation(s)\"). Never inferred from the conduct described."},"ingest_lane":{"type":["string","null"],"description":"Which writer produced the row. Provenance, not classification."}}},"Change":{"type":"object","description":"One observed change to a record (insert or update).","properties":{"event_id":{"type":"string","format":"uuid","description":"Opaque, unique per change (append-only history row id)."},"entity":{"type":"string","enum":["law_record","jurisdiction"],"description":"Which dataset changed."},"record_id":{"type":["string","null"],"format":"uuid","description":"The /v1/laws/{id} key (law_record only; null for jurisdiction)."},"scope":{"type":["string","null"],"enum":["state","federal","eu","global"]},"jurisdiction":{"type":"object","properties":{"slug":{"type":"string","example":"washington"},"name":{"type":["string","null"],"example":"Washington"},"abbr":{"type":["string","null"],"example":"WA"}}},"identifier":{"type":["string","null"],"example":"HB 1170"},"title":{"type":["string","null"]},"change_kind":{"type":"string","enum":["insert","update"]},"changed_fields":{"type":["array","null"],"description":"Public field names that changed on an update (null on insert). Internal metadata churn appears as \"metadata\".","items":{"type":"string"}},"field_changes":{"type":"array","description":"Compact from→to value diff for the scalar fields that changed (empty on insert or a metadata-only update).","items":{"type":"object","properties":{"field":{"type":"string","example":"status"},"from":{},"to":{}}}},"observed_at":{"type":"string","format":"date-time","description":"When this state was first observed. Use as the ?since= cursor."},"source_run_id":{"type":["string","null"],"format":"uuid","description":"The scrape run that produced this state."},"attribution":{"type":"string","example":"Data by AI Law Tracker (CC BY 4.0) — https://ai-law-tracker.com"}}},"NewsItem":{"type":"object","description":"One AI-law news headline. COPYRIGHT: only the headline, a short excerpt, the publisher name and the source URL are served — never full article text.","properties":{"id":{"type":"string","format":"uuid"},"scope":{"type":"string","enum":["state","federal","eu","global"]},"jurisdiction":{"type":"object","properties":{"slug":{"type":"string","example":"california"},"name":{"type":["string","null"],"example":"California"}}},"title":{"type":["string","null"],"description":"The headline."},"published_date":{"type":["string","null"],"format":"date"},"source":{"type":["string","null"],"example":"Reuters","description":"The publisher name."},"url":{"type":["string","null"],"description":"The publisher's article URL (the source link)."},"excerpt":{"type":["string","null"],"description":"Short summary — Developer+ only (withheld on the free/anon taste; NEVER full article text)."},"fetched_at":{"type":["string","null"],"format":"date-time","description":"Freshness stamp — Developer+ only."},"gated":{"type":"boolean","description":"Present (true) on the free/anon taste envelope — the excerpt is withheld behind a Developer key."},"attribution":{"type":"string","example":"Data by AI Law Tracker (CC BY 4.0) — https://ai-law-tracker.com"}}},"EnforcementItem":{"type":"object","description":"One AI enforcement action or litigation matter, over news_articles (change_type enforcement|litigation). Only status published rows are ever returned. Pending and approved rows are internal editorial states, so an empty data[] is expected until a story is actually published. Enterprise-tier only — every other tier gets 403 tier_upgrade_required before this schema is reached.","properties":{"id":{"type":"string","format":"uuid"},"change_type":{"type":"string","enum":["enforcement","litigation"],"description":"'enforcement' = an agency action; 'litigation' = a civil docket."},"title":{"type":["string","null"]},"agency":{"type":["string","null"],"description":"WHO acted — the regulator/AG (null on a private litigation matter with no agency)."},"scope":{"type":"string","enum":["state","federal","eu","global"]},"jurisdiction":{"type":"object","properties":{"slug":{"type":["string","null"]},"name":{"type":["string","null"]}}},"date":{"type":["string","null"],"format":"date-time","description":"published_at, else approved_at, else the draft's created_at."},"source_url":{"type":["string","null"],"description":"The official source: the agency's release, or the court docket."},"respondent":{"type":["string","null"],"description":"AGAINST WHOM the action/suit is brought."},"allegation":{"type":["string","null"],"description":"WHAT was alleged."},"outcome":{"type":["string","null"],"description":"HOW it ended (e.g. settlement, suit filed, pending)."},"penalty":{"type":["string","null"],"description":"WHAT it cost, verbatim from the source."},"statutory_basis":{"type":["string","null"],"description":"UNDER WHICH LAW, verbatim from the source."},"forum":{"type":["string","null"],"description":"The court, for a litigation row (null on enforcement)."},"summary":{"type":["string","null"]},"gated":{"type":"boolean","description":"Reserved — always absent for the Enterprise-only 200 response (no teaser tier reaches this schema)."},"attribution":{"type":"string","example":"Data by AI Law Tracker (CC BY 4.0) — https://ai-law-tracker.com"}}},"Webhook":{"type":"object","description":"A change-notification subscription.","properties":{"id":{"type":"string","format":"uuid"},"target_url":{"type":"string","description":"HTTPS endpoint that receives signed POSTs."},"events":{"type":"array","items":{"type":"string","enum":["law.created","law.updated"]}},"scope":{"type":["string","null"],"enum":["state","federal","eu","global"],"description":"Optional filter — only changes in this scope."},"jurisdiction":{"type":["string","null"],"description":"Optional filter — only changes for this jurisdiction slug."},"active":{"type":"boolean"},"failure_count":{"type":"integer","description":"Consecutive failed deliveries; the webhook auto-disables at 10."},"disabled_at":{"type":["string","null"],"format":"date-time"},"disabled_reason":{"type":["string","null"]},"last_delivery_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":"string","format":"date-time"}}},"WebhookPayload":{"type":"object","description":"The signed POST body a subscriber receives for one change.","properties":{"event":{"type":"string","enum":["law.created","law.updated"]},"event_id":{"type":"string","format":"uuid","description":"Unique per change (append-only history row id)."},"delivery_id":{"type":"string","format":"uuid","description":"Unique per delivery attempt — idempotency key for the receiver."},"webhook_id":{"type":"string","format":"uuid"},"change_kind":{"type":"string","enum":["insert","update"]},"changed_fields":{"type":["array","null"],"items":{"type":"string"},"description":"Fields that changed on an update (null on insert)."},"observed_at":{"type":"string","format":"date-time"},"record":{"$ref":"#/components/schemas/Record"},"attribution":{"type":"string","example":"Data by AI Law Tracker (CC BY 4.0) — https://ai-law-tracker.com"}}},"Obligation":{"type":"object","description":"A derived AI-law obligation — who must do what, by when, or owe what penalty. Retrieved from curated primary sources (no LLM); NOT legal advice.","properties":{"law":{"type":"string","example":"HB 3773 — AI in Employment (amends the IL Human Rights Act)"},"jurisdiction":{"type":"string","example":"Illinois"},"layer":{"type":"string","enum":["state","federal","landscape","country"],"description":"“landscape” = a notable law that may not apply to you (out-of-state); see may_not_apply."},"applies_because":{"type":["string","null"],"description":"Why this obligation was surfaced for the given context."},"obligation":{"type":["string","null"],"description":"The plain-English duty (\"what must I do\")."},"deadline":{"type":["string","null"],"description":"Free-text effective/compliance date verbatim from the source (\"by when\")."},"penalty":{"type":["string","null"]},"status":{"type":["string","null"]},"citation":{"type":["string","null"],"example":"42 U.S.C. § 2000e"},"government_body":{"type":["string","null"],"example":"EEOC"},"may_not_apply":{"type":"boolean","description":"true when the law binds another jurisdiction and may not apply to the caller."},"source_url":{"type":["string","null"],"description":"Primary/official source for this obligation."},"source_tier":{"type":"string","enum":["primary","secondary","unverified"],"description":"Grounding tier of source_url."}}},"Penalty":{"type":"object","description":"A penalty / enforcement record for one applicable law.","properties":{"law":{"type":"string"},"jurisdiction":{"type":"string"},"layer":{"type":"string","enum":["state","federal","landscape","country"]},"penalty":{"type":["string","null"]},"citation":{"type":["string","null"]},"government_body":{"type":["string","null"]},"status":{"type":["string","null"]},"may_not_apply":{"type":"boolean"},"source_url":{"type":["string","null"]},"source_tier":{"type":"string","enum":["primary","secondary","unverified"]}}},"Risk":{"type":"object","description":"Deterministic 1–10 risk score (same inputs → same score; no model).","properties":{"score":{"type":"integer","minimum":1,"maximum":10},"level":{"type":"string","enum":["Low","Medium","High","Critical"]},"factors":{"type":"array","items":{"type":"string"},"description":"Named contributions to the score (full result only; withheld in a preview)."}}},"Assessment":{"type":"object","description":"A company-profile applicability + risk assessment.","properties":{"risk":{"$ref":"#/components/schemas/Risk"},"applicable_law_count":{"type":"integer"},"jurisdictions":{"type":"array","items":{"type":"string"}},"obligations":{"type":"array","items":{"$ref":"#/components/schemas/Obligation"}},"no_law":{"type":"array","items":{"type":"object","properties":{"jurisdiction":{"type":"string"},"note":{"type":"string"},"layer":{"type":"string"}}}},"unmapped_sectors":{"type":"array","items":{"type":"string"}}}},"Error":{"type":"object","properties":{"api_version":{"type":"string"},"error":{"type":"object","properties":{"code":{"type":"string","example":"rate_limited"},"message":{"type":"string"},"docs":{"type":"string"},"retry_after":{"type":"integer","description":"Seconds (429 only)."}},"required":["code","message"]}}}}},"paths":{"/health":{"get":{"summary":"Liveness + backend status","responses":{"200":{"description":"OK"}},"operationId":"getHealth"}},"/accuracy":{"get":{"summary":"Public accuracy ledger — source-health summary + change-observation stats","description":"The machine-readable form of the public /accuracy page. Returns the latest source-liveness sweep summary (how many cited sources were checked, verified live, confirmed broken, or unverified), the count of confirmed-broken sources in the review queue, and the total append-only change-observations on record. Free/public: no tier gate, rate-limited like any endpoint. Every figure is a live count over real rows.","responses":{"200":{"description":"Accuracy summary.","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"source_health":{"type":"object","properties":{"checked":{"type":"integer"},"live":{"type":"integer"},"confirmed_broken":{"type":"integer"},"unverified":{"type":"integer"},"live_pct":{"type":["integer","null"]},"last_checked_at":{"type":["string","null"],"format":"date-time"}}},"observations":{"type":"object","properties":{"total":{"type":"integer"},"since":{"type":["string","null"],"format":"date-time"}}}}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"getAccuracy"}},"/laws":{"get":{"summary":"List legal records (filter, sort, paginate)","description":"TIER-GATING: filters and sorting (scope, jurisdiction, status, in_force, updated_since, sort, order) are honoured at EVERY tier including anonymous — they are documented query semantics, so they are never silently dropped. What Free/anonymous callers get instead is low volume and shallow pagination: anon 5 rows per page with a trimmed field envelope, free-key 25 rows with the full field set. Developer+ raises the page size and unlocks deep pagination, the change feed and per-record history. When a request is capped, the response echoes meta.gated + an upgrade hint (it is never a hard error).","parameters":[{"name":"scope","in":"query","schema":{"type":"string","enum":["state","federal","eu","global"]},"description":"Filter by scope."},{"name":"jurisdiction","in":"query","schema":{"type":"string"},"description":"Exact jurisdiction slug (e.g. colorado, eu, us-federal, canada)."},{"name":"status","in":"query","schema":{"type":"string"},"description":"Case-insensitive substring match on status."},{"name":"in_force","in":"query","schema":{"type":"boolean"},"description":"Filter by the in_force flag."},{"name":"updated_since","in":"query","schema":{"type":"string","format":"date-time"},"description":"Only records updated at/after this ISO timestamp."},{"name":"q","in":"query","schema":{"type":"string"},"description":"Substring search over title + summary."},{"name":"sort","in":"query","schema":{"type":"string","enum":["updated_at","record_date","title"],"default":"updated_at"}},{"name":"order","in":"query","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}},{"name":"limit","in":"query","schema":{"type":"integer","default":20,"maximum":100}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"A page of records.","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Record"}},"meta":{"type":"object","properties":{"total":{"type":"integer"},"count":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"}}}}}}}},"400":{"description":"Invalid parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Backend unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"listLaws"}},"/laws/{id}":{"get":{"summary":"Get one record by uuid","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The record","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Record"}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"getLaw"}},"/laws/{id}/history":{"get":{"summary":"Full change timeline for one record","description":"Every snapshot of the record (ascending observed_at), each with change_kind, changed_fields and the record values as of that snapshot. TIER-GATING: Developer+ only — anonymous/Free callers get 403 tier_upgrade_required. Lookback window climbs by tier: Developer 30 days, Pro 365 days, Business/Enterprise full history.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The record timeline.","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"data":{"type":"object","properties":{"record_id":{"type":"string","format":"uuid"},"count":{"type":"integer"},"timeline":{"type":"array","items":{"type":"object","properties":{"observed_at":{"type":"string","format":"date-time"},"change_kind":{"type":"string","enum":["insert","update"]},"changed_fields":{"type":["array","null"],"items":{"type":"string"}},"source_run_id":{"type":["string","null"],"format":"uuid"},"record":{"$ref":"#/components/schemas/Record"}}}}}}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Backend unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"getLawHistory"}},"/eu-ai-act-provisions":{"get":{"summary":"List EU AI Act provisions (article/paragraph/recital/annex text)","description":"Article/paragraph/recital/annex-level text of the EU AI Act (Regulation (EU) 2024/1689, CELEX 32024R1689) — the provision-level companion to /v1/laws, which carries the Act as one instrument-level row. Filters: provision_type ('paragraph'|'article_body'|'recital'|'annex'), article_number, celex (default 32024R1689), q (full-text search over the provision text). Pagination: limit (<=100, default 25), offset. Rows are ordered by anchor_id, the EUR-Lex structural id ('005.001' | 'rct.001' | 'anx.I').","parameters":[{"name":"provision_type","in":"query","schema":{"type":"string","enum":["paragraph","article_body","recital","annex"]}},{"name":"article_number","in":"query","schema":{"type":"integer"}},{"name":"celex","in":"query","schema":{"type":"string"}},{"name":"q","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","maximum":100,"default":25}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"A page of provisions.","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"celex":{"type":"string"},"provision_type":{"type":"string","enum":["paragraph","article_body","recital","annex"]},"chapter":{"type":"object","properties":{"number":{"type":["string","null"]},"title":{"type":["string","null"]}}},"section":{"type":"object","properties":{"number":{"type":["string","null"]},"title":{"type":["string","null"]}}},"article":{"type":"object","properties":{"number":{"type":["integer","null"]},"title":{"type":["string","null"]}}},"paragraph_number":{"type":["integer","null"]},"anchor_id":{"type":"string"},"text":{"type":"string"},"source_url":{"type":"string"},"extracted_at":{"type":"string","format":"date-time"},"extraction_method":{"type":"string"}}}},"meta":{"type":"object","properties":{"total":{"type":"integer"},"count":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"}}}}}}}},"400":{"description":"Invalid parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Backend unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"listEuAiActProvisions"}},"/changes":{"get":{"summary":"Unified changelog (poll for what changed since X)","description":"Time-ordered feed of every observed insert/update across the dataset, unioned from the append-only history of legal records and jurisdiction summaries. Poll with ?since=<meta.cursor>. TIER-GATING: Developer+ only — anonymous/Free callers get 403 tier_upgrade_required (the change feed is the paid differentiator). The lookback window is clamped per tier (Developer 30-day, Pro 90-day, Business/Enterprise full) — see meta.window.","parameters":[{"name":"since","in":"query","schema":{"type":"string","format":"date-time"},"description":"Only changes observed after this ISO timestamp (pass the previous response meta.cursor to poll)."},{"name":"scope","in":"query","schema":{"type":"string","enum":["state","federal","eu","global"]},"description":"Filter by scope."},{"name":"jurisdiction","in":"query","schema":{"type":"string"},"description":"Exact jurisdiction slug."},{"name":"entity","in":"query","schema":{"type":"string","enum":["law_record","jurisdiction"]},"description":"Restrict to one dataset (default: both)."},{"name":"significant","in":"query","schema":{"type":"boolean","default":false},"description":"Drop internal metadata-only updates (keeps inserts + real field changes)."},{"name":"order","in":"query","schema":{"type":"string","enum":["asc","desc"],"default":"desc"},"description":"Order by observed_at."},{"name":"limit","in":"query","schema":{"type":"integer","default":50,"maximum":100}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"A page of changes.","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Change"}},"meta":{"type":"object","properties":{"total":{"type":"integer"},"count":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"},"order":{"type":"string","enum":["asc","desc"]},"cursor":{"type":["string","null"],"format":"date-time","description":"Newest observed_at on this page; pass as ?since= to poll."},"window":{"type":"object","properties":{"tier":{"type":"string"},"lookback_days":{"type":["integer","null"],"description":"null = unbounded (paid tiers)."},"clamped":{"type":"boolean","description":"true when the requested since was older than the tier window."}}}}}}}}}},"400":{"description":"Invalid parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Backend unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"listChanges"}},"/feed":{"get":{"summary":"Lean stream of recent significant changes","description":"Convenience view over /changes with significant=true and no value diffs — the newest meaningful changes, human-scannable. TIER-GATING: same as /changes — Developer+ only (403 tier_upgrade_required for anonymous/Free).","parameters":[{"name":"since","in":"query","schema":{"type":"string","format":"date-time"},"description":"Only changes observed after this ISO timestamp (pass the previous response meta.cursor to poll)."},{"name":"scope","in":"query","schema":{"type":"string","enum":["state","federal","eu","global"]},"description":"Filter by scope."},{"name":"jurisdiction","in":"query","schema":{"type":"string"},"description":"Exact jurisdiction slug."},{"name":"entity","in":"query","schema":{"type":"string","enum":["law_record","jurisdiction"]},"description":"Restrict to one dataset (default: both)."},{"name":"limit","in":"query","schema":{"type":"integer","default":50,"maximum":100}}],"responses":{"200":{"description":"Recent significant changes."},"503":{"description":"Backend unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"getFeed"}},"/jurisdictions":{"get":{"summary":"List covered jurisdictions with record counts","parameters":[{"name":"scope","in":"query","schema":{"type":"string","enum":["state","federal","eu","global"]}}],"responses":{"200":{"description":"Jurisdiction index"}},"operationId":"listJurisdictions"}},"/search":{"get":{"summary":"Search records by title/summary text","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string"}},{"name":"scope","in":"query","schema":{"type":"string","enum":["state","federal","eu","global"]},"description":"Filter by scope."},{"name":"jurisdiction","in":"query","schema":{"type":"string"},"description":"Exact jurisdiction slug (e.g. colorado, eu, us-federal, canada)."},{"name":"status","in":"query","schema":{"type":"string"},"description":"Case-insensitive substring match on status."},{"name":"in_force","in":"query","schema":{"type":"boolean"},"description":"Filter by the in_force flag."},{"name":"updated_since","in":"query","schema":{"type":"string","format":"date-time"},"description":"Only records updated at/after this ISO timestamp."},{"name":"sort","in":"query","schema":{"type":"string","enum":["updated_at","record_date","title"],"default":"updated_at"}},{"name":"order","in":"query","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}},{"name":"limit","in":"query","schema":{"type":"integer","default":20,"maximum":100}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Ranked results"},"400":{"description":"Missing q","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"searchLaws"}},"/news":{"get":{"summary":"AI-law news headlines (filter, keyword, date range; newest-first)","description":"The audited AI-regulation news feed (headline + short excerpt + publisher + source URL — never full article text). Free/anon get a TASTE: fewer results, shallow pagination, only the newest headlines (a recency window) and the excerpt withheld. Developer+ gets the full archive, high volume and the excerpt. meta.window shows the tier recency floor; meta.gated + meta.upgrade show what was limited.","parameters":[{"name":"scope","in":"query","schema":{"type":"string","enum":["state","federal","eu","global"]},"description":"Filter by scope."},{"name":"jurisdiction","in":"query","schema":{"type":"string"},"description":"Exact jurisdiction slug (e.g. california, federal, eu, global)."},{"name":"q","in":"query","schema":{"type":"string"},"description":"Keyword substring search over the headline + excerpt."},{"name":"from","in":"query","schema":{"type":"string","format":"date"},"description":"Only headlines published on/after this date (YYYY-MM-DD). Free/anon are clamped to their recency window (see meta.window)."},{"name":"since","in":"query","schema":{"type":"string","format":"date"},"description":"Alias for `from` — poll for headlines since a date."},{"name":"to","in":"query","schema":{"type":"string","format":"date"},"description":"Only headlines published on/before this date (YYYY-MM-DD)."},{"name":"limit","in":"query","schema":{"type":"integer","default":20,"maximum":100},"description":"Free/anon are capped lower (a taste)."},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"A page of news headlines.","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"data":{"type":"array","items":{"$ref":"#/components/schemas/NewsItem"}},"meta":{"type":"object","properties":{"total":{"type":"integer"},"count":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"},"tier":{"type":"string"},"window":{"type":"object","description":"The recency gate applied to this response.","properties":{"tier":{"type":"string"},"recency_days":{"type":["integer","null"],"description":"null = full archive (Developer+)."},"floor":{"type":["string","null"],"format":"date","description":"Earliest published_date returned."},"clamped":{"type":"boolean","description":"true when the request reached older than the tier window."}}},"gated":{"type":"array","items":{"type":"string"},"description":"What was limited for this tier (e.g. excerpt, recency, limit)."},"upgrade":{"type":"string"}}}}}}}},"400":{"description":"Invalid parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Backend unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"listNews"}},"/enforcement":{"get":{"summary":"AI enforcement actions + litigation (agency actions and civil dockets; newest-first) — Enterprise only","description":"AI-related regulatory enforcement (FTC/DOJ/SEC/state AG actions, etc.) and civil litigation (federal court dockets), over the same six AET fields — agency, respondent, allegation, outcome, penalty, statutory basis — plus forum for litigation rows. `change_type` tells the two lanes apart. ONLY status published rows are ever returned: every pending or approved draft stays internal, so an empty data[] with meta.total: 0 is the expected response until a story is actually published. TIER-GATING: Enterprise-only. Anonymous, Free, and every self-serve paid tier (Developer $29 / Pro $99 / Business $299) get a hard 403 tier_upgrade_required — there is no teaser and no partial access below Enterprise. Same hard-gate pattern as /v1/changes, /v1/feed, and /v1/webhooks.","parameters":[{"name":"scope","in":"query","schema":{"type":"string","enum":["state","federal","eu","global"]},"description":"Filter by scope."},{"name":"jurisdiction","in":"query","schema":{"type":"string"},"description":"Exact jurisdiction slug."},{"name":"q","in":"query","schema":{"type":"string"},"description":"Keyword substring search over title + summary."},{"name":"agency","in":"query","schema":{"type":"string"},"description":"Substring match on the acting agency/regulator (e.g. FTC, DOJ, California Attorney General)."},{"name":"change_type","in":"query","schema":{"type":"string","enum":["enforcement","litigation"]},"description":"Restrict to one lane: enforcement (agency actions) or litigation (civil dockets). Default: both."},{"name":"date_from","in":"query","schema":{"type":"string","format":"date"},"description":"Only items recorded on/after this date (YYYY-MM-DD)."},{"name":"date_to","in":"query","schema":{"type":"string","format":"date"},"description":"Only items recorded on/before this date (YYYY-MM-DD)."},{"name":"limit","in":"query","schema":{"type":"integer","default":20,"maximum":100}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"A page of enforcement/litigation items (Enterprise callers only).","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"data":{"type":"array","items":{"$ref":"#/components/schemas/EnforcementItem"}},"meta":{"type":"object","properties":{"total":{"type":"integer"},"count":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"},"tier":{"type":"string"},"gated":{"type":"array","items":{"type":"string"},"description":"What was limited for this tier (e.g. limit, offset)."},"upgrade":{"type":"string"}}}}}}}},"400":{"description":"Invalid parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Below Enterprise tier — tier_upgrade_required.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Backend unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"listEnforcement"}},"/countries":{"get":{"summary":"National jurisdictions with binding-record counts and measured zero-result coverage","description":"data contains jurisdictions with binding AI-specific records. meta.screened_without_ai_instrument keeps tracked countries discoverable when the measured result is no binding AI-specific instrument; those entries do not inflate binding-law totals.","responses":{"200":{"description":"Country index plus measured no-binding-instrument coverage metadata."},"503":{"description":"Backend unavailable"}},"operationId":"listCountries"}},"/states":{"get":{"summary":"US state jurisdictions with record counts","responses":{"200":{"description":"State index"},"503":{"description":"Backend unavailable"}},"operationId":"listStates"}},"/categories":{"get":{"summary":"Dataset facets: record_type + scope distributions","responses":{"200":{"description":"Category facets ({ record_types[], scopes[] } of { value, count })."},"503":{"description":"Backend unavailable"}},"operationId":"listCategories"}},"/sectors":{"get":{"summary":"Sector index (valid slugs for /obligations, /penalties, /assess)","responses":{"200":{"description":"List of { slug, name, risk, description, has_federal_framework }."}},"operationId":"listSectors"}},"/sectors/{sector}":{"get":{"summary":"One sector: overview + derived obligations & penalties","description":"The free awareness OVERVIEW of a sector (name, risk, enforcement bodies, federal penalty structure) plus the DERIVED per-law obligations & penalties. The overview is open to every tier; the derived obligations/penalties are the interpreted layer — full for Pro+, a one-item preview (meta.preview=true) + upsell below. NOT legal advice.","parameters":[{"name":"sector","in":"path","required":true,"schema":{"type":"string"},"description":"A sector slug (see /sectors)."}],"responses":{"200":{"description":"The sector cross-section."},"404":{"description":"Unknown sector","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"getSector"}},"/deadlines":{"get":{"summary":"Upcoming AI-law effective / compliance dates (JSON or iCal)","description":"A forward-looking compliance calendar derived deterministically from the curated corpus — each entry carries the VERBATIM source deadline text + primary-source URL (no fabricated dates; a jurisdiction whose deadline text has no explicit date is only counted in meta.undated). Free for every tier. Pass ?format=ical (alias ics) for an RFC 5545 .ics you can subscribe to (webcal). The interpreted \"what must I do about each deadline\" layer is on /obligations + /assess.","parameters":[{"name":"scope","in":"query","schema":{"type":"string","enum":["state","federal","eu","global"]},"description":"Filter by scope."},{"name":"jurisdiction","in":"query","schema":{"type":"string"},"description":"Exact jurisdiction slug (e.g. california, eu-germany)."},{"name":"upcoming","in":"query","schema":{"type":"boolean","default":true},"description":"Only future dates (default). Set false (or all=true) to include past effective dates."},{"name":"format","in":"query","schema":{"type":"string","enum":["json","ical","ics"],"default":"json"},"description":"ical/ics returns a text/calendar .ics feed."}],"responses":{"200":{"description":"A page of deadlines (application/json) or an .ics feed (text/calendar)."},"400":{"description":"Invalid parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"listDeadlines"}},"/bills":{"get":{"summary":"Curated landmark-bill index","description":"The named, name-searchable AI laws (valid slugs for /bills/{slug}), from the primary-sourced landmark registry. Free.","responses":{"200":{"description":"List of { slug, bill_number, title, jurisdiction, status, deadline, official_url, verified_on }."}},"operationId":"listBills"}},"/bills/{slug}":{"get":{"summary":"One landmark bill: sources, citations, cross-links","description":"One curated bill — core fields, tiered source URLs, citations (identifier + audited alternate names), and cross-links. Where a matching legal_records row exists, the response binds the live change timeline (links.history → /laws/{id}/history). Primary-sourced; the DB binding is best-effort (a miss omits the link, never fabricates it).","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"},"description":"A bill slug (see /bills)."}],"responses":{"200":{"description":"The bill detail."},"404":{"description":"Unknown bill","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"getBill"}},"/laws/{id}/sources":{"get":{"summary":"Source URLs backing one record (tiered primary/secondary)","description":"A record's own official/.gov link plus the curated jurisdiction sources, each tiered primary/secondary. Basic tiers (anon/Free) get primary sources only; Developer+ get the full set incl. secondary/analysis links. Only real held URLs — never fabricated.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The record sources."},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Backend unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"listLawSources"}},"/laws/{id}/citations":{"get":{"summary":"Citation projection for one record","description":"A record's identifier, title, audited alternate names, and a formatting-convenience suggested citation over public metadata (labelled — never an official cite). Free at every tier.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The record citations."},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Backend unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"listLawCitations"}},"/auth/token":{"post":{"summary":"Self-serve: issue a FREE API token by email","description":"A conventional token endpoint over the same key store as POST /keys. Submit an email; get a free-tier token, emailed once (durable copy) and returned once here. Only ever mints a FREE token (no privilege escalation); the owner/HMAC secret is never exposed. Paid tiers are granted via Polar checkout (POST /checkout). Throttled per IP; one active token per email.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email"}}}}}},"responses":{"201":{"description":"Token issued (shown once)."},"400":{"description":"Invalid email","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A token already exists for this email","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"createAuthToken"}},"/obligations":{"get":{"summary":"Derived AI-law obligations for a jurisdiction / sector / use","description":"The interpreted \"what must I do\" layer — who must do what, by when, or owe what penalty — for the given context. Every obligation is grounded in a real law record + its primary source (no LLM). Provide at least a jurisdiction or a sector. NOT legal advice. Paid feature (Pro+); lower tiers receive a one-item preview (meta.preview=true) with an upgrade hint.","parameters":[{"name":"jurisdiction","in":"query","schema":{"type":"string"},"description":"A US state slug (e.g. california) OR a covered country slug (e.g. canada, eu-germany). See /jurisdictions."},{"name":"sector","in":"query","schema":{"type":"string"},"description":"A sector slug (see /sectors), e.g. healthcare, finance, hr-recruiting."},{"name":"use","in":"query","schema":{"type":"string"},"description":"Comma-separated AI uses: hiring, customer, content, analytics, product, other."},{"name":"decision_impact","in":"query","schema":{"type":"string","enum":["hiring_firing","credit_insurance","healthcare","housing","internal_only","not_sure"]},"description":"What the AI decides about people (escalates applicability)."}],"responses":{"200":{"description":"The derived obligations for the context.","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Obligation"}},"meta":{"type":"object","properties":{"tier":{"type":"string"},"total":{"type":"integer"},"count":{"type":"integer"},"no_law":{"type":"array","items":{"type":"object"},"description":"Jurisdictions with no applicable statute (an honest fact, not an obligation)."},"preview":{"type":"boolean","description":"true when the result was capped for an under-tier caller."},"required_tier":{"type":["string","null"]},"upgrade":{"type":["string","null"]},"disclaimer":{"type":"string"},"attribution":{"type":"string"}}}}}}}},"400":{"description":"Missing/invalid jurisdiction or sector","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"listObligations"}},"/penalties":{"get":{"summary":"Penalty & enforcement dataset for the applicable laws","description":"Per applicable law: the monetary/other penalty, enforcing body, citation, and primary source, plus a sector-level penalty-structure summary (full result only). Provide at least a jurisdiction or a sector. Paid feature (Developer+); lower tiers receive a one-item preview.","parameters":[{"name":"jurisdiction","in":"query","schema":{"type":"string"},"description":"A US state slug (e.g. california) OR a covered country slug (e.g. canada, eu-germany). See /jurisdictions."},{"name":"sector","in":"query","schema":{"type":"string"},"description":"A sector slug (see /sectors), e.g. healthcare, finance, hr-recruiting."}],"responses":{"200":{"description":"Penalties for the context.","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Penalty"}},"meta":{"type":"object","properties":{"tier":{"type":"string"},"total":{"type":"integer"},"count":{"type":"integer"},"sector_summary":{"type":["object","null"],"properties":{"sector":{"type":"string"},"penalty_structure":{"type":["string","null"]},"enforcement_bodies":{"type":"array","items":{"type":"string"}}}},"preview":{"type":"boolean"},"required_tier":{"type":["string","null"]},"upgrade":{"type":["string","null"]},"disclaimer":{"type":"string"},"attribution":{"type":"string"}}}}}}}},"400":{"description":"Missing/invalid jurisdiction or sector","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"listPenalties"}},"/assess":{"post":{"summary":"Company profile → applicable obligations + 1–10 risk score","description":"The compliance-report engine (deterministic, no LLM — cannot hallucinate) as an API. POST a business profile; get the applicable AI-law obligations plus a reproducible 1–10 risk score with a named factor breakdown. state + sector are required. Paid feature (Pro+); lower tiers receive a preview (risk band + counts + one sample obligation; factor breakdown withheld).","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["state","sector"],"properties":{"state":{"type":"string","description":"US state slug (e.g. california)."},"sector":{"type":"string","description":"Sector slug (see /sectors)."},"aiUse":{"type":"array","items":{"type":"string","enum":["hiring","customer","content","analytics","product","other"]}},"ai_decision_impact":{"type":"string","enum":["hiring_firing","credit_insurance","healthcare","housing","internal_only","not_sure"]},"countries":{"type":"array","items":{"type":"string"},"description":"EU/global country slugs also operated in/served."},"bias_audit":{"type":"string","enum":["recent","old","never","unknown"]},"ai_policy":{"type":"string","enum":["formal","informal","none","developing"]},"ai_source":{"type":"string","enum":["custom","third_party","embedded","combination","not_sure"]},"size":{"type":"string"}}}}}},"responses":{"200":{"description":"The assessment.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Assessment"}}}}}},"400":{"description":"Missing state/sector or malformed body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"createAssessment"}},"/report":{"post":{"summary":"On-demand AI compliance report (PDF or signed link) — the $79 report engine as an API","description":"Generate the personalized, source-grounded AI-law compliance report for a business profile — the SAME deterministic engine behind the $79 /compliance-report product (no LLM in the grounded path — it cannot invent a statute, deadline, or penalty). POST state + sector (+ optional AI-use profile). Default response is JSON: the risk assessment (1–10 score + obligations) plus a signed `report.download_url` for the rendered PDF. Pass `format:\"pdf\"` (or send `Accept: application/pdf`) to stream the PDF binary inline instead. Paid feature (Pro+) with a monthly report quota per tier (Pro 5/mo, Business 25/mo); when the quota is exhausted the endpoint returns 402 with an upgrade / single-report hint. Lower tiers receive a preview (risk band + counts + one sample obligation) with the PDF/download withheld behind an upgrade hint. Informational only — NOT legal advice.","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["state","sector"],"properties":{"state":{"type":"string","description":"US state slug (e.g. california). `jurisdiction` is accepted as an alias."},"jurisdiction":{"type":"string","description":"Alias for `state` (US state slug)."},"sector":{"type":"string","description":"Sector slug (see /sectors)."},"aiUse":{"type":"array","items":{"type":"string","enum":["hiring","customer","content","analytics","product","other"]}},"ai_decision_impact":{"type":"string","enum":["hiring_firing","credit_insurance","healthcare","housing","internal_only","not_sure"]},"countries":{"type":"array","items":{"type":"string"},"description":"EU/global country slugs also operated in/served."},"bias_audit":{"type":"string","enum":["recent","old","never","unknown"]},"ai_policy":{"type":"string","enum":["formal","informal","none","developing"]},"ai_source":{"type":"string","enum":["custom","third_party","embedded","combination","not_sure"]},"size":{"type":"string","description":"Company size band (e.g. startup, small, medium, enterprise)."},"company":{"type":"string","description":"Company name printed on the report (optional)."},"email":{"type":"string","format":"email","description":"Delivery email printed on the report footer (optional)."},"format":{"type":"string","enum":["json","pdf"],"description":"json (default) → summary + signed download link; pdf → stream the PDF binary."}}}}}},"responses":{"200":{"description":"The report — JSON (assessment + download link) or, with format=pdf/Accept: application/pdf, the PDF binary.","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"data":{"type":"object","properties":{"risk":{"$ref":"#/components/schemas/Risk"},"applicable_law_count":{"type":"integer"},"jurisdictions":{"type":"array","items":{"type":"string"}},"obligations":{"type":"array","items":{"$ref":"#/components/schemas/Obligation"}},"report":{"type":"object","properties":{"available":{"type":"boolean"},"format":{"type":"string","example":"pdf"},"filename":{"type":"string"},"download_url":{"type":"string","format":"uri","description":"Signed private link to fetch the rendered PDF."},"expires_in_days":{"type":"integer"},"required_tier":{"type":"string","description":"On a preview, the tier that unlocks the PDF."}}}}}}}},"application/pdf":{"schema":{"type":"string","format":"binary","description":"The rendered compliance-report PDF."}}}},"400":{"description":"Missing state/sector or malformed body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"createReport"}},"/keys":{"post":{"summary":"Self-serve: issue a FREE API key by email","description":"Submit an email to mint a free-tier key. The plaintext key is emailed to that address (your durable copy — find it again there anytime) AND returned once in this response. We never store the plaintext server-side. One active free key per email; abusive request rates are throttled per IP.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email","description":"Where the key is delivered."}}}}}},"responses":{"201":{"description":"Key issued (plaintext shown once).","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"key":{"type":"string","example":"alt_free_…","description":"Plaintext key — shown once, not recoverable."},"key_prefix":{"type":"string","example":"alt_free_ab12"},"id":{"type":"string","format":"uuid"},"tier":{"type":"string","example":"free"},"email":{"type":"string"},"email_delivery":{"type":"object","properties":{"delivered":{"type":"boolean"}}}}}}}},"400":{"description":"Invalid email","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A key already exists for this email","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many key requests","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Key store not available","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"createApiKey"}},"/me":{"get":{"summary":"Your account: tier, limits & live usage (requires an API key)","description":"Returns the presenting key's own account — tier, effective rate/quota limits, live durable usage (requests used today + this month, from the api_usage counter), remaining, reset times, and the capabilities the tier unlocks. The key IS the credential; no separate login. Powers the self-serve dashboard at /developers/dashboard. This call itself counts as one request.","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"responses":{"200":{"description":"Your account snapshot.","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"data":{"type":"object","properties":{"key_prefix":{"type":"string","example":"alt_free_ab12"},"tier":{"type":"string","example":"free"},"owner":{"type":["string","null"],"description":"Your account email, masked."},"revoked":{"type":"boolean"},"created_at":{"type":["string","null"],"format":"date-time"},"last_used_at":{"type":["string","null"],"format":"date-time"},"limits":{"type":"object","properties":{"per_min":{"type":"integer"},"per_day":{"type":"integer"},"per_month":{"type":["integer","null"],"description":"null = unbounded (enterprise)."}}},"usage":{"type":"object","properties":{"tracking":{"type":"boolean","description":"false until the api_usage migration is applied; per-period counts are then null (not fabricated)."},"day":{"type":"object","properties":{"used":{"type":["integer","null"]},"limit":{"type":["integer","null"]},"remaining":{"type":["integer","null"]},"resets_in_seconds":{"type":"integer"}}},"month":{"type":"object","properties":{"used":{"type":["integer","null"]},"limit":{"type":["integer","null"]},"remaining":{"type":["integer","null"]},"resets_in_seconds":{"type":"integer"}}}}},"capabilities":{"type":"object","description":"What this tier unlocks (see tier-gating notes on each endpoint).","properties":{"list_max":{"type":"integer"},"full_fields":{"type":"boolean"},"advanced_filters":{"type":"boolean"},"changes_window_days":{"description":"null = feature off, \"full\", or a day count."},"history_window_days":{"description":"null = feature off, \"full\", or a day count."},"webhooks":{"description":"Allowance (integer) or \"unlimited\"."},"bulk_export":{"type":"boolean"}}}}}}}}}},"401":{"description":"API key required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key revoked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"getMe"},"delete":{"summary":"Revoke your own key (requires an API key)","description":"Self-service revoke of the presenting key. Irreversible — the key can no longer authenticate afterwards. Create a new key to keep using the API.","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"responses":{"200":{"description":"Key revoked.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"key_prefix":{"type":"string"},"revoked":{"type":"boolean"}}}}}}}},"401":{"description":"API key required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"deleteMe"}},"/webhooks":{"post":{"summary":"Subscribe to change events (Pro+ · requires an API key)","description":"Create a webhook. When a matching legal record change is observed, an HMAC-SHA256-signed POST is delivered to target_url. The signing_secret is returned ONCE in this response. Verify each delivery (see x-webhooks). TIER-GATING: Pro+ only (Free/Developer allowance = 0 → 403 tier_upgrade_required). Per-key subscription cap: Pro 3, Business 25, Enterprise unlimited.","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["target_url"],"properties":{"target_url":{"type":"string","description":"Public HTTPS endpoint."},"events":{"type":"array","items":{"type":"string","enum":["law.created","law.updated"]},"description":"Default: law.created, law.updated."},"scope":{"type":"string","enum":["state","federal","eu","global"],"description":"Optional filter."},"jurisdiction":{"type":"string","description":"Optional exact-slug filter."}}}}}},"responses":{"201":{"description":"Created (includes signing_secret, shown once).","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Webhook"}}}}}},"400":{"description":"Invalid target_url or events","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"API key required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Per-key webhook limit reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Webhooks not enabled yet","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"createWebhook"},"get":{"summary":"List this key's webhooks","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"responses":{"200":{"description":"The key’s subscriptions.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Webhook"}}}}}}},"401":{"description":"API key required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"listWebhooks"}},"/us-law":{"get":{"summary":"List + filter the general US law corpus","description":"Statutes, regulations and federal executive instruments at title/chapter/part level, each with its official citation, status, effective date, the official government source URL, and a many-to-many classification into 33 branches and 227 subcategories. Records LINK to the official text; they do not reproduce it.\n\nMETERED ON RECORDS SERVED, not just on requests. A request cap stops a fast client; a record cap stops a patient one, and only the second is priced against the size of the corpus. Every response carries `meta.record_budget` with what is left in the day and 30-day windows; exhausting it returns 429 `record_budget_exceeded` (distinct from 429 `rate_limited`).\n\nPRODUCT SCOPE: this endpoint belongs to the US Law Platform. A key licensed only for AI Law Tracker (`product: ai_law`) is NOT refused here — it is served at the PUBLIC (keyless) capability level, the same few records any anonymous caller gets. The response headers say so explicitly: `X-ALT-Product` (what your key holds), `X-ALT-Product-Surface` (`us_law`) and `X-ALT-Product-Scope` (`in_product` | `out_of_product`). Your request rate and daily/monthly quota are NEVER degraded — those are metered per key wherever you call. What degrades is capability: page size, pagination depth, field envelope and the record budget.","parameters":[{"name":"branch","in":"query","schema":{"type":"string"},"description":"PRIMARY branch id from /us-law/taxonomy. Matches only records whose primary classification is this branch - narrower than branch_any, and usually not what you want for a coverage question."},{"name":"branch_any","in":"query","schema":{"type":"string"},"description":"Branch id matched against ANY assignment, primary or secondary. Records are genuinely multi-branch (HIPAA is health law AND privacy law), so this is the complete answer: branch=health_law matches 1,942 records, branch_any=health_law matches 2,852."},{"name":"domain","in":"query","schema":{"type":"string"},"description":"Subcategory id matched against ANY assignment, primary or secondary."},{"name":"domain_primary","in":"query","schema":{"type":"string"},"description":"Subcategory id, primary classification only."},{"name":"jurisdiction","in":"query","schema":{"type":"string"},"description":"Jurisdiction slug, e.g. california. Comma-separated for several: california,new-york."},{"name":"jurisdiction_level","in":"query","schema":{"type":"string"},"description":"federal and/or state, comma-separated."},{"name":"instrument_type","in":"query","schema":{"type":"string"},"description":"Document KIND: statute, regulation, executive_order, proclamation, agency_guidance, constitution, presidential_memorandum... Comma-separated for several. SCARCE types (executive orders, proclamations, agency guidance and other presidential instruments - about 3% of the corpus) are content-gated below the top tiers: the response is a small real SAMPLE, reported as meta.sampled with meta.sampled_reason \"scarce_instrument_type\", never a silent truncation. Listing a scarce type alongside a common one still arms that gate."},{"name":"status","in":"query","schema":{"type":"string"},"description":"in_force, superseded, repealed, enacted, unknown. Comma-separated for several."},{"name":"in_force","in":"query","schema":{"type":"boolean"},"description":"Operative law only (or only non-operative)."},{"name":"is_binding","in":"query","schema":{"type":"boolean"},"description":"Whether the instrument carries the force of law. false selects the guidance-type corpus."},{"name":"effective_from","in":"query","schema":{"type":"string","format":"date"},"description":"Effective on or after this date (YYYY-MM-DD)."},{"name":"effective_to","in":"query","schema":{"type":"string","format":"date"}},{"name":"enacted_from","in":"query","schema":{"type":"string","format":"date"}},{"name":"enacted_to","in":"query","schema":{"type":"string","format":"date"}},{"name":"repealed_from","in":"query","schema":{"type":"string","format":"date"}},{"name":"repealed_to","in":"query","schema":{"type":"string","format":"date"}},{"name":"retrieved_since","in":"query","schema":{"type":"string","format":"date-time"},"description":"Records WE re-fetched on or after this time. This is our freshness stamp, NOT a claim that the law changed then - for that see /us-law/records/{record_uid}/history."},{"name":"verified_since","in":"query","schema":{"type":"string","format":"date-time"},"description":"Records WE re-verified on or after this time. Same caveat as retrieved_since."},{"name":"citation","in":"query","schema":{"type":"string"},"description":"Exact citation match, case-insensitive - e.g. 45 CFR Part 164. Use citation_prefix to widen."},{"name":"citation_prefix","in":"query","schema":{"type":"string"},"description":"Citation starts-with, e.g. 45 CFR for everything under that part."},{"name":"identifier","in":"query","schema":{"type":"string"},"description":"Exact identifier match, e.g. Pub. L. 117-58."},{"name":"record_uid","in":"query","schema":{"type":"string"},"description":"Fetch specific records by uid; comma-separated, up to 100. The batch form of /us-law/records/{record_uid}."},{"name":"q","in":"query","schema":{"type":"string"},"description":"Substring match on title / short title / citation. For ranked full text over the summary as well, use /us-law/search."},{"name":"sort","in":"query","schema":{"type":"string","enum":["effective_date","enacted_date","repealed_date","retrieved_at","last_verified_at","title","citation"],"default":"effective_date"}},{"name":"order","in":"query","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50,"maximum":100},"description":"Clamped to your tier cap; the clamp is reported in `meta.gated`."},{"name":"offset","in":"query","schema":{"type":"integer","default":0},"description":"Clamped to your tier pagination depth."}],"responses":{"200":{"description":"Matching records, plus the record-budget state.","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"data":{"type":"array","items":{"$ref":"#/components/schemas/UsLawRecord"}},"meta":{"type":"object","properties":{"total":{"type":"integer"},"count":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"},"tier":{"type":"string","description":"The tier you were SERVED at — `anon` when out of product."},"fields":{"type":"string","enum":["basic","full"]},"gated":{"type":"array","items":{"type":"string"},"description":"Which parameters your tier clamped."},"sampled":{"type":"boolean","description":"True when the CONTENT gate fired (a scarce instrument type)."},"sampled_reason":{"type":["string","null"]},"record_budget":{"type":"object","properties":{"enforced":{"type":"boolean"},"records_remaining_today":{"type":["integer","null"]},"records_remaining_period":{"type":["integer","null"]}}},"upgrade":{"type":["string","null"]}}},"attribution":{"type":"string"}}}}}},"429":{"description":"Rate limited, or `record_budget_exceeded`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Corpus backend unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"listUsLaw"}},"/us-law/search":{"get":{"summary":"Full-text, citation and presidential-number search over the US law corpus","description":"Websearch-syntax full text (\"quoted phrases\", -exclusion) with a citation-substring fallback; the strategy that answered is reported in `meta.strategy`. A query that is a presidential document number (\"EO 14110\", \"Proclamation 10925\") is resolved against the INDEXED number column only — a miss returns nothing with an explanatory `meta.notice`, never a guessed match, because misidentifying a presidential document is worse than returning nothing.\n\nMETERED ON RECORDS SERVED, not just on requests. A request cap stops a fast client; a record cap stops a patient one, and only the second is priced against the size of the corpus. Every response carries `meta.record_budget` with what is left in the day and 30-day windows; exhausting it returns 429 `record_budget_exceeded` (distinct from 429 `rate_limited`).\n\nPRODUCT SCOPE: this endpoint belongs to the US Law Platform. A key licensed only for AI Law Tracker (`product: ai_law`) is NOT refused here — it is served at the PUBLIC (keyless) capability level, the same few records any anonymous caller gets. The response headers say so explicitly: `X-ALT-Product` (what your key holds), `X-ALT-Product-Surface` (`us_law`) and `X-ALT-Product-Scope` (`in_product` | `out_of_product`). Your request rate and daily/monthly quota are NEVER degraded — those are metered per key wherever you call. What degrades is capability: page size, pagination depth, field envelope and the record budget.","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","maxLength":200}},{"name":"branch","in":"query","schema":{"type":"string"},"description":"PRIMARY branch id from /us-law/taxonomy. Matches only records whose primary classification is this branch - narrower than branch_any, and usually not what you want for a coverage question."},{"name":"branch_any","in":"query","schema":{"type":"string"},"description":"Branch id matched against ANY assignment, primary or secondary. Records are genuinely multi-branch (HIPAA is health law AND privacy law), so this is the complete answer: branch=health_law matches 1,942 records, branch_any=health_law matches 2,852."},{"name":"domain","in":"query","schema":{"type":"string"},"description":"Subcategory id matched against ANY assignment, primary or secondary."},{"name":"domain_primary","in":"query","schema":{"type":"string"},"description":"Subcategory id, primary classification only."},{"name":"jurisdiction","in":"query","schema":{"type":"string"},"description":"Jurisdiction slug, e.g. california. Comma-separated for several: california,new-york."},{"name":"jurisdiction_level","in":"query","schema":{"type":"string"},"description":"federal and/or state, comma-separated."},{"name":"instrument_type","in":"query","schema":{"type":"string"},"description":"Document KIND: statute, regulation, executive_order, proclamation, agency_guidance, constitution, presidential_memorandum... Comma-separated for several. SCARCE types (executive orders, proclamations, agency guidance and other presidential instruments - about 3% of the corpus) are content-gated below the top tiers: the response is a small real SAMPLE, reported as meta.sampled with meta.sampled_reason \"scarce_instrument_type\", never a silent truncation. Listing a scarce type alongside a common one still arms that gate."},{"name":"status","in":"query","schema":{"type":"string"},"description":"in_force, superseded, repealed, enacted, unknown. Comma-separated for several."},{"name":"in_force","in":"query","schema":{"type":"boolean"},"description":"Operative law only (or only non-operative)."},{"name":"is_binding","in":"query","schema":{"type":"boolean"},"description":"Whether the instrument carries the force of law. false selects the guidance-type corpus."},{"name":"effective_from","in":"query","schema":{"type":"string","format":"date"},"description":"Effective on or after this date (YYYY-MM-DD)."},{"name":"effective_to","in":"query","schema":{"type":"string","format":"date"}},{"name":"enacted_from","in":"query","schema":{"type":"string","format":"date"}},{"name":"enacted_to","in":"query","schema":{"type":"string","format":"date"}},{"name":"repealed_from","in":"query","schema":{"type":"string","format":"date"}},{"name":"repealed_to","in":"query","schema":{"type":"string","format":"date"}},{"name":"retrieved_since","in":"query","schema":{"type":"string","format":"date-time"},"description":"Records WE re-fetched on or after this time. This is our freshness stamp, NOT a claim that the law changed then - for that see /us-law/records/{record_uid}/history."},{"name":"verified_since","in":"query","schema":{"type":"string","format":"date-time"},"description":"Records WE re-verified on or after this time. Same caveat as retrieved_since."},{"name":"citation","in":"query","schema":{"type":"string"},"description":"Exact citation match, case-insensitive - e.g. 45 CFR Part 164. Use citation_prefix to widen."},{"name":"citation_prefix","in":"query","schema":{"type":"string"},"description":"Citation starts-with, e.g. 45 CFR for everything under that part."},{"name":"identifier","in":"query","schema":{"type":"string"},"description":"Exact identifier match, e.g. Pub. L. 117-58."},{"name":"record_uid","in":"query","schema":{"type":"string"},"description":"Fetch specific records by uid; comma-separated, up to 100. The batch form of /us-law/records/{record_uid}."},{"name":"sort","in":"query","schema":{"type":"string","enum":["relevance","effective_date","enacted_date","title"],"default":"relevance"}},{"name":"order","in":"query","schema":{"type":"string","enum":["asc","desc"],"default":"desc"},"description":"Ignored when sort=relevance."},{"name":"limit","in":"query","schema":{"type":"integer","default":20,"maximum":100}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Search results.","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"data":{"type":"array","items":{"$ref":"#/components/schemas/UsLawRecord"}},"meta":{"type":"object"},"attribution":{"type":"string"}}}}}},"400":{"description":"Missing or invalid q.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited, or `record_budget_exceeded`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"searchUsLaw"}},"/us-law/taxonomy":{"get":{"summary":"The classification tree + corpus health (OPEN — no key, not metered)","description":"The 33 branches and 227 subcategories the corpus is classified into, with descriptions, so a consumer can build ?branch= / ?domain= filters without guessing. Deliberately OPEN to everyone and NOT metered: it DESCRIBES the corpus, it is not the corpus, and a classification a customer cannot inspect is a black box.\n\nAlso returns `meta.health` — `records_total`, `records_placeholder` (records still in the `other_unclassified` bucket) and `avg_domains_per_record`. That placeholder count is published rather than hidden: it is the honest measure of how far the classification actually reaches, and it is the number every public coverage claim on the site is checked against.","responses":{"200":{"description":"Branches, subcategories and corpus health.","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"data":{"type":"object","properties":{"branches":{"type":"array","items":{"type":"object"}}}},"meta":{"type":"object","properties":{"branches":{"type":"integer"},"subcategories":{"type":"integer"},"health":{"type":"object"}}}}}}}}},"operationId":"getUsLawTaxonomy"}},"/us-law/jurisdictions":{"get":{"summary":"Per-jurisdiction coverage rollup (OPEN — no key, not metered)","description":"One row per jurisdiction: record counts by instrument type, the code edition held, and the verification stamps. Aggregated in the database — this endpoint must never be answered by paging the corpus, since inviting a caller to walk 31,800 records just to count them is exactly the bulk copy the record budget exists to prevent. Open for the same reason as /us-law/taxonomy: coverage is how you evaluate the dataset before paying for it.","parameters":[{"name":"jurisdiction_level","in":"query","schema":{"type":"string","enum":["federal","state"]}}],"responses":{"200":{"description":"Coverage rollup.","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"data":{"type":"array","items":{"type":"object"}}}}}}}},"operationId":"listUsLawJurisdictions"}},"/us-law/opinions":{"get":{"deprecated":true,"summary":"RETIRED — US court opinions (410 corpus_retired)","description":"⛔ RETIRED 2026-08-22 — THIS ENDPOINT NOW RETURNS 410 `corpus_retired`.\n\nThe US court-opinion corpus (988,554 records) is out of scope for this API and is no longer served. Opinion identifications remain available at https://www.courtlistener.com. No other /v1 surface is affected, and nothing is charged against your record budget for this path — the refusal is returned before the tier gate and before any metering.\n\nThe original description is kept verbatim below, as the record of what this endpoint did. A restore therefore reinstates a KNOWN contract rather than a reconstructed one.\n\n─────────────────────────────────────────────────────────────\n\nPublished opinions filed 2015-01-01 onward from federal appellate courts and state supreme/appellate courts. Each record IDENTIFIES a decision — case name, court, filing date, docket number, reporter citation, and how many later opinions cite it — and links to the full decision at `absolute_url`.\n\nTHERE IS NO OPINION TEXT AND NO HOLDING IN THIS CORPUS. `q` is a websearch full-text match over the CASE NAME only (quoted phrases and -exclusion work: `\"Trump v. Cook\"`, `monsanto -durnell`), and every response that ran one says so in `meta.search_field`. Do not describe this endpoint as searching the text of decisions.\n\nMETERED ON RECORDS SERVED, on the SAME budget as /v1/us-law rather than a second one. That is deliberate: a separate allowance would have widened every existing key the day this dataset shipped. Every response carries `meta.record_budget`; exhausting it returns 429 `record_budget_exceeded`.\n\nTWO LIMITS COME FROM THE SIZE OF THE TABLE, NOT FROM YOUR TIER, and they apply identically at every tier including Enterprise. (1) `meta.total` is the PLANNER’S ESTIMATE above 1,000 rows — it measured 53% low on one full-text query — so it is always accompanied by `meta.total_is_estimate`; pass `count=exact` for the true number, at up to ~3.3 s. (2) `sort=citation_count` and `cited_min` have no index behind them and are refused with 400 unless the query already carries a narrowing filter; unfiltered, they are cancelled by the database statement timeout.\n\nPRODUCT SCOPE: this endpoint belongs to the US Law Platform. A key licensed only for AI Law Tracker is served here at the public (keyless) level, reported in `X-ALT-Product-Scope` — not refused.","parameters":[{"name":"court","in":"query","schema":{"type":"string"},"description":"Court slug, comma-separated for several (max 25), e.g. scotus,ca9. The valid values are published by /us-law/courts, which needs no key."},{"name":"court_level","in":"query","schema":{"type":"string"},"description":"federal_appellate, state_supreme and/or state_appellate, comma-separated."},{"name":"jurisdiction_level","in":"query","schema":{"type":"string"},"description":"federal and/or state, comma-separated. `state` covers both state_supreme and state_appellate. Combined with court_level it means the INTERSECTION; a contradictory pair returns an empty page rather than a silently dropped filter."},{"name":"cluster_id","in":"query","schema":{"type":"string"},"description":"Fetch specific opinions by cluster id; comma-separated, up to 100. The batch form of /us-law/opinions/{cluster_id}."},{"name":"filed_from","in":"query","schema":{"type":"string","format":"date"},"description":"Filed on or after this date (YYYY-MM-DD)."},{"name":"filed_to","in":"query","schema":{"type":"string","format":"date"},"description":"Filed on or before this date (YYYY-MM-DD)."},{"name":"q","in":"query","schema":{"type":"string","maxLength":200},"description":"Websearch full-text over the CASE NAME. Quoted phrases and -exclusion supported. It does NOT search opinion text — this corpus holds none."},{"name":"citation","in":"query","schema":{"type":"string","maxLength":120},"description":"Exact reporter citation, e.g. 2022 OK 38. CASE-SENSITIVE against the canonical citation: the index that makes this a 212 ms lookup instead of a 6.3 s scan cannot answer a case-insensitive match."},{"name":"citation_prefix","in":"query","schema":{"type":"string","maxLength":120},"description":"Citation starts-with, e.g. \"2022 OK\" for that year and reporter. The deliberate widening of `citation`, asked for by name so you know which you got."},{"name":"cited_min","in":"query","schema":{"type":"integer","minimum":0},"description":"Only opinions cited by at least this many later opinions. Requires at least one narrowing filter (see the endpoint description)."},{"name":"sort","in":"query","schema":{"type":"string","enum":["date_filed","citation_count"],"default":"date_filed"},"description":"citation_count requires at least one narrowing filter. case_name sorting is not offered — no index, and nobody pages a million captions alphabetically."},{"name":"order","in":"query","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}},{"name":"count","in":"query","schema":{"type":"string","enum":["estimated","exact"],"default":"estimated"},"description":"exact costs up to ~3.3 s and needs a key (any key, including a free one) — an unauthenticated request that can pin a database core for 3 s is a self-inflicted denial-of-service. A keyless caller silently gets `estimated` and sees `count` in meta.gated."},{"name":"limit","in":"query","schema":{"type":"integer","default":25,"maximum":100},"description":"Clamped to your tier cap; the clamp is reported in meta.gated."},{"name":"offset","in":"query","schema":{"type":"integer","default":0},"description":"Clamped to your tier pagination depth."}],"responses":{"200":{"description":"Matching opinions, plus the record-budget state.","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"data":{"type":"array","items":{"$ref":"#/components/schemas/CourtOpinion"}},"meta":{"type":"object","properties":{"total":{"type":"integer","description":"READ total_is_estimate BEFORE quoting this number."},"total_is_estimate":{"type":"boolean","description":"true when `total` is the query planner’s estimate rather than a count. Set whenever the result exceeds 1,000 rows and `count=exact` was not requested."},"count":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"},"tier":{"type":"string","description":"The tier you were SERVED at — `anon` when out of product."},"fields":{"type":"string","enum":["basic","full"]},"gated":{"type":"array","items":{"type":"string"},"description":"Which parameters your tier clamped."},"search_field":{"type":["string","null"],"description":"Present when `q` ran. Always `case_name`."},"corpus":{"type":"object","description":"`full_text: false` plus where the text actually is."},"record_budget":{"type":"object","properties":{"enforced":{"type":"boolean"},"records_remaining_today":{"type":["integer","null"]},"records_remaining_period":{"type":["integer","null"]}}},"disclaimer":{"type":"string"},"upgrade":{"type":["string","null"]}}},"attribution":{"type":"string"}}}}}},"400":{"description":"invalid_request — an unparseable filter, or an unindexed sort/filter without a narrowing filter.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"tier_upgrade_required.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited, or `record_budget_exceeded`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Corpus backend unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"listCourtOpinions"}},"/us-law/opinions/{cluster_id}":{"get":{"deprecated":true,"summary":"RETIRED — one court opinion (410 corpus_retired)","description":"⛔ RETIRED 2026-08-22 — THIS ENDPOINT NOW RETURNS 410 `corpus_retired`. The US court-opinion corpus is no longer served; see https://www.courtlistener.com. Nothing is charged against your record budget for this path. Original description kept verbatim below.\n\n─────────────────────────────────────────────────────────────\n\nThe complete record for one CourtListener cluster id — the `cluster_id` field of any list result. Provenance (absolute_url, source_authority, bulk_edition, retrieved_at) is never withheld at any tier: the link to the decision is how you check our work, and withholding it to build an upsell would mean selling an unverifiable claim.\n\nThe record identifies the decision; it does not contain it. `meta.corpus.full_text_at` points at the opinion itself.\n\nTo fetch many at once use /us-law/opinions?cluster_id=1,2,3 (up to 100).","parameters":[{"name":"cluster_id","in":"path","required":true,"schema":{"type":"integer"},"description":"CourtListener cluster id."}],"responses":{"200":{"description":"The opinion.","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"data":{"$ref":"#/components/schemas/CourtOpinion"},"meta":{"type":"object"},"attribution":{"type":"string"}}}}}},"400":{"description":"cluster_id is not a positive integer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"tier_upgrade_required.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No opinion with that cluster_id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited, or record_budget_exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"getCourtOpinion"}},"/us-law/courts":{"get":{"deprecated":true,"summary":"RETIRED — court-opinion coverage (410 corpus_retired)","description":"⛔ RETIRED 2026-08-22 — THIS ENDPOINT NOW RETURNS 410 `corpus_retired`.\n\nIt retired WITH the corpus it measured. The court REGISTRY (293 courts) still exists, but a coverage table reporting zero opinions for every court would read as a fact about those courts rather than about us — which is the exact misreading this endpoint was built to prevent. Original description kept verbatim below.\n\n─────────────────────────────────────────────────────────────\n\nOne row per REGISTERED court: how many opinions we hold, how many carry a reporter citation, and the earliest and latest filing dates. It is both the coverage table and the lookup the `court=` filter needs — a filter whose valid values are undiscoverable is not a filter, which is why this is open.\n\n293 courts are registered and 146 hold opinions, so 147 rows come back with `opinions: 0`. They are not hidden: omitting them would overstate coverage. Read the date spans too — scotus shows 37,792 rows because CourtListener publishes orders and summary dispositions as clusters, and those thin out sharply after 2020.\n\nTHE COUNTS ARE MATERIALISED AND THE RESPONSE SAYS WHEN. Computed live the aggregate takes 2.8 s against 988,554 rows, which on a keyless endpoint would be a self-inflicted denial-of-service. So every response carries `meta.counts_refreshed_at`, and `meta.counts_stale` goes true once the rollup is more than 48 hours old (the refresh runs daily). The numbers are never presented as current — they are presented with the timestamp that says how current they are.","parameters":[{"name":"court_level","in":"query","schema":{"type":"string","enum":["federal_appellate","state_supreme","state_appellate"]}},{"name":"jurisdiction_level","in":"query","schema":{"type":"string","enum":["federal","state"]}},{"name":"with_opinions","in":"query","schema":{"type":"boolean"},"description":"true = only courts we hold opinions for; false = only the registered courts we hold nothing for."}],"responses":{"200":{"description":"Coverage rollup.","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"data":{"type":"array","items":{"type":"object"}},"meta":{"type":"object","properties":{"count":{"type":"integer"},"totals":{"type":"object"},"counts_refreshed_at":{"type":["string","null"],"format":"date-time"},"counts_stale":{"type":"boolean"},"corpus":{"type":"object"}}}}}}}},"400":{"description":"invalid_request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Corpus backend unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"listCourts"}},"/us-law/export":{"get":{"summary":"Bulk export manifest — NOT self-serve, licensed tiers only","description":"Plans a bulk export of any slice /us-law can filter and returns a MANIFEST: the exact row count, what it will cost against your record allowance, and one SIGNED, short-lived download URL per part (NDJSON | CSV | JSON). The bytes come from the signed part URLs; this call serves no records and charges nothing.\n\nNOT SOLD SELF-SERVE AT ANY PRICE. Taking the whole corpus as a file is a licensing conversation, not a checkout — every self-serve plan keeps full API access to the same data and pages it instead. A below-tier caller gets 403 `tier_upgrade_required` naming the tier it opens at.\n\nPart URLs carry a signed token rather than your API key, so a link can be handed to a loader without handing over your credential; every download is still metered against the key that created it.\n\nPRODUCT SCOPE: this endpoint belongs to the US Law Platform. A key licensed only for AI Law Tracker (`product: ai_law`) is NOT refused here — it is served at the PUBLIC (keyless) capability level, the same few records any anonymous caller gets. The response headers say so explicitly: `X-ALT-Product` (what your key holds), `X-ALT-Product-Surface` (`us_law`) and `X-ALT-Product-Scope` (`in_product` | `out_of_product`). Your request rate and daily/monthly quota are NEVER degraded — those are metered per key wherever you call. What degrades is capability: page size, pagination depth, field envelope and the record budget.","parameters":[{"name":"format","in":"query","schema":{"type":"string","enum":["ndjson","csv","json"],"default":"ndjson"}},{"name":"fields","in":"query","schema":{"type":"string","enum":["full","basic"],"default":"full"},"description":"A tier restricted to the trimmed envelope cannot obtain the full one by asking; `basic` can only be chosen downward."},{"name":"jurisdiction","in":"query","schema":{"type":"string"}},{"name":"instrument_type","in":"query","schema":{"type":"string"}},{"name":"branch","in":"query","schema":{"type":"string"}},{"name":"domain","in":"query","schema":{"type":"string"}},{"name":"in_force","in":"query","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Export manifest with signed part URLs.","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"export":{"type":"object","properties":{"job_id":{"type":"string"},"format":{"type":"string"},"content_type":{"type":"string"},"fields":{"type":"string"},"records":{"type":"integer"},"corpus_records":{"type":"integer"},"parts":{"type":"integer"},"part_size":{"type":"integer"},"expires_at":{"type":"string","format":"date-time"},"record_cost":{"type":"integer","description":"What downloading every part will charge."},"export_max_rows":{"type":"integer"}}},"parts":{"type":"array","items":{"type":"object","properties":{"part":{"type":"integer"},"records":{"type":"integer"},"url":{"type":"string"},"expires_at":{"type":"string","format":"date-time"}}}},"attribution":{"type":"string"}}}}}},"400":{"description":"`export_too_large` — narrow the filter, or an invalid format.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`tier_upgrade_required` — bulk export is not included on this tier.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"`record_budget_insufficient` — refused up front rather than failing part-way and leaving a truncated file.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`export_unavailable` — download signing not configured.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"createUsLawExport"}},"/us-law/records/{record_uid}":{"get":{"summary":"One US-law record, in full","description":"The complete record for one record_uid, including provenance (official_url, source_authority, full_text_url, full_text_sha256, retrieved_at, last_verified_at). Provenance is never withheld at any tier: on a legal surface the citation and the link to the government source are how you check our work, and withholding them to create an upsell would mean selling an unverifiable claim.\n\nTo fetch many at once use /us-law?record_uid=uid1,uid2 (up to 100).","parameters":[{"name":"record_uid","in":"path","required":true,"schema":{"type":"string","maxLength":200}}],"responses":{"200":{"description":"The record.","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"data":{"$ref":"#/components/schemas/UsLawRecord"},"meta":{"type":"object"},"attribution":{"type":"string"}}}}}},"403":{"description":"tier_upgrade_required.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No record with that record_uid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited, or record_budget_exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"getUsLawRecord"}},"/us-law/records/{record_uid}/history":{"get":{"summary":"What changed on this record (capture began 2026-08-20)","description":"The recorded change log for one record: one entry per changed FIELD, newest first, across status, dates, citation, identifier, title, instrument type, classification, source URLs and summary.\n\nREAD meta.capture_started_at BEFORE READING data. Nothing recorded a record-level diff on this corpus before 2026-08-20, and there is deliberately NO BACKFILL, because a backfill would have to invent what the record used to say. An empty result therefore means \"we did not observe a change since capture began\" and says so in meta.notice — it is NEVER a claim that the law has not changed.\n\nTIER: sampled below Pro (the most recent few entries, with the true total stated), full at Pro and above on either product ladder.","parameters":[{"name":"record_uid","in":"path","required":true,"schema":{"type":"string","maxLength":200}}],"responses":{"200":{"description":"The change log, possibly empty.","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"data":{"type":"array","items":{"type":"object","properties":{"record_uid":{"type":"string"},"changed_at":{"type":"string","format":"date-time"},"field":{"type":"string"},"old_value":{"type":["string","null"]},"new_value":{"type":["string","null"]}}}},"meta":{"type":"object","properties":{"total":{"type":"integer"},"count":{"type":"integer"},"access":{"type":"string","enum":["sample","full"]},"sampled":{"type":"boolean"},"capture_started_at":{"type":"string","format":"date"},"notice":{"type":["string","null"]},"tracked_fields":{"type":"array","items":{"type":"string"}}}},"attribution":{"type":"string"}}}}}},"403":{"description":"tier_upgrade_required.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No record with that record_uid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited, or record_budget_exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"getUsLawRecordHistory"}},"/us-law/compare":{"get":{"summary":"Cross-jurisdiction comparison — what does every state say about X?","description":"One row per jurisdiction holding law in a branch or subcategory, with record counts, how many are in force, the split by instrument type, the latest effective date and when we last verified it. This is the answer you would otherwise have to page the entire 31,867-record corpus to assemble.\n\nCOUNTING. `records` counts EVERY domain assignment, primary or secondary; `records_primary` counts only records whose PRIMARY classification is this branch. Both are reported because they differ a lot (health_law: 2,852 vs 1,942) and a comparison built on primary assignments alone would report that a state has no privacy law when its privacy statutes happen to be filed under consumer protection first.\n\nTIER. Ordinary single-field filtering on /us-law is open at every tier including keyless — discovery is never the thing that is metered. This is the assembled answer, so below Pro it returns a real 5-jurisdiction SAMPLE with the true totals stated in meta, and the full table at Pro and above on either product ladder.","parameters":[{"name":"branch","in":"query","schema":{"type":"string"},"description":"Branch id from /us-law/taxonomy. Either branch or domain is required."},{"name":"domain","in":"query","schema":{"type":"string"},"description":"Subcategory id, for a narrower comparison. Mutually exclusive with branch."},{"name":"jurisdiction_level","in":"query","schema":{"type":"string","enum":["federal","state"]}},{"name":"in_force_only","in":"query","schema":{"type":"boolean"},"description":"Only jurisdictions holding at least one operative record."}],"responses":{"200":{"description":"One row per jurisdiction, most records first.","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"data":{"type":"array","items":{"type":"object","properties":{"jurisdiction_level":{"type":"string"},"jurisdiction_slug":{"type":"string"},"jurisdiction_name":{"type":"string"},"branch_id":{"type":"string"},"branch_label":{"type":"string"},"records":{"type":"integer"},"records_primary":{"type":"integer"},"in_force":{"type":"integer"},"statutes":{"type":"integer"},"regulations":{"type":"integer"},"other_instruments":{"type":"integer"},"latest_effective_date":{"type":["string","null"],"format":"date"},"last_verified_at":{"type":["string","null"],"format":"date-time"}}}},"meta":{"type":"object","properties":{"axis":{"type":"string","enum":["branch","domain"]},"id":{"type":"string"},"jurisdictions_total":{"type":"integer"},"jurisdictions_returned":{"type":"integer"},"records_total":{"type":"integer"},"records_total_primary_only":{"type":"integer"},"access":{"type":"string","enum":["sample","full"]},"sampled":{"type":"boolean"},"notice":{"type":["string","null"]},"upgrade":{"type":["string","null"]}}},"attribution":{"type":"string"}}}}}},"400":{"description":"Neither branch nor domain given, or both.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"tier_upgrade_required.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited, or record_budget_exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"compareUsLawJurisdictions"}},"/us-law/export/download":{"get":{"summary":"Download one part of a bulk export","description":"Streams a single part of an export planned by GET /us-law/export. Authenticated by the SIGNED TOKEN in the manifest, not by an API key — so a part URL can be handed to a loader without handing over your credential. Tokens are short-lived and each download is still metered against the key that created the manifest. Any API key sent alongside is ignored: authority here comes from the token.","parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string"},"description":"The signed token from a manifest part URL."}],"responses":{"200":{"description":"The part, as NDJSON, CSV or JSON per the manifest.","content":{"application/x-ndjson":{"schema":{"type":"string"}},"text/csv":{"schema":{"type":"string"}}}},"400":{"description":"invalid_token — missing, unreadable, or failed signature verification.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"token_expired — request a fresh manifest.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"record_budget_exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"downloadUsLawExportPart"}},"/disclosures":{"get":{"summary":"SEC EDGAR AI risk disclosures (ENTERPRISE ONLY)","description":"AI-related risk-factor disclosures extracted from SEC EDGAR filings. ENTERPRISE-ONLY: there is no teaser and no partial access on any self-serve tier — a below-tier caller gets 403 tier_upgrade_required, never a trimmed response. Documented here so the capability is discoverable; the gate is in the route, not in this spec.","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"q","in":"query","schema":{"type":"string"}},{"name":"company","in":"query","schema":{"type":"string"}},{"name":"cik","in":"query","schema":{"type":"string"},"description":"Numeric CIK."},{"name":"form","in":"query","schema":{"type":"string"},"description":"Filing form type, e.g. 10-K."},{"name":"date_from","in":"query","schema":{"type":"string","format":"date"}},{"name":"date_to","in":"query","schema":{"type":"string","format":"date"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50,"maximum":100}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Matching disclosures.","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"data":{"type":"array","items":{"type":"object"}},"meta":{"type":"object"},"attribution":{"type":"string"}}}}}},"400":{"description":"Invalid parameter.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"tier_upgrade_required — Enterprise only.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"listDisclosures"}},"/enforcement/matters":{"get":{"summary":"Enforcement + litigation matters — list, filter and search","description":"Regulatory enforcement actions and private litigation involving AI, at MATTER level: forum, agency, parties, status, relief and the statutes invoked. One row per dispute, not per press release — an agency action with a complaint, a settlement and a final order is three rows on /v1/enforcement and ONE matter here.\n\nOPEN AT EVERY TIER since 2026-08-22. It used to answer a hard 403 below Enterprise, which made the dataset invisible and therefore unsellable. What is metered instead is DEPTH: the assembled chain on /enforcement/matters/{matter_uid} — parties, relief amounts, the event timeline and the cited statutes — is sampled below the paid step. A record budget would have been theatre on a 91-row registry.\n\nA SECOND GATE THAT IS NOT ABOUT MONEY: 30 of 91 matters are duplicates of another row or still carry an untranslated CAPTION, and are withheld from every caller not licensed for the raw registry — `meta.registry.withheld_not_publish_ready` reports how many THIS query hid. A further 6 ARE published with one descriptive field nulled and named in `unavailable_fields`; withholding a $1.4bn settlement because its forum_name has an untranslated clause would have been a worse answer. See /enforcement/coverage for the full breakdown.\n\nREAD `verification` BEFORE QUOTING ANYTHING. Every matter currently held is `single_source`.\n\nAn empty data[] means no matter matched — never that an agency has taken no action. /enforcement/sources says which of the 254 monitored sources are actually answering.","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"jurisdiction","in":"query","schema":{"type":"string"},"description":"Jurisdiction slug, comma-separated for several."},{"name":"jurisdiction_level","in":"query","schema":{"type":"string"},"description":"federal, state and/or multistate, comma-separated."},{"name":"forum_type","in":"query","schema":{"type":"string"},"description":"Comma-separated. Values from /enforcement/categories."},{"name":"matter_type","in":"query","schema":{"type":"string"},"description":"enforcement_action, civil_litigation, guidance_document, investigation, inquiry_6b. Comma-separated."},{"name":"matter_status","in":"query","schema":{"type":"string"},"description":"Comma-separated. Values from /enforcement/categories."},{"name":"agency","in":"query","schema":{"type":"string"},"description":"Agency code, e.g. FTC, DOJ, SEC, Texas AG. Comma-separated for several; a single value may contain spaces, parentheses and accents. NOTE: an agency_code that itself contains a COMMA cannot be matched here, because the comma is the multi-value delimiter — three live values are in that state. Use q= for those; it searches agency_code as a substring."},{"name":"ai_role","in":"query","schema":{"type":"string"},"description":"Comma-separated. Several roles mean the matter carries ALL of them."},{"name":"domain","in":"query","schema":{"type":"string"},"description":"Primary subject domain id, comma-separated."},{"name":"verification","in":"query","schema":{"type":"string"},"description":"Corroboration level. Currently every held matter is single_source."},{"name":"date_from","in":"query","schema":{"type":"string","format":"date"},"description":"Bounds filed_date, which is null on 71 of 91 matters — a date filter therefore EXCLUDES the undated majority."},{"name":"date_to","in":"query","schema":{"type":"string","format":"date"}},{"name":"q","in":"query","schema":{"type":"string","maxLength":200},"description":"Substring over caption, summary and agency."},{"name":"tier","in":"query","schema":{"type":"string"},"description":"A (enforcement decision) or B (enforcement-adjacent signal). Comma-separated. Matters recorded before 2026-08-22 carry no tier and are returned by neither value."},{"name":"sort","in":"query","schema":{"type":"string","enum":["filed_date","decided_date","first_seen_at","last_verified_at","closed_date"],"default":"filed_date"}},{"name":"order","in":"query","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50,"maximum":100},"description":"Clamped to your tier cap; the clamp is reported in meta.gated."},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Matching matters, plus what the tier and the readiness gate withheld.","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"data":{"type":"array","items":{"$ref":"#/components/schemas/EnforcementMatter"}},"meta":{"type":"object","properties":{"total":{"type":"integer","description":"EXACT, never an estimate — the registry is 91 rows."},"total_is_estimate":{"type":"boolean","description":"Always false here. Present so a consumer need not remember which endpoints can promise an exact count."},"count":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"},"tier":{"type":"string"},"gated":{"type":"array","items":{"type":"string"}},"registry":{"type":"object","properties":{"raw_registry_access":{"type":"boolean"},"withheld_not_publish_ready":{"type":"integer"},"withheld_reason":{"type":["string","null"]},"chains":{"type":"string","enum":["sample","full"]},"chains_open_at":{"type":["string","null"]}}},"disclaimer":{"type":"string"}}},"attribution":{"type":"string"}}}}}},"400":{"description":"Invalid parameter.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Enforcement backend unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"listEnforcementMatters"}},"/enforcement/matters/{matter_uid}":{"get":{"summary":"One enforcement matter, with its chain","description":"The matter plus its EVENTS (timeline), PARTIES, RELIEF, statutory CITATIONS and the SOURCE DOCUMENTS each claim traces to. This is the dossier the product is sold on.\n\nTHE CHAIN IS WHAT IS METERED. Below the paid step each chain is a 2-row sample and `data.chain_totals` reports the true size of every one of them — never an empty wall, and never a sample you cannot tell is a sample. Listing and searching matters stays fully open.\n\nFIELDS THAT LOOK LIKE HEDGES AND ARE THE PRODUCT: `events[].is_date_estimated` (the source gave a year, not a day), `verification`, `laws[].link_status` (`unlinked` = we hold the citation verbatim but have not resolved it — a confidently wrong citation is worse), and `duplicate_of`.\n\nPARTIES ARE REDACTED BY POLICY, in the database, not here: 97 of 235 party rows publish and the rest are withheld — named private individuals and minors by default. See the pii_class and redaction_policy vocabularies on /enforcement/categories.\n\nA 404 is returned both for a matter that does not exist AND for one withheld pending review, on purpose: distinguishable codes would turn the readiness gate into an enumeration oracle.","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"matter_uid","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9-]{3,120}$"},"description":"An opaque stable key, not a description — read caption for the matter name."}],"responses":{"200":{"description":"The matter, with parties, events, relief, cited statutes and source documents.","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"data":{"allOf":[{"$ref":"#/components/schemas/EnforcementMatter"},{"type":"object","properties":{"events":{"type":"array","items":{"type":"object"}},"parties":{"type":"array","items":{"type":"object"}},"relief":{"type":"array","items":{"type":"object"}},"laws":{"type":"array","items":{"type":"object"}},"sources":{"type":"array","items":{"type":"object"}},"chain_totals":{"type":"object","description":"The TRUE size of every chain, whether or not the rows above were sampled."},"chains_sampled":{"type":"boolean"}}}]},"meta":{"type":"object"},"attribution":{"type":"string"}}}}}},"400":{"description":"matter_uid is not a slug.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No PUBLISHED matter with that matter_uid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"getEnforcementMatter"}},"/enforcement/sources":{"get":{"summary":"What we monitor, and whether it is answering (OPEN — no key, not metered)","description":"The 254 official sources behind the enforcement layer — agency newsrooms, AG press feeds, court dockets — with the last successful read, the fault state and whether each is stale against its own silence budget.\n\nIT PUBLISHES THE BAD NEWS. 132 of 254 are enabled and 123 are stale (measured 2026-08-22). Those go out as they are, on the same argument /v1/us-law/jurisdictions publishes its OLDEST verification stamp: an enforcement product whose coverage table only showed the healthy sources would be advertising, not data.\n\nFAULTS ARE CLASSIFIED, NOT QUOTED. `last_fault_reason_code` is a closed vocabulary (blocked, unauthorized, not_found, timeout, adapter_missing, egress_unavailable, other) with a one-line label; the raw internal fault text never leaves the server.\n\nRead this before concluding anything from an empty /enforcement/matters result: a stale source is a gap in OUR monitoring, never a statement that an authority has taken no action.","parameters":[{"name":"jurisdiction_level","in":"query","schema":{"type":"string","enum":["federal","state","multistate","territory","local","international"]}},{"name":"is_enabled","in":"query","schema":{"type":"boolean"}},{"name":"is_stale","in":"query","schema":{"type":"boolean"},"description":"true = sources not read inside their own max_silence_hours."}],"responses":{"200":{"description":"Source health.","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"data":{"type":"array","items":{"type":"object"}},"meta":{"type":"object","properties":{"count":{"type":"integer"},"totals":{"type":"object"},"faults_by_reason":{"type":"object"},"fault_reason_labels":{"type":"object"},"newest_success_at":{"type":["string","null"]},"oldest_success_at":{"type":["string","null"]}}}}}}}},"400":{"description":"Invalid parameter.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Enforcement backend unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"listEnforcementSources"}},"/enforcement/categories":{"get":{"summary":"The enforcement controlled vocabularies (OPEN — no key, not metered)","description":"Thirteen closed vocabularies, 104 terms: matter_type, matter_status, forum_type, party_role, party_kind, relief_type, event_type, ai_role, law_relation, verification, jurisdiction_level, pii_class and redaction_policy. `code` is the API value; `label` and `description` are for display.\n\nThese are the exact values the /enforcement/matters filters accept, which is why the endpoint is open: a documented filter whose valid values are undiscoverable is not a filter.\n\nTWO OF THEM DESCRIBE WHAT WE DO NOT PUBLISH. pii_class and redaction_policy are the terms behind the party gate that withholds 138 of 235 party rows. Publishing the vocabulary is how that policy becomes checkable rather than merely asserted.","parameters":[{"name":"kind","in":"query","schema":{"type":"string","pattern":"^[a-z_]{2,40}$"},"description":"Return just one vocabulary."}],"responses":{"200":{"description":"The vocabularies.","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"data":{"type":"object"},"meta":{"type":"object"}}}}}},"404":{"description":"No vocabulary by that name.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"listEnforcementCategories"}},"/enforcement/coverage":{"get":{"summary":"How big the enforcement registry actually is (OPEN — no key, not metered)","description":"Counts the registry rather than serving it: matters held, matters publishable, and how many are withheld as duplicates or for untranslated internal language — plus breakdowns by matter type, jurisdiction level and agency, and the de-duplicated monetary relief total.\n\nTHE WITHHELD COUNTS ARE THE POINT. A caller who sees `total: 61` on /enforcement/matters would reasonably conclude the registry IS 61 matters. It is 91: 11 duplicates and 21 untranslated captions (overlapping) leave 30 withheld, and 6 of the published ones carry a nulled field. This is the same commitment /v1/us-law/taxonomy makes by publishing `records_placeholder`.\n\nThe relief total is computed over PUBLISHABLE, de-duplicated matters only and says so in `relief.basis`. Summed naively across all 91 rows it is wrong by at least the $3.2M DOJ/OpenAI settlement, which is present twice under two matter_uids.","responses":{"200":{"description":"Registry shape.","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"data":{"type":"object","properties":{"matters":{"type":"object"},"by_matter_type":{"type":"object"},"by_jurisdiction_level":{"type":"object"},"by_agency":{"type":"object"},"relief":{"type":"object"}}},"meta":{"type":"object"}}}}}},"503":{"description":"Enforcement backend unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"getEnforcementCoverage"}},"/webhooks/{id}":{"get":{"summary":"Get one subscription","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The subscription","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Webhook"}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"getWebhook"},"delete":{"summary":"Unsubscribe","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Deleted"},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"operationId":"deleteWebhook"}}},"x-news":{"description":"GET /v1/news copyright + tier gate. We serve ONLY the headline, a short excerpt, the publisher name and the source URL — never full article text. Free = a taste (newest headlines only, low volume, excerpt withheld); Developer+ = the full archive, high volume + the excerpt.","recency_window_days":{"anonymous":14,"free_key":45,"developer":null,"pro":null,"business":null},"excerpt":"Developer+ only (withheld on the free/anon taste)."},"x-webhooks":{"description":"Outbound change notifications. Subscribe with POST /v1/webhooks; deliveries are POSTed to target_url with an HMAC-SHA256 signature.","events":["law.created","law.updated"],"payload":{"$ref":"#/components/schemas/WebhookPayload"},"headers":{"X-ALT-Signature":"sha256=<hex HMAC-SHA256 of `${timestamp}.${rawBody}` under your signing_secret>","X-ALT-Timestamp":"Unix seconds; folded into the signed content (reject if skew is large).","X-ALT-Event":"law.created | law.updated","X-ALT-Delivery":"Delivery uuid — use as an idempotency key.","X-ALT-Webhook-Id":"The subscription uuid."},"delivery":"At-least-once. Up to 6 attempts with exponential backoff; 10 consecutive failures auto-disable the webhook. De-duplicate on X-ALT-Delivery / event_id.","verify_example_node":"const crypto = require('crypto');\nfunction verify(req, secret) {\n  const ts = req.headers['x-alt-timestamp'];\n  const sig = (req.headers['x-alt-signature'] || '').replace(/^sha256=/, '');\n  const expected = crypto.createHmac('sha256', secret).update(`${ts}.${req.rawBody}`).digest('hex');\n  const a = Buffer.from(sig), b = Buffer.from(expected);\n  return a.length === b.length && crypto.timingSafeEqual(a, b);\n}"},"x-rate-limits":{"description":"A KEY IS REQUIRED on every data endpoint (since 2026-08-20); a keyless request answers 401 key_required. Free keys are self-serve and need no card — POST /v1/keys, or https://ai-law-tracker.com/developers#get-key. Open without a key: /v1/health, /v1/openapi.json, /v1/keys, /v1/checkout, /v1/auth, /v1/us-law/taxonomy and /v1/us-law/jurisdictions. Per-key limits are enforced by the gate; every response carries X-RateLimit-Limit/Remaining/Reset and a 429 includes Retry-After. Per-key overrides (rate_limit/daily_limit/monthly_limit) take precedence over the tier defaults — GET /v1/me always reports YOUR effective numbers.","keyless":"not served — 401 key_required (see the open-endpoint list above)","free_key":"60 req/min, 300 req/day, 9000 req/month","starter":"150 req/min, 5000 req/day, 150000 req/month","pro":"300 req/min, 10000 req/day, 300000 req/month","business":"1000 req/min, 15000 req/day, 450000 req/month","oem":"1500 req/min, 20000 req/day, 600000 req/month","enterprise":"2000 req/min, 2000000 req/day (custom above this — contact sales)","us_law_platform":{"us_free":"US Law — Free — 60 req/min, 500 req/day, 750 records/day","us_entry":"US Law — Starter — 100 req/min, 5000 req/day, 2500 records/day","us_solo":"US Law — Solo — 150 req/min, 10000 req/day, 2800 records/day","us_starter":"US Law — Pro — 300 req/min, 25000 req/day, 3100 records/day","us_pro":"US Law — Business — 600 req/min, 100000 req/day, 75000 records/day","us_enterprise":"US Law — Enterprise — 2000 req/min, 500000 req/day, 250000 records/day"}},"x-pricing":{"description":"Two product lines over two corpora. AI Law Tracker sells the AI-specific corpus (/laws, /search, /news, the interpreted obligations layer); the US Law Platform sells the general US-law corpus (/us-law) and is metered on RECORDS SERVED rather than requests. A key is licensed for one line or the other (or both). See https://ai-law-tracker.com/pricing.","ai_law":[{"id":"free","name":"Free","price_usd_month":0,"self_serve":false,"note":"Demo & prototyping"},{"id":"starter","name":"Starter","price_usd_month":49,"self_serve":true,"note":"Ship your first integration"},{"id":"pro","name":"Pro","price_usd_month":99,"self_serve":true,"note":"AI products & vendors"},{"id":"business","name":"Business","price_usd_month":299,"self_serve":true,"note":"Vendors, firms & gov-affairs"},{"id":"oem","name":"OEM / White-label","price_usd_month":499,"self_serve":false,"note":"Embed & redistribute the data"},{"id":"enterprise","name":"Enterprise","price_usd_month":null,"self_serve":false,"note":"Big 4, insurers & RegTech platforms"}],"us_law":[{"id":"us_free","name":"US Law — Free","price_usd_month":0,"records_per_day":750,"self_serve":false,"note":"Evaluate the corpus before you commit"},{"id":"us_entry","name":"US Law — Starter","price_usd_month":99,"records_per_day":2500,"self_serve":true,"note":"Evaluate in production, on one project"},{"id":"us_solo","name":"US Law — Solo","price_usd_month":199,"records_per_day":2800,"self_serve":true,"note":"One developer, one application"},{"id":"us_starter","name":"US Law — Pro","price_usd_month":499,"records_per_day":3100,"self_serve":true,"note":"A team building on the corpus, over the API"},{"id":"us_pro","name":"US Law — Business","price_usd_month":1500,"records_per_day":75000,"self_serve":false,"note":"Pipelines & bulk export, under licence"},{"id":"us_enterprise","name":"US Law — Enterprise","price_usd_month":null,"records_per_day":250000,"self_serve":false,"note":"Platforms, insurers & redistribution"}],"retired":[{"id":"developer","name":"Developer","price_usd_month":29,"note":"Withdrawn from sale 2026-08-19. Existing keys keep every limit and capability they had; no new checkout is accepted. Replaced by Starter ($49)."}]},"x-attribution":"Data by AI Law Tracker (CC BY 4.0) — https://ai-law-tracker.com"}