NPO Bank Account Verification API
Match the full NPO name to an open bank account. Registration or ID number is optional.
Use the full NPO name. Use the full NPO name recorded by the bank for the account-name check. Abbreviated account labels can return a name mismatch.
This is an asynchronous check. POST /api/external/npo-bank-account-verification returns HTTP 202 with a job ID. Read the saved result or receive a signed webhook when bank processing finishes. Processing can take several hours or the next banking window.
Request
Send x-api-key, Content-Type: application/json and a fresh Idempotency-Key for a new check. Keep the same key and body when retrying an uncertain submission.
{
"companyName": "Example Community Organisation",
"bankName": "ABSA",
"bankAccountNumber": "1234567889",
"bankBranchCode": "632005",
"bankAccountType": "current",
"consentConfirmed": true,
"purpose": "Verify the organisation bank account",
"webhookUrl": "https://your-domain.example/webhooks/verifynow",
"webhookSecret": "replace-with-your-own-secret-at-least-32-characters",
"mode": "sandbox"
}idnumber is optional; companyRegistrationNumber is an alias. If both are supplied, their values must agree. Enter the registration/ID number held by the bank when available. Omitted fields are reported as Not provided.
The account number must contain 7–13 digits and the branch code six digits. The endpoint accepts the bank name and branch code supplied; supported coverage depends on the bank. Name (up to 160 characters), initials and account type may be omitted, but a name match is required for a verified outcome. Account types: current, cheque, savings, transmission, bond, credit-card or unknown.
consentConfirmed must be true. Purpose is 3–160 characters; webhookSecret is 32–256 characters. Supply a public HTTPS webhook URL. Mode is sandbox or production.
Result and missing ID
Verified means the account was found, is open and matches the full NPO name. A supplied account type or identifier must also match. An omitted ID remains Not provided and does not cause review. Missing or mismatched required checks return review.
{
"id": "evt_00000000000040008000000000000001",
"type": "npo_bank.verification.completed",
"createdAt": "2026-10-29T10:00:00.000Z",
"data": {
"jobId": "00000000-0000-4000-8000-000000000001",
"status": "completed",
"mode": "production",
"reportType": "npo-bank",
"creditsUsed": 7,
"inputStatus": {
"idnumber": "Not provided",
"companyName": "Provided",
"initials": "Not provided",
"bankAccountType": "Provided"
},
"result": {
"outcome": "verified",
"inputStatus": {
"idnumber": "Not provided",
"companyName": "Provided",
"initials": "Not provided",
"bankAccountType": "Provided"
},
"checks": {
"accountFound": true,
"accountOpen": true,
"surnameMatch": true,
"accountTypeMatch": true,
"companyRegistrationMatch": "Not provided",
"initialsMatch": "Not provided",
"accountNumberLengthValid": true,
"acceptsCredits": true,
"acceptsDebits": true
},
"bank": {
"name": "ABSA",
"accountNumberLast4": "7889"
}
}
}
}Status and webhook recovery
GET /api/external/npo-bank-account-verification/jobs/{jobId} returns the owned job and its result at zero credits. Results are withheld while billing is pending.
POST /api/external/npo-bank-account-verification/jobs/{jobId}/retry-webhook with {} redelivers the saved result. Supply both webhook fields to change the receiver. It does not create another bank enquiry.
Events are npo_bank.verification.completed and npo_bank.verification.failed. Verify the HMAC-SHA256 signature over the timestamp and raw body, reject stale timestamps and deduplicate event IDs. Follow the bank webhook guide for signing and recovery. A job without a final result times out after 48 hours.
Sandbox and billing
Sandbox uses synthetic data and zero credits. Account numbers ending in 90 return review; 91 simulates a submission failure. Other valid sandbox account numbers return positive name/account checks. Missing IDs remain Not provided.
For a specific case, send x-verifynow-sandbox-scenario with mode: sandbox and a fresh Idempotency-Key. This explicit scenario takes precedence over account suffixes. The header is ignored in production.
| Scenario | Outcome | Expected behaviour |
|---|---|---|
| verified_without_id | verified | Use the full name and omit both identifier fields. ID remains Not provided. |
| name_mismatch | review | The supplied NPO name does not match. |
| account_not_found | review | Account found and open are false. |
| closed_account | review | The account is found but closed. |
| account_type_mismatch | review | Supply a known account type; its match is false. |
| identity_mismatch | review | Supply an identifier; its match is false. |
| name_unavailable | review | The bank name-match result is unavailable (null). |
| verification_timed_out | failed | A failed callback carries verification_timed_out. |
Use https://www.verifynow.co.za/api/bank-verification/callback-check as a sandbox receiver with your own signing secret. Your production integration should use its own HTTPS receiver. Poll saved jobs at zero credits.
Production uses the configured NPO service price shown on pricing. Completed results, including review, use credits. Failed verifications use zero customer credits. Keep sufficient credits available until processing finishes.