API Keys and IP Whitelist
Generate credentials, rotate keys, whitelist source IPs, and choose HMAC v1 or HMAC v2 request signing.
API credentials are managed from Settings -> API Keys in the merchant portal. Each credential has:
| Value | Purpose |
|---|---|
| API key | Public identifier sent as x-api-key. |
| Signing key | HMAC secret used to sign requests and verify signed responses. Shown once. |
Store the signing key in a secret manager immediately. If it is exposed, rotate the API key from the portal and update your integration.
IP whitelist
Use Settings -> IP Whitelist to restrict an API key to known server egress IPs.
- If the whitelist has entries, calls from any other source IP are rejected.
- If the whitelist is empty, the key is accepted from any source IP.
- Production integrations should whitelist stable backend egress IPs whenever possible.
Rejected calls are logged internally as ip_not_whitelisted and return an
opaque unauthenticated response to API clients.
Signing versions
BridgPay supports two request signing formats:
| Version | Use for | Headers |
|---|---|---|
| v1 legacy | Requests without query strings, legacy SDK/Postman compatibility. | x-api-key, x-timestamp, x-signature |
| v2 preferred | Any request with query parameters, plus all new integrations. | x-bridg-sig-version: 2, x-api-key, x-timestamp, x-nonce, x-signature |
These are signing versions, not URL versions. Keep calling /v1/...
endpoints. To use HMAC v2, add x-bridg-sig-version: 2 and sign the v2
canonical string.
Important: v1 signing intentionally refuses requests that include a non-empty query string. Use v2 for list/search endpoints such as:
GET /v1/beneficiaries?limit=50&offset=0GET /v1/wallet/transactions?limit=50&offset=0GET /v1/payouts?since=2026-05-01T00:00:00.000Z&until=2026-06-01T00:00:00.000Z
Simple GET endpoints without query parameters, such as the
Balance Check API at GET /v1/wallet, can
be signed with v1 or v2. New integrations should still prefer v2.
HMAC v2 canonical request
METHOD|HOST|PATH_AND_QUERY|API_KEY|TIMESTAMP|NONCE|SHA256_HEX(BODY)
Rules:
METHODis uppercase.HOSTis the request host as sent, lower-cased, including port if present.PATH_AND_QUERYincludes the path and exact query string.API_KEYis the same value sent inx-api-key.TIMESTAMPis Unix epoch milliseconds.NONCEis a unique value per request, usually a UUID.SHA256_HEX(BODY)is the SHA-256 hex digest of the exact request body string. ForGET/DELETE, use the empty string.
HMAC v2 TypeScript example
import crypto from 'crypto';
export function signRequestV2({
method,
host,
pathAndQuery,
body,
apiKey,
apiSecret,
}: {
method: string;
host: string;
pathAndQuery: string;
body: string;
apiKey: string;
apiSecret: string;
}) {
const timestamp = Date.now().toString();
const nonce = crypto.randomUUID();
const bodyHash = crypto.createHash('sha256').update(body).digest('hex');
const canonical = [
method.toUpperCase(),
host.toLowerCase(),
pathAndQuery,
apiKey,
timestamp,
nonce,
bodyHash,
].join('|');
return {
'x-bridg-sig-version': '2',
'x-api-key': apiKey,
'x-timestamp': timestamp,
'x-nonce': nonce,
'x-signature': crypto
.createHmac('sha256', apiSecret)
.update(canonical)
.digest('hex'),
};
}
Use HMAC v1 only when you need compatibility with an existing integration that does not send query parameters. See Canonical Request Format and Generate Request Signature.