Authentication

Authentication

BillerAPI uses two authentication mechanisms depending on the type of operation.

Authentication Methods

Choose the right method for your use case

API Key (Bearer)

Server-to-server API calls using your bak_test_/bak_live_ API key.

Authorization: Bearer bak_test_…

Access Tokens (Bearer)

Per-account tokens from the link token exchange, used for bill retrieval.

Authorization: Bearer <token>

API Key

Use your API key for all server-to-server API calls: biller search, link token creation, webhook registration, and more. Send it as a Bearer token on every request — the key is self-contained, so no other header is needed.

Authorization: Bearer bak_test_…

Getting Your Key

  1. Sign up at the Client Portal to create a developer account
  2. Navigate to Dashboard → API Keys
  3. Copy your sandbox key, or generate a production key once you go live

Key Formats

EnvironmentKey PrefixModeBase URL
Sandboxbak_test_*testhttps://sandbox.api.billerapi.com
Productionbak_live_*livehttps://api.billerapi.com

The key prefix tells you which environment you're in at a glance. Client-secret response objects also carry a mode field (test or live) so sandbox vs production is visible on the wire.

Example: List billers with your API key
const response = await fetch('https://sandbox.api.billerapi.com/v1/billers', {
  headers: {
    'Authorization': `Bearer ${process.env.BILLERAPI_API_KEY}`,
  },
});
const data = await response.json();

Keep your key safe

Never expose your API key in client-side code (browser, mobile app). All API calls using your key must originate from your server.

One credential per environment

Use a bak_test_ key for sandbox and a bak_live_ key for production. Do not combine keys with a separate client id or secret header.

Access Tokens (Bearer)

Access tokens are scoped to a single linked account. You obtain them by exchanging the public token returned by Elements after a user completes the linking flow.

How to Get an Access Token

1

Create a link token

POST /v1/link-tokens with your API key

2

User completes Connect flow

Elements opens an iframe where the user links their biller account

3

Exchange the public token

POST /v1/link-tokens/exchange returns an access_token

4

Use the access token

Pass as Authorization: Bearer <access_token> for bill retrieval endpoints

Example: Fetch bills with an access token
const response = await fetch(
  'https://sandbox.api.billerapi.com/v1/bills?account_link_id=link_123',
  {
    headers: {
      'Authorization': `Bearer ${accessToken}`,
    },
  }
);
const bills = await response.json();

Environments

Use the sandbox environment for development and testing. Switch to production when you're ready to go live.

EnvironmentBase URLDescription
Sandboxhttps://sandbox.api.billerapi.comTest billers, deterministic data, no real accounts
Productionhttps://api.billerapi.comLive billers, real account data

Note

Sandbox uses test billers with magic account numbers that produce deterministic responses. See the Getting Started guide for sandbox test data.

Error Handling

All errors return a consistent JSON response format.

Error Response
{
  "error_code": "UNAUTHORIZED",
  "error_type": "auth",
  "error_message": "Invalid client credentials.",
  "docs_url": "https://docs.billerapi.com/errors/UNAUTHORIZED",
  "request_id": "d94f5e2a-8c3b-4f1e-9a7d-6b2c1e0f8a34"
}

Common Error Codes

StatusMeaningAction
401Invalid or missing credentialsCheck client ID/secret or refresh token
403Insufficient permissionsVerify your account has the required scopes
429Rate limit exceededBack off and retry after the Retry-After period
500Internal server errorRetry with exponential backoff; contact support if persistent

Rate Limits

BillerAPI enforces per-client rate limits. The exact per-endpoint thresholds are subject to change — do not hard-code specific numbers. When you exceed a limit the API returns 429 Too Many Requests with a Retry-After header (and a numeric retry_after field in the error body). Always honor it. See Rate Limits for the backoff strategy.

Security Best Practices

  • Store credentials in environment variables, never in source code
  • Rotate client secrets periodically via the dashboard
  • Use separate credentials for sandbox and production
  • Verify webhook signatures before processing events
  • Never expose client secrets in frontend code or public repositories
  • Never log full credentials — redact secrets in logs

Related API Reference

Was this page helpful?