{"openapi":"3.1.0","info":{"title":"LakeHoldings Address Intelligence API","description":"Lake Holdings Address Intelligence exposes a consistent API over the live\n`lakeHoldings.addressmonger` corpus. The application reads source address records through a\ndedicated MongoDB principal that is verified at startup to hold read-only privileges.\n\n**Core capabilities**\n\n* Validate and enrich a structured U.S. address with DPV, RDI, vacancy, CMRA, carrier route,\n  congressional district, county, timezone, precision, and coordinate fields.\n* Suggest complete authoritative addresses as a user types.\n* Find nearby known addresses from latitude and longitude.\n* Search allowlisted address fields through approved indexes with signed cursor pagination.\n\n**Authentication and limits**\n\nSend a scoped API key as `Authorization: Bearer <key>` or `X-API-Key: <key>`. Each key has\nexplicit scopes, a per-minute rate limit, a persistent daily quota, optional expiration, and\nimmediate owner-controlled revocation. Invite-approved developers create keys in the portal.\n\n**Safety boundary**\n\nThe public API never accepts raw MongoDB operators, collection names, sort expressions, or\nindex hints. Query shapes, projections, limits, timeouts, and indexes are selected by the\napplication. Portal identity and audit data live in a separate writable PostgreSQL database;\nthe source address corpus is never updated by this service.","version":"1.0.0"},"paths":{"/healthz":{"get":{"tags":["health"],"summary":"Liveness probe","description":"Liveness. Deliberately checks nothing external.\n\nA 200 here means the process is running and can serve HTTP. That is exactly the\nquestion an orchestrator's restart decision should depend on.","operationId":"healthz_healthz_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}}},"security":[]}},"/readyz":{"get":{"tags":["health"],"summary":"Readiness probe","description":"Readiness. Authenticated because it discloses internal component state.","operationId":"readyz_readyz_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessResponse"}}}}}}},"/metrics":{"get":{"tags":["health"],"summary":"Prometheus metrics","description":"Prometheus scrape endpoint.\n\nAuthenticated because the metric labels disclose release ids, batch volumes and\nmatch-quality distributions. The existing Prometheus on VM104 scrapes it with a\ndedicated token holding only ``metrics:read``.","operationId":"prometheus_metrics_metrics_get","responses":{"200":{"description":"Successful Response"}}}},"/v1/normalize":{"post":{"tags":["addresses"],"summary":"Normalize an address to USPS Publication 28 form","description":"Pure normalization: no reference-data lookup, so no release dependency.\n\nKept separate from validation because it is genuinely useful on its own — callers\nstandardising a CRM export do not need, and should not pay for, candidate retrieval.","operationId":"normalize_endpoint_v1_normalize_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NormalizeRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Normalize Endpoint V1 Normalize Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/validate":{"post":{"tags":["addresses"],"summary":"Validate an address against the authoritative DPV corpus","description":"Return source-backed validity and deliverability without mutating the corpus.","operationId":"validate_endpoint_v1_validate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MongoValidateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/resolve":{"post":{"tags":["addresses"],"summary":"Resolve one location string to the AGB field set","description":"Take one unstructured location string and return parsed components, geocode,\nmetro and graded existence evidence.\n\nThe evidence block is the point of this endpoint. A bare coordinate cannot distinguish a\nconfirmed rooftop from a position interpolated along a street segment, and those two\nanswers warrant very different downstream treatment.","operationId":"resolve_endpoint_v1_resolve_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResolveRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgbLocation"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/resolve/batch":{"post":{"tags":["addresses"],"summary":"Resolve up to 100 location strings in one request","description":"Same contract as ``/v1/resolve``, for many strings at once.\n\nResults are returned in request order and every input yields exactly one result, so a\ncaller can join by position. A row that fails to parse returns an ``error`` object in\nplace of the fields rather than being omitted: dropping it would silently shift every\nlater row onto the wrong input, which is the failure mode that makes positional joins\ndangerous.","operationId":"resolve_batch_endpoint_v1_resolve_batch_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResolveBatchRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgbBatchResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/candidates":{"post":{"tags":["addresses"],"summary":"Return ranked candidate matches","description":"Ranked candidates with per-candidate score explanations.\n\nExists so that a human reviewer resolving an ambiguous address can see the competing\noptions and why each scored as it did, rather than being handed a bare verdict.","operationId":"candidates_endpoint_v1_candidates_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CandidatesRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Candidates Endpoint V1 Candidates Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/geocode":{"post":{"tags":["addresses"],"summary":"Geocode an address","operationId":"geocode_endpoint_v1_geocode_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GeocodeRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Geocode Endpoint V1 Geocode Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/reverse-geocode":{"post":{"tags":["addresses"],"summary":"Find addresses near a coordinate","operationId":"reverse_geocode_endpoint_v1_reverse_geocode_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReverseGeocodeRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Reverse Geocode Endpoint V1 Reverse Geocode Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["authoritative-addresses"],"summary":"Find authoritative addresses near a coordinate","operationId":"reverse_geocode_endpoint_v1_reverse_geocode_get","parameters":[{"name":"lat","in":"query","required":true,"schema":{"type":"number","maximum":90,"minimum":-90,"title":"Lat"}},{"name":"lon","in":"query","required":true,"schema":{"type":"number","maximum":180,"minimum":-180,"title":"Lon"}},{"name":"radius_meters","in":"query","required":false,"schema":{"type":"integer","maximum":5000,"minimum":10,"default":250,"title":"Radius Meters"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":10,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReverseGeocodeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/dedupe":{"post":{"tags":["addresses"],"summary":"Group addresses that refer to the same location","description":"Group by canonical key.\n\nGrouping uses the canonical key rather than fuzzy comparison between inputs, which\nmakes the result transitive and order-independent. Pairwise fuzzy clustering is not:\nA~B and B~C without A~C produces groups that depend on input order, which is\nunacceptable for a deduplication result a customer will act on.","operationId":"dedupe_endpoint_v1_dedupe_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DedupeRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Dedupe Endpoint V1 Dedupe Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/suggest":{"get":{"tags":["authoritative-addresses"],"summary":"Suggest authoritative addresses as a user types","operationId":"suggest_endpoint_v1_suggest_get","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":3,"maxLength":120,"title":"Q"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":20,"minimum":1,"default":10,"title":"Limit"}},{"name":"zip","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^\\d{5}$"},{"type":"null"}],"title":"Zip"}},{"name":"city","in":"query","required":false,"schema":{"anyOf":[{"type":"string","minLength":1,"maxLength":100},{"type":"null"}],"title":"City"}},{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^[A-Za-z]{2}$"},{"type":"null"}],"title":"State"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuggestResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/search":{"post":{"tags":["authoritative-addresses"],"summary":"Search authoritative address fields through approved indexes","operationId":"search_endpoint_v1_search_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddressSearchRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddressSearchResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/portal/api/register":{"post":{"tags":["developer-portal"],"summary":"Create a pending account with a single-use invitation","operationId":"register_endpoint_portal_api_register_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[]}},"/portal/api/login":{"post":{"tags":["developer-portal"],"summary":"Create a secure browser session","operationId":"login_endpoint_portal_api_login_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[]}},"/portal/api/logout":{"post":{"tags":["developer-portal"],"summary":"Revoke the current browser session","operationId":"logout_endpoint_portal_api_logout_post","responses":{"204":{"description":"Successful Response"}},"security":[{"PortalSession":[]}]}},"/portal/api/me":{"get":{"tags":["developer-portal"],"summary":"Return the signed-in account","operationId":"me_endpoint_portal_api_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortalUserResponse"}}}}},"security":[{"PortalSession":[]}]}},"/portal/api/key-requests":{"get":{"tags":["developer-portal"],"summary":"List the signed-in user's API-key requests","operationId":"list_key_requests_endpoint_portal_api_key_requests_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyRequestListResponse"}}}}},"security":[{"PortalSession":[]}]},"post":{"tags":["developer-portal"],"summary":"Submit an API-key request for administrator approval","operationId":"submit_key_request_endpoint_portal_api_key_requests_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyRequestCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyRequestSummary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"PortalSession":[]}]}},"/portal/api/key-requests/{key_request_id}/activate":{"post":{"tags":["developer-portal"],"summary":"Activate an approved API-key request and reveal its secret once","operationId":"activate_key_request_endpoint_portal_api_key_requests__key_request_id__activate_post","parameters":[{"name":"key_request_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Key Request Id"}}],"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"PortalSession":[]}]}},"/portal/api/key-requests/{key_request_id}":{"delete":{"tags":["developer-portal"],"summary":"Cancel one pending API-key request","operationId":"cancel_key_request_endpoint_portal_api_key_requests__key_request_id__delete","parameters":[{"name":"key_request_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Key Request Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"PortalSession":[]}]}},"/portal/api/keys":{"get":{"tags":["developer-portal"],"summary":"List API-key metadata without revealing secrets","operationId":"list_keys_endpoint_portal_api_keys_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyListResponse"}}}}},"security":[{"PortalSession":[]}]}},"/portal/api/keys/{kid}":{"delete":{"tags":["developer-portal"],"summary":"Revoke one owned API key","operationId":"revoke_key_endpoint_portal_api_keys__kid__delete","parameters":[{"name":"kid","in":"path","required":true,"schema":{"type":"string","title":"Kid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyRevokeRequest"}}}},"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"PortalSession":[]}]}},"/portal/api/admin/invitations":{"post":{"tags":["developer-portal"],"summary":"Create a single-use developer invitation","operationId":"create_invitation_endpoint_portal_api_admin_invitations_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationCreateRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationCreateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"PortalSession":[]}]}},"/portal/api/admin/key-requests/pending":{"get":{"tags":["developer-portal"],"summary":"List pending API-key requests for administrator review","operationId":"pending_key_requests_endpoint_portal_api_admin_key_requests_pending_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyRequestListResponse"}}}}},"security":[{"PortalSession":[]}]}},"/portal/api/admin/key-requests/{key_request_id}/review":{"post":{"tags":["developer-portal"],"summary":"Approve or reject one pending API-key request","operationId":"review_key_request_endpoint_portal_api_admin_key_requests__key_request_id__review_post","parameters":[{"name":"key_request_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Key Request Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyRequestReview"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyRequestSummary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"PortalSession":[]}]}},"/portal/api/admin/users/pending":{"get":{"tags":["developer-portal"],"summary":"List accounts awaiting administrator approval","operationId":"pending_users_endpoint_portal_api_admin_users_pending_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/PortalUserResponse"},"type":"array","title":"Response Pending Users Endpoint Portal Api Admin Users Pending Get"}}}}},"security":[{"PortalSession":[]}]}},"/portal/api/admin/users/{user_id}/approval":{"post":{"tags":["developer-portal"],"summary":"Approve or reject a pending account","operationId":"approve_user_endpoint_portal_api_admin_users__user_id__approval_post","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserApprovalRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortalUserResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"PortalSession":[]}]}},"/v1/batches":{"post":{"tags":["batches"],"summary":"Submit a batch job","description":"Queue a batch job and return immediately.\n\nReturns 202 rather than 200 because the work has been accepted, not performed. The\ncaller polls the status endpoint. Synchronous processing is not offered at all: a\nmulti-million-row job cannot fit inside an HTTP request, and pretending otherwise\nwould produce timeouts that look like failures while the work actually continues.","operationId":"submit_batch_v1_batches_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchSubmitRequest"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Submit Batch V1 Batches Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["batches"],"summary":"List batches","operationId":"list_batches_v1_batches_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":25,"title":"Limit"}},{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Batches V1 Batches Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/batches/{batch_id}":{"get":{"tags":["batches"],"summary":"Get batch status","operationId":"get_batch_v1_batches__batch_id__get","parameters":[{"name":"batch_id","in":"path","required":true,"schema":{"type":"string","title":"Batch Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Batch V1 Batches  Batch Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/batches/{batch_id}/cancel":{"post":{"tags":["batches"],"summary":"Cancel a batch","description":"Request cancellation.\n\nCancellation is cooperative: the state is set to ``canceled`` and the worker notices\nat its next checkpoint. Killing a worker mid-write could leave a partial output file\nthat looks complete, which is worse than a slightly delayed stop.","operationId":"cancel_batch_v1_batches__batch_id__cancel_post","parameters":[{"name":"batch_id","in":"path","required":true,"schema":{"type":"string","title":"Batch Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Cancel Batch V1 Batches  Batch Id  Cancel Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/datasets":{"get":{"tags":["releases"],"summary":"Describe the active data release and its sources","description":"Report the active release, its sources, licences and attribution.\n\nThis is a data-plane endpoint rather than an admin one because callers have a\nlegitimate need for it: the licences carry attribution obligations that pass through\nto whoever uses our output (PRD 12.5), and a caller cannot comply with an obligation\nthey cannot see.","operationId":"datasets_v1_datasets_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Datasets V1 Datasets Get"}}}}}}},"/v1/admin/releases":{"get":{"tags":["releases"],"summary":"List data releases","operationId":"list_releases_v1_admin_releases_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":25,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Releases V1 Admin Releases Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/releases/activate":{"post":{"tags":["releases"],"summary":"Activate a data release","description":"Activate a release.\n\nRuns inside one transaction so the supersede-and-activate pair cannot half-apply. A\nconcurrent activation is reported as a conflict rather than silently overwritten,\nbecause two operators activating different releases at once must not end with one\nchange invisibly lost.","operationId":"activate_release_v1_admin_releases_activate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseActivateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Activate Release V1 Admin Releases Activate Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/releases/rollback":{"post":{"tags":["releases"],"summary":"Roll back to a previous release","operationId":"rollback_release_v1_admin_releases_rollback_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseRollbackRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Rollback Release V1 Admin Releases Rollback Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/releases/{release_id}/gates":{"get":{"tags":["releases"],"summary":"Read gate results","operationId":"release_gates_v1_admin_releases__release_id__gates_get","parameters":[{"name":"release_id","in":"path","required":true,"schema":{"type":"string","title":"Release Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Release Gates V1 Admin Releases  Release Id  Gates Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/tokens":{"post":{"tags":["admin:tokens"],"summary":"Mint a child token","description":"Mint a scoped child token.\n\nThe parent's scope set bounds the child's: a token can never grant a privilege it\ndoes not itself hold. That rule is enforced in the service layer rather than here, so\nit applies identically to the CLI and to any future caller.","operationId":"issue_token_v1_admin_tokens_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenIssueRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenIssueResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["admin:tokens"],"summary":"List tokens","description":"List token metadata.\n\nNever returns a secret, because none is stored — only Argon2 hashes. A caller who\nloses a token must have a new one minted.","operationId":"list_tokens_v1_admin_tokens_get","parameters":[{"name":"include_revoked","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Revoked"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Tokens V1 Admin Tokens Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/tokens/{kid}/revoke":{"post":{"tags":["admin:tokens"],"summary":"Revoke a token and its descendants","description":"Revoke a token, cascading to every token minted beneath it.\n\nCascading is the only safe default: if a token is compromised, anything minted with\nit must be considered compromised too. Revoking only the named token would leave an\nattacker's own children working.","operationId":"revoke_token_v1_admin_tokens__kid__revoke_post","parameters":[{"name":"kid","in":"path","required":true,"schema":{"type":"string","title":"Kid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenRevokeRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Revoke Token V1 Admin Tokens  Kid  Revoke Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"AddressInput":{"properties":{"address_line1":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Address Line1"},"address_line2":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Address Line2"},"city":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"City"},"state":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"State"},"postal_code":{"anyOf":[{"type":"string","maxLength":12},{"type":"null"}],"title":"Postal Code"},"country":{"type":"string","maxLength":2,"minLength":2,"title":"Country","default":"US"},"urbanization":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Urbanization"},"freeform":{"anyOf":[{"type":"string","maxLength":400},{"type":"null"}],"title":"Freeform"}},"additionalProperties":false,"type":"object","title":"AddressInput","description":"Structured or free-form address input.\n\nBoth forms are accepted because callers differ: CRM exports arrive structured, while\nscraped or user-typed data arrives as one string. Supplying both is rejected rather\nthan silently preferring one, since the two could disagree and the caller would never\nknow which was used."},"AddressRecord":{"properties":{"address_id":{"type":"string","title":"Address Id"},"active":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Active"},"line1":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Line1"},"last_line":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Line"},"city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City"},"state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"},"zip":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Zip"},"plus4":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plus4"},"lat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lat"},"lon":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lon"},"precision":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Precision"},"dpv":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dpv"},"dpv_footnotes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dpv Footnotes"},"rdi":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rdi"},"cmra":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cmra"},"vacant":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Vacant"},"no_stat":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"No Stat"},"congress":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Congress"},"county":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"County"},"county_fips":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"County Fips"},"carrier_route":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Carrier Route"},"record_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Record Type"},"distance_meters":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Distance Meters"}},"additionalProperties":true,"type":"object","required":["address_id"],"title":"AddressRecord","description":"Stable public projection of one source document."},"AddressSearchFilters":{"properties":{"zip":{"anyOf":[{"type":"string","pattern":"^\\d{5}$"},{"type":"null"}],"title":"Zip"},"plus4":{"anyOf":[{"type":"string","pattern":"^\\d{4}$"},{"type":"null"}],"title":"Plus4"},"city":{"anyOf":[{"type":"string","maxLength":100,"minLength":1},{"type":"null"}],"title":"City"},"state":{"anyOf":[{"type":"string","pattern":"^[A-Za-z]{2}$"},{"type":"null"}],"title":"State"},"county":{"anyOf":[{"type":"string","maxLength":100,"minLength":1},{"type":"null"}],"title":"County"},"county_fips":{"anyOf":[{"type":"string","pattern":"^\\d{5}$"},{"type":"null"}],"title":"County Fips"},"congress":{"anyOf":[{"type":"string","maxLength":3,"minLength":1},{"type":"null"}],"title":"Congress"},"carrier_route":{"anyOf":[{"type":"string","maxLength":8,"minLength":1},{"type":"null"}],"title":"Carrier Route"},"line1_prefix":{"anyOf":[{"type":"string","maxLength":120,"minLength":3},{"type":"null"}],"title":"Line1 Prefix"},"pri_num":{"anyOf":[{"type":"string","maxLength":20,"minLength":1},{"type":"null"}],"title":"Pri Num"},"street":{"anyOf":[{"type":"string","maxLength":100,"minLength":1},{"type":"null"}],"title":"Street"},"suffix":{"anyOf":[{"type":"string","maxLength":20,"minLength":1},{"type":"null"}],"title":"Suffix"},"pre_dir":{"anyOf":[{"type":"string","maxLength":4,"minLength":1},{"type":"null"}],"title":"Pre Dir"},"post_dir":{"anyOf":[{"type":"string","maxLength":4,"minLength":1},{"type":"null"}],"title":"Post Dir"},"sec_desig":{"anyOf":[{"type":"string","maxLength":20,"minLength":1},{"type":"null"}],"title":"Sec Desig"},"sec_num":{"anyOf":[{"type":"string","maxLength":30,"minLength":1},{"type":"null"}],"title":"Sec Num"},"dpv":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":8},{"type":"null"}],"title":"Dpv"},"dpv_footnotes":{"anyOf":[{"type":"string","maxLength":20,"minLength":1},{"type":"null"}],"title":"Dpv Footnotes"},"rdi":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":4},{"type":"null"}],"title":"Rdi"},"cmra":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":4},{"type":"null"}],"title":"Cmra"},"vacant":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":4},{"type":"null"}],"title":"Vacant"},"no_stat":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":4},{"type":"null"}],"title":"No Stat"},"active":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":4},{"type":"null"}],"title":"Active"},"record_type":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":8},{"type":"null"}],"title":"Record Type"},"zip_type":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":8},{"type":"null"}],"title":"Zip Type"},"precision":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":8},{"type":"null"}],"title":"Precision"},"enhanced_match":{"anyOf":[{"type":"string","maxLength":100,"minLength":1},{"type":"null"}],"title":"Enhanced Match"},"src":{"anyOf":[{"type":"string","maxLength":50,"minLength":1},{"type":"null"}],"title":"Src"},"first_seen_from":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"First Seen From"},"first_seen_to":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"First Seen To"}},"additionalProperties":false,"type":"object","title":"AddressSearchFilters","description":"Allowlisted filters; callers can never submit raw MongoDB operators."},"AddressSearchRequest":{"properties":{"filters":{"$ref":"#/components/schemas/AddressSearchFilters"},"page_size":{"type":"integer","maximum":100.0,"minimum":1.0,"title":"Page Size","default":25},"cursor":{"anyOf":[{"type":"string","maxLength":2048},{"type":"null"}],"title":"Cursor"}},"additionalProperties":false,"type":"object","required":["filters"],"title":"AddressSearchRequest"},"AddressSearchResponse":{"properties":{"count":{"type":"integer","title":"Count"},"results":{"items":{"$ref":"#/components/schemas/AddressRecord"},"type":"array","title":"Results"},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"applied_index":{"type":"string","title":"Applied Index"},"source":{"type":"string","title":"Source","default":"lakeHoldings.addressmonger"}},"type":"object","required":["count","results","applied_index"],"title":"AddressSearchResponse"},"AgbBatchError":{"properties":{"code":{"type":"string","title":"Code"},"detail":{"type":"string","title":"Detail"}},"type":"object","required":["code","detail"],"title":"AgbBatchError"},"AgbBatchItem":{"properties":{"agb_location":{"type":"string","title":"Agb Location","description":"The input string, echoed back unchanged."},"agb_location_street_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agb Location Street Address"},"agb_location_address_line_2":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agb Location Address Line 2","description":"Unit, PO box or rural route line."},"agb_location_locality":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agb Location Locality"},"agb_location_region":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agb Location Region","description":"Two-letter state code."},"agb_location_country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agb Location Country"},"agb_location_continent":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agb Location Continent"},"agb_location_postal_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agb Location Postal Code","description":"ZIP5 only."},"agb_location_postal_code_ext":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agb Location Postal Code Ext","description":"ZIP+4 extension. Supplied from USPS enrichment where we hold it, otherwise echoed from the input. Never returned without a ZIP5, since an extension alone is not a usable postal code."},"agb_location_address_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agb Location Address Type","description":"USPS residential delivery indicator: Residential or Commercial. Null where unknown, which is not a claim either way."},"agb_location_metro":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agb Location Metro","description":"CBSA name from a spatial containment test. Null where the coordinate falls in no CBSA, which is much of the country."},"agb_location_metro_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agb Location Metro Type","description":"metropolitan or micropolitan. Not interchangeable: CBSAs are built from whole counties, so an address far from any city can still fall inside one."},"agb_location_geo":{"anyOf":[{"$ref":"#/components/schemas/AgbGeo"},{"type":"null"}],"description":"Null when no position could be established, or when one was deliberately withheld. Check agb_location_evidence.notes to tell those apart."},"agb_location_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agb Location Name","description":"POI name. Currently always null: no loaded source carries business or POI names."},"agb_location_full_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agb Location Full Address"},"agb_location_evidence":{"anyOf":[{"$ref":"#/components/schemas/AgbEvidence"},{"type":"null"}]},"suggestions":{"anyOf":[{"$ref":"#/components/schemas/SuggestionBlock"},{"type":"null"}],"description":"Present only when the lookup failed and alternatives were sought. The AGB fields above are never populated from a suggestion."},"release_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Release Id","description":"The data release that produced this answer."},"recommended_action":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recommended Action","description":"accept, review or reject, from the scoring policy. Read alongside agb_location_evidence.verified: an interpolated match can be 'accept' while not being a confirmed address."},"index":{"type":"integer","title":"Index","description":"Zero-based position of this result's input in the request."},"error":{"anyOf":[{"$ref":"#/components/schemas/AgbBatchError"},{"type":"null"}],"description":"Present when this input could not be processed. The slot is still returned so positional joins stay safe."}},"type":"object","required":["agb_location","agb_location_street_address","agb_location_locality","agb_location_country","agb_location_continent","agb_location_full_address","index"],"title":"AgbBatchItem"},"AgbBatchResponse":{"properties":{"count":{"type":"integer","title":"Count"},"release_id":{"type":"string","title":"Release Id"},"results":{"items":{"$ref":"#/components/schemas/AgbBatchItem"},"type":"array","title":"Results","description":"One result per input, in request order. Never shorter than the input list."}},"type":"object","required":["count","release_id","results"],"title":"AgbBatchResponse"},"AgbEvidence":{"properties":{"verified":{"type":"boolean","title":"Verified","description":"True only for point evidence, meaning a source record exists for this address. False for interpolated, street-level or unmatched results."},"basis":{"type":"string","title":"Basis","description":"How the position was derived, e.g. address_point, street_range_interpolated."},"match_level":{"type":"string","title":"Match Level"},"confidence":{"type":"string","title":"Confidence","description":"high, medium, low, very_low or none."},"uncertainty_radius_m":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Uncertainty Radius M","description":"How far competing street segments disagreed, in metres. This measures source disagreement, NOT distance from the true location: segments can agree with each other and all be wrong."},"usps_deliverable":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Usps Deliverable","description":"USPS deliverability, populated only where DPV data is present. Null means unknown, not undeliverable. Distinct from `verified`, which says a source record describes this address, not that mail will arrive."},"dpv_match_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dpv Match Code","description":"Raw USPS delivery point validation code. Y and S are deliverable. D means the building was confirmed but a unit number is missing, so mail is NOT deliverable as addressed. N means not deliverable."},"notes":{"items":{"type":"string"},"type":"array","title":"Notes","description":"Plain-language qualifications, including any reason a position was withheld."}},"type":"object","required":["verified","basis","match_level","confidence"],"title":"AgbEvidence","description":"Graded existence evidence.\n\n``verified`` is the field that answers \"does this address exist as a source record\". It is\ndeliberately separate from ``recommended_action``: an interpolated position can score well\nenough to accept while still not being a confirmed address, and collapsing the two would\nhide that distinction from consumers."},"AgbGeo":{"properties":{"latitude":{"type":"number","title":"Latitude"},"longitude":{"type":"number","title":"Longitude"}},"type":"object","required":["latitude","longitude"],"title":"AgbGeo"},"AgbLocation":{"properties":{"agb_location":{"type":"string","title":"Agb Location","description":"The input string, echoed back unchanged."},"agb_location_street_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agb Location Street Address"},"agb_location_address_line_2":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agb Location Address Line 2","description":"Unit, PO box or rural route line."},"agb_location_locality":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agb Location Locality"},"agb_location_region":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agb Location Region","description":"Two-letter state code."},"agb_location_country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agb Location Country"},"agb_location_continent":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agb Location Continent"},"agb_location_postal_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agb Location Postal Code","description":"ZIP5 only."},"agb_location_postal_code_ext":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agb Location Postal Code Ext","description":"ZIP+4 extension. Supplied from USPS enrichment where we hold it, otherwise echoed from the input. Never returned without a ZIP5, since an extension alone is not a usable postal code."},"agb_location_address_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agb Location Address Type","description":"USPS residential delivery indicator: Residential or Commercial. Null where unknown, which is not a claim either way."},"agb_location_metro":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agb Location Metro","description":"CBSA name from a spatial containment test. Null where the coordinate falls in no CBSA, which is much of the country."},"agb_location_metro_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agb Location Metro Type","description":"metropolitan or micropolitan. Not interchangeable: CBSAs are built from whole counties, so an address far from any city can still fall inside one."},"agb_location_geo":{"anyOf":[{"$ref":"#/components/schemas/AgbGeo"},{"type":"null"}],"description":"Null when no position could be established, or when one was deliberately withheld. Check agb_location_evidence.notes to tell those apart."},"agb_location_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agb Location Name","description":"POI name. Currently always null: no loaded source carries business or POI names."},"agb_location_full_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agb Location Full Address"},"agb_location_evidence":{"anyOf":[{"$ref":"#/components/schemas/AgbEvidence"},{"type":"null"}]},"suggestions":{"anyOf":[{"$ref":"#/components/schemas/SuggestionBlock"},{"type":"null"}],"description":"Present only when the lookup failed and alternatives were sought. The AGB fields above are never populated from a suggestion."},"release_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Release Id","description":"The data release that produced this answer."},"recommended_action":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recommended Action","description":"accept, review or reject, from the scoring policy. Read alongside agb_location_evidence.verified: an interpolated match can be 'accept' while not being a confirmed address."}},"type":"object","required":["agb_location","agb_location_street_address","agb_location_locality","agb_location_country","agb_location_continent","agb_location_full_address"],"title":"AgbLocation","description":"The AGB consumer field set.\n\n``agb_location_postal_code`` carries ZIP5 only, matching the consumer's existing contract,\nwith the ZIP+4 extension surfaced separately rather than folded in or dropped."},"ApiKeyCreateResponse":{"properties":{"kid":{"type":"string","title":"Kid"},"token":{"type":"string","title":"Token"},"name":{"type":"string","title":"Name"},"scopes":{"items":{"type":"string"},"type":"array","title":"Scopes"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"rate_limit_per_minute":{"type":"integer","title":"Rate Limit Per Minute"},"daily_quota":{"type":"integer","title":"Daily Quota"},"warning":{"type":"string","title":"Warning","default":"Store this API key now. Only its hash is retained."}},"type":"object","required":["kid","token","name","scopes","expires_at","rate_limit_per_minute","daily_quota"],"title":"ApiKeyCreateResponse"},"ApiKeyListResponse":{"properties":{"count":{"type":"integer","title":"Count"},"results":{"items":{"$ref":"#/components/schemas/ApiKeySummary"},"type":"array","title":"Results"}},"type":"object","required":["count","results"],"title":"ApiKeyListResponse"},"ApiKeyRequestCreate":{"properties":{"name":{"type":"string","maxLength":100,"minLength":1,"title":"Name"},"environment":{"type":"string","enum":["development","staging","production"],"title":"Environment"},"business_purpose":{"type":"string","maxLength":1000,"minLength":3,"title":"Business Purpose"},"scopes":{"items":{"type":"string"},"type":"array","maxItems":3,"minItems":1,"title":"Scopes","default":["address:read","address:search"]},"ttl_days":{"anyOf":[{"type":"integer","maximum":3650.0,"minimum":1.0},{"type":"null"}],"title":"Ttl Days","default":365},"rate_limit_per_minute":{"anyOf":[{"type":"integer","maximum":10000.0,"minimum":1.0},{"type":"null"}],"title":"Rate Limit Per Minute"},"expected_requests_per_day":{"anyOf":[{"type":"integer","maximum":100000000.0,"minimum":1.0},{"type":"null"}],"title":"Expected Requests Per Day"}},"additionalProperties":false,"type":"object","required":["name","environment","business_purpose"],"title":"ApiKeyRequestCreate"},"ApiKeyRequestListResponse":{"properties":{"count":{"type":"integer","title":"Count"},"results":{"items":{"$ref":"#/components/schemas/ApiKeyRequestSummary"},"type":"array","title":"Results"}},"type":"object","required":["count","results"],"title":"ApiKeyRequestListResponse"},"ApiKeyRequestReview":{"properties":{"approve":{"type":"boolean","title":"Approve","default":true},"reason":{"anyOf":[{"type":"string","maxLength":500,"minLength":1},{"type":"null"}],"title":"Reason"}},"additionalProperties":false,"type":"object","title":"ApiKeyRequestReview"},"ApiKeyRequestSummary":{"properties":{"id":{"type":"string","title":"Id"},"user_id":{"type":"string","title":"User Id"},"user_email":{"type":"string","title":"User Email"},"user_display_name":{"type":"string","title":"User Display Name"},"name":{"type":"string","title":"Name"},"environment":{"type":"string","enum":["development","staging","production"],"title":"Environment"},"business_purpose":{"type":"string","title":"Business Purpose"},"scopes":{"items":{"type":"string"},"type":"array","title":"Scopes"},"ttl_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ttl Days"},"rate_limit_per_minute":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rate Limit Per Minute"},"expected_requests_per_day":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Expected Requests Per Day"},"status":{"type":"string","enum":["pending","approved","rejected","activated","cancelled"],"title":"Status"},"reviewed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Reviewed At"},"review_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Review Reason"},"activated_kid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Activated Kid"},"activated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Activated At"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","user_id","user_email","user_display_name","name","environment","business_purpose","scopes","ttl_days","rate_limit_per_minute","expected_requests_per_day","status","reviewed_at","review_reason","activated_kid","activated_at","created_at"],"title":"ApiKeyRequestSummary"},"ApiKeyRevokeRequest":{"properties":{"reason":{"type":"string","maxLength":500,"minLength":1,"title":"Reason","default":"revoked by owner"}},"additionalProperties":false,"type":"object","title":"ApiKeyRevokeRequest"},"ApiKeySummary":{"properties":{"kid":{"type":"string","title":"Kid"},"name":{"type":"string","title":"Name"},"scopes":{"items":{"type":"string"},"type":"array","title":"Scopes"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"rate_limit_per_minute":{"type":"integer","title":"Rate Limit Per Minute"},"daily_quota":{"type":"integer","title":"Daily Quota"},"revoked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Revoked At"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"active":{"type":"boolean","title":"Active"}},"type":"object","required":["kid","name","scopes","expires_at","rate_limit_per_minute","daily_quota","revoked_at","last_used_at","created_at","active"],"title":"ApiKeySummary"},"BatchSubmitRequest":{"properties":{"operation":{"type":"string","enum":["validate","geocode","normalize","dedupe"],"title":"Operation"},"input_uri":{"type":"string","maxLength":1024,"title":"Input Uri"},"output_uri":{"anyOf":[{"type":"string","maxLength":1024},{"type":"null"}],"title":"Output Uri"},"profile":{"$ref":"#/components/schemas/ValidationProfile","default":"standard"},"idempotency_key":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"Idempotency Key"},"callback_url":{"anyOf":[{"type":"string","maxLength":1024},{"type":"null"}],"title":"Callback Url"}},"additionalProperties":false,"type":"object","required":["operation","input_uri"],"title":"BatchSubmitRequest"},"CandidatesRequest":{"properties":{"address":{"$ref":"#/components/schemas/AddressInput"},"limit":{"type":"integer","maximum":25.0,"minimum":1.0,"title":"Limit","default":5},"profile":{"$ref":"#/components/schemas/ValidationProfile","default":"standard"}},"additionalProperties":false,"type":"object","required":["address"],"title":"CandidatesRequest"},"DedupeRequest":{"properties":{"addresses":{"items":{"$ref":"#/components/schemas/AddressInput"},"type":"array","maxItems":1000,"minItems":2,"title":"Addresses"},"granularity":{"type":"string","enum":["unit","building"],"title":"Granularity","default":"unit"}},"additionalProperties":false,"type":"object","required":["addresses"],"title":"DedupeRequest"},"GeocodeRequest":{"properties":{"address":{"$ref":"#/components/schemas/AddressInput"},"profile":{"$ref":"#/components/schemas/ValidationProfile","default":"standard"},"allow_interpolation":{"type":"boolean","title":"Allow Interpolation","default":true}},"additionalProperties":false,"type":"object","required":["address"],"title":"GeocodeRequest"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HealthResponse":{"properties":{"status":{"type":"string","enum":["ok","degraded","unhealthy"],"title":"Status"},"version":{"type":"string","title":"Version"},"environment":{"type":"string","title":"Environment"},"instance":{"type":"string","title":"Instance"}},"type":"object","required":["status","version","environment","instance"],"title":"HealthResponse"},"InvitationCreateRequest":{"properties":{"email_restriction":{"anyOf":[{"type":"string","maxLength":320,"minLength":3},{"type":"null"}],"title":"Email Restriction"},"role":{"type":"string","enum":["member","admin"],"title":"Role","default":"member"},"auto_approve":{"type":"boolean","title":"Auto Approve","default":false},"ttl_hours":{"anyOf":[{"type":"integer","maximum":720.0,"minimum":1.0},{"type":"null"}],"title":"Ttl Hours"}},"additionalProperties":false,"type":"object","title":"InvitationCreateRequest"},"InvitationCreateResponse":{"properties":{"invitation_code":{"type":"string","title":"Invitation Code"},"signup_url":{"type":"string","title":"Signup Url"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"},"warning":{"type":"string","title":"Warning","default":"Store or send this invitation now. Its plaintext cannot be retrieved again."}},"type":"object","required":["invitation_code","signup_url","expires_at"],"title":"InvitationCreateResponse"},"LoginRequest":{"properties":{"email":{"type":"string","maxLength":320,"minLength":3,"title":"Email"},"password":{"type":"string","maxLength":128,"minLength":1,"title":"Password"}},"additionalProperties":false,"type":"object","required":["email","password"],"title":"LoginRequest"},"MongoValidateResponse":{"properties":{"valid":{"type":"boolean","title":"Valid"},"deliverable":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Deliverable"},"match_type":{"type":"string","enum":["exact","not_found"],"title":"Match Type"},"confidence":{"type":"string","enum":["high","none"],"title":"Confidence"},"normalized":{"additionalProperties":true,"type":"object","title":"Normalized"},"address":{"anyOf":[{"$ref":"#/components/schemas/AddressRecord"},{"type":"null"}]},"suggestions":{"items":{"$ref":"#/components/schemas/AddressRecord"},"type":"array","title":"Suggestions"},"source":{"type":"string","title":"Source","default":"lakeHoldings.addressmonger"}},"type":"object","required":["valid","deliverable","match_type","confidence","normalized","address"],"title":"MongoValidateResponse"},"NormalizeRequest":{"properties":{"address":{"$ref":"#/components/schemas/AddressInput"},"ruleset_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ruleset Version"}},"additionalProperties":false,"type":"object","required":["address"],"title":"NormalizeRequest"},"PortalUserResponse":{"properties":{"id":{"type":"string","title":"Id"},"email":{"type":"string","title":"Email"},"display_name":{"type":"string","title":"Display Name"},"status":{"type":"string","enum":["pending","active","disabled"],"title":"Status"},"role":{"type":"string","enum":["member","admin"],"title":"Role"},"approved_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Approved At"},"last_login_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Login At"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","email","display_name","status","role","approved_at","last_login_at","created_at"],"title":"PortalUserResponse"},"ReadinessResponse":{"properties":{"ready":{"type":"boolean","title":"Ready"},"degraded":{"type":"boolean","title":"Degraded"},"checks":{"additionalProperties":true,"type":"object","title":"Checks"},"active_release_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Active Release Id"}},"type":"object","required":["ready","degraded","checks"],"title":"ReadinessResponse"},"RegisterRequest":{"properties":{"invitation_code":{"type":"string","maxLength":256,"minLength":40,"title":"Invitation Code"},"email":{"type":"string","maxLength":320,"minLength":3,"title":"Email"},"display_name":{"type":"string","maxLength":120,"minLength":1,"title":"Display Name"},"password":{"type":"string","maxLength":128,"minLength":12,"title":"Password"}},"additionalProperties":false,"type":"object","required":["invitation_code","email","display_name","password"],"title":"RegisterRequest"},"RegistrationResponse":{"properties":{"user":{"$ref":"#/components/schemas/PortalUserResponse"},"message":{"type":"string","title":"Message"}},"type":"object","required":["user","message"],"title":"RegistrationResponse"},"ReleaseActivateRequest":{"properties":{"release_id":{"type":"string","maxLength":100,"minLength":1,"title":"Release Id"},"force":{"type":"boolean","title":"Force","default":false},"justification":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}],"title":"Justification"}},"additionalProperties":false,"type":"object","required":["release_id"],"title":"ReleaseActivateRequest"},"ReleaseRollbackRequest":{"properties":{"reason":{"type":"string","maxLength":1000,"minLength":1,"title":"Reason"},"target_release_id":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Target Release Id"}},"additionalProperties":false,"type":"object","required":["reason"],"title":"ReleaseRollbackRequest"},"ResolveBatchRequest":{"properties":{"locations":{"items":{"type":"string","maxLength":400,"minLength":1},"type":"array","maxItems":100,"minItems":1,"title":"Locations"},"country":{"type":"string","maxLength":2,"minLength":2,"title":"Country","default":"US"},"profile":{"$ref":"#/components/schemas/ValidationProfile","default":"standard"},"include_metro":{"type":"boolean","title":"Include Metro","default":true},"include_evidence":{"type":"boolean","title":"Include Evidence","default":true}},"additionalProperties":false,"type":"object","required":["locations"],"title":"ResolveBatchRequest","description":"Many location strings in one request.\n\nExists because the per-request overhead dominates: a single indexed lookup runs in about\n0.2 ms while a whole HTTP round trip costs roughly 33 ms. Batching amortises auth,\nconnection handling and the CBSA join across the set. For volumes beyond a few hundred\nthousand, the asynchronous ``/v1/batches`` job path is still the right tool, since it\ncheckpoints and resumes."},"ResolveRequest":{"properties":{"location":{"type":"string","maxLength":400,"minLength":1,"title":"Location"},"country":{"type":"string","maxLength":2,"minLength":2,"title":"Country","default":"US"},"profile":{"$ref":"#/components/schemas/ValidationProfile","default":"standard"},"include_metro":{"type":"boolean","title":"Include Metro","default":true},"include_evidence":{"type":"boolean","title":"Include Evidence","default":true},"include_suggestions":{"type":"boolean","title":"Include Suggestions","default":true},"max_suggestions":{"type":"integer","maximum":5.0,"minimum":1.0,"title":"Max Suggestions","default":5}},"additionalProperties":false,"type":"object","required":["location"],"title":"ResolveRequest","description":"One unstructured location string in, the full AGB field set out.\n\nDeliberately takes a bare string rather than the nested ``AddressInput`` used elsewhere.\nCallers of this endpoint hold a single opaque location value (``agb_location``) and have\nnothing to put in structured fields; requiring them to wrap it would be ceremony with no\nbenefit. The other endpoints keep ``AddressInput`` because they genuinely support both\nforms."},"ReverseGeocodeRequest":{"properties":{"latitude":{"type":"number","maximum":90.0,"minimum":-90.0,"title":"Latitude"},"longitude":{"type":"number","maximum":180.0,"minimum":-180.0,"title":"Longitude"},"radius_meters":{"type":"integer","maximum":2000.0,"minimum":1.0,"title":"Radius Meters","default":150},"limit":{"type":"integer","maximum":25.0,"minimum":1.0,"title":"Limit","default":5}},"additionalProperties":false,"type":"object","required":["latitude","longitude"],"title":"ReverseGeocodeRequest"},"ReverseGeocodeResponse":{"properties":{"query":{"additionalProperties":{"anyOf":[{"type":"number"},{"type":"integer"}]},"type":"object","title":"Query"},"count":{"type":"integer","title":"Count"},"results":{"items":{"$ref":"#/components/schemas/AddressRecord"},"type":"array","title":"Results"},"source":{"type":"string","title":"Source","default":"lakeHoldings.addressmonger"}},"type":"object","required":["query","count","results"],"title":"ReverseGeocodeResponse"},"SessionResponse":{"properties":{"user":{"$ref":"#/components/schemas/PortalUserResponse"},"csrf_token":{"type":"string","title":"Csrf Token"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"}},"type":"object","required":["user","csrf_token","expires_at"],"title":"SessionResponse"},"SuggestResponse":{"properties":{"query":{"type":"string","title":"Query"},"count":{"type":"integer","title":"Count"},"results":{"items":{"$ref":"#/components/schemas/AddressRecord"},"type":"array","title":"Results"},"source":{"type":"string","title":"Source","default":"lakeHoldings.addressmonger"}},"type":"object","required":["query","count","results"],"title":"SuggestResponse"},"SuggestionBlock":{"properties":{"not_found_reason":{"type":"string","title":"Not Found Reason","description":"Why the input did not resolve. Distinguishes an absent record from an invalid address, because several states have sparse source coverage."},"count":{"type":"integer","title":"Count"},"suggestions":{"items":{"$ref":"#/components/schemas/SuggestionItem"},"type":"array","title":"Suggestions","description":"Ranked best first. At most five."}},"type":"object","required":["not_found_reason","count"],"title":"SuggestionBlock","description":"Suggestions plus a stated reason the input did not resolve.\n\nNested under one key rather than merged into the AGB record, so a caller that ignores it\ncannot mistake a suggested address for the resolved one. Nothing in the AGB fields is\nrewritten from a suggestion: these are offers, never substitutions."},"SuggestionGeo":{"properties":{"latitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Latitude"},"longitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Longitude"}},"type":"object","title":"SuggestionGeo"},"SuggestionItem":{"properties":{"address":{"type":"string","title":"Address","description":"Full formatted address of the suggested record."},"house_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"House Number"},"street":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Street"},"locality":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Locality"},"region":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Region"},"postal_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Postal Code"},"geo":{"anyOf":[{"$ref":"#/components/schemas/SuggestionGeo"},{"type":"null"}]},"verified":{"type":"boolean","title":"Verified","description":"Always true: suggestions are real source records, never constructed strings.","default":true},"reason":{"type":"string","title":"Reason","description":"Why this candidate is offered, in plain language. Present because a bare score cannot be reasoned about by a human or an LLM, while a stated reason can."},"score":{"type":"number","title":"Score","description":"Relative rank within this response only. Banded by evidence strength: an exact house number in another ZIP outranks a neighbouring number, which outranks a similar street name. Not a probability."},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"},"strategy":{"type":"string","title":"Strategy","description":"Which rule produced this candidate: nearest_house_number, same_street_other_zip or similar_street_name."}},"type":"object","required":["address","reason","score","strategy"],"title":"SuggestionItem","description":"One offered alternative address.\n\nComplete by design: a chooser should not need a second round trip to act on a suggestion,\nso every item carries its own coordinate and provenance."},"TokenIssueRequest":{"properties":{"name":{"type":"string","maxLength":100,"minLength":1,"title":"Name"},"owner":{"type":"string","maxLength":200,"minLength":1,"title":"Owner"},"scopes":{"items":{"type":"string"},"type":"array","maxItems":20,"minItems":1,"title":"Scopes"},"ttl_days":{"anyOf":[{"type":"integer","maximum":3650.0,"minimum":1.0},{"type":"null"}],"title":"Ttl Days"},"rate_limit_per_minute":{"anyOf":[{"type":"integer","maximum":100000.0,"minimum":1.0},{"type":"null"}],"title":"Rate Limit Per Minute"},"allowed_profiles":{"items":{"type":"string"},"type":"array","title":"Allowed Profiles"},"provider_authorized":{"type":"boolean","title":"Provider Authorized","default":false},"allowed_cidrs":{"items":{"type":"string"},"type":"array","title":"Allowed Cidrs"}},"additionalProperties":false,"type":"object","required":["name","owner","scopes"],"title":"TokenIssueRequest"},"TokenIssueResponse":{"properties":{"kid":{"type":"string","title":"Kid"},"token":{"type":"string","title":"Token"},"scopes":{"items":{"type":"string"},"type":"array","title":"Scopes"},"expires_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expires At"},"warning":{"type":"string","title":"Warning","default":"Store this token now. Only its hash is retained, so it cannot be shown again."}},"type":"object","required":["kid","token","scopes","expires_at"],"title":"TokenIssueResponse"},"TokenRevokeRequest":{"properties":{"reason":{"type":"string","maxLength":500,"minLength":1,"title":"Reason"}},"additionalProperties":false,"type":"object","required":["reason"],"title":"TokenRevokeRequest"},"UserApprovalRequest":{"properties":{"approve":{"type":"boolean","title":"Approve","default":true},"reason":{"anyOf":[{"type":"string","maxLength":500,"minLength":1},{"type":"null"}],"title":"Reason"}},"additionalProperties":false,"type":"object","title":"UserApprovalRequest"},"ValidateRequest":{"properties":{"address":{"$ref":"#/components/schemas/AddressInput"},"profile":{"$ref":"#/components/schemas/ValidationProfile","default":"standard"},"include_candidates":{"type":"boolean","title":"Include Candidates","default":false},"max_candidates":{"type":"integer","maximum":25.0,"minimum":1.0,"title":"Max Candidates","default":3},"include_suggestions":{"type":"boolean","title":"Include Suggestions","default":true},"max_suggestions":{"type":"integer","maximum":10.0,"minimum":1.0,"title":"Max Suggestions","default":5},"request_postal_validation":{"type":"boolean","title":"Request Postal Validation","default":false}},"additionalProperties":false,"type":"object","required":["address"],"title":"ValidateRequest"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"ValidationProfile":{"type":"string","enum":["standard","strict","mailing"],"title":"ValidationProfile","description":"PRD FR-008."}},"securitySchemes":{"BearerToken":{"type":"http","scheme":"bearer","description":"API key sent as 'Authorization: Bearer <token>' or X-API-Key. Keys carry scopes; a route returns 403 when the key lacks the required scope and 401 when no valid key is presented."},"PortalSession":{"type":"apiKey","in":"cookie","name":"addrintel_session","description":"Secure browser session issued by /portal/api/login."}}},"security":[{"BearerToken":[]}]}