{"openapi":"3.1.0","info":{"title":"Dira Verify API","version":"0.1.0","description":"Zambia business verification (KYB): registry, tax, VAT and annual-return checks against PACRA and ZRA, licence registers and screening lists, served with per-field provenance and issued as immutable verification records.\n\n**Attribution.** Registered information from PACRA, ZRA and the named registers; not a credit assessment. `meta.attribution` is present on every success response; every fact carries `source`, `source_url` and `read_at`/`fetched_at`.\n\n**Not a credit score.** A verification's `score` is the share of requested checks that passed — a summary of the checks, never a creditworthiness opinion. Screening matches are reported only as *pending human review*, never as facts.\n\n**Freshness.** `meta.data_as_of` is the newest successful registry read in the mirror. `POST /v1/verifications` re-reads PACRA and ZRA live unless the subject's records were read within the last 15 minutes (`cached: true` then). Search never reads live.\n\n**Authentication.** Every `/v1` data endpoint needs an API key: `Authorization: Bearer dira_live_…` (canonical) or `X-API-Key: dira_live_…`. `dira_test_` keys behave identically today. `GET /verify/{id}` and this document need no key but are limited per IP.\n\n**Errors.** Every non-2xx answer is `application/problem+json` (RFC 9457, component `Problem`). Branch on `type` and `status` — never on `detail`.\n\n**Limits.** Per-key requests/minute and a daily (Free) or monthly quota by plan (`X-RateLimit-*`, `X-Quota-*`; 429 with `Retry-After`) — a verification counts as one request. `limit` and paging depth are capped per plan; cursors are signed, valid for 1 hour and bound to the issuing key.","contact":{"name":"Bright (owner)","email":"brightl.dev@gmail.com"},"license":{"name":"Registered information attributed to PACRA, ZRA and the named registers. API: commercial terms of service.","url":"https://dira.oapps.dev/docs"}},"components":{"securitySchemes":{"bearerApiKey":{"type":"http","scheme":"bearer","bearerFormat":"dira_live_… | dira_test_…","description":"Canonical. `Authorization: Bearer <key>` where the key is `dira_live_` or `dira_test_` followed by 43 base64url characters. Shown once when issued; hashed at rest."},"apiKeyHeader":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Fallback for clients that cannot set `Authorization`. Same key format; when both headers are present `Authorization` wins."}},"schemas":{"Problem":{"type":"object","properties":{"type":{"type":"string","description":"Problem class URI. Relative `/problems/<slug>` (stable identifiers — see /docs/versioning) or `about:blank` when the status code says it all."},"title":{"type":"string","description":"Short human-readable summary of the problem class."},"status":{"type":"integer","minimum":400,"maximum":599,"description":"HTTP status code (repeated)."},"detail":{"description":"Human-readable explanation specific to this occurrence. Not a contract.","type":"string"},"instance":{"description":"The request path that produced the problem.","type":"string"},"errors":{"description":"Field-level failures (400 `/problems/validation` and `/problems/plan-limit`).","type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"JSON-pointer-ish path within the offending request part, e.g. \"/per_page\"."},"message":{"type":"string"}},"required":["field","message"]}},"plan":{"description":"On `/problems/plan-limit`: the plan the key is on (free|pro|business|enterprise).","type":"string"},"limit":{"description":"On `/problems/plan-limit`: the plan limit that was hit; null when the action is not available at all.","type":["number","null"]}},"required":["type","title","status"],"description":"RFC 7807 problem details (`application/problem+json`). Every non-2xx response of the API has this shape."},"Meta":{"type":"object","properties":{"page":{"anyOf":[{"type":"integer","exclusiveMinimum":0},{"type":"null"}],"description":"1-based page for offset-paginated lists; null on cursor lists and single resources."},"per_page":{"anyOf":[{"type":"integer","exclusiveMinimum":0},{"type":"null"}],"description":"Rows per page; null on single resources."},"total":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}],"description":"Total matching rows; null on single resources and on endpoints that deliberately do not count (e.g. /v1/tenders/latest)."},"attribution":{"type":"string","const":"Registered information from PACRA, ZRA and the named registers; not a credit assessment.","description":"Always this exact string. Reproduce it wherever the data is shown."},"next_cursor":{"description":"Cursor-paginated lists only: pass as `cursor` to fetch the next page; null on the last page; absent elsewhere.","type":["string","null"]},"data_as_of":{"description":"ISO 8601 UTC completion time of the most recent successful ingest of any source; null until the first successful ingest. See the freshness guide.","type":["string","null"]}},"required":["page","per_page","total","attribution","data_as_of"],"description":"Envelope metadata present on every success response."},"Provenance":{"type":"object","properties":{"source":{"type":"string","enum":["pacra","zra","napsa","mprs","egp","zamra","cadastre","boz","zicta","ncc","hpcz","zta","pia","sec","zica","gazette","sanctions_un","sanctions_ofac","sanctions_uk","sanctions_eu","debar_wb","debar_afdb"],"description":"Registry the record was read from."},"source_url":{"type":"string","description":"The exact request that produced the record."},"fetched_at":{"type":"string","description":"When the record was read from the source."},"content_hash":{"type":"string","description":"sha256 of the canonical payload (version identity)."}},"required":["source","source_url","fetched_at","content_hash"],"description":"Where and when a fact was read."},"EntityTax":{"type":"object","properties":{"check":{"type":"string","enum":["pass","attention","fail","unknown"],"description":"What the `tax` check reads: pass | attention | fail | unknown."},"basis":{"type":"string","enum":["company","owner_tpin","none"],"description":"`company`: the entity’s own taxpayer record (name match or hard key). `owner_tpin`: a business name linked to its owner’s personal TPIN by a human (business names are taxed under the owner). `none`: no record."},"status_label":{"type":"string","description":"Human label of the ZRA status: `Registered`, `Registration incomplete`, `Deregistered`, an unrecognised status title-cased, or `Owner’s TPIN needed`."},"status_meaning":{"type":"string","description":"One sentence saying what the label means."},"status_raw":{"description":"The ZRA `status` exactly as served (`ACTIVE`, `INTERFACE_PENDING_COMPLETION`, …); null without a record.","type":["string","null"]},"owner_tpin_required":{"type":"boolean","description":"True for a business name with no owner-TPIN link: `POST /v1/entities/{id}/owner-tpin` links the owner’s record."},"personal_data":{"type":"boolean","description":"True when the record is a natural person’s (owner TPIN). Handle as personal data; access is logged."},"payload":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}],"description":"The ZRA record (camelCase); null when none is linked."},"provenance":{"anyOf":[{"$ref":"#/components/schemas/Provenance"},{"type":"null"}]},"link_confidence":{"type":["number","null"]}},"required":["check","basis","status_label","status_meaning","status_raw","owner_tpin_required","personal_data","payload","provenance","link_confidence"],"description":"The entity’s tax reading and record."},"EntitySummary":{"type":"object","properties":{"id":{"type":"string","description":"Entity uuid — the public identifier until Dira IDs are assigned."},"dira_id":{"description":"Dira ID (`ZM-…`) when assigned.","type":["string","null"]},"name":{"type":"string","description":"Canonical registered name (PACRA)."},"kind":{"type":"string","enum":["company","business_name","cooperative","society","foreign","unknown"]},"status":{"description":"PACRA `entityStatus` of the primary record.","type":["string","null"]},"registry_no":{"description":"PACRA `entityNumber`; null when PACRA serves none.","type":["string","null"]},"tax":{"type":"object","properties":{"tpin":{"type":["string","null"]},"linked":{"type":"boolean","description":"True when a ZRA record is linked to the entity."},"confidence":{"description":"Confidence of the PACRA↔ZRA link (0–1).","type":["number","null"]},"basis":{"type":"string","enum":["company","owner_tpin","none"],"description":"`company`: the entity’s own taxpayer record (name match or hard key). `owner_tpin`: a business name linked to its owner’s personal TPIN by a human (business names are taxed under the owner). `none`: no record."}},"required":["tpin","linked","confidence","basis"]},"links":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"integer"},"description":"Linked (auto/reviewed) records per source, e.g. `{ \"pacra\": 1, \"zra\": 1 }`."},"as_of":{"anyOf":[{"type":"string","description":"ISO 8601 UTC instant."},{"type":"null"}],"description":"Newest `fetched_at` among this entity’s records."}},"required":["id","dira_id","name","kind","status","registry_no","tax","links","as_of"],"description":"One search result."},"LicenceRecord":{"type":"object","properties":{"source":{"type":"string","enum":["pacra","zra","napsa","mprs","egp","zamra","cadastre","boz","zicta","ncc","hpcz","zta","pia","sec","zica","gazette","sanctions_un","sanctions_ofac","sanctions_uk","sanctions_eu","debar_wb","debar_afdb"]},"key":{"type":"string","description":"The register’s own key for the record."},"summary":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"Register-specific summary fields."},"confidence":{"type":"number","description":"Link confidence (0–1)."},"source_url":{"type":"string"},"fetched_at":{"type":"string","description":"ISO 8601 UTC instant."}},"required":["source","key","summary","confidence","source_url","fetched_at"]},"PendingReview":{"type":"object","properties":{"source":{"type":"string","enum":["pacra","zra","napsa","mprs","egp","zamra","cadastre","boz","zicta","ncc","hpcz","zta","pia","sec","zica","gazette","sanctions_un","sanctions_ofac","sanctions_uk","sanctions_eu","debar_wb","debar_afdb"],"description":"The screening list."},"candidate":{"type":"string","description":"The listed name that scored against this entity."},"score":{"type":"number","description":"Name score (0.75–1). A score is not a match."},"source_url":{"type":"string"},"fetched_at":{"type":"string","description":"ISO 8601 UTC instant."}},"required":["source","candidate","score","source_url","fetched_at"],"description":"A screening-list name awaiting human review. Never a confirmed match."},"GazetteNotice":{"type":"object","properties":{"notice_type":{"type":"string"},"issue_date":{"type":"string"},"issue_no":{"type":"string"},"source_url":{"type":"string"},"fetched_at":{"type":"string","description":"ISO 8601 UTC instant."}},"required":["notice_type","issue_date","issue_no","source_url","fetched_at"],"description":"A Gazette notice joined by the entity’s PACRA number."},"GroupEdge":{"type":"object","properties":{"id":{"type":"integer"},"direction":{"type":"string","enum":["out","in"]},"type":{"type":"string"},"entity":{"type":"object","properties":{"id":{"type":"string"},"dira_id":{"type":["string","null"]},"name":{"type":"string"}},"required":["id","dira_id","name"]},"confidence":{"type":"number"},"evidence":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"first_seen_at":{"type":"string","description":"ISO 8601 UTC instant."},"last_seen_at":{"type":"string","description":"ISO 8601 UTC instant."}},"required":["id","direction","type","entity","confidence","evidence","first_seen_at","last_seen_at"]},"Signal":{"type":"object","properties":{"id":{"type":"integer"},"type":{"type":"string","enum":["returns_lapsed","strike_off_risk","deregistered_tax","vat_not_registered","registry_inactive","fresh_entity_award","name_lookalike","recent_status_change","group_member","no_tax_link","licence_expired","ncc_grade_below_claim","sanctions_hit","debarred","gazette_strike_off","name_changed","winding_up","licence_cancelled"]},"severity":{"type":"string","enum":["info","warn","high"]},"evidence":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"rule_version":{"type":"integer"},"opened_at":{"type":"string","description":"ISO 8601 UTC instant."},"resolved_at":{"anyOf":[{"type":"string","description":"ISO 8601 UTC instant."},{"type":"null"}]}},"required":["id","type","severity","evidence","rule_version","opened_at","resolved_at"]},"EntityProfile":{"type":"object","properties":{"id":{"type":"string"},"dira_id":{"type":["string","null"]},"name":{"type":"string"},"normalized_name":{"type":"string"},"kind":{"type":"string","enum":["company","business_name","cooperative","society","foreign","unknown"]},"created_at":{"type":"string","description":"ISO 8601 UTC instant."},"updated_at":{"type":"string","description":"ISO 8601 UTC instant."},"registry":{"anyOf":[{"type":"object","properties":{"payload":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"The PACRA record (camelCase)."},"provenance":{"$ref":"#/components/schemas/Provenance"}},"required":["payload","provenance"]},{"type":"null"}]},"tax":{"$ref":"#/components/schemas/EntityTax"},"licences":{"type":"array","items":{"$ref":"#/components/schemas/LicenceRecord"}},"screening":{"type":"object","properties":{"review_pending":{"type":"array","items":{"$ref":"#/components/schemas/PendingReview"}},"hard_key_hits":{"type":"array","items":{"$ref":"#/components/schemas/GazetteNotice"}}},"required":["review_pending","hard_key_hits"]},"group":{"type":"array","items":{"$ref":"#/components/schemas/GroupEdge"}},"signals":{"type":"array","items":{"$ref":"#/components/schemas/Signal"},"description":"Open signals."},"versions_count":{"type":"integer"},"as_of":{"anyOf":[{"type":"string","description":"ISO 8601 UTC instant."},{"type":"null"}]},"last_verification":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"issued_at":{"type":"string","description":"ISO 8601 UTC instant."},"result":{"type":"object","properties":{"passed":{"type":"integer"},"attention":{"type":"integer"},"failed":{"type":"integer"},"unknown":{"type":"integer"}},"required":["passed","attention","failed","unknown"]}},"required":["id","issued_at","result"]},{"type":"null"}],"description":"The most recent verification record YOUR account issued for this entity; null when none. Other accounts’ records are never disclosed."}},"required":["id","dira_id","name","normalized_name","kind","created_at","updated_at","registry","tax","licences","screening","group","signals","versions_count","as_of","last_verification"],"description":"Entity profile; every fact carries provenance."},"HistoryItem":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"version"},"id":{"type":"integer"},"at":{"type":"string","description":"ISO 8601 UTC instant."},"source":{"type":"string","enum":["pacra","zra","napsa","mprs","egp","zamra","cadastre","boz","zicta","ncc","hpcz","zta","pia","sec","zica","gazette","sanctions_un","sanctions_ofac","sanctions_uk","sanctions_eu","debar_wb","debar_afdb"]},"source_key":{"type":"string"},"source_url":{"type":"string"},"record_id":{"type":"string"},"fetched_at":{"type":"string","description":"ISO 8601 UTC instant."},"observed_at":{"type":"string","description":"ISO 8601 UTC instant."},"content_hash":{"type":"string"}},"required":["kind","id","at","source","source_key","source_url","record_id","fetched_at","observed_at","content_hash"]},{"type":"object","properties":{"kind":{"type":"string","const":"event"},"id":{"type":"integer"},"at":{"type":"string","description":"ISO 8601 UTC instant."},"type":{"type":"string","enum":["new_registration","status_changed","name_changed","returns_lapsed","returns_filed","tax_type_added","tax_type_removed","deregistered","tender_awarded","licence_issued","licence_expired","licence_cancelled","gazette_strike_off","winding_up","sanctions_listed","sanctions_delisted","debarred","record_removed"]},"source":{"type":"string","enum":["pacra","zra","napsa","mprs","egp","zamra","cadastre","boz","zicta","ncc","hpcz","zta","pia","sec","zica","gazette","sanctions_un","sanctions_ofac","sanctions_uk","sanctions_eu","debar_wb","debar_afdb"]},"source_url":{"type":"string"},"record_id":{"type":"string"},"record_version_id":{"anyOf":[{"type":"integer"},{"type":"null"}]},"fetched_at":{"type":"string","description":"ISO 8601 UTC instant."},"occurred_at":{"anyOf":[{"type":"string","description":"ISO 8601 UTC instant."},{"type":"null"}]},"observed_at":{"type":"string","description":"ISO 8601 UTC instant."},"content_hash":{"type":"string"},"diff":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"before":{},"after":{}},"required":["path"]}}},"required":["kind","id","at","type","source","source_url","record_id","record_version_id","fetched_at","occurred_at","observed_at","content_hash","diff"]}],"description":"A record version or an event, newest first."},"Check":{"type":"object","properties":{"status":{"type":"string","enum":["pass","attention","fail","unknown"]},"value":{"description":"The fact the status was derived from (type varies per check)."},"source":{"type":"string","description":"`pacra`, `zra`, or `dira` (derived from Dira’s own link/review state)."},"source_url":{"type":["string","null"]},"read_at":{"anyOf":[{"type":"string","description":"ISO 8601 UTC instant."},{"type":"null"}],"description":"When the underlying record was read from its source."}},"required":["status","value","source","source_url","read_at"],"additionalProperties":{},"description":"One check with its provenance and check-specific extras."},"Checks":{"type":"object","properties":{"registry":{"$ref":"#/components/schemas/Check"},"tax":{"$ref":"#/components/schemas/Check"},"vat":{"$ref":"#/components/schemas/Check"},"returns":{"$ref":"#/components/schemas/Check"},"licences":{"$ref":"#/components/schemas/Check"},"screening":{"$ref":"#/components/schemas/Check"}}},"Verification":{"type":"object","properties":{"id":{"type":"string","description":"Verification id — the public handle behind `/verify/{id}`."},"issued_at":{"type":"string","description":"ISO 8601 UTC instant."},"subject":{"type":"string","description":"The subject exactly as submitted."},"subject_kind":{"type":"string","enum":["name","tpin","dira_id","entity_id"]},"purpose":{"anyOf":[{"type":"string","enum":["supplier_onboarding","credit_application","periodic_review","other"]},{"type":"null"}]},"reference":{"type":["string","null"]},"entity":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"dira_id":{"type":["string","null"]},"name":{"type":"string"},"kind":{"type":"string","enum":["company","business_name","cooperative","society","foreign","unknown"]},"match_confidence":{"type":["number","null"]}},"required":["id","dira_id","name","kind","match_confidence"]},{"type":"null"}]},"result":{"type":"object","properties":{"passed":{"type":"integer"},"attention":{"type":"integer"},"failed":{"type":"integer"},"unknown":{"type":"integer"}},"required":["passed","attention","failed","unknown"]},"score":{"description":"passed / (passed + attention + failed). A summary of the checks — not a credit score.","type":["number","null"]},"checks":{"$ref":"#/components/schemas/Checks"},"cached":{"type":"boolean","description":"True when a check was served from the mirror rather than a live read in this request."},"sources_failed":{"type":"array","items":{"type":"string","enum":["pacra","zra","napsa","mprs","egp","zamra","cadastre","boz","zicta","ncc","hpcz","zta","pia","sec","zica","gazette","sanctions_un","sanctions_ofac","sanctions_uk","sanctions_eu","debar_wb","debar_afdb"]},"description":"Live sources that did not answer in this request."},"as_of":{"anyOf":[{"type":"string","description":"ISO 8601 UTC instant."},{"type":"null"}],"description":"Oldest `read_at` among the record-backed checks."},"report_url":{"type":"string"},"report_sha256":{"description":"sha256 of the rendered PDF; null until the report is rendered.","type":["string","null"]}},"required":["id","issued_at","subject","subject_kind","purpose","reference","entity","result","score","checks","cached","sources_failed","as_of","report_url","report_sha256"],"description":"An immutable verification record."},"SearchMeta":{"type":"object","properties":{"page":{"anyOf":[{"type":"integer","exclusiveMinimum":0},{"type":"null"}],"description":"1-based page for offset-paginated lists; null on cursor lists and single resources."},"per_page":{"anyOf":[{"type":"integer","exclusiveMinimum":0},{"type":"null"}],"description":"Rows per page; null on single resources."},"total":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}],"description":"Total matching rows; null on single resources and on endpoints that deliberately do not count (e.g. /v1/tenders/latest)."},"attribution":{"type":"string","const":"Registered information from PACRA, ZRA and the named registers; not a credit assessment.","description":"Always this exact string. Reproduce it wherever the data is shown."},"next_cursor":{"description":"Cursor-paginated lists only: pass as `cursor` to fetch the next page; null on the last page; absent elsewhere.","type":["string","null"]},"data_as_of":{"description":"ISO 8601 UTC completion time of the most recent successful ingest of any source; null until the first successful ingest. See the freshness guide.","type":["string","null"]},"searched_live":{"type":"boolean","description":"True when PACRA/ZRA were read live for this response (index miss, or `live=1`); false when it came from Dira’s index only."},"live_sources":{"type":"array","items":{"type":"string","enum":["pacra","zra"]},"description":"Registries asked live for this response, in order; empty when not searched live."},"live_errors":{"type":"array","items":{"type":"object","properties":{"source":{"type":"string","enum":["pacra","zra"]},"reason":{"type":"string","description":"Coarse reason: `http_503`, `timeout`, `schema_drift`, `network`, `unavailable`."}},"required":["source","reason"]},"description":"Registries that could not be reached during the live read. When `data` is empty and this is non-empty the answer is \"unknown\", not \"not on the register\"."}},"required":["page","per_page","total","attribution","data_as_of","searched_live","live_sources","live_errors"],"description":"Envelope metadata on search responses."},"OwnerTpinConflictProblem":{"type":"object","properties":{"type":{"type":"string","description":"Problem class URI. Relative `/problems/<slug>` (stable identifiers — see /docs/versioning) or `about:blank` when the status code says it all."},"title":{"type":"string","description":"Short human-readable summary of the problem class."},"status":{"type":"integer","minimum":400,"maximum":599,"description":"HTTP status code (repeated)."},"detail":{"description":"Human-readable explanation specific to this occurrence. Not a contract.","type":"string"},"instance":{"description":"The request path that produced the problem.","type":"string"},"errors":{"description":"Field-level failures (400 `/problems/validation` and `/problems/plan-limit`).","type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"JSON-pointer-ish path within the offending request part, e.g. \"/per_page\"."},"message":{"type":"string"}},"required":["field","message"]}},"plan":{"description":"On `/problems/plan-limit`: the plan the key is on (free|pro|business|enterprise).","type":"string"},"limit":{"description":"On `/problems/plan-limit`: the plan limit that was hit; null when the action is not available at all.","type":["number","null"]},"linked_tpin":{"description":"The owner TPIN already linked. Send `replace: true` to change it.","type":"string"}},"required":["type","title","status"]},"OwnerTpinUnavailableProblem":{"type":"object","properties":{"type":{"type":"string","description":"Problem class URI. Relative `/problems/<slug>` (stable identifiers — see /docs/versioning) or `about:blank` when the status code says it all."},"title":{"type":"string","description":"Short human-readable summary of the problem class."},"status":{"type":"integer","minimum":400,"maximum":599,"description":"HTTP status code (repeated)."},"detail":{"description":"Human-readable explanation specific to this occurrence. Not a contract.","type":"string"},"instance":{"description":"The request path that produced the problem.","type":"string"},"errors":{"description":"Field-level failures (400 `/problems/validation` and `/problems/plan-limit`).","type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"JSON-pointer-ish path within the offending request part, e.g. \"/per_page\"."},"message":{"type":"string"}},"required":["field","message"]}},"plan":{"description":"On `/problems/plan-limit`: the plan the key is on (free|pro|business|enterprise).","type":"string"},"limit":{"description":"On `/problems/plan-limit`: the plan limit that was hit; null when the action is not available at all.","type":["number","null"]},"sources":{"description":"The registries that did not answer.","type":"array","items":{"type":"string"}}},"required":["type","title","status"]},"NoMatchProblem":{"type":"object","properties":{"type":{"type":"string","description":"Problem class URI. Relative `/problems/<slug>` (stable identifiers — see /docs/versioning) or `about:blank` when the status code says it all."},"title":{"type":"string","description":"Short human-readable summary of the problem class."},"status":{"type":"integer","minimum":400,"maximum":599,"description":"HTTP status code (repeated)."},"detail":{"description":"Human-readable explanation specific to this occurrence. Not a contract.","type":"string"},"instance":{"description":"The request path that produced the problem.","type":"string"},"errors":{"description":"Field-level failures (400 `/problems/validation` and `/problems/plan-limit`).","type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"JSON-pointer-ish path within the offending request part, e.g. \"/per_page\"."},"message":{"type":"string"}},"required":["field","message"]}},"plan":{"description":"On `/problems/plan-limit`: the plan the key is on (free|pro|business|enterprise).","type":"string"},"limit":{"description":"On `/problems/plan-limit`: the plan limit that was hit; null when the action is not available at all.","type":["number","null"]},"subject":{"description":"The subject as classified and normalised.","type":"object","properties":{"kind":{"type":"string"},"submitted":{"type":"string"},"normalized":{"type":"string"}},"required":["kind","submitted","normalized"]},"no_match_record":{"description":"Hint: a no-match record type is a later item; retry with `entity_id` once the entity exists.","type":"string"}},"required":["type","title","status"]},"AmbiguousMatchProblem":{"type":"object","properties":{"type":{"type":"string","description":"Problem class URI. Relative `/problems/<slug>` (stable identifiers — see /docs/versioning) or `about:blank` when the status code says it all."},"title":{"type":"string","description":"Short human-readable summary of the problem class."},"status":{"type":"integer","minimum":400,"maximum":599,"description":"HTTP status code (repeated)."},"detail":{"description":"Human-readable explanation specific to this occurrence. Not a contract.","type":"string"},"instance":{"description":"The request path that produced the problem.","type":"string"},"errors":{"description":"Field-level failures (400 `/problems/validation` and `/problems/plan-limit`).","type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"JSON-pointer-ish path within the offending request part, e.g. \"/per_page\"."},"message":{"type":"string"}},"required":["field","message"]}},"plan":{"description":"On `/problems/plan-limit`: the plan the key is on (free|pro|business|enterprise).","type":"string"},"limit":{"description":"On `/problems/plan-limit`: the plan limit that was hit; null when the action is not available at all.","type":["number","null"]},"candidates":{"description":"Every candidate in the ambiguity band, best first.","type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"score":{"type":"number"}},"required":["id","name","score"]}}},"required":["type","title","status"]},"SourceUnavailableProblem":{"type":"object","properties":{"type":{"type":"string","description":"Problem class URI. Relative `/problems/<slug>` (stable identifiers — see /docs/versioning) or `about:blank` when the status code says it all."},"title":{"type":"string","description":"Short human-readable summary of the problem class."},"status":{"type":"integer","minimum":400,"maximum":599,"description":"HTTP status code (repeated)."},"detail":{"description":"Human-readable explanation specific to this occurrence. Not a contract.","type":"string"},"instance":{"description":"The request path that produced the problem.","type":"string"},"errors":{"description":"Field-level failures (400 `/problems/validation` and `/problems/plan-limit`).","type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"JSON-pointer-ish path within the offending request part, e.g. \"/per_page\"."},"message":{"type":"string"}},"required":["field","message"]}},"plan":{"description":"On `/problems/plan-limit`: the plan the key is on (free|pro|business|enterprise).","type":"string"},"limit":{"description":"On `/problems/plan-limit`: the plan limit that was hit; null when the action is not available at all.","type":["number","null"]},"sources":{"description":"The registries that did not answer.","type":"array","items":{"type":"string"}}},"required":["type","title","status"]},"MatchExistsProblem":{"type":"object","properties":{"type":{"type":"string","description":"Problem class URI. Relative `/problems/<slug>` (stable identifiers — see /docs/versioning) or `about:blank` when the status code says it all."},"title":{"type":"string","description":"Short human-readable summary of the problem class."},"status":{"type":"integer","minimum":400,"maximum":599,"description":"HTTP status code (repeated)."},"detail":{"description":"Human-readable explanation specific to this occurrence. Not a contract.","type":"string"},"instance":{"description":"The request path that produced the problem.","type":"string"},"errors":{"description":"Field-level failures (400 `/problems/validation` and `/problems/plan-limit`).","type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"JSON-pointer-ish path within the offending request part, e.g. \"/per_page\"."},"message":{"type":"string"}},"required":["field","message"]}},"plan":{"description":"On `/problems/plan-limit`: the plan the key is on (free|pro|business|enterprise).","type":"string"},"limit":{"description":"On `/problems/plan-limit`: the plan limit that was hit; null when the action is not available at all.","type":["number","null"]},"candidates":{"description":"The entities in the mirror that match the subject, best first.","type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"score":{"type":"number"}},"required":["id","name","score"]}}},"required":["type","title","status"]},"OwnerTpinRequest":{"type":"object","properties":{"tpin":{"type":"string","pattern":"^\\d{10}$","description":"The owner’s 10-digit personal TPIN."},"replace":{"description":"Replace an existing owner link to a different TPIN (otherwise 409). The old link is kept as `rejected` — nothing is deleted.","type":"boolean"}},"required":["tpin"]},"VerificationRequest":{"type":"object","properties":{"name":{"description":"Registered name as you have it. Fuzzy-matched; `match_confidence` is returned.","type":"string","minLength":2,"maxLength":200},"tpin":{"description":"10-digit ZRA TPIN. Exact; skips name matching.","type":"string","pattern":"^\\d{10}$"},"dira_id":{"description":"A Dira ID from a previous search or record.","type":"string","pattern":"^ZM-[0-9A-HJKMNP-TV-Z]{8}-[0-9A-HJKMNP-TV-Z]$"},"entity_id":{"description":"An entity uuid from `/v1/search` or a previous record.","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)$"},"purpose":{"description":"Kept with the record.","type":"string","enum":["supplier_onboarding","credit_application","periodic_review","other"]},"reference":{"description":"Your own reference, up to 64 characters.","type":"string","maxLength":64},"checks":{"description":"Subset of registry, tax, vat, returns, licences, screening. Default: the first four.","minItems":1,"type":"array","items":{"type":"string","enum":["registry","tax","vat","returns","licences","screening"]}}}},"NoMatchRequest":{"type":"object","properties":{"name":{"description":"The name that was searched for, exactly as submitted.","type":"string","minLength":2,"maxLength":200},"tpin":{"description":"The 10-digit TPIN that was searched for.","type":"string","pattern":"^\\d{10}$"},"purpose":{"description":"Kept with the record.","type":"string","enum":["supplier_onboarding","credit_application","periodic_review","other"]},"reference":{"description":"Your own reference, up to 64 characters.","type":"string","maxLength":64}}}}},"paths":{"/v1/openapi.json":{"get":{"operationId":"getOpenapiDocument","summary":"This OpenAPI document","tags":["Meta"],"description":"The machine-readable contract of the API (OpenAPI 3.1), generated from the same schemas that validate requests and responses. Public; per-IP rate-limited; cacheable for 5 minutes. The interactive reference is at /docs/reference.","security":[],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660}},"content":{"application/json":{"schema":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"An OpenAPI 3.1 document. See https://spec.openapis.org/oas/v3.1.0"},"example":{"openapi":"3.1.0","info":{"title":"Dira Verify API","version":"0.1.0"},"paths":{}}}}},"429":{"description":"Too many requests: per-key sliding-window limit (`/problems/rate-limited`), monthly quota (`/problems/quota-exceeded`), per-IP limit on public routes, or too many pending exports. `Retry-After` says when to retry.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait before retrying.","example":23}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/rate-limited","title":"Too Many Requests","status":429,"detail":"Rate limit of 60 requests per minute exceeded for this key. Retry after 23 s.","instance":"/v1/search?q=zambeef"}}}}}}},"/v1/search":{"get":{"operationId":"searchEntities","summary":"Search entities","tags":["Search"],"description":"Ranked search by registered name (exact > prefix > contains on the normalised name), by 10-digit TPIN, or by Dira ID. Dira’s index is searched first; when it holds nothing for a name or TPIN, PACRA and ZRA are read live (one request each, results kept and linked) and the search is re-run — expect ~5 s. Pass `live=1` to force a live read even when the index has hits (metered by the same rate limit as every read). `meta.searched_live` says which you got; `meta.live_errors` lists a registry that could not be reached — then an empty `data` means \"unknown\", not \"not on the register\". Dira-ID queries and cursor pages are never read live. Cursor-paginated: follow `meta.next_cursor` until it is null; `limit` and paging depth are capped per plan.","parameters":[{"schema":{"type":"string","minLength":2,"maxLength":200},"example":"zambeef","in":"query","name":"q","required":true,"description":"Name, TPIN or Dira ID."},{"schema":{"type":"string","enum":["company","business_name","cooperative","society","foreign","unknown"]},"in":"query","name":"kind","required":false,"description":"Filter by entity kind."},{"schema":{"type":"string","minLength":1,"maxLength":40},"in":"query","name":"status","required":false,"description":"Filter by PACRA `entityStatus` (case-insensitive), e.g. `Active`."},{"schema":{"default":"0","type":"string","enum":["0","1"]},"in":"query","name":"live","required":false,"description":"`1` forces a live PACRA + ZRA read for a name or TPIN even when the index has hits."},{"schema":{"type":"string"},"in":"query","name":"cursor","required":false,"description":"Opaque cursor from `meta.next_cursor`."},{"schema":{"default":20,"type":"integer","exclusiveMinimum":0,"maximum":100},"in":"query","name":"limit","required":false,"description":"Rows per page (default 20); capped per plan."}],"security":[{"bearerApiKey":[]},{"apiKeyHeader":[]}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/EntitySummary"}},"meta":{"$ref":"#/components/schemas/SearchMeta"}},"required":["data","meta"]},"example":{"data":[{"id":"3f1c2b7e-9a4d-4c8e-8b21-5d6f7a8b9c0d","dira_id":null,"name":"ZAMBEEF RETAILING LIMITED","kind":"company","status":"Active","registry_no":"119960035723","tax":{"tpin":"1001747472","linked":true,"confidence":1,"basis":"company"},"links":{"pacra":1,"zra":1},"as_of":"2026-09-21T09:02:58.000Z"}],"meta":{"page":null,"per_page":20,"total":null,"attribution":"Registered information from PACRA, ZRA and the named registers; not a credit assessment.","data_as_of":"2026-09-21T09:12:41.512Z","next_cursor":null,"searched_live":false,"live_sources":[],"live_errors":[]}}}}},"400":{"description":"Bad request — validation failed (`/problems/validation`, `errors[]`), the cursor is invalid/expired/foreign (`/problems/invalid-cursor`), or `per_page` exceeds the plan cap (`/problems/plan-limit`, 400 because a smaller request will succeed).","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/validation","title":"Request validation failed","status":400,"detail":"Invalid body. See errors for field-level details.","instance":"/v1/verifications","errors":[{"field":"/","message":"exactly one of name, tpin, dira_id, entity_id is required"}]}}}},"401":{"description":"Missing, malformed, unknown or revoked API key (`/problems/unauthorized`). Identical for every failure so keys cannot be enumerated.","headers":{"WWW-Authenticate":{"schema":{"type":"string"},"description":"Challenge for the missing/invalid key.","example":"Bearer realm=\"dira-api\""},"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/unauthorized","title":"Unauthorized","status":401,"detail":"A valid API key is required. Send it as `Authorization: Bearer <key>` (canonical) or `X-API-Key: <key>`.","instance":"/v1/search?q=zambeef"}}}},"403":{"description":"Authenticated, but the plan does not entitle the action (`/problems/plan-limit`): paging past the plan result window or bulk export below Business.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/plan-limit","title":"Result window exceeded for this plan","status":403,"detail":"The free plan can page at most 1000 results deep per query (you have reached 1000). Narrow the query or upgrade the plan.","instance":"/v1/search?q=zambeef&cursor=…","plan":"free","limit":1000}}}},"429":{"description":"Too many requests: per-key sliding-window limit (`/problems/rate-limited`), monthly quota (`/problems/quota-exceeded`), per-IP limit on public routes, or too many pending exports. `Retry-After` says when to retry.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"},"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait before retrying.","example":23}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/rate-limited","title":"Too Many Requests","status":429,"detail":"Rate limit of 60 requests per minute exceeded for this key. Retry after 23 s.","instance":"/v1/search?q=zambeef"}}}},"500":{"description":"Unexpected server error (`about:blank`). Details are logged server-side, never returned.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"about:blank","title":"Internal Server Error","status":500,"detail":"An unexpected error occurred.","instance":"/v1/search?q=zambeef"}}}}}}},"/v1/entities/{id}":{"get":{"operationId":"getEntity","summary":"Get an entity profile","tags":["Entities"],"description":"The registry record (PACRA), the linked tax record (ZRA), licence-register records, screening state, group edges and open signals — every fact with its `source`, `source_url`, `fetched_at` and `content_hash`. Screening matches appear only as `review_pending` (a score, never a fact); Gazette notices joined by PACRA number are `hard_key_hits`. Served from the mirror; `as_of` is the newest read among the records shown.","parameters":[{"schema":{"type":"string","minLength":1},"example":"3f1c2b7e-9a4d-4c8e-8b21-5d6f7a8b9c0d","in":"path","name":"id","required":true,"description":"Entity uuid or Dira ID (`ZM-…`)."}],"security":[{"bearerApiKey":[]},{"apiKeyHeader":[]}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/EntityProfile"},"meta":{"$ref":"#/components/schemas/Meta"}},"required":["data","meta"]},"example":{"data":{"id":"3f1c2b7e-9a4d-4c8e-8b21-5d6f7a8b9c0d","dira_id":null,"name":"ZAMBEEF RETAILING LIMITED","normalized_name":"ZAMBEEF RETAILING","kind":"company","created_at":"2026-09-21T08:40:00.000Z","updated_at":"2026-09-21T09:02:59.000Z","registry":{"payload":{"entityId":"55F24074-CBEC-4EAC-8214-0D8951310EC3","entityNumber":"119960035723","entityName":"ZAMBEEF RETAILING LIMITED","companyType":"Local Company - Limited by Shares","entityStatus":"Active","registrationDate":"1996-03-19","annualReturnStatus":false,"annualReturnMadeUpTo":"2024-09-28"},"provenance":{"source":"pacra","source_url":"https://xatu.pacra.org.zm:8344/api/v1/Search/registrysearch?Searchtext=ZAMBEEF%20RETAILING%20LIMITED","fetched_at":"2026-09-21T09:02:58.000Z","content_hash":"4c1e0f6b2a9d8e7f1c3b5a4d6e8f0a2b4c6d8e0f1a3b5c7d9e1f2a4b6c8d0e9f"}},"tax":{"check":"pass","basis":"company","status_label":"Registered","status_meaning":"Registered with ZRA.","status_raw":"ACTIVE","owner_tpin_required":false,"personal_data":false,"payload":{"tpin":"1001747472","taxPayerName":"ZAMBEEF RETAILING LIMITED","status":"ACTIVE","isDeregistered":false,"effectiveDateOfReg":"1996-05-01","taxTypes":["Pay As You Earn","Property Transfer Tax","Withholding Tax","Income Tax","Value Added Tax"]},"provenance":{"source":"zra","source_url":"https://portal.zra.org.zm/retrieveTaxpayersSearch#POST&taxpayername=ZAMBEEF%20RETAILING%20LIMITED","fetched_at":"2026-09-21T09:02:59.000Z","content_hash":"9f2a1b3c5d7e9f0a2b4c6d8e0f1a3b5c7d9e1f2a4b6c8d0e9f1a2b3c4d5e6f70"},"link_confidence":1},"licences":[],"screening":{"review_pending":[],"hard_key_hits":[]},"group":[],"signals":[{"id":41,"type":"returns_lapsed","severity":"warn","evidence":{"made_up_to":"2024-09-28"},"rule_version":1,"opened_at":"2026-09-21T09:03:00.000Z","resolved_at":null}],"versions_count":2,"as_of":"2026-09-21T09:02:59.000Z","last_verification":{"id":"7c9e6679-7425-40de-944b-e07fc1f90ae7","issued_at":"2026-09-21T09:03:41.000Z","result":{"passed":3,"attention":1,"failed":0,"unknown":0}}},"meta":{"page":null,"per_page":null,"total":null,"attribution":"Registered information from PACRA, ZRA and the named registers; not a credit assessment.","data_as_of":"2026-09-21T09:12:41.512Z"}}}}},"401":{"description":"Missing, malformed, unknown or revoked API key (`/problems/unauthorized`). Identical for every failure so keys cannot be enumerated.","headers":{"WWW-Authenticate":{"schema":{"type":"string"},"description":"Challenge for the missing/invalid key.","example":"Bearer realm=\"dira-api\""},"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/unauthorized","title":"Unauthorized","status":401,"detail":"A valid API key is required. Send it as `Authorization: Bearer <key>` (canonical) or `X-API-Key: <key>`.","instance":"/v1/search?q=zambeef"}}}},"404":{"description":"No such resource (`about:blank`).","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/no-match","title":"No matching entity","status":404,"detail":"No registered entity matched the subject at the required confidence (0.75).","instance":"/v1/verifications"}}}},"429":{"description":"Too many requests: per-key sliding-window limit (`/problems/rate-limited`), monthly quota (`/problems/quota-exceeded`), per-IP limit on public routes, or too many pending exports. `Retry-After` says when to retry.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"},"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait before retrying.","example":23}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/rate-limited","title":"Too Many Requests","status":429,"detail":"Rate limit of 60 requests per minute exceeded for this key. Retry after 23 s.","instance":"/v1/search?q=zambeef"}}}},"500":{"description":"Unexpected server error (`about:blank`). Details are logged server-side, never returned.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"about:blank","title":"Internal Server Error","status":500,"detail":"An unexpected error occurred.","instance":"/v1/search?q=zambeef"}}}}}}},"/v1/entities/{id}/history":{"get":{"operationId":"getEntityHistory","summary":"Entity timeline","tags":["Entities"],"description":"Record versions of every record linked to the entity, interleaved with the events derived from them, newest first. Cursor-paginated.","parameters":[{"schema":{"type":"string"},"in":"query","name":"cursor","required":false,"description":"Opaque cursor from `meta.next_cursor`."},{"schema":{"default":20,"type":"integer","exclusiveMinimum":0,"maximum":100},"in":"query","name":"limit","required":false,"description":"Rows per page (default 20); capped per plan."},{"schema":{"type":"string","minLength":1},"example":"3f1c2b7e-9a4d-4c8e-8b21-5d6f7a8b9c0d","in":"path","name":"id","required":true,"description":"Entity uuid or Dira ID (`ZM-…`)."}],"security":[{"bearerApiKey":[]},{"apiKeyHeader":[]}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/HistoryItem"}},"meta":{"$ref":"#/components/schemas/Meta"}},"required":["data","meta"]},"example":{"data":[{"kind":"event","id":12,"at":"2026-09-21T09:03:00.000Z","type":"returns_lapsed","source":"pacra","source_url":"https://xatu.pacra.org.zm:8344/api/v1/Search/registrysearch?Searchtext=ZAMBEEF%20RETAILING%20LIMITED","record_id":"a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d","record_version_id":2,"fetched_at":"2026-09-21T09:02:58.000Z","occurred_at":null,"observed_at":"2026-09-21T09:03:00.000Z","content_hash":"4c1e0f6b2a9d8e7f1c3b5a4d6e8f0a2b4c6d8e0f1a3b5c7d9e1f2a4b6c8d0e9f","diff":[{"path":"/annualReturnStatus","before":true,"after":false}]},{"kind":"version","id":2,"at":"2026-09-21T09:02:58.000Z","source":"pacra","source_key":"55F24074-CBEC-4EAC-8214-0D8951310EC3","source_url":"https://xatu.pacra.org.zm:8344/api/v1/Search/registrysearch?Searchtext=ZAMBEEF%20RETAILING%20LIMITED","record_id":"a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d","fetched_at":"2026-09-21T09:02:58.000Z","observed_at":"2026-09-21T09:02:58.000Z","content_hash":"4c1e0f6b2a9d8e7f1c3b5a4d6e8f0a2b4c6d8e0f1a3b5c7d9e1f2a4b6c8d0e9f"}],"meta":{"page":null,"per_page":20,"total":null,"attribution":"Registered information from PACRA, ZRA and the named registers; not a credit assessment.","data_as_of":"2026-09-21T09:12:41.512Z","next_cursor":null}}}}},"400":{"description":"Bad request — validation failed (`/problems/validation`, `errors[]`), the cursor is invalid/expired/foreign (`/problems/invalid-cursor`), or `per_page` exceeds the plan cap (`/problems/plan-limit`, 400 because a smaller request will succeed).","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/validation","title":"Request validation failed","status":400,"detail":"Invalid body. See errors for field-level details.","instance":"/v1/verifications","errors":[{"field":"/","message":"exactly one of name, tpin, dira_id, entity_id is required"}]}}}},"401":{"description":"Missing, malformed, unknown or revoked API key (`/problems/unauthorized`). Identical for every failure so keys cannot be enumerated.","headers":{"WWW-Authenticate":{"schema":{"type":"string"},"description":"Challenge for the missing/invalid key.","example":"Bearer realm=\"dira-api\""},"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/unauthorized","title":"Unauthorized","status":401,"detail":"A valid API key is required. Send it as `Authorization: Bearer <key>` (canonical) or `X-API-Key: <key>`.","instance":"/v1/search?q=zambeef"}}}},"403":{"description":"Authenticated, but the plan does not entitle the action (`/problems/plan-limit`): paging past the plan result window or bulk export below Business.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/plan-limit","title":"Result window exceeded for this plan","status":403,"detail":"The free plan can page at most 1000 results deep per query (you have reached 1000). Narrow the query or upgrade the plan.","instance":"/v1/search?q=zambeef&cursor=…","plan":"free","limit":1000}}}},"404":{"description":"No such resource (`about:blank`).","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/no-match","title":"No matching entity","status":404,"detail":"No registered entity matched the subject at the required confidence (0.75).","instance":"/v1/verifications"}}}},"429":{"description":"Too many requests: per-key sliding-window limit (`/problems/rate-limited`), monthly quota (`/problems/quota-exceeded`), per-IP limit on public routes, or too many pending exports. `Retry-After` says when to retry.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"},"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait before retrying.","example":23}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/rate-limited","title":"Too Many Requests","status":429,"detail":"Rate limit of 60 requests per minute exceeded for this key. Retry after 23 s.","instance":"/v1/search?q=zambeef"}}}},"500":{"description":"Unexpected server error (`about:blank`). Details are logged server-side, never returned.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"about:blank","title":"Internal Server Error","status":500,"detail":"An unexpected error occurred.","instance":"/v1/search?q=zambeef"}}}}}}},"/v1/entities/{id}/signals":{"get":{"operationId":"getEntitySignals","summary":"Entity signals","tags":["Entities"],"description":"Signals opened on the entity (`open`, `resolved` or `all`; default `all`), newest first. Cursor-paginated.","parameters":[{"schema":{"type":"string"},"in":"query","name":"cursor","required":false,"description":"Opaque cursor from `meta.next_cursor`."},{"schema":{"default":20,"type":"integer","exclusiveMinimum":0,"maximum":100},"in":"query","name":"limit","required":false,"description":"Rows per page (default 20); capped per plan."},{"schema":{"default":"all","type":"string","enum":["open","resolved","all"]},"in":"query","name":"status","required":false},{"schema":{"type":"string","minLength":1},"example":"3f1c2b7e-9a4d-4c8e-8b21-5d6f7a8b9c0d","in":"path","name":"id","required":true,"description":"Entity uuid or Dira ID (`ZM-…`)."}],"security":[{"bearerApiKey":[]},{"apiKeyHeader":[]}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Signal"}},"meta":{"$ref":"#/components/schemas/Meta"}},"required":["data","meta"]},"example":{"data":[{"id":41,"type":"returns_lapsed","severity":"warn","evidence":{"made_up_to":"2024-09-28"},"rule_version":1,"opened_at":"2026-09-21T09:03:00.000Z","resolved_at":null}],"meta":{"page":null,"per_page":20,"total":null,"attribution":"Registered information from PACRA, ZRA and the named registers; not a credit assessment.","data_as_of":"2026-09-21T09:12:41.512Z","next_cursor":null}}}}},"400":{"description":"Bad request — validation failed (`/problems/validation`, `errors[]`), the cursor is invalid/expired/foreign (`/problems/invalid-cursor`), or `per_page` exceeds the plan cap (`/problems/plan-limit`, 400 because a smaller request will succeed).","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/validation","title":"Request validation failed","status":400,"detail":"Invalid body. See errors for field-level details.","instance":"/v1/verifications","errors":[{"field":"/","message":"exactly one of name, tpin, dira_id, entity_id is required"}]}}}},"401":{"description":"Missing, malformed, unknown or revoked API key (`/problems/unauthorized`). Identical for every failure so keys cannot be enumerated.","headers":{"WWW-Authenticate":{"schema":{"type":"string"},"description":"Challenge for the missing/invalid key.","example":"Bearer realm=\"dira-api\""},"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/unauthorized","title":"Unauthorized","status":401,"detail":"A valid API key is required. Send it as `Authorization: Bearer <key>` (canonical) or `X-API-Key: <key>`.","instance":"/v1/search?q=zambeef"}}}},"403":{"description":"Authenticated, but the plan does not entitle the action (`/problems/plan-limit`): paging past the plan result window or bulk export below Business.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/plan-limit","title":"Result window exceeded for this plan","status":403,"detail":"The free plan can page at most 1000 results deep per query (you have reached 1000). Narrow the query or upgrade the plan.","instance":"/v1/search?q=zambeef&cursor=…","plan":"free","limit":1000}}}},"404":{"description":"No such resource (`about:blank`).","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/no-match","title":"No matching entity","status":404,"detail":"No registered entity matched the subject at the required confidence (0.75).","instance":"/v1/verifications"}}}},"429":{"description":"Too many requests: per-key sliding-window limit (`/problems/rate-limited`), monthly quota (`/problems/quota-exceeded`), per-IP limit on public routes, or too many pending exports. `Retry-After` says when to retry.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"},"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait before retrying.","example":23}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/rate-limited","title":"Too Many Requests","status":429,"detail":"Rate limit of 60 requests per minute exceeded for this key. Retry after 23 s.","instance":"/v1/search?q=zambeef"}}}},"500":{"description":"Unexpected server error (`about:blank`). Details are logged server-side, never returned.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"about:blank","title":"Internal Server Error","status":500,"detail":"An unexpected error occurred.","instance":"/v1/search?q=zambeef"}}}}}}},"/v1/entities/{id}/owner-tpin":{"post":{"operationId":"linkOwnerTpin","summary":"Link a business name to its owner's TPIN","tags":["Entities"],"description":"PACRA business names (sole traders, partnerships) are taxed under the owner’s personal TPIN and never appear in ZRA’s search by their trading name, so their profile carries no tax record until a person supplies it. Reads the taxpayer live from ZRA by TPIN, keeps the record flagged as personal data, and links it to the entity as a human-asserted link (`method: tpin`, confidence 1, `reviewed`, `reviewed_by` = you). Business names only (422 otherwise). Idempotent: the same TPIN again returns 200 with the same link; a different TPIN is 409 unless `replace: true`. Admin or verifier; auditors are refused. Returns the updated `tax` block of the profile. The access is logged.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OwnerTpinRequest"}}}},"parameters":[{"schema":{"type":"string","minLength":1},"example":"3f1c2b7e-9a4d-4c8e-8b21-5d6f7a8b9c0d","in":"path","name":"id","required":true,"description":"Entity uuid or Dira ID (`ZM-…`)."}],"security":[{"bearerApiKey":[]},{"apiKeyHeader":[]}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/EntityTax"},"meta":{"$ref":"#/components/schemas/Meta"}},"required":["data","meta"]},"example":{"data":{"check":"pass","basis":"owner_tpin","status_label":"Registered","status_meaning":"Taxed under the owner's personal TPIN — a natural person's record (personal data).","status_raw":"ACTIVE","owner_tpin_required":false,"personal_data":true,"payload":{"tpin":"1234567890","taxPayerName":"CHANDA MWAPE","status":"ACTIVE","isDeregistered":false,"effectiveDateOfReg":"2019-02-11","taxTypes":["Income Tax","Turnover Tax"]},"provenance":{"source":"zra","source_url":"https://portal.zra.org.zm/retrieveTaxpayersSearch#POST&tpin=1234567890","fetched_at":"2026-09-21T09:02:59.000Z","content_hash":"9f2a1b3c5d7e9f0a2b4c6d8e0f1a3b5c7d9e1f2a4b6c8d0e9f1a2b3c4d5e6f70"},"link_confidence":1},"meta":{"page":null,"per_page":null,"total":null,"attribution":"Registered information from PACRA, ZRA and the named registers; not a credit assessment.","data_as_of":"2026-09-21T09:12:41.512Z"}}}}},"400":{"description":"Bad request — validation failed (`/problems/validation`, `errors[]`), the cursor is invalid/expired/foreign (`/problems/invalid-cursor`), or `per_page` exceeds the plan cap (`/problems/plan-limit`, 400 because a smaller request will succeed).","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/validation","title":"Request validation failed","status":400,"detail":"Invalid body. See errors for field-level details.","instance":"/v1/verifications","errors":[{"field":"/","message":"exactly one of name, tpin, dira_id, entity_id is required"}]}}}},"401":{"description":"Missing, malformed, unknown or revoked API key (`/problems/unauthorized`). Identical for every failure so keys cannot be enumerated.","headers":{"WWW-Authenticate":{"schema":{"type":"string"},"description":"Challenge for the missing/invalid key.","example":"Bearer realm=\"dira-api\""},"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/unauthorized","title":"Unauthorized","status":401,"detail":"A valid API key is required. Send it as `Authorization: Bearer <key>` (canonical) or `X-API-Key: <key>`.","instance":"/v1/search?q=zambeef"}}}},"403":{"description":"A read-only console role (auditor) is refused with `/problems/role`.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/plan-limit","title":"Result window exceeded for this plan","status":403,"detail":"The free plan can page at most 1000 results deep per query (you have reached 1000). Narrow the query or upgrade the plan.","instance":"/v1/search?q=zambeef&cursor=…","plan":"free","limit":1000}}}},"404":{"description":"No such entity (`about:blank`), or ZRA lists no taxpayer with this TPIN (`/problems/tpin-not-found`).","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/no-match","title":"No matching entity","status":404,"detail":"No registered entity matched the subject at the required confidence (0.75).","instance":"/v1/verifications"}}}},"409":{"description":"A different owner TPIN is already linked (`/problems/owner-tpin-conflict`, `linked_tpin`). Send `replace: true` to change it.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/OwnerTpinConflictProblem"},"example":{"type":"/problems/ambiguous-match","title":"Ambiguous match","status":409,"detail":"Two or more entities match the subject within 0.05 of each other. Verify by entity_id or dira_id instead.","instance":"/v1/verifications"}}}},"413":{"description":"Request body exceeds the size limit (`/problems/payload-too-large`).","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/payload-too-large","title":"Payload Too Large","status":413,"detail":"The request body exceeds the size limit for this endpoint.","instance":"/v1/verifications"}}}},"422":{"description":"The entity is not a business name (`/problems/owner-tpin-not-applicable`): a company’s own taxpayer record is linked by name or TPIN search.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/idempotency-key-reused","title":"Idempotency-Key reused with a different request","status":422,"detail":"This Idempotency-Key was used within the last 24 hours for a different request body. Use a new key.","instance":"/v1/verifications"}}}},"429":{"description":"Too many requests: per-key sliding-window limit (`/problems/rate-limited`), monthly quota (`/problems/quota-exceeded`), per-IP limit on public routes, or too many pending exports. `Retry-After` says when to retry.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"},"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait before retrying.","example":23}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/rate-limited","title":"Too Many Requests","status":429,"detail":"Rate limit of 60 requests per minute exceeded for this key. Retry after 23 s.","instance":"/v1/search?q=zambeef"}}}},"500":{"description":"Unexpected server error (`about:blank`). Details are logged server-side, never returned.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"about:blank","title":"Internal Server Error","status":500,"detail":"An unexpected error occurred.","instance":"/v1/search?q=zambeef"}}}},"503":{"description":"ZRA did not answer and no record is stored for this TPIN (`/problems/source-unavailable`). Retry later.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/OwnerTpinUnavailableProblem"},"example":{"type":"/problems/source-unavailable","title":"A registry did not answer","status":503,"detail":"PACRA did not answer and no stored record exists for this subject. Retry later.","instance":"/v1/verifications"}}}}}},"delete":{"operationId":"unlinkOwnerTpin","summary":"Unlink a business name from its owner's TPIN","tags":["Entities"],"description":"Marks the owner-TPIN link `rejected` (nothing is deleted; `reviewed_by` records who) and clears it as the entity’s tax record. Idempotent: 200 with the `tax` block either way. Admin or verifier.","parameters":[{"schema":{"type":"string","minLength":1},"example":"3f1c2b7e-9a4d-4c8e-8b21-5d6f7a8b9c0d","in":"path","name":"id","required":true,"description":"Entity uuid or Dira ID (`ZM-…`)."}],"security":[{"bearerApiKey":[]},{"apiKeyHeader":[]}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/EntityTax"},"meta":{"$ref":"#/components/schemas/Meta"}},"required":["data","meta"]},"example":{"data":{"check":"attention","basis":"none","status_label":"Owner's TPIN needed","status_meaning":"Business names are taxed under the owner's personal TPIN; supply it to link the tax record.","status_raw":null,"owner_tpin_required":true,"personal_data":false,"payload":null,"provenance":null,"link_confidence":null},"meta":{"page":null,"per_page":null,"total":null,"attribution":"Registered information from PACRA, ZRA and the named registers; not a credit assessment.","data_as_of":"2026-09-21T09:12:41.512Z"}}}}},"400":{"description":"Bad request — validation failed (`/problems/validation`, `errors[]`), the cursor is invalid/expired/foreign (`/problems/invalid-cursor`), or `per_page` exceeds the plan cap (`/problems/plan-limit`, 400 because a smaller request will succeed).","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/validation","title":"Request validation failed","status":400,"detail":"Invalid body. See errors for field-level details.","instance":"/v1/verifications","errors":[{"field":"/","message":"exactly one of name, tpin, dira_id, entity_id is required"}]}}}},"401":{"description":"Missing, malformed, unknown or revoked API key (`/problems/unauthorized`). Identical for every failure so keys cannot be enumerated.","headers":{"WWW-Authenticate":{"schema":{"type":"string"},"description":"Challenge for the missing/invalid key.","example":"Bearer realm=\"dira-api\""},"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/unauthorized","title":"Unauthorized","status":401,"detail":"A valid API key is required. Send it as `Authorization: Bearer <key>` (canonical) or `X-API-Key: <key>`.","instance":"/v1/search?q=zambeef"}}}},"403":{"description":"Authenticated, but the plan does not entitle the action (`/problems/plan-limit`): paging past the plan result window or bulk export below Business.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/plan-limit","title":"Result window exceeded for this plan","status":403,"detail":"The free plan can page at most 1000 results deep per query (you have reached 1000). Narrow the query or upgrade the plan.","instance":"/v1/search?q=zambeef&cursor=…","plan":"free","limit":1000}}}},"404":{"description":"No such resource (`about:blank`).","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/no-match","title":"No matching entity","status":404,"detail":"No registered entity matched the subject at the required confidence (0.75).","instance":"/v1/verifications"}}}},"429":{"description":"Too many requests: per-key sliding-window limit (`/problems/rate-limited`), monthly quota (`/problems/quota-exceeded`), per-IP limit on public routes, or too many pending exports. `Retry-After` says when to retry.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"},"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait before retrying.","example":23}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/rate-limited","title":"Too Many Requests","status":429,"detail":"Rate limit of 60 requests per minute exceeded for this key. Retry after 23 s.","instance":"/v1/search?q=zambeef"}}}},"500":{"description":"Unexpected server error (`about:blank`). Details are logged server-side, never returned.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"about:blank","title":"Internal Server Error","status":500,"detail":"An unexpected error occurred.","instance":"/v1/search?q=zambeef"}}}}}}},"/v1/verifications":{"post":{"operationId":"createVerification","summary":"Issue a verification","tags":["Verifications"],"description":"Resolves the subject (exactly one of `name`, `tpin`, `dira_id`, `entity_id`) to one registered entity, re-reads PACRA and ZRA live unless the records were read within the last 15 minutes, runs the requested checks and issues an immutable record. A name must score ≥ 0.75 against an entity; two candidates within 0.05 of each other are refused as ambiguous (409, with `candidates`). Send `Idempotency-Key` (≤ 255 chars, scoped to your API key, 24 h) to make retries safe: the same key and body return **200** with the identical record. Default checks: registry, tax, vat, returns; add `licences` and `screening` explicitly. `score` is the share of checks that passed — never a credit score.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationRequest"},"example":{"name":"Zambeef Retailing Limited","purpose":"supplier_onboarding","reference":"vendor-4471","checks":["registry","tax","vat","returns"]}}}},"parameters":[{"schema":{"type":"string","minLength":1,"maxLength":255},"in":"header","name":"idempotency-key","required":false,"description":"Client-chosen key making the request idempotent for 24 hours."}],"security":[{"bearerApiKey":[]},{"apiKeyHeader":[]}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Verification"},"meta":{"$ref":"#/components/schemas/Meta"}},"required":["data","meta"]},"example":{"data":{"id":"7c9e6679-7425-40de-944b-e07fc1f90ae7","issued_at":"2026-09-21T09:03:41.000Z","subject":"Zambeef Retailing Limited","subject_kind":"name","purpose":"supplier_onboarding","reference":"vendor-4471","entity":{"id":"3f1c2b7e-9a4d-4c8e-8b21-5d6f7a8b9c0d","dira_id":null,"name":"ZAMBEEF RETAILING LIMITED","kind":"company","match_confidence":1},"result":{"passed":3,"attention":1,"failed":0,"unknown":0},"score":0.75,"checks":{"registry":{"status":"pass","value":"Active","source":"pacra","source_url":"https://xatu.pacra.org.zm:8344/api/v1/Search/registrysearch?Searchtext=ZAMBEEF%20RETAILING%20LIMITED","read_at":"2026-09-21T09:02:58.000Z","registry_no":"119960035723","company_type":"Local Company - Limited by Shares","registration_date":"1996-03-19"},"tax":{"status":"pass","value":"registered","source":"zra","source_url":"https://portal.zra.org.zm/retrieveTaxpayersSearch#POST&taxpayername=ZAMBEEF%20RETAILING%20LIMITED","read_at":"2026-09-21T09:02:59.000Z","tpin":"1001747472","status_label":"Registered","status_raw":"ACTIVE","meaning":"Registered with ZRA.","registered_on":"1996-05-01","tax_types":["Pay As You Earn","Income Tax","Value Added Tax"],"deregistered":false,"basis":"company","personal_data":false,"link_confidence":1},"vat":{"status":"pass","value":true,"source":"zra","source_url":"https://portal.zra.org.zm/retrieveTaxpayersSearch#POST&taxpayername=ZAMBEEF%20RETAILING%20LIMITED","read_at":"2026-09-21T09:02:59.000Z","tax_types":["Pay As You Earn","Income Tax","Value Added Tax"]},"returns":{"status":"attention","value":"not_current","source":"pacra","source_url":"https://xatu.pacra.org.zm:8344/api/v1/Search/registrysearch?Searchtext=ZAMBEEF%20RETAILING%20LIMITED","read_at":"2026-09-21T09:02:58.000Z","made_up_to":"2024-09-28"}},"cached":false,"sources_failed":[],"as_of":"2026-09-21T09:02:58.000Z","report_url":"https://dira.oapps.dev/verify/7c9e6679-7425-40de-944b-e07fc1f90ae7","report_sha256":null},"meta":{"page":null,"per_page":null,"total":null,"attribution":"Registered information from PACRA, ZRA and the named registers; not a credit assessment.","data_as_of":"2026-09-21T09:12:41.512Z"}}}}},"201":{"description":"Created — the verification record was issued.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Verification"},"meta":{"$ref":"#/components/schemas/Meta"}},"required":["data","meta"]},"example":{"data":{"id":"7c9e6679-7425-40de-944b-e07fc1f90ae7","issued_at":"2026-09-21T09:03:41.000Z","subject":"Zambeef Retailing Limited","subject_kind":"name","purpose":"supplier_onboarding","reference":"vendor-4471","entity":{"id":"3f1c2b7e-9a4d-4c8e-8b21-5d6f7a8b9c0d","dira_id":null,"name":"ZAMBEEF RETAILING LIMITED","kind":"company","match_confidence":1},"result":{"passed":3,"attention":1,"failed":0,"unknown":0},"score":0.75,"checks":{"registry":{"status":"pass","value":"Active","source":"pacra","source_url":"https://xatu.pacra.org.zm:8344/api/v1/Search/registrysearch?Searchtext=ZAMBEEF%20RETAILING%20LIMITED","read_at":"2026-09-21T09:02:58.000Z","registry_no":"119960035723","company_type":"Local Company - Limited by Shares","registration_date":"1996-03-19"},"tax":{"status":"pass","value":"registered","source":"zra","source_url":"https://portal.zra.org.zm/retrieveTaxpayersSearch#POST&taxpayername=ZAMBEEF%20RETAILING%20LIMITED","read_at":"2026-09-21T09:02:59.000Z","tpin":"1001747472","status_label":"Registered","status_raw":"ACTIVE","meaning":"Registered with ZRA.","registered_on":"1996-05-01","tax_types":["Pay As You Earn","Income Tax","Value Added Tax"],"deregistered":false,"basis":"company","personal_data":false,"link_confidence":1},"vat":{"status":"pass","value":true,"source":"zra","source_url":"https://portal.zra.org.zm/retrieveTaxpayersSearch#POST&taxpayername=ZAMBEEF%20RETAILING%20LIMITED","read_at":"2026-09-21T09:02:59.000Z","tax_types":["Pay As You Earn","Income Tax","Value Added Tax"]},"returns":{"status":"attention","value":"not_current","source":"pacra","source_url":"https://xatu.pacra.org.zm:8344/api/v1/Search/registrysearch?Searchtext=ZAMBEEF%20RETAILING%20LIMITED","read_at":"2026-09-21T09:02:58.000Z","made_up_to":"2024-09-28"}},"cached":false,"sources_failed":[],"as_of":"2026-09-21T09:02:58.000Z","report_url":"https://dira.oapps.dev/verify/7c9e6679-7425-40de-944b-e07fc1f90ae7","report_sha256":null},"meta":{"page":null,"per_page":null,"total":null,"attribution":"Registered information from PACRA, ZRA and the named registers; not a credit assessment.","data_as_of":"2026-09-21T09:12:41.512Z"}}}}},"400":{"description":"Bad request — validation failed (`/problems/validation`, `errors[]`), the cursor is invalid/expired/foreign (`/problems/invalid-cursor`), or `per_page` exceeds the plan cap (`/problems/plan-limit`, 400 because a smaller request will succeed).","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/validation","title":"Request validation failed","status":400,"detail":"Invalid body. See errors for field-level details.","instance":"/v1/verifications","errors":[{"field":"/","message":"exactly one of name, tpin, dira_id, entity_id is required"}]}}}},"401":{"description":"Missing, malformed, unknown or revoked API key (`/problems/unauthorized`). Identical for every failure so keys cannot be enumerated.","headers":{"WWW-Authenticate":{"schema":{"type":"string"},"description":"Challenge for the missing/invalid key.","example":"Bearer realm=\"dira-api\""},"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/unauthorized","title":"Unauthorized","status":401,"detail":"A valid API key is required. Send it as `Authorization: Bearer <key>` (canonical) or `X-API-Key: <key>`.","instance":"/v1/search?q=zambeef"}}}},"403":{"description":"The API key is not attached to an account (`/problems/account-required`); verifications are issued to an account. A read-only console role (auditor) is refused with `/problems/role`.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/plan-limit","title":"Result window exceeded for this plan","status":403,"detail":"The free plan can page at most 1000 results deep per query (you have reached 1000). Narrow the query or upgrade the plan.","instance":"/v1/search?q=zambeef&cursor=…","plan":"free","limit":1000}}}},"404":{"description":"No entity matched the subject at the required confidence (`/problems/no-match`). `subject` carries the normalised form.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/NoMatchProblem"},"example":{"type":"/problems/no-match","title":"No matching entity","status":404,"detail":"No registered entity matched the subject at the required confidence (0.75).","instance":"/v1/verifications"}}}},"409":{"description":"Two or more entities match within 0.05 of each other (`/problems/ambiguous-match`); `candidates` lists them — retry with `entity_id`.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/AmbiguousMatchProblem"},"example":{"type":"/problems/ambiguous-match","title":"Ambiguous match","status":409,"detail":"Two or more entities match the subject within 0.05 of each other. Verify by entity_id or dira_id instead.","instance":"/v1/verifications"}}}},"413":{"description":"Request body exceeds the size limit (`/problems/payload-too-large`).","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/payload-too-large","title":"Payload Too Large","status":413,"detail":"The request body exceeds the size limit for this endpoint.","instance":"/v1/verifications"}}}},"422":{"description":"The `Idempotency-Key` was used within 24 h for a different request body (`/problems/idempotency-key-reused`).","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/idempotency-key-reused","title":"Idempotency-Key reused with a different request","status":422,"detail":"This Idempotency-Key was used within the last 24 hours for a different request body. Use a new key.","instance":"/v1/verifications"}}}},"429":{"description":"Too many requests: per-key sliding-window limit (`/problems/rate-limited`), monthly quota (`/problems/quota-exceeded`), per-IP limit on public routes, or too many pending exports. `Retry-After` says when to retry.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"},"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait before retrying.","example":23}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/rate-limited","title":"Too Many Requests","status":429,"detail":"Rate limit of 60 requests per minute exceeded for this key. Retry after 23 s.","instance":"/v1/search?q=zambeef"}}}},"500":{"description":"Unexpected server error (`about:blank`). Details are logged server-side, never returned.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"about:blank","title":"Internal Server Error","status":500,"detail":"An unexpected error occurred.","instance":"/v1/search?q=zambeef"}}}},"503":{"description":"A registry did not answer and no stored record exists for the subject (`/problems/source-unavailable`). Retry later.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/SourceUnavailableProblem"},"example":{"type":"/problems/source-unavailable","title":"A registry did not answer","status":503,"detail":"PACRA did not answer and no stored record exists for this subject. Retry later.","instance":"/v1/verifications"}}}}}}},"/v1/verifications/{id}":{"get":{"operationId":"getVerification","summary":"Get a verification","tags":["Verifications"],"description":"The immutable record exactly as issued. Only the issuing account can read it; any other id — unknown or another account’s — is 404.","parameters":[{"schema":{"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)$"},"in":"path","name":"id","required":true,"description":"Verification id."}],"security":[{"bearerApiKey":[]},{"apiKeyHeader":[]}],"responses":{"200":{"description":"OK","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Verification"},"meta":{"$ref":"#/components/schemas/Meta"}},"required":["data","meta"]},"example":{"data":{"id":"7c9e6679-7425-40de-944b-e07fc1f90ae7","issued_at":"2026-09-21T09:03:41.000Z","subject":"Zambeef Retailing Limited","subject_kind":"name","purpose":"supplier_onboarding","reference":"vendor-4471","entity":{"id":"3f1c2b7e-9a4d-4c8e-8b21-5d6f7a8b9c0d","dira_id":null,"name":"ZAMBEEF RETAILING LIMITED","kind":"company","match_confidence":1},"result":{"passed":3,"attention":1,"failed":0,"unknown":0},"score":0.75,"checks":{"registry":{"status":"pass","value":"Active","source":"pacra","source_url":"https://xatu.pacra.org.zm:8344/api/v1/Search/registrysearch?Searchtext=ZAMBEEF%20RETAILING%20LIMITED","read_at":"2026-09-21T09:02:58.000Z","registry_no":"119960035723","company_type":"Local Company - Limited by Shares","registration_date":"1996-03-19"},"tax":{"status":"pass","value":"registered","source":"zra","source_url":"https://portal.zra.org.zm/retrieveTaxpayersSearch#POST&taxpayername=ZAMBEEF%20RETAILING%20LIMITED","read_at":"2026-09-21T09:02:59.000Z","tpin":"1001747472","status_label":"Registered","status_raw":"ACTIVE","meaning":"Registered with ZRA.","registered_on":"1996-05-01","tax_types":["Pay As You Earn","Income Tax","Value Added Tax"],"deregistered":false,"basis":"company","personal_data":false,"link_confidence":1},"vat":{"status":"pass","value":true,"source":"zra","source_url":"https://portal.zra.org.zm/retrieveTaxpayersSearch#POST&taxpayername=ZAMBEEF%20RETAILING%20LIMITED","read_at":"2026-09-21T09:02:59.000Z","tax_types":["Pay As You Earn","Income Tax","Value Added Tax"]},"returns":{"status":"attention","value":"not_current","source":"pacra","source_url":"https://xatu.pacra.org.zm:8344/api/v1/Search/registrysearch?Searchtext=ZAMBEEF%20RETAILING%20LIMITED","read_at":"2026-09-21T09:02:58.000Z","made_up_to":"2024-09-28"}},"cached":false,"sources_failed":[],"as_of":"2026-09-21T09:02:58.000Z","report_url":"https://dira.oapps.dev/verify/7c9e6679-7425-40de-944b-e07fc1f90ae7","report_sha256":null},"meta":{"page":null,"per_page":null,"total":null,"attribution":"Registered information from PACRA, ZRA and the named registers; not a credit assessment.","data_as_of":"2026-09-21T09:12:41.512Z"}}}}},"400":{"description":"Bad request — validation failed (`/problems/validation`, `errors[]`), the cursor is invalid/expired/foreign (`/problems/invalid-cursor`), or `per_page` exceeds the plan cap (`/problems/plan-limit`, 400 because a smaller request will succeed).","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/validation","title":"Request validation failed","status":400,"detail":"Invalid body. See errors for field-level details.","instance":"/v1/verifications","errors":[{"field":"/","message":"exactly one of name, tpin, dira_id, entity_id is required"}]}}}},"401":{"description":"Missing, malformed, unknown or revoked API key (`/problems/unauthorized`). Identical for every failure so keys cannot be enumerated.","headers":{"WWW-Authenticate":{"schema":{"type":"string"},"description":"Challenge for the missing/invalid key.","example":"Bearer realm=\"dira-api\""},"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/unauthorized","title":"Unauthorized","status":401,"detail":"A valid API key is required. Send it as `Authorization: Bearer <key>` (canonical) or `X-API-Key: <key>`.","instance":"/v1/search?q=zambeef"}}}},"404":{"description":"No such resource (`about:blank`).","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/no-match","title":"No matching entity","status":404,"detail":"No registered entity matched the subject at the required confidence (0.75).","instance":"/v1/verifications"}}}},"429":{"description":"Too many requests: per-key sliding-window limit (`/problems/rate-limited`), monthly quota (`/problems/quota-exceeded`), per-IP limit on public routes, or too many pending exports. `Retry-After` says when to retry.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"},"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait before retrying.","example":23}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/rate-limited","title":"Too Many Requests","status":429,"detail":"Rate limit of 60 requests per minute exceeded for this key. Retry after 23 s.","instance":"/v1/search?q=zambeef"}}}},"500":{"description":"Unexpected server error (`about:blank`). Details are logged server-side, never returned.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"about:blank","title":"Internal Server Error","status":500,"detail":"An unexpected error occurred.","instance":"/v1/search?q=zambeef"}}}}}}},"/v1/verifications/{id}/report.pdf":{"get":{"operationId":"getVerificationReport","summary":"Download the verification PDF","tags":["Verifications"],"description":"The record as a PDF: subject, match confidence, the checks with their source and read time, the attribution sentence, and the public verify link with its QR code. Rendered deterministically from the stored record on every request, so the bytes never change; the first render stamps `report_sha256` on the record and `X-Report-SHA256` carries it on every response. Owner account only; other ids are 404.","parameters":[{"schema":{"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)$"},"in":"path","name":"id","required":true,"description":"Verification id."}],"security":[{"bearerApiKey":[]},{"apiKeyHeader":[]}],"responses":{"200":{"description":"The report. `Content-Disposition: inline`.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/pdf":{"schema":{"type":"string","description":"PDF bytes (A4, one page)."},"example":"%PDF-1.7\n%âãÏÓ\n1 0 obj ..."}}},"400":{"description":"Bad request — validation failed (`/problems/validation`, `errors[]`), the cursor is invalid/expired/foreign (`/problems/invalid-cursor`), or `per_page` exceeds the plan cap (`/problems/plan-limit`, 400 because a smaller request will succeed).","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/validation","title":"Request validation failed","status":400,"detail":"Invalid body. See errors for field-level details.","instance":"/v1/verifications","errors":[{"field":"/","message":"exactly one of name, tpin, dira_id, entity_id is required"}]}}}},"401":{"description":"Missing, malformed, unknown or revoked API key (`/problems/unauthorized`). Identical for every failure so keys cannot be enumerated.","headers":{"WWW-Authenticate":{"schema":{"type":"string"},"description":"Challenge for the missing/invalid key.","example":"Bearer realm=\"dira-api\""},"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/unauthorized","title":"Unauthorized","status":401,"detail":"A valid API key is required. Send it as `Authorization: Bearer <key>` (canonical) or `X-API-Key: <key>`.","instance":"/v1/search?q=zambeef"}}}},"404":{"description":"No such resource (`about:blank`).","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/no-match","title":"No matching entity","status":404,"detail":"No registered entity matched the subject at the required confidence (0.75).","instance":"/v1/verifications"}}}},"429":{"description":"Too many requests: per-key sliding-window limit (`/problems/rate-limited`), monthly quota (`/problems/quota-exceeded`), per-IP limit on public routes, or too many pending exports. `Retry-After` says when to retry.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"},"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait before retrying.","example":23}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/rate-limited","title":"Too Many Requests","status":429,"detail":"Rate limit of 60 requests per minute exceeded for this key. Retry after 23 s.","instance":"/v1/search?q=zambeef"}}}},"500":{"description":"Unexpected server error (`about:blank`). Details are logged server-side, never returned.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"about:blank","title":"Internal Server Error","status":500,"detail":"An unexpected error occurred.","instance":"/v1/search?q=zambeef"}}}}}}},"/v1/no-match":{"post":{"operationId":"createNoMatchRecord","summary":"File a no-match record","tags":["Verifications"],"description":"Files an immutable record stating that the subject (exactly one of `name`, `tpin`) was searched for and no registered entity was found — proof for the file that the check was done. The record has no entity and no checks, but the same `/verify/{id}` page and PDF as a verification. Refused with 409 (`/problems/match-exists`, `candidates`) when the mirror already holds a matching entity; issue a verification for it instead. No live registry read is made.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NoMatchRequest"}}}},"security":[{"bearerApiKey":[]},{"apiKeyHeader":[]}],"responses":{"201":{"description":"Created — the verification record was issued.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Verification"},"meta":{"$ref":"#/components/schemas/Meta"}},"required":["data","meta"]},"example":{"data":{"id":"b1d4e2a0-5c6f-4a7b-9e8d-0f1a2b3c4d5e","issued_at":"2026-09-21T09:05:12.000Z","subject":"Kwacha Logistics","subject_kind":"name","purpose":"supplier_onboarding","reference":"vendor-4472","entity":null,"result":{"passed":0,"attention":0,"failed":0,"unknown":0},"score":null,"checks":{},"cached":false,"sources_failed":[],"as_of":null,"report_url":"https://dira.oapps.dev/verify/b1d4e2a0-5c6f-4a7b-9e8d-0f1a2b3c4d5e","report_sha256":null},"meta":{"page":null,"per_page":null,"total":null,"attribution":"Registered information from PACRA, ZRA and the named registers; not a credit assessment.","data_as_of":"2026-09-21T09:12:41.512Z"}}}}},"400":{"description":"Bad request — validation failed (`/problems/validation`, `errors[]`), the cursor is invalid/expired/foreign (`/problems/invalid-cursor`), or `per_page` exceeds the plan cap (`/problems/plan-limit`, 400 because a smaller request will succeed).","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/validation","title":"Request validation failed","status":400,"detail":"Invalid body. See errors for field-level details.","instance":"/v1/verifications","errors":[{"field":"/","message":"exactly one of name, tpin, dira_id, entity_id is required"}]}}}},"401":{"description":"Missing, malformed, unknown or revoked API key (`/problems/unauthorized`). Identical for every failure so keys cannot be enumerated.","headers":{"WWW-Authenticate":{"schema":{"type":"string"},"description":"Challenge for the missing/invalid key.","example":"Bearer realm=\"dira-api\""},"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/unauthorized","title":"Unauthorized","status":401,"detail":"A valid API key is required. Send it as `Authorization: Bearer <key>` (canonical) or `X-API-Key: <key>`.","instance":"/v1/search?q=zambeef"}}}},"403":{"description":"The API key is not attached to an account (`/problems/account-required`), or the console role is read-only (`/problems/role`).","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/plan-limit","title":"Result window exceeded for this plan","status":403,"detail":"The free plan can page at most 1000 results deep per query (you have reached 1000). Narrow the query or upgrade the plan.","instance":"/v1/search?q=zambeef&cursor=…","plan":"free","limit":1000}}}},"409":{"description":"A registered entity in the mirror matches the subject (`/problems/match-exists`); `candidates` lists them. Verify one of them instead.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/MatchExistsProblem"},"example":{"type":"/problems/ambiguous-match","title":"Ambiguous match","status":409,"detail":"Two or more entities match the subject within 0.05 of each other. Verify by entity_id or dira_id instead.","instance":"/v1/verifications"}}}},"413":{"description":"Request body exceeds the size limit (`/problems/payload-too-large`).","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/payload-too-large","title":"Payload Too Large","status":413,"detail":"The request body exceeds the size limit for this endpoint.","instance":"/v1/verifications"}}}},"429":{"description":"Too many requests: per-key sliding-window limit (`/problems/rate-limited`), monthly quota (`/problems/quota-exceeded`), per-IP limit on public routes, or too many pending exports. `Retry-After` says when to retry.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"},"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait before retrying.","example":23}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/rate-limited","title":"Too Many Requests","status":429,"detail":"Rate limit of 60 requests per minute exceeded for this key. Retry after 23 s.","instance":"/v1/search?q=zambeef"}}}},"500":{"description":"Unexpected server error (`about:blank`). Details are logged server-side, never returned.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"X-Quota-Limit":{"schema":{"type":"integer"},"description":"Requests allowed in this key's current quota window (a UTC calendar DAY on the Free plan, a UTC calendar month on paid plans). Absent on unlimited plans.","example":10000},"X-Quota-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current quota window. Absent on unlimited plans.","example":9213},"X-Quota-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the quota window resets (next UTC midnight on Free, the 1st of the next UTC month on paid plans). Absent on unlimited plans.","example":1788220800},"X-Throttled":{"schema":{"type":"string"},"description":"Present (value `abuse-review`) only while the key is under automated abuse review: the per-minute limit is divided by 10 until a human clears it.","example":"abuse-review"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"about:blank","title":"Internal Server Error","status":500,"detail":"An unexpected error occurred.","instance":"/v1/search?q=zambeef"}}}}}}},"/verify/{id}":{"get":{"operationId":"checkVerification","summary":"Confirm a verification is genuine","tags":["Public"],"description":"Public, no API key. Resolves the id printed on a verification report (and encoded in its QR) to the issued record’s public summary: who it was issued to, when, the subject name, the result counts and the report hash. Per-IP rate-limited; never cached. Browsers (`Accept: text/html`) get the same facts as a server-rendered page; every other client gets JSON.","parameters":[{"schema":{"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)$"},"in":"path","name":"id","required":true,"description":"Verification id from the report."}],"security":[],"responses":{"200":{"description":"The public summary — JSON, or the HTML page for `Accept: text/html`.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660}},"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"issued_at":{"type":"string","description":"ISO 8601 UTC instant."},"subject_name":{"type":"string"},"issued_to":{"description":"Organisation the record was issued to.","type":["string","null"]},"result":{"type":"object","properties":{"passed":{"type":"integer"},"attention":{"type":"integer"},"failed":{"type":"integer"}},"required":["passed","attention","failed"]},"report_sha256":{"type":["string","null"]},"genuine":{"type":"boolean","enum":[true]}},"required":["id","issued_at","subject_name","issued_to","result","report_sha256","genuine"],"description":"The public hash check — nothing more."},"example":{"id":"7c9e6679-7425-40de-944b-e07fc1f90ae7","issued_at":"2026-09-21T09:03:41.000Z","subject_name":"ZAMBEEF RETAILING LIMITED","issued_to":"Acme Procurement Ltd","result":{"passed":3,"attention":1,"failed":0},"report_sha256":null,"genuine":true}},"text/html":{"schema":{"type":"string","description":"The server-rendered verify page (no client JS)."},"example":"<!doctype html>\n<html lang=\"en\"><head>…</head><body><main>…<h1>This record is genuine</h1>…</main></body></html>"}}},"400":{"description":"Bad request — validation failed (`/problems/validation`, `errors[]`), the cursor is invalid/expired/foreign (`/problems/invalid-cursor`), or `per_page` exceeds the plan cap (`/problems/plan-limit`, 400 because a smaller request will succeed).","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/validation","title":"Request validation failed","status":400,"detail":"Invalid body. See errors for field-level details.","instance":"/v1/verifications","errors":[{"field":"/","message":"exactly one of name, tpin, dira_id, entity_id is required"}]}}}},"404":{"description":"No such resource (`about:blank`).","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/no-match","title":"No matching entity","status":404,"detail":"No registered entity matched the subject at the required confidence (0.75).","instance":"/v1/verifications"}}}},"429":{"description":"Too many requests: per-key sliding-window limit (`/problems/rate-limited`), monthly quota (`/problems/quota-exceeded`), per-IP limit on public routes, or too many pending exports. `Retry-After` says when to retry.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660},"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait before retrying.","example":23}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"/problems/rate-limited","title":"Too Many Requests","status":429,"detail":"Rate limit of 60 requests per minute exceeded for this key. Retry after 23 s.","instance":"/v1/search?q=zambeef"}}}},"500":{"description":"Unexpected server error (`about:blank`). Details are logged server-side, never returned.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"},"description":"Requests allowed per minute (sliding window) — for the API key on protected routes, per client IP on public routes and on 401 answers.","example":60},"X-RateLimit-Remaining":{"schema":{"type":"integer"},"description":"Requests left in the current minute window.","example":57},"X-RateLimit-Reset":{"schema":{"type":"integer"},"description":"Unix time (seconds) at which the current window ends.","example":1786953660}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"about:blank","title":"Internal Server Error","status":500,"detail":"An unexpected error occurred.","instance":"/v1/search?q=zambeef"}}}}}}}},"servers":[{"url":"https://dira.oapps.dev","description":"This deployment"}],"tags":[{"name":"Search","description":"Ranked entity search over the mirror (no live registry read)."},{"name":"Entities","description":"Entity profiles with per-field provenance, the version + event timeline, and signals."},{"name":"Verifications","description":"Live-or-cached checks against PACRA, ZRA and the linked registers, issued as immutable records — plus no-match records and the report PDF."},{"name":"Public","description":"Unauthenticated verification hash check (`/verify/{id}`). Per-IP limited."},{"name":"Meta","description":"This document. Public, per-IP rate-limited."}],"externalDocs":{"description":"API reference","url":"https://dira.oapps.dev/docs/reference"}}