{"openapi":"3.0.3","info":{"title":"Exclia API","version":"1.0.0","description":"Exclusion screening for platforms. Authenticate every request with your API key as a bearer token. Coverage is the same metadata the in-app coverage page shows, and usage is the same consumption the invoice bills for the period.\n## Rate limits\n\nEvery `/v1` request counts against your organization’s plan ceiling, per API key, in a fixed \none-minute window:\n\n| Plan | Burst limit | Included calls per month | Past the allowance |\n| --- | --- | --- | --- |\n| Trial | 30 requests per minute | 1,000 | refused until the 1st of the next month |\n| Small | 30 requests per minute | 500 | refused until the 1st of the next month |\n| Medium | 60 requests per minute | 5,000 | refused until the 1st of the next month |\n| Large | 120 requests per minute | 25,000 | billed at the published rates |\n| Enterprise | 600 requests per minute | custom | billed at the published rates |\n\nBoth numbers are resolved from your plan on every call, so an upgrade takes effect immediately — \nthere is nothing to redeploy or re-issue. Every plan may call `/v1`. The two columns bound \ndifferent things: the burst limit is how fast, the monthly allowance is how much.\n\nPast the monthly allowance, a plan that bills the excess simply continues; a plan that does not \nrefuses with `402` and `code: \"api_allowance_reached\"`, naming the date the count returns to zero \nand the plans that would give more room before then. Nothing is charged for a refused call, and \nno usage is recorded for it.\n\nOver the ceiling, the response is `429` with `code: \"rate_limited\"` and a `Retry-After` header \ngiving the seconds until the window resets. Refused requests still count toward the window, so \nretrying before `Retry-After` does not help. The limit is enforced against a shared counter, so it \nis the same ceiling regardless of how many servers are answering — and if that counter is briefly \nunreachable we refuse requests rather than serve them uncounted.\n\nThe free public lookup (`POST /public/lookup`) is limited separately, and has no key: \n5 requests per minute per IP address, and \n120 requests per minute across all callers.\n## Webhooks\n\nWhen you configure a webhook endpoint, Exclia pushes signed deliveries for three events: \n`match_status_change` (a monitored entity’s screening status changed), `batch_completed`, and \n`list_update`. Screening payloads carry only `clear` or `potential_match` with per-field evidence \nand provenance (`list_version` ids and retrieval dates) — never an automated “excluded” verdict.\n\nEach delivery is a JSON body with headers `Exclia-Webhook-Id` (the delivery id), `Exclia-Event-Type`, \nand `Exclia-Signature: t=<unixSeconds>,v1=<hex>`.\n\n### Verifying a delivery\n1. Read `t` and `v1` from the `Exclia-Signature` header.\n2. Reject the delivery if `t` is more than 5 minutes from your current time (replay protection).\n3. Compute `HMAC-SHA256(signingSecret, \"<t>.\" + rawRequestBody)` as lowercase hex — use the EXACT \n   received bytes, before any JSON re-serialization.\n4. Constant-time compare your hex digest to `v1`. If they differ, the payload was tampered with or \n   signed with a different secret — discard it. Only on a match do you trust the event.\n5. Respond `2xx` to acknowledge. A non-2xx or timeout is retried with exponential backoff; every \n   attempt is recorded in your delivery log, and you can replay any delivery from it.\n\nYour signing secret is shown once when you register or rotate the endpoint. Rotate it if it leaks; \nthe previous secret stops signing immediately.\n## Changelog\n\nChanges to the `/v1` contract, newest first. **Breaking** marks a change that can turn a \nrequest that used to succeed into a failure.\n\n### 2026-08-30\n\n`POST /v1/screen` returns its `matches` ordered strongest first, and every match now carries a `score` between 0 and 1. Responses also carry `recallCapped`.\n\nNothing is required — the fields are additive and the order is the array you already receive. Two things are worth knowing. `score` is a DETERMINISTIC ORDERING FIGURE, not a probability and not a confidence: 1 means the name matched exactly, and lower values rank a close or partial name below it. It is computed from the name comparison and the corroborating fields, never from a search relevance score, so the same subject and the same list versions always produce the same value and the same order. Do not threshold on it — every match, at every score, carries the same \"Potential match — verification required\" label and still needs a person to verify it. And `recallCapped: true` means the check reached its candidate limit: the matches are the strongest of what was found, and there may be more. Narrow the subject (add a date of birth, an NPI or a state) rather than paging — there is no paging on this endpoint.\n\n### 2026-08-23 · Breaking\n\nA person is identified by one `name` on `POST /v1/screen` and `PUT /v1/monitor`. The `firstName`, `middleName`, `lastName` and `suffix` fields are gone.\n\nSend the whole name — including any generational suffix — in `name`. A body still carrying the old fields is refused with a 400 naming `name`, rather than an anonymous unrecognized-field error, so the failure says what to change. Organizations are unaffected: they keep `legalName`.\n"},"servers":[{"url":"https://api.exclia.com/v1","description":"Production"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"http","scheme":"bearer","description":"Your API key, sent as `Authorization: Bearer <key>`."}},"schemas":{"CoverageResponse":{"type":"object","properties":{"sources":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","minLength":1},"name":{"type":"string","minLength":1},"listVersionId":{"type":"string","minLength":1},"retrievedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"cadence":{"type":"string","enum":["daily","weekly","monthly","quarterly","on_change","irregular"]},"cadenceLabel":{"type":"string","minLength":1}},"required":["key","name","listVersionId","retrievedAt","cadence","cadenceLabel"],"additionalProperties":false}},"additionalSources":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","minLength":1},"name":{"type":"string","minLength":1},"listVersionId":{"type":"string","minLength":1},"retrievedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"cadence":{"type":"string","enum":["daily","weekly","monthly","quarterly","on_change","irregular"]},"cadenceLabel":{"type":"string","minLength":1}},"required":["key","name","listVersionId","retrievedAt","cadence","cadenceLabel"],"additionalProperties":false}},"registrySources":{"type":"array","items":{"type":"object","properties":{"sourceKey":{"type":"string","enum":["NPPES"]},"scope":{"type":"string","enum":["organization_registry"]},"excludedFromMedicaidDenominator":{"type":"boolean","enum":[true]},"status":{"type":"string","enum":["live","stale","disabled","unavailable"]},"versionId":{"nullable":true,"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"retrievedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"artifactRetrievedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"sourceUrl":{"nullable":true,"type":"string","format":"uri"},"periodEnd":{"nullable":true,"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},"organizationCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"artifactChecksum":{"nullable":true,"type":"string"},"type1PublicPagesEnabled":{"type":"boolean","enum":[false]}},"required":["sourceKey","scope","excludedFromMedicaidDenominator","status","versionId","retrievedAt","artifactRetrievedAt","sourceUrl","periodEnd","organizationCount","artifactChecksum","type1PublicPagesEnabled"],"additionalProperties":false}},"gaps":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","minLength":1},"name":{"type":"string","minLength":1},"reason":{"type":"string","minLength":1}},"required":["key","name","reason"],"additionalProperties":false}},"totals":{"type":"object","properties":{"screened":{"type":"integer","minimum":0,"maximum":9007199254740991},"total":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["screened","total"],"additionalProperties":false},"asOf":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["sources","gaps","totals","asOf"],"additionalProperties":false},"ApiUsageSummary":{"type":"object","properties":{"period":{"type":"string","pattern":"^\\d{4}-(0[1-9]|1[0-2])$"},"screenCalls":{"type":"integer","minimum":0,"maximum":9007199254740991},"recordMonths":{"type":"integer","minimum":0,"maximum":9007199254740991},"price":{"type":"object","properties":{"screenCallCents":{"type":"integer","minimum":0,"maximum":9007199254740991},"recordMonthCents":{"type":"integer","minimum":0,"maximum":9007199254740991},"subtotalCents":{"type":"integer","minimum":0,"maximum":9007199254740991},"platformMinimumCents":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalCents":{"type":"integer","minimum":0,"maximum":9007199254740991},"minimumApplied":{"type":"boolean"}},"required":["screenCallCents","recordMonthCents","subtotalCents","platformMinimumCents","totalCents","minimumApplied"],"additionalProperties":false}},"required":["period","screenCalls","recordMonths","price"],"additionalProperties":false},"ScreenRequest":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["person"]},"name":{"type":"string","minLength":1,"maxLength":255},"aliases":{"maxItems":50,"type":"array","items":{"type":"string","maxLength":255}},"dateOfBirth":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"npi":{"type":"string","minLength":10,"maxLength":10},"state":{"type":"string","minLength":2,"maxLength":2},"providerType":{"type":"string","maxLength":255}},"required":["type","name"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","enum":["organization"]},"legalName":{"type":"string","minLength":1,"maxLength":255},"aliases":{"maxItems":50,"type":"array","items":{"type":"string","maxLength":255}},"npi":{"type":"string","minLength":10,"maxLength":10},"state":{"type":"string","minLength":2,"maxLength":2}},"required":["type","legalName"],"additionalProperties":false}]},"ScreenResponse":{"type":"object","properties":{"status":{"type":"string","enum":["clear","potential_match"]},"matches":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string","minLength":1},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","enum":["name","npi","state","providerType","dateOfBirth"]},"state":{"type":"string","enum":["matched","not_matched","unknown"]},"rosterValue":{"nullable":true,"type":"string"},"listValue":{"nullable":true,"type":"string"},"strong":{"type":"boolean"}},"required":["field","state","rosterValue","listValue","strong"],"additionalProperties":false}},"provenance":{"type":"object","properties":{"sourceList":{"type":"string","minLength":1},"listVersionId":{"type":"string","minLength":1},"retrievedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["sourceList","listVersionId","retrievedAt"],"additionalProperties":false},"score":{"type":"number","minimum":0,"maximum":1}},"required":["label","fields","provenance","score"],"additionalProperties":false}},"sources":{"type":"array","items":{"type":"object","properties":{"source":{"type":"string","minLength":1},"listVersionId":{"type":"string","minLength":1},"retrievedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["source","listVersionId","retrievedAt"],"additionalProperties":false}},"checkedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"recallCapped":{"type":"boolean"}},"required":["status","matches","sources","checkedAt","recallCapped"],"additionalProperties":false},"ScreenValidationError":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_request"]},"message":{"type":"string"},"fields":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}},"required":["code","message","fields"],"additionalProperties":false},"MonitorRequest":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["person"]},"name":{"type":"string","minLength":1,"maxLength":255},"aliases":{"maxItems":50,"type":"array","items":{"type":"string","maxLength":255}},"dateOfBirth":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"npi":{"type":"string","minLength":10,"maxLength":10},"state":{"type":"string","minLength":2,"maxLength":2},"providerType":{"type":"string","maxLength":255}},"required":["type","name"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","enum":["organization"]},"legalName":{"type":"string","minLength":1,"maxLength":255},"aliases":{"maxItems":50,"type":"array","items":{"type":"string","maxLength":255}},"npi":{"type":"string","minLength":10,"maxLength":10},"state":{"type":"string","minLength":2,"maxLength":2}},"required":["type","legalName"],"additionalProperties":false}]},"MonitorResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"status":{"type":"string","enum":["clear","potential_match"]},"matches":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string","minLength":1},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","enum":["name","npi","state","providerType","dateOfBirth"]},"state":{"type":"string","enum":["matched","not_matched","unknown"]},"rosterValue":{"nullable":true,"type":"string"},"listValue":{"nullable":true,"type":"string"},"strong":{"type":"boolean"}},"required":["field","state","rosterValue","listValue","strong"],"additionalProperties":false}},"provenance":{"type":"object","properties":{"sourceList":{"type":"string","minLength":1},"listVersionId":{"type":"string","minLength":1},"retrievedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["sourceList","listVersionId","retrievedAt"],"additionalProperties":false},"score":{"type":"number","minimum":0,"maximum":1}},"required":["label","fields","provenance","score"],"additionalProperties":false}},"sources":{"type":"array","items":{"type":"object","properties":{"source":{"type":"string","minLength":1},"listVersionId":{"type":"string","minLength":1},"retrievedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["source","listVersionId","retrievedAt"],"additionalProperties":false}},"checkedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["id","status","matches","sources","checkedAt"],"additionalProperties":false},"MonitorRemoved":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["id"],"additionalProperties":false},"BatchScreenRequest":{"type":"object","properties":{"items":{"minItems":1,"maxItems":2000,"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["person"]},"name":{"type":"string","minLength":1,"maxLength":255},"aliases":{"maxItems":50,"type":"array","items":{"type":"string","maxLength":255}},"dateOfBirth":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"npi":{"type":"string","minLength":10,"maxLength":10},"state":{"type":"string","minLength":2,"maxLength":2},"providerType":{"type":"string","maxLength":255}},"required":["type","name"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","enum":["organization"]},"legalName":{"type":"string","minLength":1,"maxLength":255},"aliases":{"maxItems":50,"type":"array","items":{"type":"string","maxLength":255}},"npi":{"type":"string","minLength":10,"maxLength":10},"state":{"type":"string","minLength":2,"maxLength":2}},"required":["type","legalName"],"additionalProperties":false}]}}},"required":["items"],"additionalProperties":false},"BatchScreenAccepted":{"type":"object","properties":{"jobId":{"type":"string","minLength":1}},"required":["jobId"],"additionalProperties":false},"BatchJobStatus":{"type":"object","properties":{"jobId":{"type":"string","minLength":1},"state":{"type":"string","enum":["queued","processing","completed"]},"totalItems":{"type":"integer","minimum":0,"maximum":9007199254740991},"completedItems":{"type":"integer","minimum":0,"maximum":9007199254740991},"failedItems":{"type":"integer","minimum":0,"maximum":9007199254740991},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"startedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"completedAt":{"nullable":true,"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"results":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"index":{"type":"integer","minimum":0,"maximum":9007199254740991},"outcome":{"type":"string","enum":["completed"]},"result":{"type":"object","properties":{"status":{"type":"string","enum":["clear","potential_match"]},"matches":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string","minLength":1},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","enum":["name","npi","state","providerType","dateOfBirth"]},"state":{"type":"string","enum":["matched","not_matched","unknown"]},"rosterValue":{"nullable":true,"type":"string"},"listValue":{"nullable":true,"type":"string"},"strong":{"type":"boolean"}},"required":["field","state","rosterValue","listValue","strong"],"additionalProperties":false}},"provenance":{"type":"object","properties":{"sourceList":{"type":"string","minLength":1},"listVersionId":{"type":"string","minLength":1},"retrievedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["sourceList","listVersionId","retrievedAt"],"additionalProperties":false},"score":{"type":"number","minimum":0,"maximum":1}},"required":["label","fields","provenance","score"],"additionalProperties":false}},"sources":{"type":"array","items":{"type":"object","properties":{"source":{"type":"string","minLength":1},"listVersionId":{"type":"string","minLength":1},"retrievedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["source","listVersionId","retrievedAt"],"additionalProperties":false}},"checkedAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},"recallCapped":{"type":"boolean"}},"required":["status","matches","sources","checkedAt","recallCapped"],"additionalProperties":false}},"required":["index","outcome","result"],"additionalProperties":false},{"type":"object","properties":{"index":{"type":"integer","minimum":0,"maximum":9007199254740991},"outcome":{"type":"string","enum":["error"]},"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_request"]},"message":{"type":"string"},"fields":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}},"required":["code","message","fields"],"additionalProperties":false}},"required":["index","outcome","error"],"additionalProperties":false}]}}},"required":["jobId","state","totalItems","completedItems","failedItems","createdAt","startedAt","completedAt"],"additionalProperties":false},"ApiError":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","rate_limited","forbidden","invalid_request","not_found"]},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false}}},"paths":{"/screen":{"post":{"operationId":"screenEntity","tags":["Screen"],"summary":"Screen one person or organization","description":"Screen a single person or organization synchronously against the current pinned list versions. Returns status `clear` or `potential_match` with per-field evidence and provenance — never an automated \"excluded\" verdict. Each successful call counts toward the org’s metered API usage. Pass an optional `Idempotency-Key` header so retries are not double-counted.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Optional dedup key for metering. Retries with the same key are not double-counted; when omitted a unique key is generated server-side so the call still counts once."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScreenRequest"},"examples":{"person":{"summary":"A person","value":{"type":"person","name":"Jane Q. Example","dateOfBirth":"1980-04-12","npi":"1234567893","state":"NJ"}},"organization":{"summary":"An organization","value":{"type":"organization","legalName":"Example Home Health LLC","state":"NJ"}}}}}},"responses":{"200":{"description":"Screen result with status, evidence, and provenance.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScreenResponse"}}}},"400":{"description":"Invalid payload; `fields` names each invalid field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScreenValidationError"}}}},"401":{"description":"Missing or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"The organization has used its monthly allowance on a plan that does not bill the excess. The response names the date the count returns to zero and the plans that would give more room before then. Nothing is charged and no usage is recorded for a refused call.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"The organization is read-only — a lapsed trial, or a payment that has run past its grace period. Reads of your own data continue; writes and screenings do not.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"The plan’s documented rate limit was exceeded — see “Rate limits” above for the ceiling per tier. Also returned, briefly, if the rate-limiter store is unreachable: requests are refused rather than served uncounted, so retry after the indicated delay.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}}}}}},"/batch":{"post":{"operationId":"submitBatchScreen","tags":["Batch"],"summary":"Submit a batch screen job","description":"Accept a JSON list of entities for asynchronous screening. Returns immediately with a job id; poll `GET /batch/{jobId}` for state (queued → processing → completed) and per-item results. Each completed item is metered like a single screen. Requires an `Idempotency-Key` so retries return the same job without duplicate work. One invalid item is reported individually and never fails the batch.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"},"example":"roster-import-2026-10-06","description":"Required client-supplied dedup key. Resubmitting with the same key returns the same job id and performs no additional screening or metering."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchScreenRequest"},"example":{"items":[{"type":"person","name":"Jane Q. Example","dateOfBirth":"1980-04-12","npi":"1234567893","state":"NJ"},{"type":"organization","legalName":"Example Home Health LLC","state":"NJ"}]}}}},"responses":{"202":{"description":"Batch accepted; process in the background.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchScreenAccepted"}}}},"400":{"description":"Invalid payload or missing Idempotency-Key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScreenValidationError"}}}},"401":{"description":"Missing or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"The organization has used its monthly allowance on a plan that does not bill the excess. The response names the date the count returns to zero and the plans that would give more room before then. Nothing is charged and no usage is recorded for a refused call.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"The organization is read-only — a lapsed trial, or a payment that has run past its grace period. Reads of your own data continue; writes and screenings do not.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"The plan’s documented rate limit was exceeded — see “Rate limits” above for the ceiling per tier. Also returned, briefly, if the rate-limiter store is unreachable: requests are refused rather than served uncounted, so retry after the indicated delay.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}}}}}},"/batch/{jobId}":{"get":{"operationId":"getBatchJob","tags":["Batch"],"summary":"Get batch job status and results","description":"Poll a batch job’s lifecycle state. When `state` is `completed`, the response includes per-item results: `clear` or `potential_match` with evidence and provenance, or an isolated item error. Never an automated excluded boolean.","parameters":[{"name":"jobId","in":"path","required":true,"schema":{"type":"string"},"description":"The job id returned by `POST /batch`."}],"responses":{"200":{"description":"Job status; results present when completed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchJobStatus"}}}},"401":{"description":"Missing or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"The organization has used its monthly allowance on a plan that does not bill the excess. The response names the date the count returns to zero and the plans that would give more room before then. Nothing is charged and no usage is recorded for a refused call.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"The organization is read-only — a lapsed trial, or a payment that has run past its grace period. Reads of your own data continue; writes and screenings do not.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Unknown job id for this API key’s org.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"The plan’s documented rate limit was exceeded — see “Rate limits” above for the ceiling per tier. Also returned, briefly, if the rate-limiter store is unreachable: requests are refused rather than served uncounted, so retry after the indicated delay.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}}}}}},"/monitor":{"put":{"operationId":"enrollMonitor","tags":["Monitor"],"summary":"Enroll an entity in continuous monitoring","description":"Enroll one person or organization in continuous monitoring. The entity is screened immediately and added to your organization’s monitoring (tagged source `api`); the response returns its monitored-record id and current status — `clear` or `potential_match` with per-field evidence and provenance, never an automated \"excluded\" verdict. From then on it is re-screened whenever a covered source publishes a new immutable list version, and a match-status-change webhook announces any change. Each entity under monitoring accrues one metered record-month per billing month, reported by `GET /usage`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MonitorRequest"},"examples":{"person":{"summary":"A person","value":{"type":"person","name":"Jane Q. Example","dateOfBirth":"1980-04-12","npi":"1234567893","state":"NJ"}},"organization":{"summary":"An organization","value":{"type":"organization","legalName":"Example Home Health LLC","state":"NJ"}}}}}},"responses":{"200":{"description":"Enrolled; monitored-record id plus current status, evidence, and provenance.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MonitorResponse"}}}},"400":{"description":"Invalid payload; `fields` names each invalid field.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScreenValidationError"}}}},"401":{"description":"Missing or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"The organization has used its monthly allowance on a plan that does not bill the excess. The response names the date the count returns to zero and the plans that would give more room before then. Nothing is charged and no usage is recorded for a refused call.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"The organization is read-only — a lapsed trial, or a payment that has run past its grace period. Reads of your own data continue; writes and screenings do not.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"The plan’s documented rate limit was exceeded — see “Rate limits” above for the ceiling per tier. Also returned, briefly, if the rate-limiter store is unreachable: requests are refused rather than served uncounted, so retry after the indicated delay.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}}}}}},"/monitor/{id}":{"delete":{"operationId":"removeMonitor","tags":["Monitor"],"summary":"Remove an entity from continuous monitoring","description":"Take an entity out of continuous monitoring by its monitored-record id. No further re-screens or webhooks are produced for it. An unknown id — or a second delete for an id already removed — returns 404.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"The monitored-record id returned by `PUT /monitor`."}],"responses":{"200":{"description":"Removed; the monitored-record id that left monitoring.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MonitorRemoved"}}}},"401":{"description":"Missing or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"The organization has used its monthly allowance on a plan that does not bill the excess. The response names the date the count returns to zero and the plans that would give more room before then. Nothing is charged and no usage is recorded for a refused call.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"The organization is read-only — a lapsed trial, or a payment that has run past its grace period. Reads of your own data continue; writes and screenings do not.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Unknown or already-removed monitored-record id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"The plan’s documented rate limit was exceeded — see “Rate limits” above for the ceiling per tier. Also returned, briefly, if the rate-limiter store is unreachable: requests are refused rather than served uncounted, so retry after the indicated delay.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}}}}}},"/lists":{"get":{"operationId":"getCoverage","tags":["Coverage"],"summary":"Live coverage and list versions","description":"Every source screened against with its current immutable list_version id, retrieval date, and update cadence, plus honestly-stated gaps. Reads the same coverage metadata as the in-app coverage page, so both agree at the same moment.","responses":{"200":{"description":"Current coverage and freshness.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CoverageResponse"}}}},"401":{"description":"Missing or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"The organization has used its monthly allowance on a plan that does not bill the excess. The response names the date the count returns to zero and the plans that would give more room before then. Nothing is charged and no usage is recorded for a refused call.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"The organization is read-only — a lapsed trial, or a payment that has run past its grace period. Reads of your own data continue; writes and screenings do not.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"The plan’s documented rate limit was exceeded — see “Rate limits” above for the ceiling per tier. Also returned, briefly, if the rate-limiter store is unreachable: requests are refused rather than served uncounted, so retry after the indicated delay.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}}}}}},"/usage":{"get":{"operationId":"getUsage","tags":["Usage"],"summary":"Current billing-period consumption","description":"This billing period’s metered consumption — /v1/screen calls and monitored record-months, priced — matching exactly what is metered for billing over the same period, so you can reconcile before the invoice arrives.","responses":{"200":{"description":"Current-period usage, priced.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiUsageSummary"}}}},"401":{"description":"Missing or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"The organization has used its monthly allowance on a plan that does not bill the excess. The response names the date the count returns to zero and the plans that would give more room before then. Nothing is charged and no usage is recorded for a refused call.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"The organization is read-only — a lapsed trial, or a payment that has run past its grace period. Reads of your own data continue; writes and screenings do not.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"The plan’s documented rate limit was exceeded — see “Rate limits” above for the ceiling per tier. Also returned, briefly, if the rate-limiter store is unreachable: requests are refused rather than served uncounted, so retry after the indicated delay.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}}}}}}}}