---
title: "Verify a bank account"
method: POST
path: "/bank-account-verifications"
---

# Verify a bank account

`POST /bank-account-verifications`

Verifies a bank account by checking that the account exists, is open, and that the account holder details match the provided identity information.

This service is available for South African bank accounts only. Identifying documents and business registrations default to South Africa (`ZA`) when `country` is omitted; explicit non-ZA values are passed through.

## Request body

- object
  - `bankAccount` BankAccount, required — The bank account being verified. `bank` is required. `branchCode` is optional; when omitted the corresponding universal branch code for the supplied `bank` is used.
    - `bank` 'absa' | 'african_bank' | 'capitec' | 'discovery_bank' | 'fnb' | 'grindrod_bank' | 'investec' | 'nedbank' | 'sasfin_bank' | 'standard_bank' | 'za_bidvest' | 'tymebank' | 'za_access_bank' | 'za_albaraka_bank' | 'za_bank_zero' | 'za_standard_chartered_bank', required — The bank where the account is held. Required. This is an enum of supported South African banks (it is not an opaque identifier).
    - `branchCode` string — The 6-digit branch code. Optional. When omitted, the universal branch code for the supplied `bank` is used. Supply this when you want to verify against a specific branch.
    - `number` string, required — The bank account number to verify. Numeric digits only, 6–13 characters.
    - `type` 'current' | 'savings' | 'credit' | 'loan' | 'investment' | 'other' | 'unknown' — The type of bank account. Mirrors the upstream `AccountType` enum; `credit` and `investment` are accepted for parity with the GraphQL contract.
  - `accountHolder` union, required — The account holder details to verify against. The `type` discriminator selects whether this is an individual or a business. Business verification is for South African registered businesses only.
    - object — An individual account holder.
      - `type` 'individual', required — The account holder type.
      - `familyName` string — Surname or family name of the individual.
      - `initials` string — Initials of the account holder (e.g. "JP" for Jonathan Paul).
      - `phone` string — Phone number to verify against the account holder details, if available.
      - `email` string, email — Email address to verify against the account holder details, if available.
      - `identifyingDocument` object, required — The identifying document for the individual. The `country` field is an ISO 3166-1 alpha-2 code and defaults to `ZA` because BAVS today is a South African–only service; the field is exposed for forward compatibility and parity with the upstream `CountryCode` contract.
        - `type` 'identity_document' | 'passport', required — The type of identifying document.
        - `country` string — ISO 3166-1 alpha-2 country code where the document was issued. Defaults to `ZA` for South Africa.
        - `number` string, required — The document number.
    - object — A business account holder. Business verification is for South African registered businesses only today; the `country` field is exposed for parity with the upstream `BusinessRegistrationInput` contract.
      - `type` 'business', required — The account holder type.
      - `registrationNumber` string, required — The South African business registration number.
      - `country` string — ISO 3166-1 alpha-2 country code where the business is registered. Defaults to `ZA` for South Africa.
      - `name` string — The registered business name.
      - `phone` string — Phone number to verify against the account holder details, if available.
      - `email` string, email — Email address to verify against the account holder details, if available.

## Response `200`

Verification completed successfully. The response contains the verification results.

- BankAccountVerification — A bank account verification resource.
  - `id` string, required — The unique identifier for this bank account verification. Formatted as `bav_` followed by a 22-character base62 identifier.
  - `bankAccount` VerifiedBankAccount, required — The bank account as resolved by the verification provider.
    - `bank` string, nullable — The bank where the account is held. May be `null` if the account is invalid or cannot be verified.
    - `branchCode` string, nullable — The branch code of the bank account. May be `null` if the account is invalid or cannot be verified.
    - `number` string, nullable — The bank account number that was verified. May be `null` if the account is invalid or cannot be verified.
    - `type` string, nullable — The type of bank account. May be `null` if the account is invalid or cannot be verified.
  - `accountHolder` union, required — The verified account holder details. Either an individual or a business. Mirrors the request `accountHolder` shape — per-check verdicts live on the `verificationResult.accountHolder` sub-object on the verification resource.
    - object — A verified individual account holder.
      - `type` 'individual', required — The type of account holder.
      - `familyName` string — The family name (surname) of the account holder. Omitted if the caller did not provide a `familyName` in the request and the bank did not return one.
      - `initials` string — The initials of the account holder. Omitted if the caller did not provide `initials` in the request and the bank did not return any.
      - `identifyingDocument` object — The identifying document details. Omitted when the bank did not return a document.
        - `type` 'identity_document' | 'passport', required — The type of identifying document.
        - `country` string, required — ISO 3166-1 alpha-2 country code of the document. Bank account verification is a South African–only service, so in practice this is typically `ZA`. The field reflects whatever the upstream verification returned and is not normalized.
        - `number` string, required — The document number.
    - object — A verified business account holder.
      - `type` 'business', required — The type of account holder.
      - `registrationNumber` string — The registration number of the business. Omitted if the bank did not return one.
      - `country` string — ISO 3166-1 alpha-2 country code where the business is registered. Echoed from the request when supplied.
      - `name` string — The registered name of the business. Omitted if the bank did not return one.
  - `verificationResult` object, required — The verification outcome. The shape mirrors the request: `bankAccount` and `accountHolder` sub-objects carry the per-check verdicts for the corresponding fields in the request. `outcome` is the rolled-up decision. **Outcome derivation:** `outcome` is `refuted` if any per-field verdict under `bankAccount` or `accountHolder` is `refuted`, OR if the bank tells us the account is closed (`bankAccount.isOpen === false`) — a closed account is treated as not safely usable even when every identity/account-holder check passes. Otherwise `outcome` is `indeterminate` if any verdict is `indeterminate` and none are `refuted`; otherwise `verified`. **Verdict values:** every verdict is one of `verified`, `refuted`, or `indeterminate` — never `null`. `indeterminate` is used when the bank could not perform the check (or when the caller did not supply the input needed to perform it). **Bank-returned facts:** `isOpen`, `isOpenForMoreThanThreeMonths`, `acceptsDebits`, and `acceptsCredits` are `boolean | null`. `null` means the bank did not return a value (typical when `outcome` is `indeterminate`). The `outcome` override above only fires on an explicit `false` for `isOpen`, not on `null`.
    - `outcome` 'verified' | 'refuted' | 'indeterminate', required — The outcome of a single verification check. `verified` indicates the data matched, `refuted` indicates it did not match, and `indeterminate` indicates the check could not be performed conclusively (e.g. the bank does not support the check, the upstream system is unavailable, or the field was not provided).
    - `bankAccount` object, required — Per-check verdicts and bank-returned facts for the bank account.
      - `exists` 'verified' | 'refuted' | 'indeterminate', required — The outcome of a single verification check. `verified` indicates the data matched, `refuted` indicates it did not match, and `indeterminate` indicates the check could not be performed conclusively (e.g. the bank does not support the check, the upstream system is unavailable, or the field was not provided).
      - `typeMatch` 'verified' | 'refuted' | 'indeterminate', required — The outcome of a single verification check. `verified` indicates the data matched, `refuted` indicates it did not match, and `indeterminate` indicates the check could not be performed conclusively (e.g. the bank does not support the check, the upstream system is unavailable, or the field was not provided).
      - `isOpen` boolean, nullable, required — Whether the account is currently open. `null` when the bank did not return a value.
      - `isOpenForMoreThanThreeMonths` boolean, nullable, required — Whether the account has been open for more than three months. `null` when the bank did not return a value.
      - `acceptsDebits` boolean, nullable, required — Whether the account accepts debit transactions. `null` when the bank did not return a value.
      - `acceptsCredits` boolean, nullable, required — Whether the account accepts credit transactions. `null` when the bank did not return a value.
    - `accountHolder` union, required
      - object — Per-check verdicts for an individual account holder.
        - `identifyingDocument` 'verified' | 'refuted' | 'indeterminate', required — The outcome of a single verification check. `verified` indicates the data matched, `refuted` indicates it did not match, and `indeterminate` indicates the check could not be performed conclusively (e.g. the bank does not support the check, the upstream system is unavailable, or the field was not provided).
        - `familyName` 'verified' | 'refuted' | 'indeterminate', required — The outcome of a single verification check. `verified` indicates the data matched, `refuted` indicates it did not match, and `indeterminate` indicates the check could not be performed conclusively (e.g. the bank does not support the check, the upstream system is unavailable, or the field was not provided).
        - `initials` 'verified' | 'refuted' | 'indeterminate', required — The outcome of a single verification check. `verified` indicates the data matched, `refuted` indicates it did not match, and `indeterminate` indicates the check could not be performed conclusively (e.g. the bank does not support the check, the upstream system is unavailable, or the field was not provided).
        - `phone` 'verified' | 'refuted' | 'indeterminate', required — The outcome of a single verification check. `verified` indicates the data matched, `refuted` indicates it did not match, and `indeterminate` indicates the check could not be performed conclusively (e.g. the bank does not support the check, the upstream system is unavailable, or the field was not provided).
        - `email` 'verified' | 'refuted' | 'indeterminate', required — The outcome of a single verification check. `verified` indicates the data matched, `refuted` indicates it did not match, and `indeterminate` indicates the check could not be performed conclusively (e.g. the bank does not support the check, the upstream system is unavailable, or the field was not provided).
      - object — Per-check verdicts for a business account holder.
        - `registrationNumber` 'verified' | 'refuted' | 'indeterminate', required — The outcome of a single verification check. `verified` indicates the data matched, `refuted` indicates it did not match, and `indeterminate` indicates the check could not be performed conclusively (e.g. the bank does not support the check, the upstream system is unavailable, or the field was not provided).
        - `name` 'verified' | 'refuted' | 'indeterminate', required — The outcome of a single verification check. `verified` indicates the data matched, `refuted` indicates it did not match, and `indeterminate` indicates the check could not be performed conclusively (e.g. the bank does not support the check, the upstream system is unavailable, or the field was not provided).
        - `phone` 'verified' | 'refuted' | 'indeterminate', required — The outcome of a single verification check. `verified` indicates the data matched, `refuted` indicates it did not match, and `indeterminate` indicates the check could not be performed conclusively (e.g. the bank does not support the check, the upstream system is unavailable, or the field was not provided).
        - `email` 'verified' | 'refuted' | 'indeterminate', required — The outcome of a single verification check. `verified` indicates the data matched, `refuted` indicates it did not match, and `indeterminate` indicates the check could not be performed conclusively (e.g. the bank does not support the check, the upstream system is unavailable, or the field was not provided).
  - `createdAt` string, date-time, required — The UTC timestamp indicating when the bank account verification was created. Formatted as an ISO 8601 string (e.g., `2024-01-15T09:30:00Z`).
  - `updatedAt` string, date-time, required — The UTC timestamp indicating when the bank account verification was last modified. Bank account verifications are immutable, so this value always matches `createdAt`. Included to align with the standard v2 resource shape.

## Other responses

- `202` — Verification is in progress. Resubmit the same request to check for results.
- `400` — Bad request. The request body is malformed or fails schema validation.
- `401` — Unauthorized. The access token is missing, expired, or invalid.
- `403` — Forbidden. The access token does not have the required scope.
- `422` — Verification error. The request was valid but the verification could not be completed due to a business logic error.
- `503` — Service unavailable. The verification service is temporarily unavailable for maintenance.

---

[API](https://skmtc.dev/stitch/apis/stitch-api.md) · [All operations](https://skmtc.dev/stitch/apis/stitch-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/stitch/stitch-api/revisions/8c5a258567d0/schema)
