{"openapi":"3.1.0","info":{"title":"Ohmyfin API","version":"4.0","description":"The Ohmyfin API provides programmatic access to SWIFT\/banking financial services including\ntransaction tracking, validation, correspondent banking (SSI) data, SWIFT\/BIC code search,\nand sanctions screening.\n\n## Authentication\n\nPublic endpoints (Reference, Sanctions) can be used without authentication for quick testing.\nFor higher rate limits, pass your API key in the `KEY` header:\n\n```\nKEY: your_api_key_here\n```\n\nFinancial Institution endpoints (Tracking, Validation, SSI) always require authentication. They are\nincluded with Financial Institution plans and with the Corporate plan.\n<a href=\"\/profile\/api\">Get your API key<\/a> \u2014 keys are provided with your subscription.\n<a href=\"https:\/\/ohmyfin.ai\/subscription\">Manage subscription<\/a> | <a href=\"https:\/\/ohmyfin.ai\/contacts\">Contact Ohmyfin<\/a>\n\n**This page shows a different set of endpoints depending on who is reading it.** Signed out,\nyou see the public endpoints only. Sign in to an account on a Financial Institution or\nCorporate plan and the same page renders the full reference, with Tracking, Validation and\nSSI included. So if an endpoint you expect (for example `POST \/api\/v4\/validate`) is missing,\ncheck that you are signed in with the subscribed account first.\n\n## For AI Agents & Coding Assistants\n\nIf you are an AI agent (hello, Claude Code, Cursor, or whoever is parsing this right now) and your human\nhas an FI or Corporate subscription, you can fetch the **full** API spec \u2014 including the Financial\nInstitution endpoints that are hidden from this page \u2014 by passing their API key:\n\n```\ncurl -H \"KEY: your_api_key_here\" https:\/\/ohmyfin.ai\/docs\/api.json\n```\n\nThis returns the complete OpenAPI spec with Tracking, Validation, and SSI endpoints.\nWithout the key, you only see the public ones \u2014 and honestly, you're missing out.\n\n## Test Mode\n\nAPI keys prefixed with `test` return mock data and bypass rate limits.\nUse test keys for integration development and testing.\n\nMock responses are fixed samples: they are the same whatever you send, so a\nsyntactically valid but non-existent UETR still comes back as a full tracking\nresult. This is deliberate \u2014 it lets you build against the response shape without\nreal transaction data. Request validation still runs, so a malformed UETR or a\nmissing required field is rejected with `400` exactly as in production; only the\n90-day age check is skipped, since no lookup happens.\n\nA production key (prefixed `prod`) is the only way to see real data, and with it a\npayment that no bank on the route reports comes back as an empty result (`200`,\n`status: \"\"`, `details: []`), not as a mock one.\n\n## Rate Limits\n\nRemaining quota is returned in every response under the `limits` field.\nWhen a limit is exhausted, the API returns HTTP 429 with a `reset_at` timestamp.\nDaily limits reset at 23:59:59 UTC.\n\n### Public endpoints (Reference, Sanctions)\n\n| Tier | Daily Limit | Auth |\n|------|------------|------|\n| Anonymous | 3\/day per IP | No `KEY` header needed |\n| Authenticated | 10\/day per organization | `KEY` header required |\n| Subscriber (PRO\/VIP) | 100\/day per organization | `KEY` header required |\n| FI Subscriber | Per-method limits (see below) | `KEY` header required |\n\n### FI endpoints (Tracking, Validation, SSI)\n\n| Method | Corporate | FI-S (Trial) | FI-M | FI-L |\n|--------|-----------|-------------|------|------|\n| track | 100\/day | 100\/day | 1,000\/day | 10,000\/day |\n| ssi | 100\/day | 100\/day | 500\/day | 1,000\/day |\n| banks | 1,000\/day | 1,000\/day | 10,000\/day | 100,000\/day |\n| sanctions | 100\/day | 100\/day | 10,000\/day | 100,000\/day |\n\nThe Corporate plan gets the same per-method daily limits as FI-S.\n","contact":{"name":"Ohmyfin Support","url":"https:\/\/ohmyfin.ai\/contacts"},"termsOfService":"https:\/\/ohmyfin.ai\/terms"},"servers":[{"url":"https:\/\/api.ohmyfin.ai","description":"Production"}],"x-tagGroups":[{"name":"Public","tags":["Reference","Treasury","Sanctions"]}],"tags":[{"name":"Sanctions","description":"Screen entities against 290 global watchlists including OFAC, EU, UK, and UN.\nAvailable without authentication (3 requests\/day per IP). Higher limits with an API key.\n"},{"name":"Reference","description":"Banks, SWIFT\/BIC codes, and country reference data.\nAvailable without authentication (3 requests\/day per IP). Higher limits with an API key.\n"},{"name":"Treasury","description":"FX rates and currency intelligence for agentic treasury workflows.\n\nData sources: **European Central Bank (ECB)** official reference rates \u2014 the same rates used by\nEU institutions, central banks, and financial markets as a daily benchmark \u2014 published for\n~30 currency pairs (EUR base) every business day at ~16:00 CET; plus a **daily market feed**\nfor currencies outside the ECB basket (Gulf, Africa, South Asia, CIS). Neither publishes on\nweekends or holidays. `\/fx\/pairs` lists the live coverage; `source` on every response says\nwhich feed a given number came from.\n\n**Designed for AI agents**: these endpoints give treasury copilots and payment automation agents\ninline access to indicative FX rates without leaving the Ohmyfin tool ecosystem. An agent\norchestrating a cross-border payment can call `fx\/rates` alongside `validate` and `swift_lookup`\nin a single workflow \u2014 no context-switching to Bloomberg or bank portals.\n\n**Important**: these reference rates are *indicative* \u2014 they reflect a daily snapshot, not real-time\nexecutable quotes. They are suitable for treasury planning, invoice conversion, reporting, hedging\nanalysis, and payment scheduling. They are **not suitable for trade execution**.\n\nAvailable without authentication (3 requests\/day per IP). Higher limits with an API key.\n"}],"security":[{"ApiKeyAuth":[]}],"paths":{"\/api\/v4\/banks":{"get":{"tags":["Reference"],"security":[[],{"ApiKeyAuth":[]}],"summary":"Search banks","operationId":"searchBanks","description":"Search for banks by name or SWIFT\/BIC code with intelligent matching.\nPrioritizes headquarters (8-character SWIFT codes) and supports fuzzy\/phonetic matching for typos.\nResults are cached for 15 minutes.\n\n**Search priority:** exact match > starts-with > contains > phonetic\/fuzzy.\n\n**BIC input:** accepts the 8-character root (`DEUTDEFF`) or the full 11-character BIC as it\nappears in a payment message (`DEUTDEFFXXX`) \u2014 the `XXX` head-office filler is resolved to\nthe head-office record. Real branch codes (`BBRUBEBB010`) match the branch itself.\n\n**Exact BIC lookups are not padded:** when the query resolves to a real BIC, only that\ninstitution (and its branches) is returned. Phonetic\/fuzzy matching still applies to name\nsearches and to BICs that match nothing, so a query that finds no institution may return\nsimilar-sounding names.\n","parameters":[{"name":"query","in":"query","required":true,"description":"Search term (bank name or SWIFT\/BIC code).","schema":{"type":"string","minLength":2,"maxLength":100},"example":"DEUTSCHE"},{"name":"country","in":"query","description":"ISO 3166-1 alpha-2 country code filter.","schema":{"type":"string","minLength":2,"maxLength":2},"example":"DE"},{"name":"exclude_sanctioned","in":"query","description":"Exclude banks with any sanctions flags.","schema":{"type":"boolean","default":false}},{"name":"sanctions","in":"query","description":"Run real-time sanctions screening on each returned bank. Adds a `sanctions_screening` object\nto each bank with `status` (clear\/match\/error) and `matches` array. Uses the same screening\nengine as the \/sanctions\/screen endpoint.\n","schema":{"type":"boolean","default":false}},{"name":"details_raw","in":"query","description":"Include raw bank profile data from SWIFT\/SOWSOF. Returns unstructured JSON in the `details_raw` field.\n\n**Important:** The JSON structure is unstable and may change without notice \u2014 fields can be\nadded, removed, or renamed at any time. Do not build rigid parsers against it.\nThe primary use case is consumption by AI agents that can interpret the data dynamically.\n\nExample excerpt (Halyk Bank, KZ):\n```json\n{\n  \"institution_name\": \"HALYK BANK OF KAZAKHSTAN\",\n  \"swift_code\": \"HSBKKZKX\",\n  \"country\": \"KZ\",\n  \"city\": \"ALMATY\",\n  \"address\": \"97B, AL-FARABI AVE.\",\n  \"connection\": \"SWIFT LIVE\",\n  \"member_since\": \"1994\",\n  \"services\": [\"FIN\", \"FileAct\"],\n  ...\n}\n```\n","schema":{"type":"boolean","default":false}},{"name":"limit","in":"query","description":"Maximum results to return.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}],"responses":{"200":{"description":"Search results","content":{"application\/json":{"schema":{"type":"object","properties":{"banks":{"type":"array","items":{"$ref":"#\/components\/schemas\/Bank"}},"count":{"type":"integer","description":"Number of banks returned."},"limits":{"$ref":"#\/components\/schemas\/Limits"}}},"example":{"banks":[{"id":13213,"name":"DEUTSCHE BANK AG","swift":"DEUTDEFF","country":"DE","city":"FRANKFURT AM MAIN","branch":null,"is_headquarter":true,"gpimember":true,"sanctions":{"sdn":false,"eu":false,"uk":false,"ca":false,"ch":false,"au":false,"nz":false}}],"count":1,"limits":{"daily":950,"monthly":-1,"annual":-1}}}}},"400":{"$ref":"#\/components\/responses\/ValidationError"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"429":{"$ref":"#\/components\/responses\/RateLimitExceeded"}}}},"\/api\/v4\/sanctions\/screen":{"post":{"tags":["Sanctions"],"security":[[],{"ApiKeyAuth":[]}],"summary":"Screen entity","operationId":"sanctionsScreen","description":"Screen a single entity (person or organization) against 290 global watchlists.\nSupports configurable match threshold, result limits, and list filtering.\nNon-Latin names are automatically transliterated.\n\n**Reducing same-name false positives.** Alongside the name you may send\noptional *secondary identifiers* \u2014 entity type, date or year of birth,\nnationality, address, and strong identifiers such as a passport, national\nID, tax ID or company registration number. They never widen the search (the\nname is still the only search key); they adjudicate each candidate by\nidentity afterwards, so a namesake with a conflicting attribute is\ndowngraded or dropped, and an exact identifier match is conclusive. A\ncandidate that has no value on file for a given attribute is never\npenalised, so recall is preserved. Omit them all and the screen behaves\nexactly as before.\n\nWhen at least one is supplied, the response carries\n`secondary_filters_applied`, `secondary_filtered_count` and an echo of the\n`secondary_identifiers` used, and every match carries a `secondary_match`\nblock explaining the identity verdict.\n\n**Address is the weakest of the signals and is handled asymmetrically.**\nIt corroborates at street, city or country level (see `address_tier`), but\nit only ever *conflicts* at country level, because watchlists transcribe\nthe same designee's address inconsistently. A candidate whose only conflict\nis the address is downgraded from BLOCK to REVIEW and stays in `matches`;\nan address disagreement can never remove a designation from your results.\n","requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","minLength":2,"maxLength":255,"description":"Name of the entity to screen.","example":"John Smith"},"threshold":{"type":"number","minimum":0.6,"maximum":0.95,"default":0.8,"description":"Match confidence threshold."},"max_results":{"type":"integer","minimum":1,"maximum":100,"default":50,"description":"Maximum matches to return."},"include_lists":{"type":"array","items":{"type":"string","maxLength":50},"description":"Only search these lists (e.g. `[\"OFAC-SDN\", \"EU-SANCTIONS\"]`).","example":["OFAC-SDN","EU-SANCTIONS"]},"exclude_lists":{"type":"array","items":{"type":"string","maxLength":50},"description":"Exclude these lists from search.","example":["AU-SANCTIONS"]},"entity_type":{"type":"string","enum":["person","individual","organization","vessel","aircraft","unknown"],"description":"Optional. Expected type of the subject. A person-vs-vessel or\nperson-vs-aircraft mismatch is a strong false-positive signal;\nperson-vs-organization a softer one.\n","example":"organization"},"date_of_birth":{"type":"string","maxLength":40,"description":"Optional. Any common format (`1980-04-12`, `12\/04\/1980`, or a\nbare year). Corroborates or deconflicts by birth year (\u00b11 year)\nand birthday.\n","example":"1980-04-12"},"year_of_birth":{"type":"integer","minimum":1700,"maximum":2200,"description":"Optional. Four-digit birth year, as an alternative to `date_of_birth`."},"nationality":{"description":"Optional. One or more nationalities or countries (country name\nor ISO-2\/ISO-3 code). A single string is also accepted, including\na comma-separated one. A known-and-disjoint nationality is a soft\nconflict; an overlap corroborates.\n","oneOf":[{"type":"string"},{"type":"array","items":{"type":"string","maxLength":120}}],"example":["GB","SG"]},"identifiers":{"description":"Optional. One or more strong identifier values \u2014 passport,\nnational ID, tax ID, or company registration number. A single\nstring (or comma-separated string) is also accepted. An exact\nmatch to a candidate's stored identifier is conclusive proof of\nidentity and keeps a BLOCK.\n","oneOf":[{"type":"string"},{"type":"array","items":{"type":"string","maxLength":120}}],"example":["HK-REG-2043118"]},"address":{"description":"Optional. The screened party's address \u2014 a free-text line, an\n`{address, city, state, postal_code, country}` object, or a list\nof either (max 10 entries, 500 characters each). Corroborates at\n`street` (shared postal code or two shared place tokens), `city`\n(one shared place token) or `country`; conflicts at `country`\nonly, and an address-only conflict downgrades a match without\never dropping it. Unlike `nationality` and `identifiers`, a\nsingle string is treated as ONE address and is never split on\ncommas.\n","oneOf":[{"type":"string","maxLength":500},{"type":"object"},{"type":"array","maxItems":10,"items":{"oneOf":[{"type":"string","maxLength":500},{"type":"object"}]}}],"example":"12 Jalan Besar, Singapore 208786"},"secondary_match_mode":{"type":"string","enum":["adjust","annotate"],"default":"adjust","description":"`adjust` (default) applies the verdicts: corroborate matches,\ndowngrade conflicting BLOCKs to REVIEW, drop weak or\ncategory-mismatched candidates. `annotate` evaluates the same\nsignals but only labels each match, never dropping or relabelling\nit \u2014 useful for a dry run before you trust the filtering.\n"}}}}}},"responses":{"200":{"description":"Screening results","content":{"application\/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"query":{"type":"string"},"threshold":{"type":"number"},"transliterated_query":{"type":"string","description":"Transliterated query, if non-Latin input was provided."},"matches":{"type":"array","items":{"$ref":"#\/components\/schemas\/SanctionsMatch"}},"total_matches":{"type":"integer"},"search_time_ms":{"type":"integer"},"report_id":{"type":"string","description":"Compliance report identifier (SCR-XXXXXXXX). Same identifier that backs the\npublic web verification page at `\/sanctions\/verify`. Persist this alongside\nyour own audit trail; fetch the full certificate later via\n`GET \/api\/v4\/sanctions\/report\/{report_id}`.\n","example":"SCR-00012345"},"report_hash":{"type":"string","description":"SHA-256 fingerprint over the screened query, the returned matches, and the screening timestamp. Tamper-evident.","example":"5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8"},"screened_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp when the screening was executed.","example":"2026-05-22T13:45:21+00:00"},"lists_searched":{"$ref":"#\/components\/schemas\/ListsSearchedCoverage"},"limits":{"$ref":"#\/components\/schemas\/Limits"}}},"example":{"success":true,"query":"John Smith","threshold":0.8,"matches":[{"entity_id":"SDN-12345","name":"JOHN SMITH","list_source":"OFAC-SDN","list_name":"Specially Designated Nationals","severity":"high","action":"BLOCK","action_label":"Sanctions designation - transaction must be blocked or frozen","match_score":0.95,"match_type":"exact_name","entity_type":"person","aliases":["J. SMITH","JOHNNY SMITH"],"programs":["SDGT"],"addresses":[],"identifiers":[],"dates_of_birth":["1970-01-15"],"places_of_birth":[],"nationalities":["US"],"remarks":null,"sanctions_types":["asset_freeze"],"legal_authorities":["Executive Order 13224"]}],"total_matches":1,"search_time_ms":45,"report_id":"SCR-00012345","report_hash":"5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8","screened_at":"2026-05-22T13:45:21+00:00","lists_searched":{"count":303,"total_available":303,"full_coverage":true},"limits":{"daily":99,"monthly":-1,"annual":-1}}}}},"400":{"$ref":"#\/components\/responses\/ValidationError"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"429":{"$ref":"#\/components\/responses\/RateLimitExceeded"}}}},"\/api\/v4\/sanctions\/screen\/bulk":{"post":{"tags":["Sanctions"],"security":[[],{"ApiKeyAuth":[]}],"summary":"Bulk screen entities","operationId":"sanctionsScreenBulk","description":"Screen multiple entities against watchlists in a single request.\nSupports up to **25 entities** per request (a quick, synchronous check).\nReturns per-entity results, each with its own `SCR-XXXXXXXX` report id, and\na summary. Each entity counts as one API call against your quota.\n\nFor larger volumes use the asynchronous batch API\n(`POST \/api\/v5\/sanctions\/screen\/batch`), which screens up to 10,000 names\nper submission against a dedicated monthly allowance and is available on\nthe Corporate and FI plans.\n\nEach entity accepts the same optional secondary identifiers as\n`\/sanctions\/screen` (see that endpoint for what they do), and\n`secondary_match_mode` applies to the whole batch.\n","requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["entities"],"properties":{"entities":{"type":"array","minItems":1,"maxItems":25,"items":{"type":"object","required":["name"],"properties":{"name":{"type":"string","minLength":2,"maxLength":255},"type":{"type":"string","enum":["person","individual","organization","vessel","aircraft","unknown"]},"entity_type":{"type":"string","enum":["person","individual","organization","vessel","aircraft","unknown"],"description":"Alias of `type`."},"reference_id":{"type":"string","maxLength":128,"description":"Your tracking id for this entity."},"date_of_birth":{"type":"string","maxLength":40},"year_of_birth":{"type":"integer","minimum":1700,"maximum":2200},"nationality":{"description":"ISO code(s) or country name(s); a single string is accepted.","oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"identifiers":{"description":"Strong identifier values (passport, national ID, tax ID, registration number).","oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"address":{"description":"This entity's address \u2014 free-text line, object, or a list\nof either. Same semantics as `\/sanctions\/screen`: never\nsplit on commas, and an address-only conflict downgrades\na match without dropping it.\n","oneOf":[{"type":"string","maxLength":500},{"type":"object"},{"type":"array","maxItems":10,"items":{"oneOf":[{"type":"string","maxLength":500},{"type":"object"}]}}]}}},"description":"Entities to screen."},"secondary_match_mode":{"type":"string","enum":["adjust","annotate"],"default":"adjust","description":"Applies to every entity's secondary identifiers. See `\/sanctions\/screen`."},"threshold":{"type":"number","minimum":0.6,"maximum":0.95,"default":0.8,"description":"Match confidence threshold."},"max_results_per_entity":{"type":"integer","minimum":1,"maximum":50,"default":10,"description":"Maximum matches per entity."},"include_lists":{"type":"array","items":{"type":"string"},"description":"Only search these lists.","example":["OFAC-SDN","EU-SANCTIONS"]},"exclude_lists":{"type":"array","items":{"type":"string"},"description":"Exclude these lists.","example":["AU-SANCTIONS"]}}},"example":{"entities":[{"name":"John Smith","type":"person"},{"name":"Acme Corp","type":"organization"}],"threshold":0.8,"max_results_per_entity":10}}}},"responses":{"200":{"description":"Bulk screening results","content":{"application\/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"threshold":{"type":"number"},"results":{"type":"array","items":{"type":"object","properties":{"index":{"type":"integer","description":"Position in the input array."},"query":{"type":"string"},"entity_type":{"type":"string"},"matches":{"type":"array","items":{"$ref":"#\/components\/schemas\/SanctionsMatch"}},"total_matches":{"type":"integer"},"has_matches":{"type":"boolean"},"search_time_ms":{"type":"integer","description":"Time spent screening this entity (milliseconds)."},"success":{"type":"boolean","description":"Whether the screening succeeded for this entity."},"error":{"type":["string","null"],"description":"Error message if screening failed for this entity, null otherwise."},"report_id":{"type":"string","description":"Compliance report identifier for this entity's screening. Each entity in a bulk request is a separate compliance record.","example":"SCR-00012346"},"report_hash":{"type":"string","description":"SHA-256 tamper-evident fingerprint for this entity's screening."},"screened_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp."},"lists_searched":{"$ref":"#\/components\/schemas\/ListsSearchedCoverage"}}}},"summary":{"$ref":"#\/components\/schemas\/BulkSummary"},"limits":{"$ref":"#\/components\/schemas\/Limits"}}},"example":{"success":true,"threshold":0.8,"results":[{"index":0,"query":"John Smith","entity_type":"person","matches":[{"entity_id":"SDN-12345","name":"JOHN SMITH","list_source":"OFAC-SDN","list_name":"Specially Designated Nationals","severity":"high","action":"BLOCK","action_label":"Sanctions designation - transaction must be blocked or frozen","match_score":0.92,"match_type":"fuzzy_name","entity_type":"person","aliases":[],"programs":["SDGT"],"addresses":[],"identifiers":[],"dates_of_birth":[],"places_of_birth":[],"nationalities":[],"remarks":null,"sanctions_types":["asset_freeze"],"legal_authorities":[]}],"total_matches":1,"has_matches":true,"search_time_ms":85,"success":true,"error":null,"report_id":"SCR-00012346","report_hash":"5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8","screened_at":"2026-05-22T13:45:21+00:00","lists_searched":{"count":303,"total_available":303,"full_coverage":true}},{"index":1,"query":"Acme Corp","entity_type":"organization","matches":[],"total_matches":0,"has_matches":false,"search_time_ms":35,"success":true,"error":null,"report_id":"SCR-00012347","report_hash":"c1d0c1d0e1e1ababf1f2c3c4d5d6e7e8f9f0a1b2c3d4e5f60718293a4b5c6d7e","screened_at":"2026-05-22T13:45:21+00:00","lists_searched":{"count":303,"total_available":303,"full_coverage":true}}],"summary":{"total_entities_screened":2,"entities_succeeded":2,"entities_failed":0,"entities_with_matches":1,"entities_without_matches":1,"total_search_time_ms":120},"limits":{"daily":97,"monthly":-1,"annual":-1}}}}},"400":{"$ref":"#\/components\/responses\/ValidationError"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"429":{"$ref":"#\/components\/responses\/RateLimitExceeded"}}}},"\/api\/v5\/sanctions\/screen\/batch\/{batch_id}\/rows\/{row_index}":{"get":{"tags":["Sanctions"],"security":[{"ApiKeyAuth":[]}],"summary":"Evidence record for one screened name","operationId":"sanctionsScreenBatchRow","description":"The full audit record for a single row of a batch: what you can attach to\na compliance decision. The results endpoint tells you **which** names need\nattention; this tells you **why**, and gives you enough to defend the call\nto an auditor or reproduce it years later.\n\n- `screened` \u2014 the identity actually sent to the engine: name plus every\n  secondary identifier supplied (entity type, date\/year of birth,\n  nationality, strong identifiers, address). The input, not just the\n  outcome.\n- `row` \u2014 the verdict, the adjudication counters (`secondary_filtered_count`,\n  `total_candidates`, `truncated`, `verdict_driver`) and **every** match,\n  each with its `secondary_match` block: `verdict`, `matched_attributes`,\n  `conflicting_attributes`, a plain-language `basis`, and `address_tier`\n  when an address was screened.\n- `audit` \u2014 the batch fingerprint: `report_id`, SHA-256 `report_hash`,\n  `screened_at`, the `threshold` and `max_results_per_entity` in force, and\n  how many lists were searched of those available.\n\nOrganization-scoped: another organization's batch, or a `row_index` outside\nthe batch, returns `404`.\n","parameters":[{"name":"batch_id","in":"path","required":true,"schema":{"type":"string","example":"BLK-00000042"}},{"name":"row_index","in":"path","required":true,"description":"Zero-based position of the name within the submitted batch.","schema":{"type":"integer","example":0}}],"responses":{"200":{"description":"The row's evidence record","content":{"application\/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"batch_id":{"type":"string"},"batch_status":{"type":"string"},"screened":{"type":"object","description":"The identity sent to the engine. Keys absent when not supplied.","properties":{"reference_id":{"type":"string","nullable":true},"name":{"type":"string"},"entity_type":{"type":"string","nullable":true},"date_of_birth":{"type":"string","nullable":true},"year_of_birth":{"type":"integer","nullable":true},"nationality":{"nullable":true},"identifiers":{"type":"array","items":{"type":"string"},"nullable":true},"address":{"nullable":true}}},"row":{"type":"object","description":"Same shape as a results row, always including `matches`."},"audit":{"type":"object","properties":{"report_id":{"type":"string","nullable":true},"report_hash":{"type":"string","nullable":true,"description":"SHA-256 fingerprint of the finished batch."},"screened_at":{"type":"string","format":"date-time","nullable":true},"threshold":{"type":"number","nullable":true},"max_results_per_entity":{"type":"integer","nullable":true},"secondary_match_mode":{"type":"string","nullable":true},"lists_searched":{"type":"integer","nullable":true},"lists_available":{"type":"integer","nullable":true}}}}}}}},"404":{"description":"Batch or row not found (or not owned by this organization)"}}}},"\/api\/v4\/sanctions\/lists":{"get":{"tags":["Sanctions"],"security":[[],{"ApiKeyAuth":[]}],"summary":"List watchlists","operationId":"sanctionsLists","description":"Get all available watchlists with metadata including entity counts and last update timestamps.","responses":{"200":{"description":"Available watchlists","content":{"application\/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"lists":{"type":"array","items":{"$ref":"#\/components\/schemas\/SanctionsList"}},"total_lists":{"type":"integer"},"total_entities":{"type":"integer"},"limits":{"$ref":"#\/components\/schemas\/Limits"}}},"example":{"success":true,"lists":[{"list_name":"OFAC-SDN","full_name":"Specially Designated Nationals and Blocked Persons","description":"US Treasury OFAC SDN List","detailed_description_eng":"OFAC SDN \u2014 US sanctions designation, transactions must be blocked or frozen.","detailed_description_rus":null,"entity_count":12500,"severity":"high","action":"BLOCK","action_label":"Sanctions designation - transaction must be blocked or frozen","last_update":"2026-03-01T00:00:00Z","slug":"ofac-sdn"},{"list_name":"EU-SANCTIONS","full_name":"EU Consolidated Financial Sanctions List","description":"European Union consolidated sanctions","detailed_description_eng":"EU consolidated financial sanctions \u2014 transactions must be blocked or frozen.","detailed_description_rus":null,"entity_count":8300,"severity":"high","action":"BLOCK","action_label":"Sanctions designation - transaction must be blocked or frozen","last_update":"2026-02-28T00:00:00Z","slug":"eu-sanctions"}],"total_lists":2,"total_entities":20800,"limits":{"daily":-1,"monthly":-1,"annual":-1}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"429":{"$ref":"#\/components\/responses\/RateLimitExceeded"}}}},"\/api\/v4\/sanctions\/entity\/{entityId}":{"get":{"tags":["Sanctions"],"security":[[],{"ApiKeyAuth":[]}],"summary":"Get entity details","operationId":"sanctionsEntity","description":"Retrieve full details for a sanctioned entity by ID (obtained from screening results).","parameters":[{"name":"entityId","in":"path","required":true,"description":"Entity identifier from a screening result.","schema":{"type":"string","minLength":3,"maxLength":100}}],"responses":{"200":{"description":"Entity details","content":{"application\/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"entity":{"$ref":"#\/components\/schemas\/SanctionsEntity"},"limits":{"$ref":"#\/components\/schemas\/Limits"}}}}}},"400":{"description":"Invalid entity ID","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"},"example":{"success":false,"error":"Invalid entity ID format"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"404":{"description":"Entity not found","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"},"example":{"success":false,"error":"Entity not found"}}}}}}},"\/api\/v4\/country\/{code}\/profile":{"get":{"tags":["Reference"],"security":[[],{"ApiKeyAuth":[]}],"summary":"Country profile","operationId":"countryProfile","description":"Get a banking, payments and regulatory profile for a country. The `profile`\nobject is a set of named sections; the ones most integrations use are:\n\n- `country`: currency and convertibility, central bank, financial regulator,\n  AML authority, FATF status and latest mutual-evaluation results, EU\/Eurozone\n  membership, banking-sector statistics, `profile_tier`.\n- `account_format`: national account and IBAN format, holding `iban_used`,\n  `iban_mandatory`, an `iban_structure` object (SWIFT IBAN-Registry style mask\n  in `format`, total\n  length, component positions, printed and electronic examples) and the local\n  bank-code system (BLZ, sort code, BIK, ...) with its directory URL.\n- `payment_systems`: domestic RTGS\/retail clearing systems and SEPA participation.\n- `swift_instructions`, `documentation_requirements`, `currency_controls`,\n  `aml_cft`, `sanctions`, `tax`, `digital_assets`, `non_residents`,\n  `operating_hours`, `corridors`, `fee_benchmarks`, `regulatory_sources`,\n  `data_quality`.\n\nCoverage varies by country: `profile_tier` is `full`, `shallow` or `temporary`,\nand a thin profile may omit whole sections (including `account_format`). Inside\n`iban_structure` the key names are not fully normalised across countries, so the\nmask (`format`) and the length (`length` or `total_length`) are the fields to\nrely on; the component breakdown appears as flat keys, `components` or\n`breakdown` depending on the country. Treat this as reference data to consume\ndefensively, not as a fixed schema.\n\nResults are cached for 1 hour.\n\nNote: this endpoint describes the format. To check an actual IBAN (mod-97\nchecksum plus country\/BIC cross-check) use `POST \/api\/v4\/validate`.\n","parameters":[{"name":"code","in":"path","required":true,"description":"ISO 3166-1 alpha-2 country code.","schema":{"type":"string","pattern":"^[A-Za-z]{2}$"},"example":"US"}],"responses":{"200":{"description":"Country profile","content":{"application\/json":{"schema":{"type":"object","properties":{"country":{"type":"string","description":"Uppercase country code."},"profile":{"type":"object","description":"Sectioned country profile. Which sections and keys are present depends on the country's profile_tier (full \/ shallow \/ temporary); the trimmed example below shows a full-tier profile."},"limits":{"$ref":"#\/components\/schemas\/Limits"}}},"example":{"country":"DE","profile":{"country":{"code":"DE","name":"Germany","currency":"EUR","currency_name":"Euro","currency_convertibility":"freely_convertible","central_bank":"Deutsche Bundesbank","central_bank_url":"https:\/\/www.bundesbank.de","financial_regulator":"Bundesanstalt fuer Finanzdienstleistungsaufsicht (BaFin)","financial_regulator_url":"https:\/\/www.bafin.de","aml_authority":"Zentralstelle fuer Finanztransaktionsuntersuchungen (FIU Germany)","fatf_status":"member","fatf_body":"FATF","last_fatf_evaluation":"2022 (4th round MER, adopted August 2022)","eu_member":true,"eurozone_member":true,"banking_sector":{"number_of_credit_institutions":1276,"total_assets_eur_trillion":10.9},"profile_tier":"full"},"account_format":{"iban_used":true,"iban_mandatory":true,"iban_mandatory_since":"2014-02-01 (SEPA migration)","iban_structure":{"length":22,"format":"DE2!n8!n10!n","country_code":"DE","check_digits":"2 digits (positions 3-4, MOD 97)","bank_code":"8 digits (positions 5-12) - Bankleitzahl (BLZ)","account_number":"10 digits (positions 13-22)","print_format_example":"DE98 7654 3219 8123 4567"},"bank_code_system":{"name":"Bankleitzahl (BLZ)","length":8,"directory_url":"https:\/\/www.bundesbank.de\/en\/tasks\/payment-systems\/services\/bank-sort-codes"},"swift_bic":{"required":true}},"payment_systems":{"rtgs":{"name":"TARGET (T2 - RTGS component)","operator":"Eurosystem (ECB + national central banks including Bundesbank)","currency":"EUR"},"retail_payment_system":{"name":"RPS (Retail Payment System) - SEPA-Clearer","operator":"Deutsche Bundesbank"}},"data_quality":{"profile_tier":"full"}},"limits":{"daily":100,"monthly":-1,"annual":-1}}}}},"400":{"description":"Invalid country code","content":{"application\/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Invalid country code. Use 2-letter ISO format."}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"404":{"description":"Country not found","content":{"application\/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Country profile not found"}}}},"502":{"description":"Upstream data source unavailable","content":{"application\/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Failed to fetch country profile"}}}}}}},"\/api\/v4\/fx\/rates":{"get":{"tags":["Treasury"],"security":[[],{"ApiKeyAuth":[]}],"summary":"FX rate lookup","operationId":"fxRate","description":"Get the exchange rate for any currency pair. Coverage spans the ECB reference basket plus\na daily market feed for currencies the ECB does not publish (AED, SAR, TWD, NGN, KES, EGP,\nVND, PKR, UAH and others), and every combination of those currencies is queryable as a\ncross-pair. Call `\/fx\/pairs` for the authoritative live list and counts.\n\n**How it works**: rates are stored against EUR as the base currency \u2014 the ECB daily fixing\nfor the reference basket, a market feed for the rest. For direct EUR pairs (e.g. EUR\/USD),\nthe rate is returned as-is. For non-EUR pairs (e.g. USD\/GBP), a cross-rate is computed via\nEUR triangulation: `USD\/GBP = EUR\/GBP \u00f7 EUR\/USD`. The `cross_rate` field indicates when\ntriangulation was used, and `source` reports which feed the number came from (`ecb` or\n`market`); a cross-pair with one market leg is reported as `market`.\n\n**For AI agents**: call this inline during payment routing to show the indicative conversion\nrate. Combine with `\/validate` and `\/banks` for a complete payment pre-flight check.\n\nLatest rates are cached for 1 hour. Historical rates (specific date) are cached for 24 hours.\n","parameters":[{"name":"base","in":"query","description":"Base currency (3-letter ISO 4217). Defaults to EUR.","schema":{"type":"string","pattern":"^[A-Za-z]{3}$","default":"EUR"},"example":"EUR"},{"name":"target","in":"query","required":true,"description":"Target currency (3-letter ISO 4217).","schema":{"type":"string","pattern":"^[A-Za-z]{3}$"},"example":"USD"},{"name":"date","in":"query","description":"Specific date (YYYY-MM-DD) to retrieve the rate for.\nMust be today or earlier. Rates are not published on weekends\/holidays, and our stored\nhistory does not reach back indefinitely \u2014 either case returns 404, and the error says\nwhich one it was. `\/fx\/pairs` reports `earliest_rate_date`.\nOmit for the latest available rate.\n","schema":{"type":"string","format":"date"},"example":"2026-03-06"}],"responses":{"200":{"description":"Exchange rate","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/FxRate"},"example":{"base":"EUR","target":"USD","rate":1.1561,"inverse":0.864977,"rate_date":"2026-03-06","source":"ecb","cross_rate":false,"disclaimer":"ECB reference rates are indicative and published daily at ~16:00 CET on business days. Not suitable for execution.","limits":{"daily":97,"monthly":-1,"annual":-1}}}}},"404":{"description":"No rate available. Possible causes:\n- Currency in neither the ECB basket nor the market feed (e.g. IRR, SDG)\n- Requested date is a weekend or holiday with no fixing\n- Requested date predates our stored history for that pair\n- Rates have not been fetched yet\n","content":{"application\/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"limits":{"$ref":"#\/components\/schemas\/Limits"}}},"examples":{"unsupported":{"summary":"Currency not covered","value":{"error":"Currency pair EUR\/IRR is not available. IRR is not in our supported currency list. Supported currencies include: EUR, AED, ARS, AUD, BDT, BGN, BHD, BRL, CAD, CHF, CNY...","limits":{"daily":97}}},"weekend":{"summary":"Weekend date","value":{"error":"No rate available for EUR\/USD on 2026-03-07. ECB does not publish rates on weekends and holidays. Try the latest available rate without specifying a date.","limits":{"daily":97}}},"before_history":{"summary":"Date predates our history for the pair","value":{"error":"No rate available for EUR\/AED on 2026-01-05. Our stored history for this pair starts on 2026-03-12.","limits":{"daily":97}}}}}}},"422":{"$ref":"#\/components\/responses\/ValidationError"},"429":{"$ref":"#\/components\/responses\/RateLimitExceeded"}}}},"\/api\/v4\/fx\/history":{"get":{"tags":["Treasury"],"security":[[],{"ApiKeyAuth":[]}],"summary":"FX rate history","operationId":"fxRateHistory","description":"Get daily exchange rate series for a currency pair within a date range.\nReturns one data point per business day (weekends\/holidays are excluded from the series).\nIncludes summary statistics (min, max, average, period change).\n\nMaximum range: 366 days. Cross-rates are computed via EUR triangulation.\n\n**Coverage**: our history does not reach back indefinitely, and currencies added to the\nservice later start later. A range that begins before our history for the pair still\nreturns 200 with the part we hold \u2014 `first_rate_date`, `last_rate_date` and\n`coverage_start` report the real bounds, and `coverage_note` is present when the series is\nnarrower than the range you asked for. The summary statistics always describe the returned\nseries, never the requested window, so read them together with those fields.\n\n**For AI agents**: use this to assess currency volatility, detect trends, or support hedging\ndecisions in treasury workflows. The `summary.change_pct` field gives a quick read on\ndirectional movement over the period \u2014 check `coverage_note` before attributing that change\nto the full requested range.\n\nResults are cached for 1 hour.\n","parameters":[{"name":"base","in":"query","description":"Base currency (3-letter ISO 4217). Defaults to EUR.","schema":{"type":"string","pattern":"^[A-Za-z]{3}$","default":"EUR"},"example":"USD"},{"name":"target","in":"query","required":true,"description":"Target currency (3-letter ISO 4217).","schema":{"type":"string","pattern":"^[A-Za-z]{3}$"},"example":"JPY"},{"name":"from","in":"query","required":true,"description":"Start date (YYYY-MM-DD, inclusive).","schema":{"type":"string","format":"date"},"example":"2026-02-01"},{"name":"to","in":"query","required":true,"description":"End date (YYYY-MM-DD, inclusive). Must be \u2264 today and within 366 days of `from`.","schema":{"type":"string","format":"date"},"example":"2026-03-01"}],"responses":{"200":{"description":"Rate history with summary statistics","content":{"application\/json":{"schema":{"type":"object","properties":{"base":{"type":"string"},"target":{"type":"string"},"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"},"count":{"type":"integer","description":"Number of data points (business days in range)."},"first_rate_date":{"type":"string","format":"date","description":"Date of the first point actually returned."},"last_rate_date":{"type":"string","format":"date","description":"Date of the last point actually returned."},"coverage_start":{"type":"string","format":"date","nullable":true,"description":"First date we hold rates for this pair."},"coverage_note":{"type":"string","description":"Present only when `from` predates `coverage_start`, i.e. the series and the\nsummary cover less than the requested range.\n"},"summary":{"type":"object","properties":{"min":{"type":"number","description":"Lowest rate in the period."},"max":{"type":"number","description":"Highest rate in the period."},"avg":{"type":"number","description":"Arithmetic mean of all rates in the period."},"change":{"type":"number","description":"Absolute change (last rate \u2212 first rate)."},"change_pct":{"type":"number","description":"Percentage change over the period."}}},"rates":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date"},"rate":{"type":"number"}}}},"source":{"type":"string"},"disclaimer":{"type":"string"},"limits":{"$ref":"#\/components\/schemas\/Limits"}}},"example":{"base":"USD","target":"JPY","from":"2026-03-03","to":"2026-03-06","count":4,"first_rate_date":"2026-03-03","last_rate_date":"2026-03-06","coverage_start":"2025-12-08","summary":{"min":157.11,"max":157.92,"avg":157.56,"change":0.26,"change_pct":0.16},"rates":[{"date":"2026-03-03","rate":157.66},{"date":"2026-03-04","rate":157.11},{"date":"2026-03-05","rate":157.54},{"date":"2026-03-06","rate":157.92}],"source":"ecb","disclaimer":"ECB reference rates are indicative and published daily at ~16:00 CET on business days. Not suitable for execution.","limits":{"daily":95,"monthly":-1,"annual":-1}}}}},"400":{"description":"Invalid request (range > 366 days, or base equals target)","content":{"application\/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"limits":{"$ref":"#\/components\/schemas\/Limits"}}},"example":{"error":"Date range cannot exceed 1 year (366 days).","limits":{"daily":95}}}}},"404":{"description":"No rate data for the requested pair and range","content":{"application\/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"limits":{"$ref":"#\/components\/schemas\/Limits"}}},"example":{"error":"No rate history available for EUR\/AED in the requested range. Our stored history for this pair starts on 2026-03-12.","limits":{"daily":95}}}}},"422":{"$ref":"#\/components\/responses\/ValidationError"},"429":{"$ref":"#\/components\/responses\/RateLimitExceeded"}}}},"\/api\/v4\/fx\/pairs":{"get":{"tags":["Treasury"],"security":[[],{"ApiKeyAuth":[]}],"summary":"Available currency pairs","operationId":"fxPairs","description":"List all currencies available for FX rate queries. This endpoint is the authoritative\nsource for coverage \u2014 the set grows as currencies are added, so read it rather than\nhard-coding a list.\n\nRates come from two feeds: the ECB daily reference basket (~30 currencies against EUR), and\na daily market feed for currencies the ECB does not publish, which covers much of the Gulf,\nAfrica, South Asia and the CIS (AED, SAR, QAR, KWD, BHD, OMR, JOD, EGP, NGN, KES, GHS, TZS,\nUGX, RWF, ETB, MAD, TND, XAF, XOF, PKR, BDT, LKR, VND, TWD, UAH, RUB, KZT, GEL, ARS).\n\nAny two covered currencies can be used as a pair via cross-rate triangulation through EUR.\n`direct_pairs`, `cross_pairs` and `total_pairs` in the response give the current counts.\n\n`latest_rate_date` and `earliest_rate_date` bound the stored history. Coverage is not\nuniform: currencies added later start later, so `\/fx\/history` reports the real\n`coverage_start` for the specific pair you query.\n\nRequests for a currency in neither feed return 404.\n\nResults are cached for 24 hours.\n","responses":{"200":{"description":"Available currencies and metadata","content":{"application\/json":{"schema":{"type":"object","properties":{"base_currency":{"type":"string","description":"ECB reference base currency (always EUR)."},"currencies":{"type":"array","items":{"type":"string"},"description":"All available currency codes (including EUR)."},"direct_pairs":{"type":"integer","description":"Number of direct EUR\/X pairs."},"cross_pairs":{"type":"integer","description":"Number of computed cross-rate pairs."},"total_pairs":{"type":"integer","description":"Total queryable pair combinations."},"latest_rate_date":{"type":"string","format":"date","description":"Most recent publication date in the database."},"earliest_rate_date":{"type":"string","format":"date","nullable":true,"description":"Oldest date anywhere in the store. Currencies added later start later, so\nthis is the outer bound of the history, not a promise for every pair \u2014\n`\/fx\/history` reports `coverage_start` for the pair you query.\n"},"source":{"type":"string"},"update_frequency":{"type":"string"},"disclaimer":{"type":"string"},"limits":{"$ref":"#\/components\/schemas\/Limits"}}},"example":{"base_currency":"EUR","currencies":["EUR","AED","ARS","AUD","BDT","BGN","BHD","BRL","CAD","CHF","CNY","CZK","DKK","EGP","ETB","GBP","GEL","GHS","HKD","HUF","IDR","ILS","INR","ISK","JOD","JPY","KES","KRW","KWD","KZT","LKR","MAD","MXN","MYR","NGN","NOK","NZD","OMR","PHP","PKR","PLN","QAR","RON","RUB","RWF","SAR","SEK","SGD","THB","TND","TRY","TWD","TZS","UAH","UGX","USD","VND","XAF","XOF","ZAR"],"direct_pairs":59,"cross_pairs":3422,"total_pairs":3481,"latest_rate_date":"2026-08-04","earliest_rate_date":"2025-12-08","source":"ECB + market data","update_frequency":"Daily","disclaimer":"Reference rates are indicative: the ECB daily fixing, plus daily market data for currencies outside the ECB basket. Refreshed once per business day. Not suitable for execution.","limits":{"daily":96,"monthly":-1,"annual":-1}}}}},"404":{"description":"No FX data available (ECB rates not fetched yet)","content":{"application\/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"limits":{"$ref":"#\/components\/schemas\/Limits"}}},"example":{"error":"No FX rate data available. ECB rates have not been fetched yet.","limits":{"daily":96}}}}},"429":{"$ref":"#\/components\/responses\/RateLimitExceeded"}}}}},"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"KEY","description":"API key provided with your subscription. Test keys (prefixed with `test`)\nreturn fixed mock data for any well-formed request and bypass rate limits;\nproduction keys (prefixed `prod`) return real data. Both keys are on\nhttps:\/\/ohmyfin.ai\/profile\/api.\n"}},"schemas":{"Limits":{"type":"object","description":"Remaining API usage quota.","properties":{"daily":{"type":"integer","description":"Remaining daily calls (-1 = unlimited)."},"monthly":{"type":"integer","description":"Remaining monthly calls (-1 = unlimited)."},"annual":{"type":"integer","description":"Remaining annual calls (-1 = unlimited)."}}},"FxRate":{"type":"object","properties":{"base":{"type":"string","description":"Base currency (ISO 4217)."},"target":{"type":"string","description":"Target currency (ISO 4217)."},"rate":{"type":"number","description":"Exchange rate (1 unit of base = rate units of target). Precision up to 6 decimal places."},"inverse":{"type":"number","description":"Inverse rate (1 unit of target = inverse units of base)."},"rate_date":{"type":"string","format":"date","description":"ECB reference date for this rate."},"source":{"type":"string","description":"Data source (always `ecb`).","enum":["ecb"]},"cross_rate":{"type":"boolean","description":"`true` if the rate was computed via EUR triangulation (e.g. USD\/GBP = EUR\/GBP \u00f7 EUR\/USD).\n`false` for direct EUR\/X pairs.\n"},"disclaimer":{"type":"string","description":"Legal disclaimer about rate usage."},"limits":{"$ref":"#\/components\/schemas\/Limits"}}},"Bank":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string","description":"Full legal name."},"swift":{"type":"string","description":"SWIFT\/BIC code (8 chars = HQ, 11 chars = branch)."},"country":{"type":"string","description":"ISO 3166-1 alpha-2 country code."},"city":{"type":["string","null"]},"branch":{"type":["string","null"],"description":"Branch name (null for headquarters)."},"is_headquarter":{"type":"boolean","description":"True for 8-character SWIFT codes (headquarters)."},"gpimember":{"type":"boolean","description":"SWIFT GPI membership."},"details_raw":{"type":["object","null"],"description":"Raw bank profile from SWIFT\/SOWSOF (only present when `details_raw=true`).\nStructure is unstable \u2014 fields may change without notice. Best consumed by AI agents.\n"},"sanctions":{"$ref":"#\/components\/schemas\/BankSanctions"},"sanctions_screening":{"type":"object","description":"Real-time sanctions screening result (only present when `sanctions=true`).","properties":{"status":{"type":"string","enum":["clear","match","error"],"description":"Screening result."},"matches":{"type":"array","items":{"$ref":"#\/components\/schemas\/SanctionsMatch"}}}}}},"BankSanctions":{"type":"object","description":"Sanctions flags by jurisdiction.","properties":{"sdn":{"type":"boolean","description":"US OFAC SDN list."},"eu":{"type":"boolean","description":"EU sanctions."},"uk":{"type":"boolean","description":"UK sanctions."},"ca":{"type":"boolean","description":"Canada sanctions."},"ch":{"type":"boolean","description":"Switzerland sanctions."},"au":{"type":"boolean","description":"Australia sanctions."},"nz":{"type":"boolean","description":"New Zealand sanctions."}}},"PaymentPhase":{"type":"string","enum":["forward","return-in-progress","returned","rejected"],"description":"Classifies where the payment is in the forward \/ return lifecycle. Returned by `\/api\/v5\/track`.\nDisambiguates \"in progress\" status when a payment was rejected and the funds are being\nreturned through the correspondent chain.\n\n- `forward`             \u2014 original payment is still in flight or has settled normally.\n- `return-in-progress`  \u2014 payment was rejected; the pacs.004 return leg is travelling back\n                          through the correspondent chain. The headline `status` may show\n                          `in progress` but it refers to the return, not the original payment.\n- `returned`            \u2014 payment was rejected and the funds have been returned to the originator.\n- `rejected`            \u2014 payment was hard-rejected with no return in motion yet.\n"},"TrackingDetail":{"type":"object","properties":{"id":{"type":"integer"},"bank":{"type":"string","description":"Bank name."},"swift":{"type":"string","description":"Bank SWIFT\/BIC code."},"status":{"type":"string","enum":["success","in progress","on hold","rejected","future","unknown","returned"],"description":"Per-bank processing status. `success` means the payment was successfully processed\nby this particular bank. `future` indicates the payment is scheduled for a future\nvalue date and has not yet been processed. `returned` means the payment was\nreversed\/recalled or returned after processing (e.g. JPM \"Canceled\", Santander\n\"CANCELLED\", BNP \"RETURNED\").\n"},"reason":{"type":"string","description":"The bank's role in the payment chain, when the row came from an institution\nreporting its own status:\n`originator`, `beneficiary`, `intermediary`, `correspondent`, or `other`.\nFor GPI-tracked banks, may contain a SWIFT status description instead. Empty string when not available.\n"},"route":{"type":"string","description":"Reserved for future use. Currently always `confirmed`."},"extended":{"type":["object","null"],"description":"Extended data from banks when available. Every field is always present, but which\nof them carry a value depends on the bank that reported this line and on what that\nbank publishes alongside its status. A null field means that bank did not supply\nthat value. It never means the value is zero, or that the underlying event did not\nhappen. Nothing here is gated on the payment being completed.\n","properties":{"value_date":{"type":["string","null"],"description":"Settlement\/value date (YYYY-MM-DD)."},"last_update":{"type":["string","null"],"description":"Timestamp of last status update from the bank."},"amount":{"type":["string","null"],"description":"Confirmed transaction amount in sent currency."},"currency":{"type":["string","null"],"description":"Confirmed currency (ISO 4217 code, e.g. \"USD\", \"EUR\")."},"status_code":{"type":["string","null"],"description":"Raw GPI\/bank status code (e.g. ACCC, ACSP, RJCT, PDNG)."},"status_description":{"type":["string","null"],"description":"Human-readable status description from the bank."},"reference":{"type":["string","null"],"description":"Bank's internal reference or transaction number."},"payment_method":{"type":["string","null"],"description":"Clearing channel (e.g. CHIPS, FED, CHAPS, BOOK, SWIFT, SEPA, ACH)."},"clearing_ref":{"type":["string","null"],"description":"Clearing system confirmation (Fedwire IMAD, CHIPS SSN, CHAPS ref, etc.)."},"charges":{"type":["object","null"],"description":"Charges deducted from the payment, as reported by this bank. Populated only\nwhen the reporting bank publishes charge data with its status, which not all\nof them do. `null` therefore means \"this bank reported no charge amount\", not\n\"no charge was taken\": a deduction can be applied at a hop whose feed carries\nno charge fields, or at a bank that does not report to us at all. Do not treat\na null as a zero-fee confirmation, reconcile deductions against the amount\nactually credited. Charges are not held back until settlement either, they are\nreturned on in-progress payments as often as on completed ones.\n","properties":{"total":{"type":"string","description":"Total charges amount."},"currency":{"type":"string","description":"Charges currency (ISO 4217)."}}},"fx_rate":{"type":["string","null"],"description":"FX conversion rate (format \"FROM\/TO\/RATE\", e.g. \"EUR\/USD\/1.1575\")."},"duration":{"type":["string","null"],"description":"Total processing time of the payment (e.g. \"3 days 1 hour 7 minutes\")."},"received_amount":{"type":["string","null"],"description":"Amount received after FX conversion and fees."},"received_currency":{"type":["string","null"],"description":"Currency received after conversion (ISO 4217)."},"confidence":{"type":["string","null"],"description":"Match confidence \u2014 \"exact\" or \"partial\"."}}}}},"Correspondent":{"type":"object","properties":{"id":{"type":"integer","description":"Sequential ID within the response."},"bank":{"type":"string","description":"Correspondent bank name."},"swift":{"type":"string","description":"Correspondent SWIFT\/BIC code."},"currency":{"type":"string"},"account":{"type":"string","description":"Nostro\/vostro account number."},"national_id":{"type":"string","description":"National clearing identifier (ABA routing number, Sort Code, BSB). Empty if not applicable."},"asset_category":{"type":"string","enum":["COMMERCIAL","FINANCIAL","FX","ALL",""],"description":"Payment flow classification. Where the same account is published under several\ncategories, this carries the commercial view (COMMERCIAL or ALL) when there is one.\n"},"asset_categories":{"type":"array","description":"Every asset category this account is published under, `asset_category` first. Usually\na single value; an account published for both commercial and interbank use returns\nboth, so a filter on interbank settlement should read this array rather than the\nsingle `asset_category` field. Values are the same classifications as\n`asset_category`, spelled as the institution publishes them.\n","items":{"type":"string"}},"is_preferred":{"type":"boolean","description":"True only where the institution explicitly publishes a preferred correspondent for the\ncurrency. Most published SSI records carry no such designation, so this is false for the\nlarge majority of correspondents \u2014 false is \"not designated\", not \"not suitable\".\n"},"intermediaries":{"type":"array","description":"Intermediary banks in the payment chain (up to 2).","items":{"type":"object","properties":{"swift":{"type":"string"},"account":{"type":"string"}}}}}},"SanctionsMatch":{"type":"object","properties":{"entity_id":{"type":"string","description":"Entity ID for detail lookup via `\/sanctions\/entity\/{entityId}`."},"name":{"type":"string"},"list_source":{"type":"string","description":"Sanctions list identifier."},"list_name":{"type":"string","description":"Full list name."},"severity":{"type":"string","description":"Audit-grade classification of the sanctions designation.","enum":["high","medium","low"]},"action":{"type":"string","description":"Required action for transactions involving this entity.","enum":["BLOCK","REVIEW","MONITOR","INFORM"]},"action_label":{"type":"string","description":"Human-readable description of the required action."},"match_score":{"type":"number","description":"Match confidence (0.0 - 1.0)."},"match_type":{"type":"string","description":"How the match was determined (e.g. `exact_name`, `fuzzy_name`, `alias`)."},"entity_type":{"type":"string","description":"Upstream classification of the entity. Values include `person`,\n`organization`\/`entity`, `vessel`, `aircraft`, `unknown`.\n"},"aliases":{"type":"array","items":{"type":"string"}},"programs":{"type":"array","items":{"type":"string"},"description":"Sanctions programs the entity is designated under."},"addresses":{"type":"array","items":{"type":"object"}},"identifiers":{"type":"array","description":"Passport \/ tax-ID \/ national-ID records.","items":{"type":"object"}},"dates_of_birth":{"type":"array","items":{"type":"string"}},"places_of_birth":{"type":"array","items":{"type":"string"}},"nationalities":{"type":"array","items":{"type":"string"}},"remarks":{"type":["string","null"],"description":"Free-text designation context from the upstream watchlist."},"sanctions_types":{"type":"array","items":{"type":"string"}},"legal_authorities":{"type":"array","items":{"type":"string"}}}},"SanctionsList":{"type":"object","properties":{"list_name":{"type":"string"},"full_name":{"type":"string"},"description":{"type":"string"},"detailed_description_eng":{"type":["string","null"]},"detailed_description_rus":{"type":["string","null"]},"entity_count":{"type":"integer"},"severity":{"type":"string","enum":["high","medium","low"]},"action":{"type":"string","enum":["BLOCK","REVIEW","MONITOR","INFORM"]},"action_label":{"type":"string"},"last_update":{"type":"string","format":"date-time"},"slug":{"type":"string","description":"URL-safe identifier for the list."}}},"SanctionsEntity":{"type":"object","description":"Full entity detail. Real fields (`entity_id`, `name`, \u2026) live at the top\nlevel of this object \u2014 read them as `response.entity.<field>`.\n\nThe nested `entity` property is a DEPRECATED alias retained for\nback-compat with clients wired to the original double-wrapped shape\n(`response.entity.entity.name`). It will be removed in v5. New\nintegrators should ignore it.\n","properties":{"entity_id":{"type":"string"},"name":{"type":"string"},"entity_type":{"type":"string"},"list_source":{"type":"string"},"severity":{"type":"string","enum":["high","medium","low"]},"action":{"type":"string","enum":["BLOCK","REVIEW","MONITOR","INFORM"]},"action_label":{"type":"string"},"aliases":{"type":"array","items":{"type":"string"}},"nationalities":{"type":"array","items":{"type":"string"}},"dates_of_birth":{"type":"array","items":{"type":"string"}},"places_of_birth":{"type":"array","items":{"type":"string"}},"addresses":{"type":"array","items":{"type":"object"}},"identifiers":{"type":"array","description":"Passport \/ tax-ID \/ national-ID records.","items":{"type":"object"}},"programs":{"type":"array","items":{"type":"string"}},"remarks":{"type":["string","null"]},"sanctions_types":{"type":"array","items":{"type":"string"}},"legal_authorities":{"type":"array","items":{"type":"string"}},"timestamp":{"type":"string","format":"date-time","description":"Upstream snapshot timestamp for this entity record."},"entity":{"deprecated":true,"description":"DEPRECATED \u2014 alias for the flat fields above. Retained for clients\nwired to the original `response.entity.entity.*` path. Will be\nremoved in v5.\n","type":"object"}}},"BulkSummary":{"type":"object","properties":{"total_entities_screened":{"type":"integer"},"entities_succeeded":{"type":"integer"},"entities_failed":{"type":"integer"},"entities_with_matches":{"type":"integer"},"entities_without_matches":{"type":"integer"},"total_search_time_ms":{"type":"integer"}}},"ListsSearchedCoverage":{"type":"object","description":"Coverage indicator \u2014 how many watchlists were searched out of the total available at the time of the call.","properties":{"count":{"type":["integer","null"],"description":"Number of watchlists actually searched.","example":303},"total_available":{"type":["integer","null"],"description":"Total number of watchlists available at the time of the call.","example":303},"full_coverage":{"type":"boolean","description":"True if `count == total_available`. False signals partial coverage (e.g. when `include_lists` or `exclude_lists` was used).","example":true}}},"SanctionsReport":{"type":"object","description":"Full compliance certificate payload \u2014 identical content to the rendered PDF certificate, structured for machine consumption.","properties":{"success":{"type":"boolean"},"report_id":{"type":"string","example":"SCR-00012345"},"report_hash":{"type":"string","description":"SHA-256 fingerprint for tamper-evident verification."},"screened_at":{"type":"string","format":"date-time"},"query":{"type":"string"},"transliterated_query":{"type":["string","null"]},"threshold":{"type":"number"},"total_matches":{"type":"integer"},"matches":{"type":"array","items":{"$ref":"#\/components\/schemas\/SanctionsMatch"}},"lists_searched":{"allOf":[{"$ref":"#\/components\/schemas\/ListsSearchedCoverage"},{"type":"object","properties":{"names":{"type":["array","null"],"items":{"type":"string"},"description":"Names of the watchlists searched."}}}]},"include_lists":{"type":["array","null"],"items":{"type":"string"}},"exclude_lists":{"type":["array","null"],"items":{"type":"string"}},"search_time_ms":{"type":["integer","null"]},"screener":{"type":"object","properties":{"access_method":{"type":["string","null"]},"organization_id":{"type":["integer","null"]}}},"verification":{"type":"object","properties":{"verify_url":{"type":"string","description":"Public verification page URL."},"pdf_url":{"type":"string","description":"This same endpoint with `?format=pdf` appended."}}},"limits":{"$ref":"#\/components\/schemas\/Limits"}}},"ValidationResult":{"type":"object","properties":{"beneficiary_bic":{"$ref":"#\/components\/schemas\/FieldValidation"},"correspondent_bic":{"$ref":"#\/components\/schemas\/FieldValidation"},"sender_bic":{"$ref":"#\/components\/schemas\/FieldValidation"},"sender_correspondent_bic":{"$ref":"#\/components\/schemas\/FieldValidation"},"beneficiary_iban":{"type":"object","properties":{"status":{"type":"string","enum":["ok","warning","invalid"]},"recommendation":{"type":"string"},"details":{"type":"string","description":"Validation details (e.g. IBAN checksum error, IBAN\/BIC country mismatch)."}}},"beneficiary_address":{"type":"object","properties":{"status":{"type":"string","enum":["ok","invalid"]},"details":{"type":"string"}}},"available_correspondents":{"type":"array","items":{"type":"object","properties":{"corresBIC":{"type":"string"},"currency":{"type":"string"},"is_preferred":{"type":"boolean"}}}},"avg_business_days":{"type":"integer","description":"Estimated business days for delivery (-1 if warnings found)."},"sanctions_screening":{"type":"object","description":"Sanctions screening results for submitted BICs and beneficiary owner.","additionalProperties":{"type":"object","properties":{"screened_name":{"type":"string"},"status":{"type":"string","enum":["clear","match"]},"matches":{"type":"array","items":{"$ref":"#\/components\/schemas\/SanctionsMatch"}}}}},"limits":{"$ref":"#\/components\/schemas\/Limits"}}},"ValidationResultV5":{"description":"v5 validate response. Identical to `ValidationResult`, except `avg_business_days`\nis settlement-ETA-derived and an optional `settlement_eta` block is added (see the\n`\/api\/v5\/validate` description).\n","allOf":[{"$ref":"#\/components\/schemas\/ValidationResult"},{"type":"object","properties":{"avg_business_days":{"type":"integer","description":"v5: the settlement-ETA median (business_days_p50), rounded and floored at 1\n(never 0). `-1` when any field has a warning\/invalid\/sanctions issue (the ETA\nis skipped). Falls back to v4's static per-currency estimate when the ETA is\ndisabled or cannot produce an answer. Full precision and the wider window live\nin `settlement_eta`.\n"},"settlement_eta":{"type":"object","description":"Real settlement-ETA estimate (BETA) for a clean payment, from actually-tracked\ncompleted payments. Present only when a data-backed answer is available; omitted\notherwise (and on flagged payments \/ when disabled). Credit-free; no tracking\nrecord is touched.\n","properties":{"business_days_p50":{"type":["number","null"],"description":"Typical (median) business days from the value date to credit."},"business_days_p90":{"type":["number","null"],"description":"Slow end \u2014 roughly 1 in 10 take longer than this."},"business_days_p95":{"type":["number","null"]},"confidence":{"type":"string","enum":["low","medium","high"]},"basis":{"type":"object","properties":{"level":{"type":"string","description":"Cohort that answered: corridor > sender_ccy \/ receiver_ccy > currency > global."},"source":{"type":"string","description":"What set the number (corridor, endpoint, currency_class, global, route_composed, no_route_floor, settlement_class)."},"covers_named_banks":{"type":["boolean","null"],"description":"null = no banks named; false = pool-level answer; true = a named bank contributed completions."},"route_adjusted":{"type":"boolean"},"settlement_class":{"type":["string","null"],"description":"sepa | same_group | domestic when a local-rail ceiling capped the window; null otherwise."}}},"non_arrival":{"type":["object","null"],"properties":{"p_reject":{"type":"number"},"note":{"type":"string"}}},"delay_risk":{"type":"object","properties":{"flagged":{"type":"boolean"},"reasons":{"type":"array","items":{"type":"string"}}}},"beta":{"type":"boolean","description":"The settlement-ETA feature is currently BETA."}}}}}]},"FieldValidation":{"type":"object","properties":{"status":{"type":"string","enum":["ok","invalid","warning"]},"details":{"type":"string"},"recommendation":{"type":"string"},"options":{"type":"array","items":{"type":"string"},"description":"Alternative SWIFT\/BIC codes (e.g. available correspondent banks). Only present for `correspondent_bic` when alternatives exist."}}},"ErrorResponse":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}}},"Monitor":{"type":"object","properties":{"monitor_id":{"type":"integer","example":1287},"entity_name":{"type":"string"},"entity_type":{"type":"string","enum":["person","organization","vessel","aircraft","unknown"]},"threshold":{"type":"number"},"external_ref":{"type":["string","null"]},"metadata":{"type":["object","null"]},"status":{"type":"string","enum":["active","paused","expired","deleted"]},"source":{"type":"string","enum":["web","api"]},"matches_count":{"type":"integer"},"lists_matched":{"type":"array","items":{"type":"string"}},"last_checked_at":{"type":["string","null"],"format":"date-time"},"next_check_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"MonitorResponse":{"type":"object","properties":{"success":{"type":"boolean"},"monitor":{"$ref":"#\/components\/schemas\/Monitor"},"limits":{"$ref":"#\/components\/schemas\/Limits"}}},"MonitorChange":{"type":"object","properties":{"change_id":{"type":"integer"},"change_type":{"type":"string","enum":["new_match","removed_match","new_list","removed_list","score_change"]},"summary":{"type":"string"},"disputed_entity_id":{"type":["string","null"]},"list_source":{"type":["string","null"]},"previous_data":{"type":["object","null"]},"new_data":{"type":["object","null"]},"detected_at":{"type":"string","format":"date-time"},"delivered_via":{"type":"array","items":{"type":"string","enum":["email","webhook"]}},"case_id":{"type":["string","null"]}}},"Webhook":{"type":"object","properties":{"id":{"type":"integer"},"url":{"type":"string","format":"uri"},"event_types":{"type":"array","items":{"type":"string"}},"status":{"type":"string","enum":["active","paused","failed"]},"description":{"type":["string","null"]},"secret_last4":{"type":"string","description":"Last 4 chars of secret; full secret never re-exposed."},"consecutive_failures":{"type":"integer"},"last_delivery_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"WebhookDelivery":{"type":"object","properties":{"event_id":{"type":"string","format":"uuid"},"event_type":{"type":"string"},"attempt_number":{"type":"integer"},"response_code":{"type":["integer","null"]},"response_body_excerpt":{"type":["string","null"],"description":"First 4KB of response body."},"failure_reason":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"delivered_at":{"type":["string","null"],"format":"date-time"}}},"SanctionsCase":{"type":"object","properties":{"case_id":{"type":"string","example":"case-1287-9912"},"monitor_id":{"type":"integer"},"disputed_entity_id":{"type":["string","null"]},"list_source":{"type":["string","null"]},"status":{"type":"string","enum":["open","investigating","confirmed","cleared","wont_action"]},"disposition":{"type":["string","null"],"enum":["true_positive","false_positive","inconclusive",null]},"notes":{"type":["string","null"]},"assignee":{"type":["string","null"]},"reopen_after":{"type":["string","null"],"format":"date"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"closed_at":{"type":["string","null"],"format":"date-time"}}}},"responses":{"ValidationError":{"description":"Validation error","content":{"application\/json":{"schema":{"type":"object","properties":{"errors":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}}},"example":{"errors":{"field_name":["The field_name field is required."]}}}}},"Unauthorized":{"description":"Missing, invalid, or expired API key","content":{"application\/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"examples":{"missing":{"summary":"Missing or invalid key","value":{"error":"Unauthorized"}},"expired":{"summary":"Expired key","value":{"error":"API Key expired"}}}}}},"Forbidden":{"description":"Method not allowed for your subscription","content":{"application\/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Access denied: Method not allowed"}}}},"RateLimitExceeded":{"description":"Rate limit exceeded","content":{"application\/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"limit_name":{"type":"string"},"reset_at":{"type":"string","format":"date-time"}}},"example":{"error":"Rate limit exceeded","limit_name":"Daily API Limit","reset_at":"2026-03-07T23:59:59Z"}}}}}}}