South Africa's first Open Banking platform providing RESTful APIs for accounts, payments, instant EFT transfers, and digital wallet services using OAuth 2.0 authentication.
Nedbank API Marketplace is South Africa's first Open Banking platform, making it the first bank in Africa to provide APIs meeting open banking standards and PSD2 compliance. The marketplace offers a comprehensive suite of RESTful APIs that enable third-party developers and fintech partners to integrate with Nedbank's banking services securely. Whether you need to retrieve account information, initiate payments, or offer instant EFT transfers, Nedbank's API Marketplace provides production-grade banking APIs with industry-standard OAuth 2.0 security.
All Nedbank APIs use OAuth 2.0 as the primary authentication mechanism, providing secure, standardized authorization flows for developers.
The standard three-legged OAuth 2.0 flow is used for accessing customer-specific data:
1. Authorization Request
User is redirected to Nedbank's authorization endpoint
2. User Grants Consent
Customer authenticates and approves access scopes
3. Authorization Code Exchange
Your application exchanges the code for access token
4. API Requests
Use the access token to call protected APIs
POST https://api.nedbank.co.za/apimarket/sandbox/nboauth/oauth20/token
Per RFC 7636 (and mandatory per RFC 9700 for public clients), the authorization code flow should be paired with PKCE. Generate a code_verifier (random string, 43–128 characters), hash it as code_challenge, and include in the authorization request:
# Authorization request (include these query params)
code_challenge=BASE64URL(SHA256(code_verifier))
code_challenge_method=S256
# Token exchange (include code_verifier for server to verify)
code_verifier=YOUR_RANDOM_VERIFIER_STRING
const crypto = require('crypto');
function generatePKCE() {
const verifier = crypto.randomBytes(32).toString('base64url');
const challenge = crypto.createHash('sha256').update(verifier).digest('base64url');
return { verifier, challenge };
}
Confirm PKCE support with Nedbank's API portal — check whether your app type (confidential server-side vs public SPA/mobile) requires PKCE in their current implementation.
curl -X POST https://api.nedbank.co.za/apimarket/sandbox/nboauth/oauth20/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "code=AUTH_CODE_FROM_REDIRECT" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET" \
-d "redirect_uri=YOUR_REDIRECT_URI" \
-d "code_verifier=YOUR_CODE_VERIFIER"
You must subscribe to the Authorization API and Subscription API before integrating with any other APIs. Common scopes include:
accounts - Access account information and balancestransactions - Retrieve transaction historypayments - Initiate payment instructionscustomer - Access customer profile informationSecure API responses include:
x-jws-signature - JWS signature for payload verificationx-fapi-interaction-id - RFC4122 UID used as correlation identifier for request trackingRetrieve account information including balances, details, and transaction history.
Base URL: https://api.nedbank.co.za/apimarket/sandbox/open-banking
GET /v3.1/accounts HTTP/1.1
Host: api.nedbank.co.za
Authorization: Bearer {access_token}
x-fapi-interaction-id: {UUID}
Response (200 OK):
{
"Data": {
"Account": [
{
"AccountId": "50089234",
"Currency": "ZAR",
"Name": "Mr Kevin",
"Subtype": "CurrentAccount",
"Type": "Personal",
"Account": [
{
"SchemeName": "SortCodeAccountNumber",
"Identification": "40400140898283",
"Name": "Mr Kevin",
"SecondaryIdentification": "00002"
}
]
}
]
},
"Links": {
"Self": "https://api.nedbank.co.za/apimarket/sandbox/open-banking/v3.1/accounts"
},
"Meta": {
"TotalPages": 1
}
}
GET /v3.1/accounts/{AccountId}/balances HTTP/1.1
Host: api.nedbank.co.za
Authorization: Bearer {access_token}
x-fapi-interaction-id: {UUID}
Response (200 OK):
{
"Data": {
"Balance": [
{
"Amount": {
"Amount": "1230.00",
"Currency": "ZAR"
},
"CreditDebitIndicator": "Credit",
"Type": "Closing Available"
}
]
},
"Links": {
"Self": "https://api.nedbank.co.za/apimarket/sandbox/open-banking/v3.1/accounts/50089234/balances"
},
"Meta": {
"TotalPages": 1
}
}
GET /v3.1/accounts/{AccountId}/transactions HTTP/1.1
Host: api.nedbank.co.za
Authorization: Bearer {access_token}
x-fapi-interaction-id: {UUID}
Query Parameters:
fromBookingDateTime (optional) - ISO 8601 format: 2024-01-01T00:00:00ZtoBookingDateTime (optional) - ISO 8601 format: 2024-12-31T23:59:59ZResponse (200 OK):
{
"Data": {
"Transaction": [
{
"AccountId": "50089234",
"TransactionId": "TXN123456",
"CreditDebitIndicator": "Credit",
"Status": "Booked",
"BookingDateTime": "2024-01-15T10:30:00Z",
"ValueDateTime": "2024-01-15T10:30:00Z",
"Amount": {
"Amount": "150.50",
"Currency": "ZAR"
},
"Description": "Salary Payment",
"TransactionInformation": "Monthly Salary",
"SupplementaryData": {
"Reference": "SAL-2024-01"
}
}
]
},
"Links": {
"Self": "https://api.nedbank.co.za/apimarket/sandbox/open-banking/v3.1/accounts/50089234/transactions"
},
"Meta": {
"TotalPages": 1
}
}
Initiate payments to any bank account or between Nedbank accounts.
POST /v3.1/pisp/domestic-payment-consents HTTP/1.1
Host: api.nedbank.co.za
Content-Type: application/json
Authorization: Bearer {access_token}
x-fapi-interaction-id: {UUID}
Request Body:
{
"Data": {
"Initiation": {
"InstructionIdentification": "PAY-20240115-001",
"EndToEndIdentification": "E2E-REF-123",
"LocalInstrument": "UK.OBIE.SortCodeAccountNumber",
"DebtorAccount": {
"SchemeName": "SortCodeAccountNumber",
"Identification": "40400140898283",
"Name": "Mr Kevin",
"SecondaryIdentification": "00002"
},
"CreditorAccount": {
"SchemeName": "SortCodeAccountNumber",
"Identification": "20000136000000",
"Name": "Jane Doe"
},
"InstructedAmount": {
"Amount": "500.00",
"Currency": "ZAR"
},
"RemittanceInformation": {
"Unstructured": "Invoice Payment #12345"
}
}
},
"Risk": {
"PaymentContextCode": "ECommerce"
}
}
Response (201 Created):
{
"Data": {
"ConsentId": "CONS-20240115-0001",
"CreationDateTime": "2024-01-15T10:30:00Z",
"Status": "AwaitingAuthorisation",
"StatusUpdateDateTime": "2024-01-15T10:30:00Z"
},
"Links": {
"Self": "https://api.nedbank.co.za/apimarket/sandbox/open-banking/v3.1/pisp/domestic-payment-consents/CONS-20240115-0001"
},
"Meta": {
"TotalPages": 1
}
}
POST /v3.1/pisp/domestic-payments HTTP/1.1
Host: api.nedbank.co.za
Content-Type: application/json
Authorization: Bearer {access_token}
x-fapi-interaction-id: {UUID}
x-idempotency-key: {IDEMPOTENCY_KEY}
Request Body:
{
"Data": {
"ConsentId": "CONS-20240115-0001",
"Initiation": {
"InstructionIdentification": "PAY-20240115-001",
"EndToEndIdentification": "E2E-REF-123",
"InstructedAmount": {
"Amount": "500.00",
"Currency": "ZAR"
},
"CreditorAccount": {
"SchemeName": "SortCodeAccountNumber",
"Identification": "20000136000000",
"Name": "Jane Doe"
},
"RemittanceInformation": {
"Unstructured": "Invoice Payment #12345"
}
}
},
"Risk": {
"PaymentContextCode": "ECommerce"
}
}
Response (201 Created):
{
"Data": {
"DomesticPaymentId": "DOM-PAY-20240115-001",
"ConsentId": "CONS-20240115-0001",
"CreationDateTime": "2024-01-15T10:35:00Z",
"Status": "AcceptedSettlementInProcess",
"StatusUpdateDateTime": "2024-01-15T10:35:00Z"
},
"Links": {
"Self": "https://api.nedbank.co.za/apimarket/sandbox/open-banking/v3.1/pisp/domestic-payments/DOM-PAY-20240115-001"
},
"Meta": {
"TotalPages": 1
}
}
Enable real-time electronic fund transfers directly from Nedbank accounts using Nedbank Direct EFT.
POST /v1/instant-eft/transfer HTTP/1.1
Host: api.nedbank.co.za
Content-Type: application/json
Authorization: Bearer {access_token}
x-fapi-interaction-id: {UUID}
x-idempotency-key: {IDEMPOTENCY_KEY}
Request Body:
{
"DebtorAccount": {
"AccountNumber": "1234567890",
"AccountHolder": "John Smith"
},
"CreditorAccount": {
"BankCode": "051001",
"AccountNumber": "9876543210",
"AccountHolder": "Jane Doe"
},
"TransactionAmount": {
"Amount": "1500.00",
"Currency": "ZAR"
},
"Reference": "INV-2024-001",
"Description": "Payment for services rendered",
"ChannelIndicator": "Mobile"
}
Response (202 Accepted):
{
"TransactionId": "EFT-20240115-00001",
"Status": "Processing",
"CreatedDate": "2024-01-15T10:40:00Z",
"Amount": {
"Amount": "1500.00",
"Currency": "ZAR"
},
"Reference": "INV-2024-001"
}
Create and manage Nedbank MobiMoney wallet accounts with real-time payment capabilities.
POST /v2.3.0/wallets HTTP/1.1
Host: api.nedbank.co.za
Content-Type: application/json
Authorization: Bearer {access_token}
x-fapi-interaction-id: {UUID}
Request Body:
{
"customerId": "CUST-2024-001",
"walletType": "MobiMoney",
"walletName": "My Nedbank Wallet",
"currency": "ZAR",
"metadata": {
"region": "South Africa"
}
}
Response (201 Created):
{
"walletId": "WAL-20240115-001",
"customerId": "CUST-2024-001",
"walletType": "MobiMoney",
"walletName": "My Nedbank Wallet",
"status": "Active",
"balance": {
"available": "0.00",
"currency": "ZAR"
},
"createdDate": "2024-01-15T10:45:00Z"
}
GET /v2.3.0/wallets/{walletId} HTTP/1.1
Host: api.nedbank.co.za
Authorization: Bearer {access_token}
x-fapi-interaction-id: {UUID}
Response (200 OK):
{
"walletId": "WAL-20240115-001",
"customerId": "CUST-2024-001",
"walletType": "MobiMoney",
"walletName": "My Nedbank Wallet",
"status": "Active",
"balance": {
"available": "2500.00",
"currency": "ZAR"
},
"lastTransactionDate": "2024-01-15T11:30:00Z"
}
POST /v2.3.0/wallets/{walletId}/transfer HTTP/1.1
Host: api.nedbank.co.za
Content-Type: application/json
Authorization: Bearer {access_token}
x-fapi-interaction-id: {UUID}
x-idempotency-key: {IDEMPOTENCY_KEY}
Request Body:
{
"recipientWalletId": "WAL-20240115-002",
"amount": {
"amount": "250.00",
"currency": "ZAR"
},
"reference": "PEER-PAYMENT-001",
"description": "Shared lunch expense"
}
Response (202 Accepted):
{
"transactionId": "TXN-20240115-001",
"fromWalletId": "WAL-20240115-001",
"toWalletId": "WAL-20240115-002",
"amount": {
"amount": "250.00",
"currency": "ZAR"
},
"status": "Pending",
"createdDate": "2024-01-15T11:35:00Z"
}
Access verified customer profile data for KYC/AML compliance.
GET /v1/customer/{customerId} HTTP/1.1
Host: api.nedbank.co.za
Authorization: Bearer {access_token}
x-fapi-interaction-id: {UUID}
Response (200 OK):
{
"CustomerId": "CUST-2024-001",
"FirstName": "John",
"MiddleName": "Michael",
"LastName": "Smith",
"Email": "[email protected]",
"MobileNumber": "+27711234567",
"DateOfBirth": "1985-03-15",
"Nationality": "ZA",
"DocumentType": "NationalId",
"DocumentNumber": "8503151234081",
"ResidentialAddress": {
"AddressLine1": "123 Main Street",
"AddressLine2": "Johannesburg",
"City": "Johannesburg",
"PostalCode": "2000",
"Country": "ZA"
},
"VerificationStatus": "Verified",
"VerificationDate": "2024-01-10T09:00:00Z"
}
Query and manage personal loan applications.
GET /v1/personal-loans HTTP/1.1
Host: api.nedbank.co.za
Authorization: Bearer {access_token}
x-fapi-interaction-id: {UUID}
Response (200 OK):
{
"Data": {
"PersonalLoan": [
{
"PersonalLoanId": "LOAN-20240101-001",
"PLStatus": "Active",
"PLOfferId": "OFFER-12345",
"LoanAmount": {
"Amount": "50000.00",
"Currency": "ZAR"
},
"InterestRate": 10.5,
"LoanTerm": 60,
"MonthlyInstallment": {
"Amount": "943.56",
"Currency": "ZAR"
},
"StartDate": "2024-01-01",
"MaturityDate": "2028-12-31",
"RemainingBalance": {
"Amount": "48500.00",
"Currency": "ZAR"
}
}
]
},
"Links": {
"Self": "https://api.nedbank.co.za/apimarket/sandbox/personal-loans"
},
"Meta": {
"TotalPages": 1
}
}
Retrieve customer rewards points (Greenbacks or Amex Membership Rewards).
GET /v1/rewards/{customerId} HTTP/1.1
Host: api.nedbank.co.za
Authorization: Bearer {access_token}
x-fapi-interaction-id: {UUID}
Response (200 OK):
{
"CustomerId": "CUST-2024-001",
"RewardProgram": "Greenbacks",
"TotalPoints": 15750,
"AvailablePoints": 15750,
"PendingPoints": 0,
"ExpiringPoints": 250,
"ExpiryDate": "2024-12-31T23:59:59Z",
"LastTransactionDate": "2024-01-10T14:20:00Z",
"LastTransactionAmount": 150.00,
"PointsEarned": 15
}
Free APIs providing public banking information without OAuth authentication.
GET /v1/branches HTTP/1.1
Host: api.nedbank.co.za
Response (200 OK):
{
"Data": {
"Branch": [
{
"BranchId": "BRANCH-JNB-001",
"BranchCode": "051001",
"BranchName": "Johannesburg Main",
"Address": "100 Grayston Drive, Johannesburg, 2146",
"City": "Johannesburg",
"Province": "Gauteng",
"PostalCode": "2146",
"Phone": "+27113214567",
"OperatingHours": {
"Monday": "08:00-16:00",
"Tuesday": "08:00-16:00",
"Wednesday": "08:00-16:00",
"Thursday": "08:00-16:00",
"Friday": "08:00-16:00",
"Saturday": "09:00-13:00"
}
}
]
}
}
GET /v1/banks HTTP/1.1
Host: api.nedbank.co.za
Response (200 OK):
{
"Data": {
"Bank": [
{
"BankId": "BANK-ZA-001",
"BankCode": "051001",
"BankName": "Nedbank Limited",
"Country": "ZA",
"Established": 1888
}
]
}
}
Nedbank APIs support event-driven integrations through webhooks for asynchronous notifications. Configure webhook endpoints in your developer portal to receive real-time notifications about:
{
"eventId": "EVT-20240115-001",
"eventType": "payment.status.updated",
"timestamp": "2024-01-15T10:50:00Z",
"resourceId": "DOM-PAY-20240115-001",
"data": {
"status": "AcceptedSettlementInProcess",
"previousStatus": "AwaitingAuthorisation",
"amount": {
"amount": "500.00",
"currency": "ZAR"
}
}
}
Register webhooks in the Nedbank API Marketplace developer portal:
200 OK within 10 secondsA simple read-only integration to display customer account information:
async function getAccountBalance(accountId, accessToken) {
const response = await fetch(
`https://api.nedbank.co.za/apimarket/sandbox/open-banking/v3.1/accounts/${accountId}/balances`,
{
method: 'GET',
headers: {
'Authorization': `Bearer ${accessToken}`,
'x-fapi-interaction-id': generateUUID()
}
}
);
const data = await response.json();
return data.Data.Balance[0].Amount;
}
A complete payment flow with user authorization:
// Step 1: Create payment consent
async function createPaymentConsent(paymentDetails, accessToken) {
const response = await fetch(
'https://api.nedbank.co.za/apimarket/sandbox/open-banking/v3.1/pisp/domestic-payment-consents',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${accessToken}`,
'x-fapi-interaction-id': generateUUID()
},
body: JSON.stringify({
Data: {
Initiation: {
InstructionIdentification: paymentDetails.reference,
InstructedAmount: {
Amount: paymentDetails.amount,
Currency: 'ZAR'
},
CreditorAccount: {
SchemeName: 'SortCodeAccountNumber',
Identification: paymentDetails.recipientAccount
}
}
}
})
}
);
return await response.json();
}
// Step 2: Submit payment after user authorization
async function submitPayment(consentId, accessToken, idempotencyKey) {
const response = await fetch(
'https://api.nedbank.co.za/apimarket/sandbox/open-banking/v3.1/pisp/domestic-payments',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${accessToken}`,
'x-fapi-interaction-id': generateUUID(),
'x-idempotency-key': idempotencyKey
},
body: JSON.stringify({
Data: { ConsentId: consentId }
})
}
);
return await response.json();
}
Peer-to-peer wallet payments:
async function transferBetweenWallets(sourceWalletId, targetWalletId, amount, accessToken) {
const response = await fetch(
`https://api.nedbank.co.za/apimarket/sandbox/v2.3.0/wallets/${sourceWalletId}/transfer`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${accessToken}`,
'x-fapi-interaction-id': generateUUID(),
'x-idempotency-key': generateUUID()
},
body: JSON.stringify({
recipientWalletId: targetWalletId,
amount: {
amount: amount.toString(),
currency: 'ZAR'
},
reference: generateReference()
})
}
);
return await response.json();
}
Initiate real-time bank transfers:
async function initiateInstantEFT(debtorAccount, creditorAccount, amount, accessToken) {
const response = await fetch(
'https://api.nedbank.co.za/apimarket/sandbox/v1/instant-eft/transfer',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${accessToken}`,
'x-fapi-interaction-id': generateUUID(),
'x-idempotency-key': generateUUID()
},
body: JSON.stringify({
DebtorAccount: debtorAccount,
CreditorAccount: creditorAccount,
TransactionAmount: {
Amount: amount.toString(),
Currency: 'ZAR'
},
ChannelIndicator: 'Mobile'
})
}
);
return await response.json();
}
Nedbank APIs use standard HTTP status codes with detailed error responses. Always implement proper error handling in production:
{
"Errors": [
{
"ErrorCode": "UK.OBIE.Field.Invalid",
"Message": "Invalid account number",
"Path": "Data.Initiation.CreditorAccount.Identification",
"Url": "https://openbanking.atlassian.net/wiki/display/DZ/Data+Validation+Errors"
}
]
}
async function callNebankAPI(url, options) {
const maxRetries = 3;
let retryCount = 0;
while (retryCount < maxRetries) {
try {
const response = await fetch(url, options);
if (response.ok) {
return await response.json();
}
if (response.status === 429) {
// Rate limited - wait and retry
const retryAfter = response.headers.get('Retry-After') || 60;
await sleep(parseInt(retryAfter) * 1000);
retryCount++;
continue;
}
if (response.status >= 500) {
// Server error - retry with backoff
await sleep(Math.pow(2, retryCount) * 1000);
retryCount++;
continue;
}
// Client error - don't retry
const errorData = await response.json();
throw new Error(`API Error (${response.status}): ${JSON.stringify(errorData.Errors)}`);
} catch (error) {
if (retryCount === maxRetries - 1) throw error;
retryCount++;
}
}
}
Partnership Registration Required - You must register as a Nedbank API partner before accessing production APIs. Use the "Register your interest" button on https://apim.nedbank.co.za/ and a sales consultant will contact you with onboarding details.
Sandbox vs Production - Always test thoroughly in the sandbox environment (https://api.nedbank.co.za/apimarket/sandbox/) before moving to production. Sandbox and production use separate OAuth credentials and have isolated data.
ZAR Currency Default - All Nedbank APIs in South Africa operate in ZAR (South African Rand). Specify currency explicitly in requests: "Currency": "ZAR". Amounts must be formatted as strings with two decimal places: "Amount": "1500.00".
OAuth Token Expiration - Access tokens have limited lifetimes (typically 1 hour). Implement token refresh logic to obtain new tokens when expired using the refresh_token grant type:
grant_type=refresh_token&refresh_token=YOUR_REFRESH_TOKEN
Idempotency Keys Required for Payments - Always include a unique x-idempotency-key header when initiating payments or transfers to prevent duplicate submissions if requests are retried. Use a UUID or hash of the transaction details.
Subscription Required for Each API - You must explicitly subscribe to each API you want to use in the developer portal. You cannot use APIs without an active subscription. This includes the Authorization API, which is required before using any other APIs.
Rate Limits Applied Per App - Nedbank reserves the right to enforce rate limits on API calls. The platform tracks usage per application, and limits can be enforced by number of requests, frequency, currency amounts, data volume, or other metrics. Monitor your API usage in the developer portal dashboard.
Account Identification Schemes - Different APIs support different account identification schemes. For South African accounts, use "SchemeName": "SortCodeAccountNumber" or "SchemeName": "IBAN" for international accounts. Reference the specific API documentation for supported schemes.
User Authorization Required for Account Data - Accessing customer account information and transaction history requires explicit user consent through the OAuth authorization flow. Users must authenticate and approve specific data scopes before your app can access their accounts.
Webhook Endpoint Requirements - Webhook endpoints must be publicly accessible HTTPS URLs that respond with 200 OK within 10 seconds. Implement exponential backoff if your endpoint is temporarily unavailable. Nedbank will retry failed webhook deliveries up to 5 times.
PSD2 Compliance - Nedbank's API Marketplace is PSD2-compliant for applicable APIs. This means specific transaction limits may apply, and Strong Customer Authentication (SCA) may be required for sensitive operations. Consult the PSD2 section of the documentation for your jurisdiction.
Data Retention and Privacy - Customer data accessed through Nedbank APIs is governed by South African data protection laws and Nedbank's privacy policy. Only request and retain necessary data, obtain explicit consent for data usage, and securely store credentials and access tokens.
Additional Products Not Documented Here - Nedbank's API Marketplace includes products beyond what this skill covers: InstantMoney (voucher-based cash transfers without a bank account) and MobiMoney (mobile wallet). These newer products have separate API endpoints and flows. Check https://apim.nedbank.co.za/static/products for the full API catalogue and request access through the portal.
Last Updated: February 2026
Compatibility: OAuth 2.0, REST APIs, JSON request/response format
Supported Regions: South Africa, Namibia, Lesotho, eSwatini (for EFT services)
Sandbox Base URL: https://api.nedbank.co.za/apimarket/sandbox/
Portal URL: https://apim.nedbank.co.za/