Skip to content

Authentication

BankCore uses OAuth2 client credentials. The bank issues your organisation a client_id and a client_secret when your partner API client is approved. You exchange them for a bearer token, and you send that token on every other call.

The token carries everything the platform needs to know about you: which tenant you belong to, which scopes you hold, which customer record you act for, and where your fees are charged. Nothing you put in a request body can widen any of that.

POST/api/auth/channel/token

No Authorization header. The body is JSON.

Field Type Required Description
client_id string Yes Your client id, for example pa_ab12cd34. Shown on the API access page of the partner portal.
client_secret string Yes The secret issued with it. Never shown again after issue.
Terminal window
curl -X POST https://api.bankcore.ng/api/auth/channel/token \
-H "Content-Type: application/json" \
-d '{
"client_id": "pa_ab12cd34",
"client_secret": "sk_live_xxxxxxxxxxxxxxxxxxxx"
}'
{
"access_token": "eyJhbGciOiJIUzI1NiJ9.eyJjbGllbnRJZCI6InBhX2FiMTJjZDM0Iiwi...",
"token_type": "Bearer",
"expires_in": 1800,
"channel": "API",
"client_name": "Acme Payments Production"
}
Field Description
access_token A signed JWT. Send it as Authorization: Bearer <access_token>.
token_type Always Bearer.
expires_in Seconds until the token stops working. Read this value rather than assuming it; the bank can change it. The default is 30 minutes.
channel The channel your client is tagged with. Every customer and transaction you create carries it.
client_name The display name the bank gave your client.

The token endpoint is a BankCore-native endpoint, so failures come back as real HTTP statuses with a structured body.

HTTP errorCode When
401 INVALID_CLIENT Unknown client_id, or the secret does not match the current secret or the previous one inside its grace period. The message is the same in both cases on purpose.
403 CLIENT_SUSPENDED, CLIENT_REVOKED, CLIENT_PENDING_APPROVAL The client exists but is not active. Contact your relationship manager.
403 IP_NOT_ALLOWED The request came from an address outside your IP allowlist. See IP allowlist and rate limits.
  • Expiry. A call made with an expired token is refused with HTTP 401. Treat any 401 as “get a new token and retry once”.
  • Revocation. If the bank suspends or revokes your client, tokens already issued stop working at the next request, not at expiry.
  • Secret rotation. When your secret is rotated, the previous secret keeps working for a grace period so you can roll the new one out without downtime. After the grace period only the new secret is accepted. Rotation is requested through your relationship manager and the new secret is handed over out of band; it is never returned by any endpoint.
  • One token, one client. The token is bound to the client_id that requested it. If your organisation holds more than one client, each needs its own token.

You never need to decode the token, but it helps to know what it carries, because it explains what the platform will and will not let you do.

Claim Meaning
clientId Your client_id.
clientType PARTNER. This is what turns on the ownership guard described in Ownership model.
customerId The corporate customer record you act for. Every account you can reach is tied to it.
tenantId The bank tenant you belong to. Requests are pinned to it regardless of any header you send.
scopes The scopes your client holds. See Scopes.
settlementAccountId The account that funds and receives your wallet funding and charging.
feeAccountId The account your API fees are debited from.

The API access page lists every client your organisation holds, with its client_id, status, scopes, rate limits, IP allowlist and the time and address of its last use. It never shows a secret.