External bank counterparty
Use counterpartyType: "EXTERNAL_BANK" when the other party holds an account at another financial institution, in
your country or abroad. accountName is required. A request without it is rejected with
counterparty.accountName is required for this counterparty type.
| Field | Required | What it means | Why it matters for monitoring |
|---|---|---|---|
counterpartyType | Yes | EXTERNAL_BANK. | Selects the counterparty rules and the required name field. |
accountName | Yes | The beneficiary's or sender's account name. | Shown to analysts, and used as the name for PEP and sanction screening when no personal or company name is sent. |
accountNumber | No | The account at the other bank. | Rules can count how many of your customers pay the same account. It can also match an account on your blacklist. |
institutionCode | No | Your code for the other institution, such as a NIP institution code or a BIC. | Can match an institution code on your blacklist, and supports rules on specific institutions. |
accountType | No | Your label for the account type. | Rules can target specific account types. |
iban | No | The international account number. | Rules check whether an IBAN is present. |
country | No | Two-letter ISO 3166-1 code, such as NG or GB. | Country and high-risk jurisdiction rules. Can match a country on your blacklist. |
counterpartyFingerprint | No | Your own stable token for this counterparty. | Lets rules follow the same counterparty even when its account details vary. |
counterparty.country accepts only two-letter codes. Lowercase is accepted and stored in uppercase, so gb becomes
GB. Three-letter codes such as GBR are rejected with counterparty.country must be an ISO 3166-1 alpha-2 country code.
Domestic transfer through NIP
POST /api/transactions
Authorization: Bearer <oneview-service-account-api-key>
Content-Type: application/json
{
"transactionReference": "TXN-20260921-000201",
"externalReference": "NIP-000000000000000201",
"direction": "OUTBOUND",
"accountHolderType": "CUSTOMER",
"paymentMethod": "NIP",
"channel": "USSD",
"status": "POSTED",
"isCrossBorder": false,
"amount": "95000.00",
"currency": "NGN",
"feeAmount": "26.88",
"taxAmount": "2.02",
"narration": "School fees first term",
"executedAt": "2026-09-21T08:12:44Z",
"accountHolder": {
"customerUniqueId": "CUS-100231",
"accountNumber": "0012345678",
"accountName": "Ada Demo Okafor",
"riskLevel": "LOW"
},
"counterparty": {
"counterpartyType": "EXTERNAL_BANK",
"accountName": "Demo Academy Limited",
"accountNumber": "9000000010",
"institutionCode": "999999",
"accountType": "CURRENT",
"country": "NG"
},
"telemetry": {
"sessionId": "ussd-session-000000201",
"country": "NG"
}
}
externalReferenceholds the switch or session reference from the rail. It helps analysts reconcile the transaction with the NIP record. It uses the same characters astransactionReference, up to 128 characters.isCrossBorderisfalseand the currency is the base currency, so no exchange rate is needed.feeAmountandtaxAmountare charged in addition toamount. They default to"0".
Inbound transfer from another bank
Reverse direction and describe the sender as the counterparty. The account holder stays your customer, who receives
the money.
POST /api/transactions
Authorization: Bearer <oneview-service-account-api-key>
Content-Type: application/json
{
"transactionReference": "TXN-20260921-000202",
"externalReference": "NIP-000000000000000202",
"direction": "INBOUND",
"accountHolderType": "CUSTOMER",
"paymentMethod": "NIP",
"channel": "CORE_BANKING",
"status": "POSTED",
"isCrossBorder": false,
"amount": "600000.00",
"currency": "NGN",
"narration": "Payment for goods",
"executedAt": "2026-09-21T10:40:09Z",
"accountHolder": {
"customerUniqueId": "CUS-100231",
"accountNumber": "0012345678",
"accountName": "Ada Demo Okafor"
},
"counterparty": {
"counterpartyType": "EXTERNAL_BANK",
"accountName": "Chidi Demo Nwosu",
"accountNumber": "9000000011",
"institutionCode": "999998",
"country": "NG"
}
}
Cross-border payment through SWIFT
A corporate customer pays a supplier in Germany in euros.
POST /api/transactions
Authorization: Bearer <oneview-service-account-api-key>
Content-Type: application/json
{
"transactionReference": "SWF-20260921-000031",
"externalReference": "MT103-DEMO-000031",
"direction": "OUTBOUND",
"accountHolderType": "CUSTOMER",
"paymentMethod": "SWIFT",
"channel": "INTERNET_BANKING",
"status": "PENDING",
"isCrossBorder": true,
"amount": "2500.00",
"currency": "EUR",
"usdExchangeRate": "0.92",
"feeAmount": "25.00",
"narration": "Machine spare parts order PO-2026-117",
"sourceOfFunds": "BUSINESS_REVENUE",
"remittancePurposeCode": "GOODS_IMPORT",
"executedAt": "2026-09-21T12:10:00Z",
"accountHolder": {
"customerUniqueId": "CUS-500871",
"entityType": "CORPORATE",
"accountNumber": "0012345681",
"accountName": "Demo Logistics Limited",
"companyName": "Demo Logistics Limited",
"riskLevel": "MEDIUM",
"country": "NG"
},
"counterparty": {
"counterpartyType": "EXTERNAL_BANK",
"accountName": "Demo Maschinenbau GmbH",
"iban": "DE00999900001234567890",
"institutionCode": "DEMODEFFXXX",
"country": "DE"
}
}
| Field | What it means | Why it matters for monitoring |
|---|---|---|
isCrossBorder | true: the money leaves the country. | Cross-border rules, and it makes usdExchangeRate required for any currency other than USD. |
currency | EUR, which differs from the NGN base currency. | OneView marks the transaction as foreign-currency. That is derived, never sent. |
usdExchangeRate | Units of the transaction currency per 1 USD. | OneView converts the amount to USD so that one threshold works across every currency. |
remittancePurposeCode | Your purpose code for the payment, up to 32 characters. | Purpose-based rules and reporting. |
status | PENDING while the payment is not yet released. | Your lifecycle status only. |
counterparty.iban | The beneficiary IBAN. | Rules can check that an IBAN is present. |
counterparty.country | DE, a two-letter code. | Country and high-risk jurisdiction rules. |
The exchange rate direction
usdExchangeRate is how many units of the transaction currency buy 1 USD. OneView calculates the USD amount as
amount / usdExchangeRate, rounded to 4 decimal places.
EUR 2500.00at0.92EUR per USD is2500.00 / 0.92 = 2717.3913USD.EUR 100.00at0.92is108.6957USD.NGN 155050.00at1550.5NGN per USD is100.0000USD.
If you send the inverse rate by mistake, such as 1.087 USD per EUR, every USD threshold is wrong by the square of
the rate. For naira that error is enormous, so check the direction before going live.
Rules for the rate:
- The rate must be greater than zero, with up to 10 whole digits and 8 decimal places. Send it as a string.
- When
currencyisUSD, the rate is always1. You can omit it, and any other value is rejected. - For any other currency, the rate is required when
isCrossBorderistrueor when the currency differs from your base currency. If you send a rate when it is not required, OneView still uses it. - The USD amount is not returned in the ingest response.
A cross-border payment in the base currency still needs a rate. For example, an NGN payment to a beneficiary
abroad with isCrossBorder: true must include a rate such as "1550.5".
Response
This is the response to the domestic NIP transfer above:
{
"status": true,
"message": "Transaction evaluated",
"data": {
"transaction": {
"id": "3c9a7e12-6b4d-4f80-a1e5-9d2c0f7b3a68",
"transactionReference": "TXN-20260921-000201",
"direction": "OUTBOUND",
"receivedAt": "2026-09-21T08:12:44.918Z",
"replayed": false
},
"decision": {
"outcome": "PASS",
"riskScore": 0,
"evaluatedAt": "2026-09-21T08:12:44.930Z",
"evaluationMs": 7.806,
"complete": true,
"rulesEvaluated": 18,
"rulesetSnapshot": "9ffa3b395a9799b1a1104ab1b536ed1667b487510829ceefc27593941fafb35e",
"gradingVersion": 3,
"triggeredRules": []
}
}
}
Status is 201 for a new transaction, 200 for a replay. usdAmount, even when calculated from usdExchangeRate
for the SWIFT example, is never included in this response — it is visible to analysts in OneView, not returned to
the caller. See Decision responses for every outcome.
Errors specific to an external bank counterparty
| Cause | field | code | message |
|---|---|---|---|
No accountName | counterparty | required | counterparty.accountName is required for this counterparty type |
counterparty.country is a three-letter or unassigned code | counterparty.country | invalid | counterparty.country must be an ISO 3166-1 alpha-2 country code |
A non-USD, cross-border or foreign-currency transaction has no usdExchangeRate | usdExchangeRate | required | usdExchangeRate is required for cross-border or foreign-currency transactions |
usdExchangeRate is 0 or negative | usdExchangeRate | invalid | usdExchangeRate must be greater than zero |
usdExchangeRate is so small that the derived USD amount exceeds 14 whole digits | usdExchangeRate | invalid | usdExchangeRate is too small for this amount: the derived USD amount would exceed 14 whole digits |
This last error is usually a sign the rate was sent inverted — see The exchange rate direction above. See Errors for the complete catalogue.
Idempotency
Deduplication is by transactionReference and direction, the same as every transaction type. A resubmitted
identical body returns 200 with replayed: true without re-evaluating the payment or re-converting the exchange
rate. A resubmitted different body, for example a corrected usdExchangeRate under the same reference, is rejected
with 409 IDEMPOTENCY_CONFLICT — give a corrected retry a new reference instead. See Idempotency in
Submitting transactions.