Environments and base URLs
Base URL
Section titled “Base URL”The bank issues your production host when your partner API client is approved. Throughout this documentation the placeholder https://api.bankcore.ng stands in for it; substitute the host you were given. Every path in these pages is relative to that host, for example:
https://api.bankcore.ng/api/auth/channel/tokenhttps://api.bankcore.ng/api/legacy/agent/virtual_account/createThree path families exist, and they behave differently enough that it is worth recognising them:
| Prefix | Who acts | Response style |
|---|---|---|
/api/legacy/provider/** |
You, moving money from your own accounts or an agent’s you may debit | Legacy envelope: HTTP 200 with code and desc |
/api/legacy/agent/** |
An agent or merchant named by X-Agent-Account |
Legacy envelope |
everything else under /api/** |
You | BankCore-native: real HTTP status, structured error body |
See Responses and error codes for both styles.
TLS only
Section titled “TLS only”The API is served over HTTPS only. There is no plain-HTTP listener and no redirect; a request to http:// simply fails to connect. Keep your TLS stack current: the bank’s edge accepts modern cipher suites and may retire older ones without notice.
Sandbox and production
Section titled “Sandbox and production”A sandbox (UAT) host is issued alongside your credentials for integration testing. Sandbox and production are separate clients, not one client with two hosts:
- Each has its own
client_idandclient_secret. A token from one is meaningless on the other. - Each has its own scope list, IP allowlist and rate limits. Ask for the production allowlist to be set up before go-live rather than discovering it on the day; see the Go-live checklist.
- Each has its own settlement account, fee account and webhook subscriptions.
- Data does not cross over. Agents, merchants and virtual accounts you create in sandbox do not exist in production.
Clocks and timezones
Section titled “Clocks and timezones”Two date conventions are in play, matching the two response styles.
BankCore-native endpoints emit timestamps as ISO-8601 instants in UTC with a Z suffix and millisecond precision, for example 2026-04-01T20:57:11.298Z. Query parameters that take a date (from, to) accept yyyy-MM-dd.
Legacy endpoints carry a transdatetime field on money-movement responses in the compact jCard format yyyyMMddHHmmss, for example 20260401143000. It has no zone designator.
Virtual account time-to-live (ttl) is a duration in minutes from creation, so it is zone-independent.
Content types
Section titled “Content types”- Send
Content-Type: application/jsonon every request with a body. Legacy endpoints that take no body (balance, statement, agent details) are plainGETs. - KYC document uploads are the one exception and take
multipart/form-data. See KYC uploads. - Responses are always
application/json, including the filter refusals (scope, IP, rate limit) that are produced before your request reaches a controller. - Amounts are decimal numbers in naira (
50000.00), not kobo, on every endpoint documented here. Legacy responses return balances as strings with two decimal places ("145000.00"). - Account numbers are 10-digit strings. Always send them as strings; a leading zero is significant.
Pagination
Section titled “Pagination”Legacy list endpoints are 1-based: page=1 is the first page, with size (or pageSize on the biller catalogue) as the page length, and they answer { "success", "total", "data" }. BankCore-native list endpoints follow the Spring convention and are 0-based. The two never mix on one endpoint, so check which family the endpoint belongs to. See Responses and error codes.
In the portal
Section titled “In the portal”The API access page shows the client your organisation holds in that environment, with its status, scopes, rate limits and IP allowlist. Each environment has its own portal.