Quickstart

Getting Started

Quick introduction to the Billabex API. Learn how to authenticate and make your first API call.

Getting Started with the Billabex API

Welcome to the Billabex API πŸ‘‹
This guide walks you through the essential steps to authenticate and make your first successful API calls.

By the end of this guide, you will:

  • Have an OAuth client configured
  • Obtain an access token
  • Discover your organization ID
  • Perform your first read and write API calls

What Is Billabex?

Billabex is an AI-powered invoice dunning automation platform that helps businesses recover outstanding payments faster.

Our intelligent agent:

  • Follows up on unpaid invoices automatically
  • Communicates with customers in multiple languages
  • Adapts tone and timing with tact and diplomacy

Using the Billabex API, you can:

  • Manage invoices and credit notes programmatically
  • Sync customer accounts and contacts
  • Track dunning communications and balances
  • Embed Billabex into your billing workflows

Prerequisites

Before starting, make sure you have:

  1. A Billabex account
    Sign up at https://next.billabex.com/auth/sign-up
  2. An organization created in your account
  3. An OAuth client created in the Developer Portal

Step 1: Create an OAuth Client

Go to Developer Portal β†’ OAuth Clients and create a new client.

You will need to provide:

  • Client Name – Your application name
  • Redirect URI – Your OAuth callback URL
    Example: https://yourapp.com/callback
  • Scopes – Permissions your app requires
    (see the Scopes guide)

Once created, you will receive:

  • A client_id
  • A client_secret (shown only once)

Store the client secret securely.

Step 2: Implement OAuth Authentication

Billabex uses the OAuth 2.1 Authorization Code flow with PKCE.

Conceptually:

  • Your app proves its identity using PKCE
  • The user approves access
  • You receive short-lived tokens to call the API

At a high level, you will:

  1. Generate a PKCE code verifier and challenge
  2. Redirect the user to the authorization page
  3. Receive an authorization code
  4. Exchange that code for access and refresh tokens

Generate PKCE Parameters

Generate a code_verifier and a corresponding code_challenge.
Keep the verifier in memory β€” you will reuse it during token exchange.

// Generate code verifier (random string)
const codeVerifier = generateRandomString(128);

// Generate code challenge (SHA256 hash of verifier, base64url encoded)
const codeChallenge = base64UrlEncode(sha256(codeVerifier));

Redirect the User to the Authorization Page

Build the authorization URL and redirect the user to it.

const authUrl = new URL('[baseURL]/api/oauth/authorize');
authUrl.searchParams.append('client_id', 'YOUR_CLIENT_ID');
authUrl.searchParams.append('redirect_uri', 'https://yourapp.com/callback');
authUrl.searchParams.append('response_type', 'code');
authUrl.searchParams.append('scope', 'invoices:read accounts:read');
authUrl.searchParams.append('code_challenge', codeChallenge);
authUrl.searchParams.append('code_challenge_method', 'S256');
authUrl.searchParams.append('state', generateRandomString(16));

// Redirect the user to authUrl

Always validate the returned state to protect against CSRF attacks.

Exchange Authorization Code for Tokens

After user approval, your redirect URI receives an authorization code. Exchange it for tokens at the token endpoint.

const response = await fetch('[baseURL]/api/oauth/token', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    grant_type: 'authorization_code',
    code: authorizationCode,
    redirect_uri: 'https://yourapp.com/callback',
    code_verifier: codeVerifier,
    client_id: 'YOUR_CLIENT_ID',
    client_secret: 'YOUR_CLIENT_SECRET',
  }),
});

const tokens = await response.json();

Example response:

{
  "access_token": "...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "...",
  "scope": "invoices:read accounts:read"
}

For more details, see the OAuth Authentication guide.

Step 3: Get Your Organization ID

Most API endpoints require an organizationId.

Use your access token to list the organizations you belong to and select the one you want to operate on.

const response = await fetch('[baseURL]/api/public/v1/organizations?first=10', {
  headers: {
    Authorization: `Bearer ${accessToken}`,
    'Content-Type': 'application/json',
  },
});

const data = await response.json();
const organizationId = data.nodes?.[0]?.id;

Step 4: Make Your First API Call

Now that you have an access token and an organization ID, you can call the public API.

Example: list accounts for your organization.

const response = await fetch('[baseURL]/api/public/v1/accounts?organizationId=YOUR_ORG_ID&first=10', {
  headers: {
    Authorization: `Bearer ${accessToken}`,
    'Content-Type': 'application/json',
  },
});

const data = await response.json();
console.log(data);

Using cURL

curl -X GET "[baseURL]/api/public/v1/accounts?organizationId=YOUR_ORG_ID&first=10" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json"

Step 5: Handle Pagination

The Billabex API uses cursor-based pagination.

  • Read pageInfo.endCursor from the response
  • Pass it as the after parameter to fetch the next page
  • When endCursor is missing, you’ve reached the end
const nextPageResponse = await fetch(`[baseURL]/api/public/v1/accounts?organizationId=YOUR_ORG_ID&first=10&after=${data.pageInfo.endCursor}`, {
  headers: {
    Authorization: `Bearer ${accessToken}`,
    'Content-Type': 'application/json',
  },
});

Learn more in the Pagination guide.

Step 6: Create an Invoice

Creating an invoice is a write operation and requires the invoices:all scope.

This endpoint expects:

  • multipart/form-data
  • A PDF or image file
  • Invoice metadata and amounts
  • A billing address (fields may be empty but must be present)

Example payload:

const formData = new FormData();
formData.append('accountId', 'ACCOUNT_ID');
formData.append('number', 'INV-2024-001');
formData.append('issuedDate.year', '2024');
formData.append('issuedDate.month', '1');
formData.append('issuedDate.day', '15');
formData.append('dueDate.year', '2024');
formData.append('dueDate.month', '2');
formData.append('dueDate.day', '15');
formData.append('totalAmount', '1500.00');
formData.append('taxAmount', '300.00');
formData.append('paidAmount', '0');
formData.append('poNumber', 'PO-2024-001');
formData.append('billingAddress.street', '1 Example Street');
formData.append('billingAddress.city', 'Paris');
formData.append('billingAddress.postalCode', '75001');
formData.append('billingAddress.country', 'FR');
formData.append('file', fileBlob, 'invoice.pdf');

const response = await fetch('[baseURL]/api/public/v1/invoices', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${accessToken}`,
  },
  body: formData,
});

const invoice = await response.json();

Next Steps

You’re now ready to integrate with Billabex πŸŽ‰

Recommended reading:

Support

Need help or feedback on this guide?
Reach out via the website contact form.