Overview
Section titled “Overview”FOSSBilling provides a REST API for integrating external systems and building custom functionality on top of the platform.
API Endpoints
Section titled “API Endpoints”Three main entrypoints:
| Endpoint | Access Level | Purpose |
|---|---|---|
/api/admin/* | Admin only | System management |
/api/client/* | Authenticated clients | Client services |
/api/guest/* | Public | No authentication needed |
Request Format
Section titled “Request Format”- Method: Core API routes accept GET and POST. Use POST for requests with a JSON body or form data.
- Format: JSON responses. POST requests may send JSON or form data.
- Naming: Lowercase with underscores (
change_password) - Nulls: Blank fields are included as
null, not omitted - Dates: ISO 8601 format
Authentication
Section titled “Authentication”Use HTTP Basic Auth with base64 encoding:
- Username:
adminorclient(depending on endpoint) - Password: Your API key (found in client profile or admin dashboard)
Authorization: Basic base64_encode('admin:YOUR_API_KEY')Most HTTP clients (curl, Postman) handle the encoding automatically.
Browser requests from an active client or admin session use the session cookie instead. Those requests must include a valid CSRF token.
CSRF Tokens
Section titled “CSRF Tokens”CSRF protection applies to session-authenticated client and admin browser API calls. It does not apply to guest calls or external API calls authenticated with API tokens.
For browser calls, FOSSBilling accepts the token in any of these places:
CSRFTokenin the JSON bodyCSRFTokenin form data or query parametersX-CSRF-Tokenrequest header
The token must match the csrf_token cookie or the session token. The bundled JavaScript API wrapper reads the cookie and adds the token automatically.
Use Twig helpers for theme and module templates. This way, you don't need to manually attach CSRF tokens to the requests:
<form action="{{ 'profile/update'|api_url }}" {{ fb_api_form({ message: 'Saved'|trans }) }}> <input type="text" name="first_name"> <button type="submit">{{ 'Save'|trans }}</button></form>For raw fetch() requests, send the token yourself:
const token = document.cookie.match(/csrf_token=([^;]*)/)?.[1] || '';
fetch('/api/client/profile/update', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': decodeURIComponent(token), }, body: JSON.stringify({ first_name: 'Jane' }),});Example Requests
Section titled “Example Requests”curl -X POST "https://example.com/api/admin/staff/create" \ -H "Authorization: Basic $(echo -n 'admin:YOUR_API_KEY' | base64)" \ -H "Content-Type: application/json" \ -d '{ "email": "hello@fossbilling.org", "password": "Testing123+", "name": "John Doe", "admin_group_id": 1, "status": "active" }'import requestsfrom requests.auth import HTTPBasicAuth
url = "https://example.com/api/admin/staff/create"api_key = "YOUR_API_KEY"
payload = { "email": "hello@fossbilling.org", "password": "Testing123+", "name": "John Doe", "admin_group_id": 1, "status": "active"}
auth = HTTPBasicAuth('admin', api_key)headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, auth=auth)print(response.json())Run admin API calls from trusted server-side code only. Never expose an admin API key in browser JavaScript.
const url = "https://example.com/api/admin/staff/create";const apiKey = "YOUR_API_KEY";
const payload = { email: "hello@fossbilling.org", password: "Testing123+", name: "John Doe", admin_group_id: 1, status: "active"};
const headers = new Headers();headers.set("Content-Type", "application/json");headers.set("Authorization", "Basic " + Buffer.from("admin:" + apiKey).toString("base64"));
fetch(url, { method: "POST", headers: headers, body: JSON.stringify(payload)}).then(response => response.json()).then(data => console.log(data)).catch(error => console.error("Error:", error));Response Format
Section titled “Response Format”Success:
{ "result": { ... }, "error": null}Error:
{ "result": null, "error": { "message": "Error description", "code": 123 }}Common Patterns
Section titled “Common Patterns”Endpoint Structure
Section titled “Endpoint Structure”/api/{role}/{module}/{action}Examples:
/api/admin/client/get_list/api/client/profile/get/api/guest/system/version
Pagination
Section titled “Pagination”List endpoints typically accept:
page— Page number (starting at 1)per_page— Items per page
For assistance, join our Discord community.