From a6d74ef4d530986d3b823513d884f52cfd670685 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Fri, 23 Oct 2026 22:29:34 +0000
Subject: [PATCH 1/2] chore(spec): sync API spec 2026-10-23
---
openapi/SOURCE.json | 4 +-
openapi/verification.json | 973 +++++++
.../java/me/didit/resources/BankResource.java | 151 +
.../me/didit/resources/DiditResources.java | 11 +
.../types/BankAccountCheckBusinessHolder.java | 100 +
.../me/didit/types/BankAccountCheckError.java | 216 ++
.../didit/types/BankAccountCheckHolder.java | 90 +
.../types/BankAccountCheckPersonHolder.java | 100 +
.../didit/types/BankAccountCheckRequest.java | 471 +++
.../didit/types/BankAccountCheckResponse.java | 257 ++
.../didit/types/BankVerificationResult.java | 2591 +++++++++++++++++
.../java/me/didit/types/SessionDecision.java | 22 +-
.../me/didit/resources/BankResourceTest.java | 44 +
13 files changed, 5027 insertions(+), 3 deletions(-)
create mode 100644 src/main/java/me/didit/resources/BankResource.java
create mode 100644 src/main/java/me/didit/types/BankAccountCheckBusinessHolder.java
create mode 100644 src/main/java/me/didit/types/BankAccountCheckError.java
create mode 100644 src/main/java/me/didit/types/BankAccountCheckHolder.java
create mode 100644 src/main/java/me/didit/types/BankAccountCheckPersonHolder.java
create mode 100644 src/main/java/me/didit/types/BankAccountCheckRequest.java
create mode 100644 src/main/java/me/didit/types/BankAccountCheckResponse.java
create mode 100644 src/main/java/me/didit/types/BankVerificationResult.java
create mode 100644 src/test/java/me/didit/resources/BankResourceTest.java
diff --git a/openapi/SOURCE.json b/openapi/SOURCE.json
index 47946a1..689d545 100644
--- a/openapi/SOURCE.json
+++ b/openapi/SOURCE.json
@@ -1,8 +1,8 @@
{
"verification.json": {
"url": "https://docs.didit.me/openapi-25.json",
- "sha256": "9ada6192b24a5d85e983e57e87fccb6e762d74060b6f0b892928356dd432137c",
- "fetched_at": "2026-10-23T06:48:14Z"
+ "sha256": "da776b2226bd264797268988b179f37b906c0b2e4953a16111c0d4296c89fcd4",
+ "fetched_at": "2026-10-23T22:27:22Z"
},
"account.json": {
"url": "https://docs.didit.me/openapi-auth.json",
diff --git a/openapi/verification.json b/openapi/verification.json
index 73528cc..a3d5eea 100644
--- a/openapi/verification.json
+++ b/openapi/verification.json
@@ -15542,6 +15542,285 @@
]
}
},
+ "/v3/bank/account-check/": {
+ "post": {
+ "summary": "Check a bank account",
+ "description": "Check that a bank account belongs to the person or company you name, before you send money to it. No session and no sign-in: send the name and the account, read the result. It is the [account check](/core-technology/bank-verification/account-check) of the Bank Verification step, run from your backend.\n\n**What you send.** The account's `country` (ISO 3166-1 alpha-3), the `account` the way that country writes it, and the `holder` name: `full_name` for a person or `business_name` for a company. A business name checks a business account.\n\n**What you get back.** `result` is `match`, `close_match`, `no_match` or `cannot_verify`. On a `close_match`, `holder_name` is the name the bank holds the account under, when the bank returned it. `account` comes back masked to its last 4 characters.\n\n**Billing.** Each check the bank answers is billed once at the Account check price of the account's country, whatever the result: a `no_match`, an account that does not exist and a `cannot_verify` are billed too. A request answered with an error is never billed.\n\n**Every request is a new check.** There is no idempotency key and no endpoint to read a check back, so a retried request runs, and is billed, again. Store the response.\n\n**Sandbox.** A sandbox key calls no bank and is charged nothing. The last 4 characters of the IBAN, else of the account number, choose the answer: `0001` a `close_match` with a `holder_name`, `0002` a `close_match` without one, `0003` and `0006` a `no_match`, `0004` `cannot_verify`, `0005` a `503` and `0009` a `400`. Any other ending is a `match`.\n\n**API keys.** A scoped API key needs write access to sessions.",
+ "operationId": "post_v3_bank_account_check",
+ "tags": [
+ "Standalone APIs"
+ ],
+ "x-didit-sdk": {
+ "resource": "bank",
+ "method": "account_check",
+ "auth": "api_key",
+ "server": true
+ },
+ "security": [
+ {
+ "ApiKeyAuth": []
+ },
+ {
+ "BearerAuth": []
+ }
+ ],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/BankAccountCheckRequest"
+ },
+ "examples": {
+ "Person, United Kingdom": {
+ "summary": "A sort code and account number, checked against a person's name",
+ "value": {
+ "country": "GBR",
+ "account": {
+ "sort_code": "20-45-67",
+ "account_number": "31926819"
+ },
+ "holder": {
+ "full_name": "Maria Oliveira"
+ },
+ "vendor_data": "payout_20481"
+ }
+ },
+ "Company, IBAN": {
+ "summary": "An IBAN, checked against a company's name",
+ "value": {
+ "country": "DEU",
+ "account": {
+ "iban": "DE89 3704 0044 0532 0130 00"
+ },
+ "holder": {
+ "business_name": "Northwind Trading GmbH"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "The bank answered. The check is billed, whatever the result.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/BankAccountCheckResponse"
+ },
+ "examples": {
+ "Close match": {
+ "summary": "The bank holds the account under a close name",
+ "value": {
+ "request_id": "c2f4a9e0-7b1d-4c3a-9e55-1d0a6b8f2a47",
+ "result": "close_match",
+ "holder_name": "MARIA R OLIVEIRA",
+ "account": "****6819",
+ "vendor_data": "payout_20481",
+ "created_at": "2026-10-21T14:32:08Z"
+ }
+ },
+ "Match": {
+ "summary": "The bank holds the account under the name sent",
+ "value": {
+ "request_id": "5b0e2d7c-41a8-4f6e-9c3b-8e7d1a2f6c90",
+ "result": "match",
+ "holder_name": null,
+ "account": "****3000",
+ "vendor_data": null,
+ "created_at": "2026-10-21T14:35:41Z"
+ }
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Refused as sent, and not billed. `field` names the body field to correct and `reason` says why, with the same reasons the hosted account form shows. Only the first refused field is reported.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/BankAccountCheckError"
+ },
+ "examples": {
+ "Missing field": {
+ "summary": "The country's check needs a sort code",
+ "value": {
+ "detail": "The sort code is not valid (required).",
+ "code": "invalid_account_input",
+ "field": "account.sort_code",
+ "reason": "required"
+ }
+ },
+ "Invalid IBAN": {
+ "summary": "The IBAN has the wrong length for its country",
+ "value": {
+ "detail": "The iban is not valid (length).",
+ "code": "invalid_account_input",
+ "field": "account.iban",
+ "reason": "length"
+ }
+ },
+ "Refused by the bank": {
+ "summary": "The bank refused the account as sent",
+ "value": {
+ "detail": "The account was refused as typed (rejected).",
+ "code": "invalid_account_input",
+ "field": "account.account_number",
+ "reason": "rejected"
+ }
+ },
+ "No name": {
+ "summary": "`holder` has neither `full_name` nor `business_name`",
+ "value": {
+ "detail": "Send full_name for a person or business_name for a company.",
+ "code": "invalid_account_input",
+ "field": "holder",
+ "reason": "required"
+ }
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "The scoped API key has expired.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/BankAccountCheckError"
+ },
+ "examples": {
+ "Expired key": {
+ "summary": "The key's expiry date has passed",
+ "value": {
+ "detail": "This API key has expired."
+ }
+ }
+ }
+ }
+ }
+ },
+ "402": {
+ "description": "The check cannot be paid for, so it did not run. Top up your balance, then send it again.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/BankAccountCheckError"
+ },
+ "examples": {
+ "Out of credit": {
+ "summary": "Your balance cannot cover one check",
+ "value": {
+ "detail": "You don't have enough credits to perform this request. Please top up at https://business.didit.me",
+ "code": "insufficient_credits"
+ }
+ },
+ "Not in your contract": {
+ "summary": "Your contract has no price for the Account check API",
+ "value": {
+ "detail": "Your contract does not price the Account check API. Contact your account manager.",
+ "code": "contract_rate_missing"
+ }
+ }
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "The `x-api-key` header or the bearer token is missing or invalid, the request came from an address outside the key's IP list, or a scoped key has no write access to sessions.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/BankAccountCheckError"
+ },
+ "examples": {
+ "Missing or invalid credentials": {
+ "summary": "No valid API key or token",
+ "value": {
+ "detail": "You do not have permission to perform this action."
+ }
+ },
+ "No sessions write": {
+ "summary": "A scoped key without write access to sessions",
+ "value": {
+ "detail": "This API key has no write access to sessions."
+ }
+ }
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "No account check serves this account yet, so nothing was checked or billed. `country_not_covered`: none serves its country, or its kind of account (person or business) there. `bank_not_covered`: none serves its bank. `bank_verification_not_available`: Bank Verification is not available yet.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/BankAccountCheckError"
+ },
+ "examples": {
+ "Country not covered": {
+ "summary": "No account check serves the country",
+ "value": {
+ "detail": "No account check serves this country yet.",
+ "code": "country_not_covered"
+ }
+ },
+ "Bank not covered": {
+ "summary": "No account check serves the account's bank",
+ "value": {
+ "detail": "No account check serves this account's bank yet.",
+ "code": "bank_not_covered"
+ }
+ }
+ }
+ }
+ }
+ },
+ "429": {
+ "$ref": "#/components/responses/RateLimitedWrite"
+ },
+ "503": {
+ "description": "The bank could not answer. Nothing was checked or billed; send the check again later.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/BankAccountCheckError"
+ },
+ "examples": {
+ "Unavailable": {
+ "summary": "The bank did not answer",
+ "value": {
+ "detail": "The account check is temporarily unavailable and this request was not charged. Please try again.",
+ "code": "account_check_unavailable"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "curl",
+ "label": "curl",
+ "source": "curl -X POST https://verification.didit.me/v3/bank/account-check/ \\\n -H 'x-api-key: YOUR_API_KEY' \\\n -H 'Content-Type: application/json' \\\n -d '{\n \"country\": \"GBR\",\n \"account\": {\"sort_code\": \"20-45-67\", \"account_number\": \"31926819\"},\n \"holder\": {\"full_name\": \"Maria Oliveira\"},\n \"vendor_data\": \"payout_20481\"\n }'"
+ },
+ {
+ "lang": "python",
+ "label": "Python",
+ "source": "import os, requests\n\nresp = requests.post(\n \"https://verification.didit.me/v3/bank/account-check/\",\n headers={\"x-api-key\": os.environ[\"DIDIT_API_KEY\"]},\n json={\n \"country\": \"GBR\",\n \"account\": {\"sort_code\": \"20-45-67\", \"account_number\": \"31926819\"},\n \"holder\": {\"full_name\": \"Maria Oliveira\"},\n \"vendor_data\": \"payout_20481\",\n },\n timeout=30,\n)\nresp.raise_for_status()\ncheck = resp.json()\nif check[\"result\"] == \"match\":\n pass # send the payout\nelif check[\"result\"] == \"close_match\":\n print(check[\"holder_name\"]) # the name the bank holds, when it returned one"
+ },
+ {
+ "lang": "javascript",
+ "label": "JavaScript",
+ "source": "const res = await fetch('https://verification.didit.me/v3/bank/account-check/', {\n method: 'POST',\n headers: {\n 'x-api-key': process.env.DIDIT_API_KEY,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n country: 'GBR',\n account: { sort_code: '20-45-67', account_number: '31926819' },\n holder: { full_name: 'Maria Oliveira' },\n vendor_data: 'payout_20481',\n }),\n});\nconst check = await res.json();\n// check.result: match, close_match, no_match or cannot_verify"
+ }
+ ]
+ }
+ },
"/v3/email/send/": {
"post": {
"summary": "Send Email Code",
@@ -92013,6 +92292,14 @@
}
}
},
+ "bank_verifications": {
+ "type": "array",
+ "nullable": true,
+ "description": "Bank Verification results, one item per Bank Verification step, for User and Business Verification. `null` until a step produces one. Each item's `method` says how the account was verified: `open_banking` (bank sign-in) or `account_lookup` (account check), or a `microdeposits` or `statement` fallback. See [Bank verification methods](/core-technology/bank-verification/verification-methods).",
+ "items": {
+ "$ref": "#/components/schemas/BankVerificationResult"
+ }
+ },
"signatures": {
"type": "array",
"description": "Electronic Signature results, one item per signer and signature step, for User and Business Verification. Present only when the workflow has an Electronic Signature step; an empty array until a signer reaches it. See the [Electronic Signature report](/core-technology/electronic-signature/report-electronic-signature).",
@@ -103652,6 +103939,692 @@
"format": "date-time"
}
}
+ },
+ "BankAccountCheckHolder": {
+ "description": "The name the account is checked against. Send exactly one of `full_name` and `business_name`.",
+ "oneOf": [
+ {
+ "$ref": "#/components/schemas/BankAccountCheckPersonHolder"
+ },
+ {
+ "$ref": "#/components/schemas/BankAccountCheckBusinessHolder"
+ }
+ ]
+ },
+ "BankAccountCheckRequest": {
+ "type": "object",
+ "required": [
+ "country",
+ "account",
+ "holder"
+ ],
+ "properties": {
+ "country": {
+ "type": "string",
+ "minLength": 3,
+ "maxLength": 3,
+ "description": "The account's country, as an ISO 3166-1 alpha-3 code, for example `GBR`. Lowercase is accepted.",
+ "example": "GBR"
+ },
+ "account": {
+ "type": "object",
+ "description": "The account the way its country writes it: an `iban`, or an `account_number` with the bank or branch code the country needs (`sort_code`, `routing_number`, `transit_institution`, `bsb`, `ifsc`, `bank_code` or `bic`). Mexico takes a `clabe` and Argentina a `cbu_cvu`, which already name the bank. A business account adds a `registration_id` where the country asks for one. Spaces, dashes and dots are ignored. Keys the country's check does not use are ignored; a key it needs and does not get is a `400` that names it.",
+ "properties": {
+ "iban": {
+ "type": "string",
+ "maxLength": 64,
+ "description": "The IBAN, in a country that uses IBANs. It must belong to `country`."
+ },
+ "account_number": {
+ "type": "string",
+ "maxLength": 64,
+ "description": "The account number, in a country that writes the account with a separate bank or branch code."
+ },
+ "sort_code": {
+ "type": "string",
+ "maxLength": 64,
+ "description": "United Kingdom: the 6-digit sort code."
+ },
+ "routing_number": {
+ "type": "string",
+ "maxLength": 64,
+ "description": "United States: the 9-digit ABA routing number."
+ },
+ "transit_institution": {
+ "type": "string",
+ "maxLength": 64,
+ "description": "Canada: the 8-digit transit and institution number."
+ },
+ "bsb": {
+ "type": "string",
+ "maxLength": 64,
+ "description": "Australia: the 6-digit BSB."
+ },
+ "ifsc": {
+ "type": "string",
+ "maxLength": 64,
+ "description": "India: the 11-character IFSC."
+ },
+ "bank_code": {
+ "type": "string",
+ "maxLength": 64,
+ "description": "The bank's code, where the country needs one, for example in Nigeria."
+ },
+ "bic": {
+ "type": "string",
+ "maxLength": 64,
+ "description": "The bank's BIC, where the country's check asks for one."
+ },
+ "clabe": {
+ "type": "string",
+ "maxLength": 64,
+ "description": "Mexico: the 18-digit CLABE. It already names the bank."
+ },
+ "cbu_cvu": {
+ "type": "string",
+ "maxLength": 64,
+ "description": "Argentina: the 22-digit CBU or CVU. It already names the bank."
+ },
+ "registration_id": {
+ "type": "string",
+ "maxLength": 64,
+ "description": "A business account's registration number, where the country asks for one."
+ }
+ },
+ "additionalProperties": {
+ "type": "string",
+ "maxLength": 64
+ },
+ "example": {
+ "sort_code": "20-45-67",
+ "account_number": "31926819"
+ }
+ },
+ "holder": {
+ "$ref": "#/components/schemas/BankAccountCheckHolder"
+ },
+ "vendor_data": {
+ "type": "string",
+ "nullable": true,
+ "description": "Your own reference for this check, returned unchanged.",
+ "example": "payout_20481"
+ }
+ }
+ },
+ "BankAccountCheckResponse": {
+ "type": "object",
+ "required": [
+ "request_id",
+ "result",
+ "holder_name",
+ "account",
+ "vendor_data",
+ "created_at"
+ ],
+ "properties": {
+ "request_id": {
+ "type": "string",
+ "format": "uuid",
+ "description": "The ID of this check."
+ },
+ "result": {
+ "type": "string",
+ "enum": [
+ "match",
+ "close_match",
+ "no_match",
+ "cannot_verify"
+ ],
+ "description": "`match`: the bank holds the account under the name you sent. `close_match`: under a close name, for example a missing middle name or a typo. `no_match`: under another name, or there is no such account. `cannot_verify`: the bank answered without comparing the name, for example for a blocked or closed account."
+ },
+ "holder_name": {
+ "type": "string",
+ "nullable": true,
+ "description": "Only on a `close_match`, and only when the bank returned it: the name on the account, as the bank holds it. `null` otherwise."
+ },
+ "account": {
+ "type": "string",
+ "description": "The account, masked to its last 4 characters."
+ },
+ "vendor_data": {
+ "type": "string",
+ "nullable": true,
+ "description": "Your own reference, as you sent it."
+ },
+ "created_at": {
+ "type": "string",
+ "format": "date-time",
+ "description": "When the check ran, in UTC."
+ }
+ }
+ },
+ "BankAccountCheckError": {
+ "type": "object",
+ "required": [
+ "detail"
+ ],
+ "properties": {
+ "detail": {
+ "type": "string",
+ "description": "What went wrong, in English."
+ },
+ "code": {
+ "type": "string",
+ "description": "A stable code to branch on. Absent on `401` and `403`."
+ },
+ "field": {
+ "type": "string",
+ "description": "`400` only: the body field to correct, as a dotted path, for example `account.sort_code`."
+ },
+ "reason": {
+ "type": "string",
+ "enum": [
+ "required",
+ "length",
+ "format",
+ "checksum",
+ "country_mismatch",
+ "rejected"
+ ],
+ "description": "`400` only: why the field was refused. `required`, `length`, `format`, `checksum` and `country_mismatch` (an IBAN of another country) are Didit's own checks; `rejected` means the bank refused the account as sent."
+ }
+ }
+ },
+ "BankVerificationResult": {
+ "type": "object",
+ "description": "One Bank Verification step's result, for User and Business Verification. `method` says how the account was verified. See [Bank verification methods](/core-technology/bank-verification/verification-methods).",
+ "properties": {
+ "schema_version": {
+ "type": "integer",
+ "description": "Version of this result shape. `1` today."
+ },
+ "bank_verification_id": {
+ "type": "string",
+ "format": "uuid",
+ "description": "The ID of this result."
+ },
+ "node_id": {
+ "type": "string",
+ "description": "The workflow node this result belongs to."
+ },
+ "status": {
+ "type": "string",
+ "enum": [
+ "Not Finished",
+ "Approved",
+ "Declined",
+ "In Review",
+ "Expired"
+ ],
+ "description": "The step's verdict, after its actions and status rules."
+ },
+ "original_status": {
+ "type": "string",
+ "nullable": true,
+ "description": "The first verdict the step reached, before any later change such as a manual review."
+ },
+ "method": {
+ "type": "string",
+ "nullable": true,
+ "enum": [
+ "open_banking",
+ "account_lookup",
+ "microdeposits",
+ "statement"
+ ],
+ "description": "How the account was verified: `open_banking` (bank sign-in: the person signed in at their bank), `account_lookup` (account check: the person typed the account details and the bank confirmed the name), `microdeposits` or `statement` (a statement upload). `null` until an account is evaluated. Workflow rules read the same value as `bank.method`."
+ },
+ "provider": {
+ "type": "string",
+ "nullable": true,
+ "description": "The key of the route that ran the connection. Read `method`, not this key, to tell how the account was verified."
+ },
+ "credential_source": {
+ "type": "string",
+ "nullable": true,
+ "enum": [
+ "native",
+ "byok"
+ ],
+ "description": "`native`: Didit's own route, billed to your Didit balance. `byok`: a marketplace provider you connected with your own credentials."
+ },
+ "route": {
+ "type": "object",
+ "nullable": true,
+ "description": "The route chosen before consent. It never changes afterwards.",
+ "properties": {
+ "provider_key": {
+ "type": "string",
+ "nullable": true,
+ "description": "The route's key."
+ },
+ "credential_source": {
+ "type": "string",
+ "enum": [
+ "native",
+ "byok"
+ ]
+ },
+ "is_fallback": {
+ "type": "boolean",
+ "description": "Whether Didit's own route stood in for a marketplace provider that could not connect."
+ },
+ "provider_connection_id": {
+ "type": "string",
+ "nullable": true,
+ "description": "The marketplace connection used, for `byok`."
+ },
+ "requested_scopes": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "The data the connection asked for, for example `ownership` or `balances`."
+ }
+ }
+ },
+ "connection": {
+ "type": "object",
+ "nullable": true,
+ "description": "The latest attempt's connection. `null` before the first attempt.",
+ "properties": {
+ "status": {
+ "type": "string",
+ "enum": [
+ "pending",
+ "connected",
+ "cancelled",
+ "timeout",
+ "failed",
+ "unsupported",
+ "revoked",
+ "expired"
+ ]
+ },
+ "institution_id": {
+ "type": "string",
+ "nullable": true,
+ "description": "The bank's ID. `null` for an account check, where no bank is picked."
+ },
+ "institution_name": {
+ "type": "string",
+ "nullable": true,
+ "description": "The bank's name. `null` for an account check."
+ },
+ "institution_country": {
+ "type": "string",
+ "nullable": true,
+ "description": "The account's country, ISO 3166-1 alpha-3."
+ },
+ "oauth": {
+ "type": "boolean",
+ "nullable": true,
+ "description": "Whether the bank sign-in ran over OAuth or app-to-app. `null` for an account check."
+ },
+ "connected_at": {
+ "type": "string",
+ "format": "date-time",
+ "nullable": true,
+ "description": "When the connection succeeded."
+ },
+ "consent_expires_at": {
+ "type": "string",
+ "format": "date-time",
+ "nullable": true,
+ "description": "When the bank consent ends, for bank sign-in."
+ },
+ "last_refreshed_at": {
+ "type": "string",
+ "format": "date-time",
+ "nullable": true,
+ "description": "When the financial data was last read again."
+ },
+ "attempts": {
+ "type": "integer",
+ "description": "The attempts the person spent on this step, every method together."
+ },
+ "reason_code": {
+ "type": "string",
+ "nullable": true,
+ "description": "Why the connection is not simply `connected`, for example `USER_CANCELLED`, `INSTITUTION_DOWN`, `ACCOUNT_NOT_FOUND`, `REFERENCE_IDENTITY_MISSING` or `VERIFICATION_COMPLETED`."
+ }
+ }
+ },
+ "account": {
+ "type": "object",
+ "nullable": true,
+ "description": "The evaluated account. `null` until an account is evaluated.",
+ "properties": {
+ "account_id_masked": {
+ "type": "string",
+ "nullable": true,
+ "description": "The account number, masked."
+ },
+ "iban_masked": {
+ "type": "string",
+ "nullable": true,
+ "description": "The IBAN, masked."
+ },
+ "sort_code": {
+ "type": "string",
+ "nullable": true,
+ "description": "The sort code, in the United Kingdom."
+ },
+ "routing_number_masked": {
+ "type": "string",
+ "nullable": true,
+ "description": "The routing number, masked."
+ },
+ "type": {
+ "type": "string",
+ "nullable": true,
+ "enum": [
+ "checking",
+ "current",
+ "savings",
+ "business",
+ "other"
+ ]
+ },
+ "subtype": {
+ "type": "string",
+ "nullable": true,
+ "description": "The bank's own account subtype."
+ },
+ "currency": {
+ "type": "string",
+ "nullable": true,
+ "description": "ISO 4217 currency of the account."
+ },
+ "holder_type": {
+ "type": "string",
+ "nullable": true,
+ "enum": [
+ "person",
+ "business",
+ "unknown"
+ ]
+ },
+ "holders_count": {
+ "type": "integer",
+ "nullable": true
+ },
+ "is_joint": {
+ "type": "boolean",
+ "nullable": true
+ },
+ "is_business": {
+ "type": "boolean",
+ "nullable": true
+ }
+ }
+ },
+ "ownership": {
+ "type": "object",
+ "nullable": true,
+ "description": "How the account holder compared with the verified identity. `null` until an account is evaluated.",
+ "properties": {
+ "result": {
+ "type": "string",
+ "enum": [
+ "match",
+ "partial_match",
+ "no_match",
+ "unknown",
+ "not_verifiable"
+ ],
+ "description": "`partial_match` is a close match. `not_verifiable`: the bank answered with no holder to compare. `unknown`: the evidence could not be read, or there was no identity to compare."
+ },
+ "reference_identity_source": {
+ "type": "string",
+ "nullable": true,
+ "description": "The step whose identity the holder was compared against: `kyc`, `database_validation`, `expected_details`, `questionnaire`, `document_ai` or `kyb`."
+ },
+ "name_score": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 100,
+ "nullable": true,
+ "description": "Didit's holder name score."
+ },
+ "provider_name_score": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 100,
+ "nullable": true,
+ "description": "The bank's own holder name score, when it returned one."
+ },
+ "address_score": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 100,
+ "nullable": true,
+ "description": "The holder address score, when address matching ran."
+ },
+ "email_score": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 100,
+ "nullable": true,
+ "description": "The holder email score, when email matching ran."
+ },
+ "phone_score": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 100,
+ "nullable": true,
+ "description": "The holder phone score, when phone matching ran."
+ },
+ "dob_score": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 100,
+ "nullable": true,
+ "description": "The holder date of birth score, when the bank shared one."
+ },
+ "close_match": {
+ "type": "boolean",
+ "nullable": true,
+ "description": "Whether the name landed in the close-match band."
+ },
+ "holder_confirmation": {
+ "type": "string",
+ "nullable": true,
+ "enum": [
+ "pending",
+ "confirmed",
+ "rejected"
+ ],
+ "description": "The person's answer when asked to confirm a close-match name. `null` when never asked."
+ },
+ "method": {
+ "type": "string",
+ "nullable": true,
+ "enum": [
+ "exact",
+ "token_set",
+ "nickname",
+ "transliteration",
+ "fuzzy",
+ "provider_only",
+ "microdeposits"
+ ],
+ "description": "Which name comparison produced the score. This is not the verification method: read the top-level `method` for that."
+ },
+ "matched_holder_index": {
+ "type": "integer",
+ "nullable": true
+ },
+ "holders": {
+ "type": "array",
+ "items": {
+ "type": "object"
+ },
+ "description": "Each holder the bank listed, with its scores."
+ },
+ "owner_identity_available": {
+ "type": "boolean",
+ "nullable": true
+ },
+ "evidence_freshness": {
+ "type": "string",
+ "nullable": true,
+ "enum": [
+ "live",
+ "cached",
+ "refreshed"
+ ]
+ },
+ "evaluated_at": {
+ "type": "string",
+ "format": "date-time",
+ "nullable": true,
+ "description": "When the verdict was computed."
+ }
+ }
+ },
+ "financial_data": {
+ "type": "object",
+ "description": "The financial data the step read. Only bank sign-in reads it.",
+ "properties": {
+ "balances": {
+ "type": "object",
+ "nullable": true,
+ "description": "With the `balances` scope."
+ },
+ "transactions": {
+ "type": "object",
+ "nullable": true,
+ "description": "With the `transactions` scope."
+ },
+ "income": {
+ "type": "object",
+ "nullable": true,
+ "description": "With the `income` scope."
+ },
+ "categorization": {
+ "type": "object",
+ "nullable": true,
+ "description": "Didit's categorization of the transactions read. `null` without them."
+ },
+ "not_collected": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "balances",
+ "income",
+ "transactions"
+ ]
+ },
+ "description": "The data the step asked for that the method which verified the account does not collect. Balances, transactions and income come from bank sign-in only, so an account verified by account check lists them here. Never a failure. Empty otherwise."
+ }
+ }
+ },
+ "billing": {
+ "type": "object",
+ "nullable": true,
+ "properties": {
+ "route": {
+ "type": "string",
+ "enum": [
+ "native",
+ "byok"
+ ]
+ },
+ "billed": {
+ "type": "boolean"
+ },
+ "marketplace_fee": {
+ "type": "string",
+ "nullable": true,
+ "description": "The marketplace platform fee charged, for `byok`."
+ },
+ "usage_type": {
+ "type": "string",
+ "nullable": true,
+ "description": "The usage line the charge was booked on."
+ }
+ }
+ },
+ "reference_identity": {
+ "type": "object",
+ "nullable": true,
+ "description": "The identity the holder was compared against, with its source."
+ },
+ "signals": {
+ "type": "object",
+ "nullable": true,
+ "description": "Account signals read from the transaction history, when the step read one."
+ },
+ "connection_abandoned": {
+ "type": "boolean",
+ "nullable": true,
+ "description": "Whether the step ended without a match after the person left at their bank."
+ },
+ "not_covered": {
+ "type": "boolean",
+ "nullable": true,
+ "description": "Whether the person's bank or country could not be reached on this step."
+ },
+ "evidence_purged_at": {
+ "type": "string",
+ "format": "date-time",
+ "nullable": true,
+ "description": "When the bank evidence was deleted under `bank_evidence_retention_days`. `null` otherwise."
+ },
+ "warnings": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "Informational codes, for example `holder_declared`. A warning never changes the status on its own."
+ },
+ "reason_codes": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "Why the verdict came out the way it did, for example `OWNER_NAME_PARTIAL`. Several may apply."
+ },
+ "created_at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updated_at": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
+ "BankAccountCheckPersonHolder": {
+ "type": "object",
+ "description": "The person who should hold the account.",
+ "required": [
+ "full_name"
+ ],
+ "properties": {
+ "full_name": {
+ "type": "string",
+ "maxLength": 255,
+ "description": "The full name of the person who should hold the account.",
+ "example": "Maria Oliveira"
+ }
+ }
+ },
+ "BankAccountCheckBusinessHolder": {
+ "type": "object",
+ "description": "The company that should hold the account. Checks a business account.",
+ "required": [
+ "business_name"
+ ],
+ "properties": {
+ "business_name": {
+ "type": "string",
+ "maxLength": 255,
+ "description": "The name of the company that should hold the account. Checks a business account."
+ }
+ }
}
},
"securitySchemes": {
diff --git a/src/main/java/me/didit/resources/BankResource.java b/src/main/java/me/didit/resources/BankResource.java
new file mode 100644
index 0000000..bfc66fd
--- /dev/null
+++ b/src/main/java/me/didit/resources/BankResource.java
@@ -0,0 +1,151 @@
+// Code generated by codegen from openapi/*.json. DO NOT EDIT.
+package me.didit.resources;
+
+import java.util.concurrent.CompletableFuture;
+import me.didit.core.ApiClient;
+import me.didit.core.ApiRequest;
+import me.didit.core.Conv;
+import me.didit.core.RawResponse;
+import me.didit.core.RequestOptions;
+import me.didit.core.ResponseHandler;
+import me.didit.core.Responses;
+import me.didit.types.BankAccountCheckRequest;
+import me.didit.types.BankAccountCheckResponse;
+
+/** The {@code bank} resource: {@code client.bank()}. */
+public final class BankResource {
+ private final ApiClient client;
+ private final WithRawResponse withRawResponse;
+
+ BankResource(ApiClient client) {
+ this.client = client;
+ this.withRawResponse = new WithRawResponse(client);
+ }
+
+ /**
+ * The same operations, returning the HTTP status, headers and request id with the parsed body.
+ *
+ * @return the raw response view
+ */
+ public WithRawResponse withRawResponse() {
+ return withRawResponse;
+ }
+
+ /**
+ * Check a bank account
+ *
+ *
Check that a bank account belongs to the person or company you name, before you send money to it. No session and no sign-in: send the name and the account, read the result. It is the [account check](/core-technology/bank-verification/account-check) of the Bank Verification step, run from your backend.
+ *
+ *
What you send. The account's country (ISO 3166-1 alpha-3), the account the way that country writes it, and the holder name: full_name for a person or business_name for a company. A business name checks a business account.
+ *
+ *
What you get back. result is match, close_match, no_match or cannot_verify. On a close_match, holder_name is the name the bank holds the account under, when the bank returned it. account comes back masked to its last 4 characters.
+ *
+ *
Billing. Each check the bank answers is billed once at the Account check price of the account's country, whatever the result: a no_match, an account that does not exist and a cannot_verify are billed too. A request answered with an error is never billed.
+ *
+ *
Every request is a new check. There is no idempotency key and no endpoint to read a check back, so a retried request runs, and is billed, again. Store the response.
+ *
+ *
Sandbox. A sandbox key calls no bank and is charged nothing. The last 4 characters of the IBAN, else of the account number, choose the answer: 0001 a close_match with a holder_name, 0002 a close_match without one, 0003 and 0006 a no_match, 0004 cannot_verify, 0005 a 503 and 0009 a 400. Any other ending is a match.
+ *
+ *
API keys. A scoped API key needs write access to sessions.
+ *
+ *
{@code POST /v3/bank/account-check/}
+ *
+ * @param params the request parameters
+ * @param options per-request options that override the client options
+ * @return the response body
+ */
+ public BankAccountCheckResponse accountCheck(BankAccountCheckRequest params, RequestOptions options) {
+ return client.execute(accountCheckRequest(params), options, ACCOUNT_CHECK_RESPONSE).data();
+ }
+
+ /**
+ * Asynchronous {@link #accountCheck(BankAccountCheckRequest, RequestOptions)}.
+ *
+ * @param params the request parameters
+ * @param options per-request options
+ * @return a future completed with the result
+ */
+ public CompletableFuture accountCheckAsync(BankAccountCheckRequest params, RequestOptions options) {
+ return client.executeAsync(accountCheckRequest(params), options, ACCOUNT_CHECK_RESPONSE).thenApply(RawResponse::data);
+ }
+
+ /**
+ * Same as {@link #accountCheck(BankAccountCheckRequest, RequestOptions)}, with the client's options.
+ *
+ * @param params the request parameters
+ * @return the result
+ */
+ public BankAccountCheckResponse accountCheck(BankAccountCheckRequest params) {
+ return client.execute(accountCheckRequest(params), RequestOptions.none(), ACCOUNT_CHECK_RESPONSE).data();
+ }
+
+ /**
+ * Asynchronous {@link #accountCheck(BankAccountCheckRequest, RequestOptions)}, with the client's options.
+ *
+ * @param params the request parameters
+ * @return a future completed with the result
+ */
+ public CompletableFuture accountCheckAsync(BankAccountCheckRequest params) {
+ return client.executeAsync(accountCheckRequest(params), RequestOptions.none(), ACCOUNT_CHECK_RESPONSE).thenApply(RawResponse::data);
+ }
+
+ private static final ResponseHandler ACCOUNT_CHECK_RESPONSE = Responses.json(Conv.model(BankAccountCheckResponse::fromJson));
+
+ private static ApiRequest accountCheckRequest(BankAccountCheckRequest params) {
+ return ApiRequest.builder("POST", "/v3/bank/account-check/")
+ .params(params)
+ .body(ApiRequest.BodyEncoding.JSON)
+ .build();
+ }
+
+ /** The {@code bank} operations returning {@link RawResponse}. */
+ public static final class WithRawResponse {
+ private final ApiClient client;
+
+ WithRawResponse(ApiClient client) {
+ this.client = client;
+ }
+
+ /**
+ * {@link #accountCheck(BankAccountCheckRequest, RequestOptions)} with the raw response.
+ *
+ * @param params the request parameters
+ * @param options per-request options
+ * @return the result
+ */
+ public RawResponse accountCheck(BankAccountCheckRequest params, RequestOptions options) {
+ return client.execute(accountCheckRequest(params), options, ACCOUNT_CHECK_RESPONSE);
+ }
+
+ /**
+ * Asynchronous {@link #accountCheck(BankAccountCheckRequest, RequestOptions)} with the raw response.
+ *
+ * @param params the request parameters
+ * @param options per-request options
+ * @return a future completed with the result
+ */
+ public CompletableFuture> accountCheckAsync(BankAccountCheckRequest params, RequestOptions options) {
+ return client.executeAsync(accountCheckRequest(params), options, ACCOUNT_CHECK_RESPONSE);
+ }
+
+ /**
+ * {@link #accountCheck(BankAccountCheckRequest, RequestOptions)} with the raw response, with the client's options.
+ *
+ * @param params the request parameters
+ * @return the result
+ */
+ public RawResponse accountCheck(BankAccountCheckRequest params) {
+ return client.execute(accountCheckRequest(params), RequestOptions.none(), ACCOUNT_CHECK_RESPONSE);
+ }
+
+ /**
+ * Asynchronous {@link #accountCheck(BankAccountCheckRequest, RequestOptions)} with the raw response, with the client's options.
+ *
+ * @param params the request parameters
+ * @return a future completed with the result
+ */
+ public CompletableFuture> accountCheckAsync(BankAccountCheckRequest params) {
+ return client.executeAsync(accountCheckRequest(params), RequestOptions.none(), ACCOUNT_CHECK_RESPONSE);
+ }
+ }
+}
diff --git a/src/main/java/me/didit/resources/DiditResources.java b/src/main/java/me/didit/resources/DiditResources.java
index 55827c8..39e4607 100644
--- a/src/main/java/me/didit/resources/DiditResources.java
+++ b/src/main/java/me/didit/resources/DiditResources.java
@@ -13,6 +13,7 @@ public abstract class DiditResources {
private final AmlResource aml;
private final AmlMonitoringResource amlMonitoring;
private final AnalyticsResource analytics;
+ private final BankResource bank;
private final BillingResource billing;
private final BiometricTemplatesResource biometricTemplates;
private final BlocklistResource blocklist;
@@ -59,6 +60,7 @@ protected DiditResources(ApiClient client) {
this.aml = new AmlResource(client);
this.amlMonitoring = new AmlMonitoringResource(client);
this.analytics = new AnalyticsResource(client);
+ this.bank = new BankResource(client);
this.billing = new BillingResource(client);
this.biometricTemplates = new BiometricTemplatesResource(client);
this.blocklist = new BlocklistResource(client);
@@ -140,6 +142,15 @@ public final AnalyticsResource analytics() {
return analytics;
}
+ /**
+ * The {@code bank} resource.
+ *
+ * @return the resource
+ */
+ public final BankResource bank() {
+ return bank;
+ }
+
/**
* The {@code billing} resource.
*
diff --git a/src/main/java/me/didit/types/BankAccountCheckBusinessHolder.java b/src/main/java/me/didit/types/BankAccountCheckBusinessHolder.java
new file mode 100644
index 0000000..371c072
--- /dev/null
+++ b/src/main/java/me/didit/types/BankAccountCheckBusinessHolder.java
@@ -0,0 +1,100 @@
+// Code generated by codegen from openapi/*.json. DO NOT EDIT.
+package me.didit.types;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import me.didit.core.Conv;
+import me.didit.core.FileUpload;
+import me.didit.core.Json;
+import me.didit.core.JsonModel;
+
+/** The company that should hold the account. Checks a business account. */
+public final class BankAccountCheckBusinessHolder extends JsonModel {
+ private static final Set KNOWN_FIELDS = Set.of("business_name");
+
+ private BankAccountCheckBusinessHolder(ObjectNode json, Map> files) {
+ super(json, files);
+ }
+
+ /**
+ * Reads a {@code BankAccountCheckBusinessHolder} from JSON. Unknown fields are kept and readable
+ * through {@link #_additionalProperties()}.
+ *
+ * @param json a JSON object
+ * @return the parsed value
+ */
+ public static BankAccountCheckBusinessHolder fromJson(JsonNode json) {
+ return new BankAccountCheckBusinessHolder(Json.copyObject(json), Map.of());
+ }
+
+ /**
+ * Returns an empty builder.
+ *
+ * @return a new builder
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Returns a builder holding a copy of every field of this value.
+ *
+ * @return a new builder
+ */
+ public Builder toBuilder() {
+ return new Builder(this);
+ }
+
+ /**
+ * The name of the company that should hold the account. Checks a business account.
+ *
+ * @return the value
+ * @throws me.didit.errors.UnexpectedResponseException when the field is absent or has another type
+ */
+ public String businessName() {
+ return Json.required(json, "business_name", Conv.STRING);
+ }
+
+ @Override
+ protected Set knownFields() {
+ return KNOWN_FIELDS;
+ }
+
+ /** Builds a {@link BankAccountCheckBusinessHolder}. */
+ public static final class Builder extends JsonModel.BaseBuilder {
+ private Builder() {}
+
+ private Builder(BankAccountCheckBusinessHolder from) {
+ super(from);
+ }
+
+ /**
+ * The name of the company that should hold the account. Checks a business account.
+ *
+ * @param businessName the value
+ * @return this builder
+ */
+ public Builder businessName(String businessName) {
+ return set("business_name", Conv.STRING, businessName);
+ }
+
+ /**
+ * Builds the value.
+ *
+ * @return a new immutable {@code BankAccountCheckBusinessHolder}
+ * @throws IllegalStateException when a required field is missing
+ */
+ public BankAccountCheckBusinessHolder build() {
+ require("business_name", false);
+ return new BankAccountCheckBusinessHolder(buildJson(), buildFiles());
+ }
+
+ @Override
+ protected Builder self() {
+ return this;
+ }
+ }
+}
diff --git a/src/main/java/me/didit/types/BankAccountCheckError.java b/src/main/java/me/didit/types/BankAccountCheckError.java
new file mode 100644
index 0000000..8566adb
--- /dev/null
+++ b/src/main/java/me/didit/types/BankAccountCheckError.java
@@ -0,0 +1,216 @@
+// Code generated by codegen from openapi/*.json. DO NOT EDIT.
+package me.didit.types;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import me.didit.core.Conv;
+import me.didit.core.FileUpload;
+import me.didit.core.Json;
+import me.didit.core.JsonModel;
+import me.didit.core.StringEnum;
+
+public final class BankAccountCheckError extends JsonModel {
+ private static final Set KNOWN_FIELDS = Set.of("detail", "code", "field", "reason");
+
+ private BankAccountCheckError(ObjectNode json, Map> files) {
+ super(json, files);
+ }
+
+ /**
+ * Reads a {@code BankAccountCheckError} from JSON. Unknown fields are kept and readable
+ * through {@link #_additionalProperties()}.
+ *
+ * @param json a JSON object
+ * @return the parsed value
+ */
+ public static BankAccountCheckError fromJson(JsonNode json) {
+ return new BankAccountCheckError(Json.copyObject(json), Map.of());
+ }
+
+ /**
+ * Returns an empty builder.
+ *
+ * @return a new builder
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Returns a builder holding a copy of every field of this value.
+ *
+ * @return a new builder
+ */
+ public Builder toBuilder() {
+ return new Builder(this);
+ }
+
+ /**
+ * What went wrong, in English.
+ *
+ * @return the value
+ * @throws me.didit.errors.UnexpectedResponseException when the field is absent or has another type
+ */
+ public String detail() {
+ return Json.required(json, "detail", Conv.STRING);
+ }
+
+ /**
+ * A stable code to branch on. Absent on 401 and 403.
+ *
+ * @return the value, or empty when the field is absent or null
+ * @throws me.didit.errors.UnexpectedResponseException when the field has another type
+ */
+ public Optional code() {
+ return Json.optional(json, "code", Conv.STRING);
+ }
+
+ /**
+ * 400 only: the body field to correct, as a dotted path, for example account.sort_code.
+ *
+ * @return the value, or empty when the field is absent or null
+ * @throws me.didit.errors.UnexpectedResponseException when the field has another type
+ */
+ public Optional field() {
+ return Json.optional(json, "field", Conv.STRING);
+ }
+
+ /**
+ * 400 only: why the field was refused. required, length, format, checksum and country_mismatch (an IBAN of another country) are Didit's own checks; rejected means the bank refused the account as sent.
+ *
+ * @return the value, or empty when the field is absent or null
+ * @throws me.didit.errors.UnexpectedResponseException when the field has another type
+ */
+ public Optional reason() {
+ return Json.optional(json, "reason", Conv.enumeration(BankAccountCheckError.Reason::of));
+ }
+
+ @Override
+ protected Set knownFields() {
+ return KNOWN_FIELDS;
+ }
+
+ /** Builds a {@link BankAccountCheckError}. */
+ public static final class Builder extends JsonModel.BaseBuilder {
+ private Builder() {}
+
+ private Builder(BankAccountCheckError from) {
+ super(from);
+ }
+
+ /**
+ * What went wrong, in English.
+ *
+ * @param detail the value
+ * @return this builder
+ */
+ public Builder detail(String detail) {
+ return set("detail", Conv.STRING, detail);
+ }
+
+ /**
+ * A stable code to branch on. Absent on 401 and 403.
+ *
+ * @param code the value
+ * @return this builder
+ */
+ public Builder code(String code) {
+ return set("code", Conv.STRING, code);
+ }
+
+ /**
+ * 400 only: the body field to correct, as a dotted path, for example account.sort_code.
+ *
+ * @param field the value
+ * @return this builder
+ */
+ public Builder field(String field) {
+ return set("field", Conv.STRING, field);
+ }
+
+ /**
+ * 400 only: why the field was refused. required, length, format, checksum and country_mismatch (an IBAN of another country) are Didit's own checks; rejected means the bank refused the account as sent.
+ *
+ * @param reason the value
+ * @return this builder
+ */
+ public Builder reason(BankAccountCheckError.Reason reason) {
+ return set("reason", Conv.enumeration(BankAccountCheckError.Reason::of), reason);
+ }
+
+ /**
+ * Builds the value.
+ *
+ * @return a new immutable {@code BankAccountCheckError}
+ * @throws IllegalStateException when a required field is missing
+ */
+ public BankAccountCheckError build() {
+ require("detail", false);
+ return new BankAccountCheckError(buildJson(), buildFiles());
+ }
+
+ @Override
+ protected Builder self() {
+ return this;
+ }
+ }
+
+ /**
+ * 400 only: why the field was refused. required, length, format, checksum and country_mismatch (an IBAN of another country) are Didit's own checks; rejected means the bank refused the account as sent.
+ *
+ * An open enum: {@link #of(String)} accepts values this SDK version does not know yet.
+ */
+ public static final class Reason extends StringEnum {
+ /** The value {@code "required"}. */
+ public static final Reason REQUIRED = new Reason("required");
+
+ /** The value {@code "length"}. */
+ public static final Reason LENGTH = new Reason("length");
+
+ /** The value {@code "format"}. */
+ public static final Reason FORMAT = new Reason("format");
+
+ /** The value {@code "checksum"}. */
+ public static final Reason CHECKSUM = new Reason("checksum");
+
+ /** The value {@code "country_mismatch"}. */
+ public static final Reason COUNTRY_MISMATCH = new Reason("country_mismatch");
+
+ /** The value {@code "rejected"}. */
+ public static final Reason REJECTED = new Reason("rejected");
+
+ private static final List KNOWN_VALUES = List.of(REQUIRED, LENGTH, FORMAT, CHECKSUM, COUNTRY_MISMATCH, REJECTED);
+
+ private Reason(String value) {
+ super(value);
+ }
+
+ /**
+ * Returns the constant for a known value, or a new instance for any other value.
+ *
+ * @param value the string value
+ * @return the enum value
+ */
+ public static Reason of(String value) {
+ return StringEnum.lookup(KNOWN_VALUES, value, Reason::new);
+ }
+
+ /**
+ * Returns the values known to this SDK version.
+ *
+ * @return the known values
+ */
+ public static List knownValues() {
+ return KNOWN_VALUES;
+ }
+
+ @Override
+ public boolean isKnown() {
+ return KNOWN_VALUES.contains(this);
+ }
+ }
+}
diff --git a/src/main/java/me/didit/types/BankAccountCheckHolder.java b/src/main/java/me/didit/types/BankAccountCheckHolder.java
new file mode 100644
index 0000000..6443a65
--- /dev/null
+++ b/src/main/java/me/didit/types/BankAccountCheckHolder.java
@@ -0,0 +1,90 @@
+// Code generated by codegen from openapi/*.json. DO NOT EDIT.
+package me.didit.types;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import java.util.Optional;
+import me.didit.core.Conv;
+import me.didit.core.Json;
+import me.didit.core.JsonUnion;
+
+/**
+ * The name the account is checked against. Send exactly one of full_name and business_name.
+ *
+ * One of: {@code BankAccountCheckPersonHolder}, {@code BankAccountCheckBusinessHolder}. Check with the {@code is...}
+ * methods and read with the {@code as...} methods.
+ */
+public final class BankAccountCheckHolder extends JsonUnion {
+ private BankAccountCheckHolder(JsonNode json) {
+ super(json);
+ }
+
+ /**
+ * Reads a {@code BankAccountCheckHolder} from JSON.
+ *
+ * @param json any JSON value
+ * @return the union
+ */
+ public static BankAccountCheckHolder fromJson(JsonNode json) {
+ return new BankAccountCheckHolder(json.deepCopy());
+ }
+
+ /**
+ * Wraps a {@code BankAccountCheckPersonHolder} value.
+ *
+ * @param value the value
+ * @return the union
+ */
+ public static BankAccountCheckHolder ofBankAccountCheckPersonHolder(BankAccountCheckPersonHolder value) {
+ return new BankAccountCheckHolder(Conv.model(BankAccountCheckPersonHolder::fromJson).write(value));
+ }
+
+ /**
+ * Whether this value is a {@code BankAccountCheckPersonHolder}.
+ *
+ * The person who should hold the account.
+ *
+ * @return true when it matches
+ */
+ public boolean isBankAccountCheckPersonHolder() {
+ return Json.hasFields(json, "full_name");
+ }
+
+ /**
+ * Reads this value as a {@code BankAccountCheckPersonHolder}.
+ *
+ * @return the value, or empty when {@link #isBankAccountCheckPersonHolder()} is false
+ */
+ public Optional asBankAccountCheckPersonHolder() {
+ return isBankAccountCheckPersonHolder() ? Optional.of(Conv.model(BankAccountCheckPersonHolder::fromJson).read(json)) : Optional.empty();
+ }
+
+ /**
+ * Wraps a {@code BankAccountCheckBusinessHolder} value.
+ *
+ * @param value the value
+ * @return the union
+ */
+ public static BankAccountCheckHolder ofBankAccountCheckBusinessHolder(BankAccountCheckBusinessHolder value) {
+ return new BankAccountCheckHolder(Conv.model(BankAccountCheckBusinessHolder::fromJson).write(value));
+ }
+
+ /**
+ * Whether this value is a {@code BankAccountCheckBusinessHolder}.
+ *
+ * The company that should hold the account. Checks a business account.
+ *
+ * @return true when it matches
+ */
+ public boolean isBankAccountCheckBusinessHolder() {
+ return Json.hasFields(json, "business_name");
+ }
+
+ /**
+ * Reads this value as a {@code BankAccountCheckBusinessHolder}.
+ *
+ * @return the value, or empty when {@link #isBankAccountCheckBusinessHolder()} is false
+ */
+ public Optional asBankAccountCheckBusinessHolder() {
+ return isBankAccountCheckBusinessHolder() ? Optional.of(Conv.model(BankAccountCheckBusinessHolder::fromJson).read(json)) : Optional.empty();
+ }
+}
diff --git a/src/main/java/me/didit/types/BankAccountCheckPersonHolder.java b/src/main/java/me/didit/types/BankAccountCheckPersonHolder.java
new file mode 100644
index 0000000..6120f90
--- /dev/null
+++ b/src/main/java/me/didit/types/BankAccountCheckPersonHolder.java
@@ -0,0 +1,100 @@
+// Code generated by codegen from openapi/*.json. DO NOT EDIT.
+package me.didit.types;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import me.didit.core.Conv;
+import me.didit.core.FileUpload;
+import me.didit.core.Json;
+import me.didit.core.JsonModel;
+
+/** The person who should hold the account. */
+public final class BankAccountCheckPersonHolder extends JsonModel {
+ private static final Set KNOWN_FIELDS = Set.of("full_name");
+
+ private BankAccountCheckPersonHolder(ObjectNode json, Map> files) {
+ super(json, files);
+ }
+
+ /**
+ * Reads a {@code BankAccountCheckPersonHolder} from JSON. Unknown fields are kept and readable
+ * through {@link #_additionalProperties()}.
+ *
+ * @param json a JSON object
+ * @return the parsed value
+ */
+ public static BankAccountCheckPersonHolder fromJson(JsonNode json) {
+ return new BankAccountCheckPersonHolder(Json.copyObject(json), Map.of());
+ }
+
+ /**
+ * Returns an empty builder.
+ *
+ * @return a new builder
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Returns a builder holding a copy of every field of this value.
+ *
+ * @return a new builder
+ */
+ public Builder toBuilder() {
+ return new Builder(this);
+ }
+
+ /**
+ * The full name of the person who should hold the account.
+ *
+ * @return the value
+ * @throws me.didit.errors.UnexpectedResponseException when the field is absent or has another type
+ */
+ public String fullName() {
+ return Json.required(json, "full_name", Conv.STRING);
+ }
+
+ @Override
+ protected Set knownFields() {
+ return KNOWN_FIELDS;
+ }
+
+ /** Builds a {@link BankAccountCheckPersonHolder}. */
+ public static final class Builder extends JsonModel.BaseBuilder {
+ private Builder() {}
+
+ private Builder(BankAccountCheckPersonHolder from) {
+ super(from);
+ }
+
+ /**
+ * The full name of the person who should hold the account.
+ *
+ * @param fullName the value
+ * @return this builder
+ */
+ public Builder fullName(String fullName) {
+ return set("full_name", Conv.STRING, fullName);
+ }
+
+ /**
+ * Builds the value.
+ *
+ * @return a new immutable {@code BankAccountCheckPersonHolder}
+ * @throws IllegalStateException when a required field is missing
+ */
+ public BankAccountCheckPersonHolder build() {
+ require("full_name", false);
+ return new BankAccountCheckPersonHolder(buildJson(), buildFiles());
+ }
+
+ @Override
+ protected Builder self() {
+ return this;
+ }
+ }
+}
diff --git a/src/main/java/me/didit/types/BankAccountCheckRequest.java b/src/main/java/me/didit/types/BankAccountCheckRequest.java
new file mode 100644
index 0000000..0535be8
--- /dev/null
+++ b/src/main/java/me/didit/types/BankAccountCheckRequest.java
@@ -0,0 +1,471 @@
+// Code generated by codegen from openapi/*.json. DO NOT EDIT.
+package me.didit.types;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import me.didit.core.Conv;
+import me.didit.core.FileUpload;
+import me.didit.core.Json;
+import me.didit.core.JsonModel;
+import org.jspecify.annotations.Nullable;
+
+public final class BankAccountCheckRequest extends JsonModel {
+ private static final Set KNOWN_FIELDS = Set.of("country", "account", "holder", "vendor_data");
+
+ private BankAccountCheckRequest(ObjectNode json, Map> files) {
+ super(json, files);
+ }
+
+ /**
+ * Reads a {@code BankAccountCheckRequest} from JSON. Unknown fields are kept and readable
+ * through {@link #_additionalProperties()}.
+ *
+ * @param json a JSON object
+ * @return the parsed value
+ */
+ public static BankAccountCheckRequest fromJson(JsonNode json) {
+ return new BankAccountCheckRequest(Json.copyObject(json), Map.of());
+ }
+
+ /**
+ * Returns an empty builder.
+ *
+ * @return a new builder
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Returns a builder holding a copy of every field of this value.
+ *
+ * @return a new builder
+ */
+ public Builder toBuilder() {
+ return new Builder(this);
+ }
+
+ /**
+ * The account's country, as an ISO 3166-1 alpha-3 code, for example GBR. Lowercase is accepted.
+ *
+ * @return the value
+ * @throws me.didit.errors.UnexpectedResponseException when the field is absent or has another type
+ */
+ public String country() {
+ return Json.required(json, "country", Conv.STRING);
+ }
+
+ /**
+ * The account the way its country writes it: an iban, or an account_number with the bank or branch code the country needs (sort_code, routing_number, transit_institution, bsb, ifsc, bank_code or bic). Mexico takes a clabe and Argentina a cbu_cvu, which already name the bank. A business account adds a registration_id where the country asks for one. Spaces, dashes and dots are ignored. Keys the country's check does not use are ignored; a key it needs and does not get is a 400 that names it.
+ *
+ * @return the value
+ * @throws me.didit.errors.UnexpectedResponseException when the field is absent or has another type
+ */
+ public BankAccountCheckRequest.Account account() {
+ return Json.required(json, "account", Conv.model(BankAccountCheckRequest.Account::fromJson));
+ }
+
+ /**
+ * The name the account is checked against. Send exactly one of full_name and business_name.
+ *
+ * @return the value
+ * @throws me.didit.errors.UnexpectedResponseException when the field is absent or has another type
+ */
+ public BankAccountCheckHolder holder() {
+ return Json.required(json, "holder", Conv.union(BankAccountCheckHolder::fromJson));
+ }
+
+ /**
+ * Your own reference for this check, returned unchanged.
+ *
+ * @return the value, or empty when the field is absent or null
+ * @throws me.didit.errors.UnexpectedResponseException when the field has another type
+ */
+ public Optional vendorData() {
+ return Json.optional(json, "vendor_data", Conv.STRING);
+ }
+
+ @Override
+ protected Set knownFields() {
+ return KNOWN_FIELDS;
+ }
+
+ /** Builds a {@link BankAccountCheckRequest}. */
+ public static final class Builder extends JsonModel.BaseBuilder {
+ private Builder() {}
+
+ private Builder(BankAccountCheckRequest from) {
+ super(from);
+ }
+
+ /**
+ * The account's country, as an ISO 3166-1 alpha-3 code, for example GBR. Lowercase is accepted.
+ *
+ * @param country the value
+ * @return this builder
+ */
+ public Builder country(String country) {
+ return set("country", Conv.STRING, country);
+ }
+
+ /**
+ * The account the way its country writes it: an iban, or an account_number with the bank or branch code the country needs (sort_code, routing_number, transit_institution, bsb, ifsc, bank_code or bic). Mexico takes a clabe and Argentina a cbu_cvu, which already name the bank. A business account adds a registration_id where the country asks for one. Spaces, dashes and dots are ignored. Keys the country's check does not use are ignored; a key it needs and does not get is a 400 that names it.
+ *
+ * @param account the value
+ * @return this builder
+ */
+ public Builder account(BankAccountCheckRequest.Account account) {
+ return set("account", Conv.model(BankAccountCheckRequest.Account::fromJson), account);
+ }
+
+ /**
+ * The name the account is checked against. Send exactly one of full_name and business_name.
+ *
+ * @param holder the value
+ * @return this builder
+ */
+ public Builder holder(BankAccountCheckHolder holder) {
+ return set("holder", Conv.union(BankAccountCheckHolder::fromJson), holder);
+ }
+
+ /**
+ * Your own reference for this check, returned unchanged.
+ *
+ * @param vendorData the value, or {@code null} to send JSON null
+ * @return this builder
+ */
+ public Builder vendorData(@Nullable String vendorData) {
+ return setNullable("vendor_data", Conv.STRING, vendorData);
+ }
+
+ /**
+ * Builds the value.
+ *
+ * @return a new immutable {@code BankAccountCheckRequest}
+ * @throws IllegalStateException when a required field is missing
+ */
+ public BankAccountCheckRequest build() {
+ require("country", false);
+ require("account", false);
+ require("holder", false);
+ return new BankAccountCheckRequest(buildJson(), buildFiles());
+ }
+
+ @Override
+ protected Builder self() {
+ return this;
+ }
+ }
+
+ /**
+ * The account the way its country writes it: an iban, or an account_number with the bank or branch code the country needs (sort_code, routing_number, transit_institution, bsb, ifsc, bank_code or bic). Mexico takes a clabe and Argentina a cbu_cvu, which already name the bank. A business account adds a registration_id where the country asks for one. Spaces, dashes and dots are ignored. Keys the country's check does not use are ignored; a key it needs and does not get is a 400 that names it.
+ */
+ public static final class Account extends JsonModel {
+ private static final Set KNOWN_FIELDS = Set.of("iban", "account_number", "sort_code", "routing_number", "transit_institution", "bsb", "ifsc", "bank_code", "bic", "clabe", "cbu_cvu", "registration_id");
+
+ private Account(ObjectNode json, Map> files) {
+ super(json, files);
+ }
+
+ /**
+ * Reads a {@code Account} from JSON. Unknown fields are kept and readable
+ * through {@link #_additionalProperties()}.
+ *
+ * @param json a JSON object
+ * @return the parsed value
+ */
+ public static Account fromJson(JsonNode json) {
+ return new Account(Json.copyObject(json), Map.of());
+ }
+
+ /**
+ * Returns an empty builder.
+ *
+ * @return a new builder
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Returns a builder holding a copy of every field of this value.
+ *
+ * @return a new builder
+ */
+ public Builder toBuilder() {
+ return new Builder(this);
+ }
+
+ /**
+ * The IBAN, in a country that uses IBANs. It must belong to country.
+ *
+ * @return the value, or empty when the field is absent or null
+ * @throws me.didit.errors.UnexpectedResponseException when the field has another type
+ */
+ public Optional iban() {
+ return Json.optional(json, "iban", Conv.STRING);
+ }
+
+ /**
+ * The account number, in a country that writes the account with a separate bank or branch code.
+ *
+ * @return the value, or empty when the field is absent or null
+ * @throws me.didit.errors.UnexpectedResponseException when the field has another type
+ */
+ public Optional accountNumber() {
+ return Json.optional(json, "account_number", Conv.STRING);
+ }
+
+ /**
+ * United Kingdom: the 6-digit sort code.
+ *
+ * @return the value, or empty when the field is absent or null
+ * @throws me.didit.errors.UnexpectedResponseException when the field has another type
+ */
+ public Optional sortCode() {
+ return Json.optional(json, "sort_code", Conv.STRING);
+ }
+
+ /**
+ * United States: the 9-digit ABA routing number.
+ *
+ * @return the value, or empty when the field is absent or null
+ * @throws me.didit.errors.UnexpectedResponseException when the field has another type
+ */
+ public Optional routingNumber() {
+ return Json.optional(json, "routing_number", Conv.STRING);
+ }
+
+ /**
+ * Canada: the 8-digit transit and institution number.
+ *
+ * @return the value, or empty when the field is absent or null
+ * @throws me.didit.errors.UnexpectedResponseException when the field has another type
+ */
+ public Optional transitInstitution() {
+ return Json.optional(json, "transit_institution", Conv.STRING);
+ }
+
+ /**
+ * Australia: the 6-digit BSB.
+ *
+ * @return the value, or empty when the field is absent or null
+ * @throws me.didit.errors.UnexpectedResponseException when the field has another type
+ */
+ public Optional bsb() {
+ return Json.optional(json, "bsb", Conv.STRING);
+ }
+
+ /**
+ * India: the 11-character IFSC.
+ *
+ * @return the value, or empty when the field is absent or null
+ * @throws me.didit.errors.UnexpectedResponseException when the field has another type
+ */
+ public Optional ifsc() {
+ return Json.optional(json, "ifsc", Conv.STRING);
+ }
+
+ /**
+ * The bank's code, where the country needs one, for example in Nigeria.
+ *
+ * @return the value, or empty when the field is absent or null
+ * @throws me.didit.errors.UnexpectedResponseException when the field has another type
+ */
+ public Optional bankCode() {
+ return Json.optional(json, "bank_code", Conv.STRING);
+ }
+
+ /**
+ * The bank's BIC, where the country's check asks for one.
+ *
+ * @return the value, or empty when the field is absent or null
+ * @throws me.didit.errors.UnexpectedResponseException when the field has another type
+ */
+ public Optional bic() {
+ return Json.optional(json, "bic", Conv.STRING);
+ }
+
+ /**
+ * Mexico: the 18-digit CLABE. It already names the bank.
+ *
+ * @return the value, or empty when the field is absent or null
+ * @throws me.didit.errors.UnexpectedResponseException when the field has another type
+ */
+ public Optional clabe() {
+ return Json.optional(json, "clabe", Conv.STRING);
+ }
+
+ /**
+ * Argentina: the 22-digit CBU or CVU. It already names the bank.
+ *
+ * @return the value, or empty when the field is absent or null
+ * @throws me.didit.errors.UnexpectedResponseException when the field has another type
+ */
+ public Optional cbuCvu() {
+ return Json.optional(json, "cbu_cvu", Conv.STRING);
+ }
+
+ /**
+ * A business account's registration number, where the country asks for one.
+ *
+ * @return the value, or empty when the field is absent or null
+ * @throws me.didit.errors.UnexpectedResponseException when the field has another type
+ */
+ public Optional registrationId() {
+ return Json.optional(json, "registration_id", Conv.STRING);
+ }
+
+ @Override
+ protected Set knownFields() {
+ return KNOWN_FIELDS;
+ }
+
+ /** Builds a {@link Account}. */
+ public static final class Builder extends JsonModel.BaseBuilder {
+ private Builder() {}
+
+ private Builder(Account from) {
+ super(from);
+ }
+
+ /**
+ * The IBAN, in a country that uses IBANs. It must belong to country.
+ *
+ * @param iban the value
+ * @return this builder
+ */
+ public Builder iban(String iban) {
+ return set("iban", Conv.STRING, iban);
+ }
+
+ /**
+ * The account number, in a country that writes the account with a separate bank or branch code.
+ *
+ * @param accountNumber the value
+ * @return this builder
+ */
+ public Builder accountNumber(String accountNumber) {
+ return set("account_number", Conv.STRING, accountNumber);
+ }
+
+ /**
+ * United Kingdom: the 6-digit sort code.
+ *
+ * @param sortCode the value
+ * @return this builder
+ */
+ public Builder sortCode(String sortCode) {
+ return set("sort_code", Conv.STRING, sortCode);
+ }
+
+ /**
+ * United States: the 9-digit ABA routing number.
+ *
+ * @param routingNumber the value
+ * @return this builder
+ */
+ public Builder routingNumber(String routingNumber) {
+ return set("routing_number", Conv.STRING, routingNumber);
+ }
+
+ /**
+ * Canada: the 8-digit transit and institution number.
+ *
+ * @param transitInstitution the value
+ * @return this builder
+ */
+ public Builder transitInstitution(String transitInstitution) {
+ return set("transit_institution", Conv.STRING, transitInstitution);
+ }
+
+ /**
+ * Australia: the 6-digit BSB.
+ *
+ * @param bsb the value
+ * @return this builder
+ */
+ public Builder bsb(String bsb) {
+ return set("bsb", Conv.STRING, bsb);
+ }
+
+ /**
+ * India: the 11-character IFSC.
+ *
+ * @param ifsc the value
+ * @return this builder
+ */
+ public Builder ifsc(String ifsc) {
+ return set("ifsc", Conv.STRING, ifsc);
+ }
+
+ /**
+ * The bank's code, where the country needs one, for example in Nigeria.
+ *
+ * @param bankCode the value
+ * @return this builder
+ */
+ public Builder bankCode(String bankCode) {
+ return set("bank_code", Conv.STRING, bankCode);
+ }
+
+ /**
+ * The bank's BIC, where the country's check asks for one.
+ *
+ * @param bic the value
+ * @return this builder
+ */
+ public Builder bic(String bic) {
+ return set("bic", Conv.STRING, bic);
+ }
+
+ /**
+ * Mexico: the 18-digit CLABE. It already names the bank.
+ *
+ * @param clabe the value
+ * @return this builder
+ */
+ public Builder clabe(String clabe) {
+ return set("clabe", Conv.STRING, clabe);
+ }
+
+ /**
+ * Argentina: the 22-digit CBU or CVU. It already names the bank.
+ *
+ * @param cbuCvu the value
+ * @return this builder
+ */
+ public Builder cbuCvu(String cbuCvu) {
+ return set("cbu_cvu", Conv.STRING, cbuCvu);
+ }
+
+ /**
+ * A business account's registration number, where the country asks for one.
+ *
+ * @param registrationId the value
+ * @return this builder
+ */
+ public Builder registrationId(String registrationId) {
+ return set("registration_id", Conv.STRING, registrationId);
+ }
+
+ /**
+ * Builds the value.
+ *
+ * @return a new immutable {@code Account}
+ */
+ public Account build() {
+ return new Account(buildJson(), buildFiles());
+ }
+
+ @Override
+ protected Builder self() {
+ return this;
+ }
+ }
+ }
+}
diff --git a/src/main/java/me/didit/types/BankAccountCheckResponse.java b/src/main/java/me/didit/types/BankAccountCheckResponse.java
new file mode 100644
index 0000000..65c5f94
--- /dev/null
+++ b/src/main/java/me/didit/types/BankAccountCheckResponse.java
@@ -0,0 +1,257 @@
+// Code generated by codegen from openapi/*.json. DO NOT EDIT.
+package me.didit.types;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import java.time.OffsetDateTime;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import me.didit.core.Conv;
+import me.didit.core.FileUpload;
+import me.didit.core.Json;
+import me.didit.core.JsonModel;
+import me.didit.core.StringEnum;
+import org.jspecify.annotations.Nullable;
+
+public final class BankAccountCheckResponse extends JsonModel {
+ private static final Set KNOWN_FIELDS = Set.of("request_id", "result", "holder_name", "account", "vendor_data", "created_at");
+
+ private BankAccountCheckResponse(ObjectNode json, Map> files) {
+ super(json, files);
+ }
+
+ /**
+ * Reads a {@code BankAccountCheckResponse} from JSON. Unknown fields are kept and readable
+ * through {@link #_additionalProperties()}.
+ *
+ * @param json a JSON object
+ * @return the parsed value
+ */
+ public static BankAccountCheckResponse fromJson(JsonNode json) {
+ return new BankAccountCheckResponse(Json.copyObject(json), Map.of());
+ }
+
+ /**
+ * Returns an empty builder.
+ *
+ * @return a new builder
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Returns a builder holding a copy of every field of this value.
+ *
+ * @return a new builder
+ */
+ public Builder toBuilder() {
+ return new Builder(this);
+ }
+
+ /**
+ * The ID of this check.
+ *
+ * @return the value
+ * @throws me.didit.errors.UnexpectedResponseException when the field is absent or has another type
+ */
+ public String requestId() {
+ return Json.required(json, "request_id", Conv.STRING);
+ }
+
+ /**
+ * match: the bank holds the account under the name you sent. close_match: under a close name, for example a missing middle name or a typo. no_match: under another name, or there is no such account. cannot_verify: the bank answered without comparing the name, for example for a blocked or closed account.
+ *
+ * @return the value
+ * @throws me.didit.errors.UnexpectedResponseException when the field is absent or has another type
+ */
+ public BankAccountCheckResponse.Result result() {
+ return Json.required(json, "result", Conv.enumeration(BankAccountCheckResponse.Result::of));
+ }
+
+ /**
+ * Only on a close_match, and only when the bank returned it: the name on the account, as the bank holds it. null otherwise.
+ *
+ * @return the value, or empty when the field is absent or null
+ * @throws me.didit.errors.UnexpectedResponseException when the field has another type
+ */
+ public Optional holderName() {
+ return Json.optional(json, "holder_name", Conv.STRING);
+ }
+
+ /**
+ * The account, masked to its last 4 characters.
+ *
+ * @return the value
+ * @throws me.didit.errors.UnexpectedResponseException when the field is absent or has another type
+ */
+ public String account() {
+ return Json.required(json, "account", Conv.STRING);
+ }
+
+ /**
+ * Your own reference, as you sent it.
+ *
+ * @return the value, or empty when the field is absent or null
+ * @throws me.didit.errors.UnexpectedResponseException when the field has another type
+ */
+ public Optional vendorData() {
+ return Json.optional(json, "vendor_data", Conv.STRING);
+ }
+
+ /**
+ * When the check ran, in UTC.
+ *
+ * @return the value
+ * @throws me.didit.errors.UnexpectedResponseException when the field is absent or has another type
+ */
+ public OffsetDateTime createdAt() {
+ return Json.required(json, "created_at", Conv.DATE_TIME);
+ }
+
+ @Override
+ protected Set knownFields() {
+ return KNOWN_FIELDS;
+ }
+
+ /** Builds a {@link BankAccountCheckResponse}. */
+ public static final class Builder extends JsonModel.BaseBuilder {
+ private Builder() {}
+
+ private Builder(BankAccountCheckResponse from) {
+ super(from);
+ }
+
+ /**
+ * The ID of this check.
+ *
+ * @param requestId the value
+ * @return this builder
+ */
+ public Builder requestId(String requestId) {
+ return set("request_id", Conv.STRING, requestId);
+ }
+
+ /**
+ * match: the bank holds the account under the name you sent. close_match: under a close name, for example a missing middle name or a typo. no_match: under another name, or there is no such account. cannot_verify: the bank answered without comparing the name, for example for a blocked or closed account.
+ *
+ * @param result the value
+ * @return this builder
+ */
+ public Builder result(BankAccountCheckResponse.Result result) {
+ return set("result", Conv.enumeration(BankAccountCheckResponse.Result::of), result);
+ }
+
+ /**
+ * Only on a close_match, and only when the bank returned it: the name on the account, as the bank holds it. null otherwise.
+ *
+ * @param holderName the value, or {@code null} to send JSON null
+ * @return this builder
+ */
+ public Builder holderName(@Nullable String holderName) {
+ return setNullable("holder_name", Conv.STRING, holderName);
+ }
+
+ /**
+ * The account, masked to its last 4 characters.
+ *
+ * @param account the value
+ * @return this builder
+ */
+ public Builder account(String account) {
+ return set("account", Conv.STRING, account);
+ }
+
+ /**
+ * Your own reference, as you sent it.
+ *
+ * @param vendorData the value, or {@code null} to send JSON null
+ * @return this builder
+ */
+ public Builder vendorData(@Nullable String vendorData) {
+ return setNullable("vendor_data", Conv.STRING, vendorData);
+ }
+
+ /**
+ * When the check ran, in UTC.
+ *
+ * @param createdAt the value
+ * @return this builder
+ */
+ public Builder createdAt(OffsetDateTime createdAt) {
+ return set("created_at", Conv.DATE_TIME, createdAt);
+ }
+
+ /**
+ * Builds the value.
+ *
+ * @return a new immutable {@code BankAccountCheckResponse}
+ * @throws IllegalStateException when a required field is missing
+ */
+ public BankAccountCheckResponse build() {
+ require("request_id", false);
+ require("result", false);
+ require("holder_name", true);
+ require("account", false);
+ require("vendor_data", true);
+ require("created_at", false);
+ return new BankAccountCheckResponse(buildJson(), buildFiles());
+ }
+
+ @Override
+ protected Builder self() {
+ return this;
+ }
+ }
+
+ /**
+ * match: the bank holds the account under the name you sent. close_match: under a close name, for example a missing middle name or a typo. no_match: under another name, or there is no such account. cannot_verify: the bank answered without comparing the name, for example for a blocked or closed account.
+ *
+ * An open enum: {@link #of(String)} accepts values this SDK version does not know yet.
+ */
+ public static final class Result extends StringEnum {
+ /** The value {@code "match"}. */
+ public static final Result MATCH = new Result("match");
+
+ /** The value {@code "close_match"}. */
+ public static final Result CLOSE_MATCH = new Result("close_match");
+
+ /** The value {@code "no_match"}. */
+ public static final Result NO_MATCH = new Result("no_match");
+
+ /** The value {@code "cannot_verify"}. */
+ public static final Result CANNOT_VERIFY = new Result("cannot_verify");
+
+ private static final List KNOWN_VALUES = List.of(MATCH, CLOSE_MATCH, NO_MATCH, CANNOT_VERIFY);
+
+ private Result(String value) {
+ super(value);
+ }
+
+ /**
+ * Returns the constant for a known value, or a new instance for any other value.
+ *
+ * @param value the string value
+ * @return the enum value
+ */
+ public static Result of(String value) {
+ return StringEnum.lookup(KNOWN_VALUES, value, Result::new);
+ }
+
+ /**
+ * Returns the values known to this SDK version.
+ *
+ * @return the known values
+ */
+ public static List knownValues() {
+ return KNOWN_VALUES;
+ }
+
+ @Override
+ public boolean isKnown() {
+ return KNOWN_VALUES.contains(this);
+ }
+ }
+}
diff --git a/src/main/java/me/didit/types/BankVerificationResult.java b/src/main/java/me/didit/types/BankVerificationResult.java
new file mode 100644
index 0000000..5062932
--- /dev/null
+++ b/src/main/java/me/didit/types/BankVerificationResult.java
@@ -0,0 +1,2591 @@
+// Code generated by codegen from openapi/*.json. DO NOT EDIT.
+package me.didit.types;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import java.time.OffsetDateTime;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import me.didit.core.Conv;
+import me.didit.core.FileUpload;
+import me.didit.core.Json;
+import me.didit.core.JsonModel;
+import me.didit.core.StringEnum;
+import org.jspecify.annotations.Nullable;
+
+/**
+ * One Bank Verification step's result, for User and Business Verification. method says how the account was verified. See [Bank verification methods](/core-technology/bank-verification/verification-methods).
+ */
+public final class BankVerificationResult extends JsonModel {
+ private static final Set KNOWN_FIELDS = Set.of("schema_version", "bank_verification_id", "node_id", "status", "original_status", "method", "provider", "credential_source", "route", "connection", "account", "ownership", "financial_data", "billing", "reference_identity", "signals", "connection_abandoned", "not_covered", "evidence_purged_at", "warnings", "reason_codes", "created_at", "updated_at");
+
+ private BankVerificationResult(ObjectNode json, Map> files) {
+ super(json, files);
+ }
+
+ /**
+ * Reads a {@code BankVerificationResult} from JSON. Unknown fields are kept and readable
+ * through {@link #_additionalProperties()}.
+ *
+ * @param json a JSON object
+ * @return the parsed value
+ */
+ public static BankVerificationResult fromJson(JsonNode json) {
+ return new BankVerificationResult(Json.copyObject(json), Map.of());
+ }
+
+ /**
+ * Returns an empty builder.
+ *
+ * @return a new builder
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Returns a builder holding a copy of every field of this value.
+ *
+ * @return a new builder
+ */
+ public Builder toBuilder() {
+ return new Builder(this);
+ }
+
+ /**
+ * Version of this result shape. 1 today.
+ *
+ * @return the value, or empty when the field is absent or null
+ * @throws me.didit.errors.UnexpectedResponseException when the field has another type
+ */
+ public Optional schemaVersion() {
+ return Json.optional(json, "schema_version", Conv.LONG);
+ }
+
+ /**
+ * The ID of this result.
+ *
+ * @return the value, or empty when the field is absent or null
+ * @throws me.didit.errors.UnexpectedResponseException when the field has another type
+ */
+ public Optional bankVerificationId() {
+ return Json.optional(json, "bank_verification_id", Conv.STRING);
+ }
+
+ /**
+ * The workflow node this result belongs to.
+ *
+ * @return the value, or empty when the field is absent or null
+ * @throws me.didit.errors.UnexpectedResponseException when the field has another type
+ */
+ public Optional nodeId() {
+ return Json.optional(json, "node_id", Conv.STRING);
+ }
+
+ /**
+ * The step's verdict, after its actions and status rules.
+ *
+ * @return the value, or empty when the field is absent or null
+ * @throws me.didit.errors.UnexpectedResponseException when the field has another type
+ */
+ public Optional status() {
+ return Json.optional(json, "status", Conv.enumeration(BankVerificationResult.Status::of));
+ }
+
+ /**
+ * The first verdict the step reached, before any later change such as a manual review.
+ *
+ * @return the value, or empty when the field is absent or null
+ * @throws me.didit.errors.UnexpectedResponseException when the field has another type
+ */
+ public Optional originalStatus() {
+ return Json.optional(json, "original_status", Conv.STRING);
+ }
+
+ /**
+ * How the account was verified: open_banking (bank sign-in: the person signed in at their bank), account_lookup (account check: the person typed the account details and the bank confirmed the name), microdeposits or statement (a statement upload). null until an account is evaluated. Workflow rules read the same value as bank.method.
+ *
+ * @return the value, or empty when the field is absent or null
+ * @throws me.didit.errors.UnexpectedResponseException when the field has another type
+ */
+ public Optional method() {
+ return Json.optional(json, "method", Conv.enumeration(BankVerificationResult.Method::of));
+ }
+
+ /**
+ * The key of the route that ran the connection. Read method, not this key, to tell how the account was verified.
+ *
+ * @return the value, or empty when the field is absent or null
+ * @throws me.didit.errors.UnexpectedResponseException when the field has another type
+ */
+ public Optional provider() {
+ return Json.optional(json, "provider", Conv.STRING);
+ }
+
+ /**
+ * native: Didit's own route, billed to your Didit balance. byok: a marketplace provider you connected with your own credentials.
+ *
+ * @return the value, or empty when the field is absent or null
+ * @throws me.didit.errors.UnexpectedResponseException when the field has another type
+ */
+ public Optional credentialSource() {
+ return Json.optional(json, "credential_source", Conv.enumeration(BankVerificationResult.CredentialSource::of));
+ }
+
+ /**
+ * The route chosen before consent. It never changes afterwards.
+ *
+ * @return the value, or empty when the field is absent or null
+ * @throws me.didit.errors.UnexpectedResponseException when the field has another type
+ */
+ public Optional route() {
+ return Json.optional(json, "route", Conv.model(BankVerificationResult.Route::fromJson));
+ }
+
+ /**
+ * The latest attempt's connection. null before the first attempt.
+ *
+ * @return the value, or empty when the field is absent or null
+ * @throws me.didit.errors.UnexpectedResponseException when the field has another type
+ */
+ public Optional connection() {
+ return Json.optional(json, "connection", Conv.model(BankVerificationResult.Connection::fromJson));
+ }
+
+ /**
+ * The evaluated account. null until an account is evaluated.
+ *
+ * @return the value, or empty when the field is absent or null
+ * @throws me.didit.errors.UnexpectedResponseException when the field has another type
+ */
+ public Optional account() {
+ return Json.optional(json, "account", Conv.model(BankVerificationResult.Account::fromJson));
+ }
+
+ /**
+ * How the account holder compared with the verified identity. null until an account is evaluated.
+ *
+ * @return the value, or empty when the field is absent or null
+ * @throws me.didit.errors.UnexpectedResponseException when the field has another type
+ */
+ public Optional ownership() {
+ return Json.optional(json, "ownership", Conv.model(BankVerificationResult.Ownership::fromJson));
+ }
+
+ /**
+ * The financial data the step read. Only bank sign-in reads it.
+ *
+ * @return the value, or empty when the field is absent or null
+ * @throws me.didit.errors.UnexpectedResponseException when the field has another type
+ */
+ public Optional financialData() {
+ return Json.optional(json, "financial_data", Conv.model(BankVerificationResult.FinancialData::fromJson));
+ }
+
+ /**
+ * The billing field.
+ *
+ * @return the value, or empty when the field is absent or null
+ * @throws me.didit.errors.UnexpectedResponseException when the field has another type
+ */
+ public Optional billing() {
+ return Json.optional(json, "billing", Conv.model(BankVerificationResult.Billing::fromJson));
+ }
+
+ /**
+ * The identity the holder was compared against, with its source.
+ *
+ * @return the value, or empty when the field is absent or null
+ * @throws me.didit.errors.UnexpectedResponseException when the field has another type
+ */
+ public Optional