---
title: "Billabex OAuth Authentication"
description: "OAuth 2.1 Authorization Code flow with PKCE and optional OpenID Connect for Billabex."
canonical: https://developer.billabex.com/en/guides/oauth/
lang: en
alternate: https://developer.billabex.com/fr/guides/oauth/
last-updated: 2026-09-13
---

# Billabex OAuth Authentication

> OAuth 2.1 Authorization Code flow with PKCE and optional OpenID Connect for Billabex.

Source: https://developer.billabex.com/en/guides/oauth/
Language: English (en)
French version: https://developer.billabex.com/fr/guides/oauth/

Billabex uses **OAuth 2.1 Authorization Code flow with PKCE** for secure API access. OpenID Connect (OIDC) is available when you include the `openid` scope. This guide explains the flow, supported features, token lifetimes, refresh behavior, and all available endpoints.

## Overview

At a high level, the flow looks like this:

1. You create an OAuth client in the Developer Portal, or in the Billabex web app under **My account → My OAuth clients**, and configure allowed redirect URIs and scopes.
2. Your app redirects the user to the authorization endpoint with PKCE parameters and requested scopes.
3. The user signs in, reviews consent, and approves access.
4. You receive an authorization code on your redirect URI.
5. You exchange the code (plus the PKCE verifier) for tokens at the token endpoint.
6. You call the API with the access token and refresh it when needed.

OAuth in Billabex is:

- **User-centric**: access is granted by a user
- **Token-based**: no API keys
- **Scoped**: permissions are explicit and minimal
- **Time-bound**: all tokens have a limited lifetime

## Token Types and Lifetimes

Billabex issues several token types. Each has a specific purpose and a fixed TTL.

| Token Type         | TTL (seconds) | TTL (human) | Description                         |
| ------------------ | ------------- | ----------- | ----------------------------------- |
| Access Token       | 3600          | 1 hour      | Used to call the public API         |
| Refresh Token      | 2592000       | 30 days     | Used to obtain new access tokens    |
| Authorization Code | 600           | 10 minutes  | Temporary code exchanged for tokens |
| ID Token (OIDC)    | 600           | 10 minutes  | Identity token (OIDC best practice) |

Notes:

- Access tokens are intentionally short-lived.
- Authorization codes and ID tokens follow OIDC security best practices.
- Expired tokens are rejected automatically.

## OAuth Actors

An OAuth flow involves three parties:

- **Resource Owner** : the user granting access
- **Client Application** : your application
- **Authorization Server** : Billabex OAuth server

Your application never handles user credentials directly.

## Supported OAuth 2.1 Features

Billabex follows OAuth 2.1 conventions with secure defaults.

- **Authorization code flow only** (`response_type=code`)
- **PKCE required** (`S256` recommended, `plain` supported for legacy clients)
- **Refresh tokens** with rotation on every use
- **Token endpoint authentication**
  - `none` for public clients
  - `client_secret_basic` or `client_secret_post` for confidential clients
- **Dynamic client registration** (RFC 7591 / 7592)
- **Token revocation** (RFC 7009)

The Developer Portal creates **confidential clients by default** and shows the `client_secret` only once.

## OAuth Endpoints

All OAuth endpoints are under the API base URL.

**Authorization**  
`GET https://next.billabex.com/api/oauth/authorize`

**Token**  
`POST https://next.billabex.com/api/oauth/token`

**Revocation**  
`POST https://next.billabex.com/api/oauth/revoke`

**UserInfo (OIDC)**  
`GET https://next.billabex.com/api/oauth/userinfo`

**Dynamic registration**  
`POST https://next.billabex.com/api/oauth/register`

**Client configuration management**  
`GET/PUT/DELETE https://next.billabex.com/api/oauth/register/{clientId}`

### Discovery and JWKS

Public endpoints at the root domain:

- `https://next.billabex.com/.well-known/oauth-authorization-server`
- `https://next.billabex.com/.well-known/openid-configuration`
- `https://next.billabex.com/.well-known/jwks.json`
- `https://next.billabex.com/.well-known/oauth-protected-resource`

### Protected Resource Metadata (RFC 9728)

Billabex exposes the OAuth 2.0 Protected Resource Metadata endpoint to help
clients discover which authorization server and scopes apply to a resource.

For a resource at `/api/public/v1/invoices`, the metadata URL is:

`https://next.billabex.com/.well-known/oauth-protected-resource/api/public/v1/invoices`

The response includes:

- `authorization_servers` for OAuth discovery
- `scopes_supported` for that specific resource path

## Authorization Request

Redirect the user to the authorization endpoint with the following parameters:

- `client_id` (required)
- `redirect_uri` (required, must match exactly)
- `response_type=code` (required)
- `scope` (recommended; if omitted, the server uses the client's allowed scopes)
- `code_challenge` (required)
- `code_challenge_method=S256` (recommended)
- `state` (required)
- `nonce` (required when using `openid`)

Always validate `state` (and `nonce` for OIDC).

## Authorization Code

After user approval, Billabex redirects back to your `redirect_uri` with:

- `code`
- `state`

The authorization code:

- Is valid for **10 minutes**
- Can be used **only once**

## Token Exchange (authorization_code)

`POST https://next.billabex.com/api/oauth/token`

Required fields:

- `grant_type=authorization_code`
- `code`
- `redirect_uri`
- `code_verifier`
- `client_id`
- `client_secret` (confidential clients)

Successful response:

```json
{
  "access_token": "...",
  "refresh_token": "...",
  "expires_in": 3600,
  "token_type": "Bearer",
  "scope": "...",
  "id_token": "..."
}
```

`id_token` is present only when `openid` is granted.

## Refreshing Access Tokens

Access tokens expire after **1 hour**.  
Use the refresh token to obtain a new access token.

### Refresh Token Rotation Policy

Billabex enforces **refresh token rotation**.

This means:

- Every refresh request **revokes the previous refresh token**
- A **new refresh token** is issued on each refresh
- Only the **most recently issued refresh token** remains valid

Important clarifications:

- Refreshing an access token does **not** revoke access by itself
- The **refresh operation** invalidates the previous refresh token
- You must **persist the new refresh token immediately**
- Reusing an old refresh token will fail

### Refresh Token Request

`POST https://next.billabex.com/api/oauth/token`

```json
{
  "grant_type": "refresh_token",
  "refresh_token": "CURRENT_REFRESH_TOKEN",
  "client_id": "CLIENT_ID",
  "client_secret": "CLIENT_SECRET"
}
```

Response:

```json
{
  "access_token": "...",
  "refresh_token": "...",
  "expires_in": 3600,
  "token_type": "Bearer",
  "scope": "..."
}
```

## Accessing the API

Send the access token as a Bearer token in the `Authorization` header on all API calls.

Scopes are enforced per endpoint. Use the [Scopes guide](/en/guides/scopes/) to request the minimum required permissions.

## Token Revocation

Revoke tokens when a user disconnects your integration.

Fields:

- `token`
- `token_type_hint` (optional)

## OpenID Connect (OIDC)

OIDC is enabled when the `openid` scope is requested.

### OIDC Scopes

- `openid`
- `profile`
- `email`

### ID Token

- Returned only when `openid` is granted
- Must be validated (signature, issuer, audience, expiry, nonce)

### UserInfo Endpoint

Returns user claims allowed by granted scopes.

## Security Best Practices

- Always use HTTPS
- Always use PKCE
- Validate `state` and `nonce`
- Store tokens securely
- Rotate refresh tokens atomically
- Never log tokens
- Request the minimum scopes needed

## Next Steps

- **[Getting Started](/en/guides/getting-started/)**
- **[OAuth Scopes](/en/guides/scopes/)**
- **[Rate Limiting](/en/guides/rate-limiting/)**
- **[API Reference](/en/api-reference/)**

## Support

Questions about OAuth or OIDC?  
Contact us via the [website contact form](https://billabex.com).

---

Billabex developer portal. OpenAPI specification: https://developer.billabex.com/openapi.json.
Agent instructions: https://developer.billabex.com/llms.txt. Complete documentation: https://developer.billabex.com/llms-full.txt.
