{"openapi":"3.1.0","info":{"title":"APZWatch API","version":"1.1.0","description":"AML screening API for persons, entities, wallets, addresses, and identifiers. Base path /api/v1. Docs: /docs and /api/v1/docs. Deprecation policy: breaking changes require a new major version path (/api/v2) with at least 6 months' notice via Deprecation/Sunset headers. Default person categories when omitted: sanctions+terror (pep/adverse_media listed in coverageGaps until explicitly requested). Rate limits: 120 req/min per key; 429 responses include Retry-After.","contact":{"name":"APZOR Pty LTD","url":"https://apzwatch.apzportal.apzor.com"}},"servers":[{"url":"https://apzwatch.apzportal.apzor.com/api/v1"}],"externalDocs":{"description":"Human-readable API docs","url":"https://apzwatch.apzportal.apzor.com/docs"},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"azw_live_… / azw_test_…"}},"parameters":{"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","minLength":8,"maxLength":255,"pattern":"^[A-Za-z0-9._~\\-:]+$"},"description":"Scoped per organisation. Same key + same body returns the original result unless historical evidence is quarantined (423 evidence_quarantined); same key + different body → 409. Quarantine means unavailable, never clear. Later new-feed license approval does not release held history."},"RequestId":{"name":"X-Request-Id","in":"header","required":false,"schema":{"type":"string","minLength":8,"maxLength":128}}},"schemas":{"ErrorEnvelope":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"},"details":{"type":"object"}},"required":["code","message","requestId"]}}},"ResponseMeta":{"type":"object","properties":{"organizationId":{"type":"string"},"requestId":{"type":"string"}}},"ListSnapshot":{"type":"object","properties":{"sourceCode":{"type":"string"},"jurisdiction":{"type":"string"},"listName":{"type":"string"},"listCode":{"type":"string"},"versionId":{"type":"string","description":"Canonical public id: {listCode}_{effectiveDate}"},"effectiveDate":{"type":"string","format":"date"},"publishedAt":{"type":"string","format":"date-time"},"fetchedAt":{"type":"string","format":"date-time"},"recordCount":{"type":"integer"},"contentHash":{"type":"string","pattern":"^sha256:[a-f0-9]{64}$"},"sourceUrl":{"type":"string","nullable":true}}},"ScreenStatus":{"type":"string","enum":["clear","review","block_recommended","pending"]},"MatchBand":{"type":"string","enum":["strong","likely","possible","unlikely"]},"SourceAttribution":{"type":"object","description":"Exact source snapshot linked to a matched wallet address.","properties":{"sourceCode":{"type":"string"},"contentHash":{"type":"string","pattern":"^sha256:[a-f0-9]{64}$"},"listCode":{"type":"string"},"listName":{"type":"string"},"sourceUrl":{"type":"string","nullable":true},"versionId":{"type":"string"},"effectiveDate":{"type":"string","format":"date"},"publishedAt":{"type":"string","format":"date-time"},"fetchedAt":{"type":"string","format":"date-time"}}},"ScreenHit":{"type":"object","properties":{"hitId":{"type":"string"},"score":{"type":"number"},"category":{"type":"string"},"primaryName":{"type":"string"},"matchBand":{"$ref":"#/components/schemas/MatchBand"},"matchFields":{"type":"object"},"watchlistEntityId":{"type":"string"},"sourceAttribution":{"$ref":"#/components/schemas/SourceAttribution"}}},"ScreenResult":{"type":"object","properties":{"resultId":{"type":"string"},"status":{"$ref":"#/components/schemas/ScreenStatus"},"subjectType":{"type":"string"},"input":{"type":"object"},"riskScore":{"type":"integer","minimum":0,"maximum":100},"hits":{"type":"array","items":{"$ref":"#/components/schemas/ScreenHit"}},"hitsMeta":{"type":"object","properties":{"returned":{"type":"integer"},"total":{"type":"integer"},"hasMore":{"type":"boolean"},"limit":{"type":"integer"}}},"listVersions":{"type":"array","items":{"$ref":"#/components/schemas/ListSnapshot"}},"coverageGaps":{"type":"array","items":{"type":"string"},"description":"Wallet results include wallet_transaction_history and wallet_indirect_exposure."},"testMode":{"type":"boolean","description":"True only for development HIBP fixtures."},"persisted":{"type":"boolean"},"metered":{"type":"boolean"},"breachCheck":{"type":"object","properties":{"provider":{"type":"string"},"providerUrl":{"type":"string","format":"uri"},"mode":{"type":"string","enum":["test"]},"outcome":{"type":"string","enum":["breaches_found","no_breaches_in_fixture"]},"breachNames":{"type":"array","items":{"type":"string"}}}},"policy":{"type":"object"},"createdAt":{"type":"string","format":"date-time"},"disclaimer":{"type":"string"},"mediaSearch":{"type":"object"}}},"BatchPersonResponse":{"type":"object","properties":{"count":{"type":"integer"},"results":{"type":"array","items":{"$ref":"#/components/schemas/ScreenResult"}}}},"MonitorWatch":{"type":"object","properties":{"id":{"type":"string"},"displayName":{"type":"string"},"subjectType":{"type":"string","enum":["person","entity","wallet"]},"status":{"type":"string"},"resultId":{"type":"string","nullable":true},"alerted":{"type":"boolean"},"screenStatus":{"type":"string","enum":["complete","pending"]},"message":{"type":"string"}}},"Webhook":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"events":{"type":"array","items":{"type":"string"}},"secret":{"type":"string","description":"Returned once on create"},"secretLast4":{"type":"string"},"enabled":{"type":"boolean"}}},"CaseSummary":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"disposition":{"type":"string","nullable":true},"screenResultId":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"AuditExport":{"type":"object","properties":{"exportedAt":{"type":"string","format":"date-time"},"count":{"type":"integer"},"total":{"type":"integer"},"truncated":{"type":"boolean"},"limit":{"type":"integer"},"nextCursor":{"type":"string","nullable":true},"events":{"type":"array","items":{"type":"object"}}}},"GraphNeighbors":{"type":"object","properties":{"profileId":{"type":"string"},"neighbors":{"type":"array","items":{"type":"object"}}}},"AiAdverseMedia":{"type":"object","properties":{"degraded":{"type":"boolean"},"model":{"type":"string"},"articles":{"type":"array","items":{"type":"object"}},"themes":{"type":"array","items":{"type":"string"}},"confidenceScore":{"type":"number"}}},"PersonScreenBody":{"type":"object","required":["fullName"],"properties":{"fullName":{"type":"string"},"givenName":{"type":"string"},"familyName":{"type":"string"},"dateOfBirth":{"type":"string"},"nationality":{"type":"string","minLength":2,"maxLength":2},"countryOfResidence":{"type":"string","minLength":2,"maxLength":2},"email":{"type":"string","format":"email"},"phone":{"type":"string"},"passportNumber":{"type":"string"},"nationalId":{"type":"string"},"externalReference":{"type":"string"},"categories":{"type":"array","items":{"type":"string","enum":["sanctions","terror","pep","adverse_media","compromised","watch"]},"description":"When omitted, defaults to sanctions+terror. pep/adverse_media appear in coverageGaps until requested."}}}},"responses":{"Unauthorized":{"description":"Invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"Forbidden":{"description":"Missing scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"RateLimited":{"description":"Rate limited","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds until the window resets"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"ScreeningTimeout":{"description":"Screening timed out (JSON 503, never HTML 504)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}},"security":[{"bearerAuth":[]}],"paths":{"/health":{"get":{"security":[],"summary":"Liveness","responses":{"200":{"description":"OK"}}}},"/health/ready":{"get":{"security":[],"summary":"Readiness (DB + approved live-list freshness)","responses":{"200":{"description":"Ready; reason is ready"},"503":{"description":"Includes a reason and nextStep distinguishing missing approved sources from service-check failures"}}}},"/docs":{"get":{"security":[],"summary":"Redirect to human docs","responses":{"301":{"description":"Redirect to /docs"}}}},"/openapi.json":{"get":{"security":[],"summary":"This OpenAPI document","responses":{"200":{"description":"OpenAPI 3.1 JSON"}}}},"/me":{"get":{"summary":"Organisation + key scopes","responses":{"200":{"description":"OK"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/usage":{"get":{"summary":"Usage meters vs plan quotas","description":"Requires usage:read.","responses":{"200":{"description":"OK"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/lists":{"get":{"summary":"Current auditable list snapshots (sha256 only)","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"lists":{"type":"array","items":{"$ref":"#/components/schemas/ListSnapshot"}}}}}}}}}}}},"/lists/{code}":{"get":{"summary":"List detail + recent sync history (canonical versionId)","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Current snapshot and sync history"},"404":{"description":"Unknown list code"}}}},"/screens/person":{"post":{"summary":"Screen a person","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PersonScreenBody"}}}},"responses":{"200":{"description":"Screen result","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ScreenResult"},"meta":{"$ref":"#/components/schemas/ResponseMeta"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"409":{"description":"Idempotency conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/ScreeningTimeout"}}}},"/screens/person/batch":{"post":{"summary":"Batch person screens (max 20)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["subjects"],"properties":{"subjects":{"type":"array","maxItems":20,"items":{"$ref":"#/components/schemas/PersonScreenBody"}}}}}}},"responses":{"200":{"description":"Batch results","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/BatchPersonResponse"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"422":{"description":"Validation"}}}},"/screens/entity":{"post":{"summary":"Screen a legal entity","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["legalName"],"properties":{"legalName":{"type":"string"},"country":{"type":"string","minLength":2,"maxLength":2},"registrationNumber":{"type":"string"},"categories":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"Screen result","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ScreenResult"},"meta":{"$ref":"#/components/schemas/ResponseMeta"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/screens/wallet":{"post":{"summary":"Screen a digital-asset wallet","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["chain","address"],"properties":{"chain":{"type":"string"},"address":{"type":"string"},"externalReference":{"type":"string"}}}}}},"responses":{"200":{"description":"Screen result","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ScreenResult"},"meta":{"$ref":"#/components/schemas/ResponseMeta"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/screens/address":{"post":{"summary":"Screen a postal address","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["line1","country"],"properties":{"line1":{"type":"string"},"line2":{"type":"string"},"city":{"type":"string"},"postalCode":{"type":"string"},"country":{"type":"string","minLength":2,"maxLength":2}}}}}},"responses":{"200":{"description":"Screen result","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ScreenResult"},"meta":{"$ref":"#/components/schemas/ResponseMeta"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/screens/compromised":{"post":{"summary":"Screen an identifier","description":"Production/staging screening remains unavailable until a verified, licensed provider is approved. In local development only, the server accepts three documented HIBP integration-test email fixtures and returns testMode:true; other addresses are rejected before any provider request. Fixture checks are not stored or billed and are not real screening results.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["idType","value"],"properties":{"idType":{"type":"string","enum":["email","phone","passport","national_id","registration_number","username"]},"value":{"type":"string"}}}}}},"responses":{"200":{"description":"Screen result","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ScreenResult"},"meta":{"$ref":"#/components/schemas/ResponseMeta"}}}}}},"400":{"description":"The submitted value is not one of the allowlisted HIBP integration-test addresses","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"503":{"description":"No production provider is connected, or the HIBP test endpoint is unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/screens/{resultId}":{"get":{"summary":"Retrieve stored screen evidence","parameters":[{"name":"resultId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Screen result","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ScreenResult"},"meta":{"$ref":"#/components/schemas/ResponseMeta"}}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/screens/{resultId}/hits":{"get":{"summary":"Paginate persisted hits (cursor = last rank)","parameters":[{"name":"resultId","in":"path","required":true,"schema":{"type":"string"}},{"name":"cursor","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","maximum":25}}],"responses":{"200":{"description":"Hit page"},"404":{"description":"Not found"}}}},"/ai/adverse-media":{"post":{"summary":"Adverse-media multi-signal discovery + advisory summary","description":"Advisory only. Live discovery belongs on this endpoint / background crawl — person screens read the cache only.","responses":{"200":{"description":"Advisory result","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/AiAdverseMedia"}}}}}},"503":{"description":"AI globally disabled"}}}},"/ai/hits/{hitId}/assist":{"post":{"summary":"Hit explanation assist (advisory)","parameters":[{"name":"hitId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Advisory explanation"},"404":{"description":"Hit not found"},"503":{"description":"AI globally disabled"}}}},"/cases":{"get":{"summary":"List cases","description":"Requires results:read.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"cases":{"type":"array","items":{"$ref":"#/components/schemas/CaseSummary"}}}}}}}}}}}},"/cases/{caseId}":{"get":{"summary":"Get case detail","responses":{"200":{"description":"OK"}}},"patch":{"summary":"Dispose / close a case","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"description":"An Idempotency-Key replay with the same request returns the original disposition result for 24 hours after reservation, without creating another audit or webhook event. After 24 hours the key remains reserved and returns 409 with idempotency_expired; it is never executed again. Reusing the key for different content returns 409 with idempotency_conflict.","responses":{"200":{"description":"OK"}}}},"/cases/{caseId}/export":{"get":{"summary":"Export case evidence pack","description":"Returns schemaVersion 1.1.0. case.provenance is present only when the linked result has the trusted local syntheticDemoFixture marker.","responses":{"200":{"description":"JSON case evidence pack"}}}},"/audit/export":{"get":{"summary":"Export audit log (paginated)","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","maximum":2000,"default":500}},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"Opaque cursor from previous nextCursor (`{iso}|{id}`)"}],"responses":{"200":{"description":"JSON events with total/truncated/nextCursor","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/AuditExport"}}}}}}}}},"/graph/{profileId}":{"get":{"summary":"List relationship neighbors for an entity profile","parameters":[{"name":"profileId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Neighbors","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/GraphNeighbors"}}}}}}}}},"/monitor":{"get":{"summary":"List continuous-monitoring watches","description":"Requires monitor:manage.","responses":{"200":{"description":"OK"}}},"post":{"summary":"Create watch + initial screen","description":"Requires monitor:manage. Honour input.categories for persons (defaults to sanctions+terror). If the initial screen exceeds the monitor budget, returns screenStatus=pending with the watch id.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["subjectType","input"],"properties":{"subjectType":{"type":"string","enum":["person","entity","wallet"]},"input":{"type":"object","description":"Person: PersonScreenBody fields including categories"},"externalReference":{"type":"string"}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/MonitorWatch"}}}}}}}}},"/monitor/{watchId}":{"post":{"summary":"Force rescreen a watch","responses":{"200":{"description":"OK"}}},"delete":{"summary":"Disable a watch","responses":{"200":{"description":"Disabled"}}}},"/webhooks":{"get":{"summary":"List webhooks","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"webhooks":{"type":"array","items":{"$ref":"#/components/schemas/Webhook"}}}}}}}}}}},"post":{"summary":"Create webhook","description":"Requires webhooks:manage. Secret returned once.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url","events"],"properties":{"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Webhook"}}}}}}}}}}}