Skip to main content
Every request to the UBN BaaS API requires authentication. Payment and KYC requests require an additional signature on top of your API key. Read this page fully before writing any integration code.
The UBN BaaS API uses a layered security model. Each layer adds protection for a more sensitive class of operation:

API Key Authentication

Every request must include your API key in the Authorization header using the ApiKey scheme.

Key prefixes and environments

Your API key prefix tells you which environment it belongs to. The platform enforces this. You cannot accidentally use a sandbox key against production or vice versa. Using the wrong key for an environment returns a 403 ENVIRONMENT_MISMATCH error immediately. See Error Reference for details.

Code examples

Never hard-code your API key in source code. Store it in an environment variable (UBN_API_KEY) and read it at runtime. If you accidentally commit a key to a public repository, revoke it immediately from the API Keys page and generate a new one.

Signing Requests

Payment and KYC endpoints require a request signature in addition to your API key. This signature proves that the request body has not been modified between your server and ours. Why we require signatures: If someone intercepts an outbound HTTP request from your server (a man-in-the-middle attack), they could change the destination account number or the transfer amount before it reaches us. Your API key alone cannot detect this. A signature, computed from the exact body you sent, makes tampering detectable: any change to the body invalidates the signature and we reject the request.

How to compute the signature

1

Serialise the request body

Take your request body as a JSON string. The serialisation must be consistent: the same object must always produce the same string. Use compact serialisation (no extra spaces) and ensure key order is deterministic.
2

Compute an HMAC-SHA256 hash

Hash the JSON string using HMAC-SHA256 with your signing secret as the key. Your signing secret is separate from your API key. You receive it during onboarding and it’s also available in the API Keys page of your dashboard.
3

Hex-encode the hash

Convert the raw binary HMAC output to a lowercase hexadecimal string.
4

Add the X-Signature header

Prepend the string sha256= to the hex digest and include it as the X-Signature header.

Code examples

The body you sign and the body you send must be byte-for-byte identical. If your HTTP client re-serialises the JSON after you sign it (for example, by sorting keys or adding spaces), the signature will not match. Always sign the exact string your client will transmit.
If you receive an INVALID_SIGNATURE error, work through this checklist:
  1. Confirm you are using the signing secret (not the API key).
  2. Confirm you are serialising with compact JSON (no extra whitespace).
  3. Confirm the body you sign is the exact bytes being sent in the HTTP request.
  4. Check that your signing secret has not been rotated since you last fetched it from the dashboard.

mTLS Client Certificates

Mutual TLS (mTLS) is required for all payment operations in the production environment. It is not required in sandbox. What mTLS means in plain English: Normally when you connect to an HTTPS server, only the server proves its identity to you (via its TLS certificate). With mTLS, you also prove your identity to the server. Both sides show their “ID card” before the connection opens. This makes it impossible for an attacker to pose as you, even if they obtain your API key.

How to get your client certificate

Your client certificate is issued during production onboarding. Contact your UBN relationship manager or email baas-support@unionbank.ng to start the process. You will receive:
  • client.crt: your client certificate (public)
  • client.key: your private key (keep this secret, never commit it)
Your private key (client.key) must be stored securely. Treat it with the same care as a password. Store it as a secret in your secrets manager, never on disk in a production server, and never in source code or environment variable files that get committed to version control.

Using mTLS with curl

Using mTLS in Node.js

mTLS is enforced at the network layer, before your request is processed. If the certificate is missing or invalid, the connection is terminated before the API key is checked. You will see a TLS handshake error, not an HTTP error response.

Idempotency Keys

What idempotency means

Networks fail. Connections drop. Load balancers time out. When you send a payment request and the response never arrives, you face a problem: did the payment go through, or not? If you retry the request and the original succeeded, you might send the same payment twice. Idempotency solves this. You generate a unique key (a UUID) and include it in the X-Idempotency-Key header. If you send the exact same key again, whether 5 milliseconds or 5 hours later, the API returns the original response without taking any new action. No duplicate payment. No duplicate account. No guessing.

Rules for idempotency keys

  • Generate a new UUID for each distinct operation. Do not reuse keys across different requests.
  • The replay window is 24 hours. After 24 hours, the same key is treated as a new request.
  • If you send the same key with a different request body, the API returns a 409 CONFLICT error. This prevents accidentally masking changes with an old key.
  • The X-Idempotency-Replayed: true response header tells you when a response is a replay. Log it: it means your retry worked and the original response is intact.
Never reuse the same idempotency key for different operations. If you send a transfer with key abc-123 and then try to create an account with the same key, the second request will either be rejected or return the transfer response, depending on timing.

Generating a UUID

Detecting a replay

In a high-reliability system, store each idempotency key alongside the result in your own database before considering the operation complete. If your process crashes before storing the result, retry with the same key, get the same response back, and then store it safely.