API reference
Customers
Customers are the people and companies the organization bills. Create them once with your own reference, keep them up to date, and read their services and statement totals.
The customer object# Someone the organization bills: an individual or a company.
Field Description id integer Flux's id for the customer. externalRef string · nullable Your id for the customer, such as a workspace id. Unique within the organization. customerType string individual or company.name string The billing name. For a company, the legal name, else the company name. For an individual, their name. legalName string · nullable Registered legal name. companyName string · nullable Trading name. Set for companies. firstName string · nullable Set for individuals. lastName string · nullable Set for individuals. email string The customer's email. Gets invoices when there's no primary contact. phone string · nullable In international format. address string · nullable Postal address. taxId string · nullable Tax identification number (TIN). Unique within the organization. vatNumber string · nullable VAT registration number. rcNumber string · nullable CAC registration (RC) number. parentCustomerId integer · nullable The group company this customer belongs to, in the same organization. regulatedEntityCount integer · nullable Number of regulated entities. 0 or more. defaultCurrency string · nullable Pre-fills the currency when someone raises an invoice for this customer in the Flux app. One of NGN, USD, CAD, EUR, GBP. defaultSettlementBankId integer · nullable The organization's bank account that this customer's payments settle into. Ids come from the Flux app. contacts array of Billing contact · nullable Billing contacts. Returned by get, create and update. Always null in list results. createdAt timestamp When the customer was created. Server time, no offset. updatedAt timestamp · nullable When the customer last changed. null if never.
{
"id" : 812 ,
"externalRef" : "ws_42" ,
"customerType" : "company" ,
"name" : "Leadway Group Plc" ,
"legalName" : "Leadway Group Plc" ,
"companyName" : "Leadway Group" ,
"firstName" : null ,
"lastName" : null ,
"email" : "finance@leadway.example" ,
"phone" : "+2348012345678" ,
"address" : "121 Funso Williams Ave, Lagos" ,
"taxId" : "12345678-0001" ,
"vatNumber" : "VAT-001" ,
"rcNumber" : "RC123456" ,
"parentCustomerId" : null ,
"regulatedEntityCount" : 3 ,
"defaultCurrency" : "NGN" ,
"defaultSettlementBankId" : null ,
"contacts" : [
{
"name" : "Finance" ,
"email" : "finance@leadway.example" ,
"phone" : null ,
"isBillingPrimary" : true ,
"ccOnInvoices" : false
},
{
"name" : "CFO" ,
"email" : "cfo@leadway.example" ,
"phone" : null ,
"isBillingPrimary" : false ,
"ccOnInvoices" : true
}
],
"createdAt" : "2026-11-01T10:20:00" ,
"updatedAt" : null
}
An email on a customer that receives invoices and receipts.
Who gets invoice and receipt emails: the primary contact (or the customer's email when there's no primary contact), plus every contact with ccOnInvoices. Duplicates are removed.
Field Description name string · nullable Label or person's name. email string Receives invoices and receipts. phone string · nullable Phone number. isBillingPrimary boolean The primary billing contact. At most one per customer. ccOnInvoices boolean Copied on invoice and receipt emails.
The enrollment object# A customer's subscription to a service in the organization's catalogue.
Enrollments are managed in the Flux app; the API reads them.
Field Description id integer Enrollment id. serviceId integer The service in the organization's catalogue. serviceName string · nullable The service's name. amount number (decimal) The agreed amount, else the service's price. Major units. enrolledFrom date Start date. enrolledTo date · nullable End date. null if open-ended. active boolean Active and within its dates today.
{
"id" : 31 ,
"serviceId" : 7 ,
"serviceName" : "Subscription" ,
"amount" : 250000.00 ,
"enrolledFrom" : "2026-10-01T00:00:00" ,
"enrolledTo" : null ,
"active" : true
}
The statement object#
Open, overdue and paid totals per currency. Counts approved and paid invoices; voided ones are excluded.
Field Description customerId integer The customer. currencies array of Currency totals One entry per currency the customer has invoices in. Empty if none.
Each entry in currencies:
Field Description currency string ISO currency code. One of NGN, USD, CAD, EUR, GBP. open number (decimal) Total of approved, unpaid invoices. Includes the overdue ones. overdue number (decimal) Total of open invoices past their due date. paid number (decimal) Total of paid invoices. openCount integer Number of open invoices. overdueCount integer Number of overdue invoices. paidCount integer Number of paid invoices.
{
"customerId" : 812 ,
"currencies" : [
{
"currency" : "NGN" ,
"open" : 500000.00 ,
"overdue" : 250000.00 ,
"paid" : 1250000.00 ,
"openCount" : 2 ,
"overdueCount" : 1 ,
"paidCount" : 5
}
]
}
Create a customer# Creates a customer. Send an Idempotency-Key so a retry can't create a second one.
Request body Field Description customerType string optional individual or company. Defaults to individual on create.email string required A valid email address. Required on create.firstName string optional Required for individuals.lastName string optional Required for individuals.phone string optional Required and must be valid for individuals. Optional for companies, but must be valid if sent.companyName string optional Required for companies.legalName string optional Registered legal name. Used as the billing name when set.address string optional Postal address.taxId string optional TIN. Another customer in the organization can't have the same one.vatNumber string optional VAT registration number.rcNumber string optional CAC registration (RC) number.externalRef string optional Your id for the customer. At most 100 characters, unique within the organization.parentCustomerId integer optional A customer in the same organization. Can't be the customer itself, or a customer whose parent is this one.regulatedEntityCount integer optional 0 or more.defaultCurrency string optional A supported currency code. One of NGN, USD, CAD, EUR, GBP.defaultSettlementBankId integer optional One of the organization's bank account ids, from the Flux app.contacts array of Billing contact (request) optional At most 20, each with a valid email, and at most one primary. On update, sending contacts replaces the whole list . Leave it out to keep the current contacts.
Validation follows the Flux app. email is always required. Individuals need firstName, lastName and a valid phone. Companies need companyName. A 409 conflict means another customer in the organization already has the same externalRef, the same taxId, or the same name and email.
Request cURL Node.js Python PHP C# Go
Copy curl -X POST "$FLUX_BASE_URL/api/v1/customers" \
-H "Authorization: ApiKey $FLUX_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: create-customer-ws_42" \
-d '{
"customerType": "company",
"companyName": "Leadway Group",
"legalName": "Leadway Group Plc",
"email": "finance@leadway.example",
"phone": "+2348012345678",
"address": "121 Funso Williams Ave, Lagos",
"taxId": "12345678-0001",
"vatNumber": "VAT-001",
"rcNumber": "RC123456",
"externalRef": "ws_42",
"regulatedEntityCount": 3,
"defaultCurrency": "NGN",
"contacts": [
{
"name": "Finance",
"email": "finance@leadway.example",
"isBillingPrimary": true,
"ccOnInvoices": false
},
{
"name": "CFO",
"email": "cfo@leadway.example",
"isBillingPrimary": false,
"ccOnInvoices": true
}
]
}'// Node.js 18+ (built-in fetch). Save as an .mjs file.
const response = await fetch(`${process.env.FLUX_BASE_URL}/api/v1/customers`, {
method: "POST",
headers: {
Authorization: `ApiKey ${process.env.FLUX_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": "create-customer-ws_42",
},
body: JSON.stringify({
customerType: "company",
companyName: "Leadway Group",
legalName: "Leadway Group Plc",
email: "finance@leadway.example",
phone: "+2348012345678",
address: "121 Funso Williams Ave, Lagos",
taxId: "12345678-0001",
vatNumber: "VAT-001",
rcNumber: "RC123456",
externalRef: "ws_42",
regulatedEntityCount: 3,
defaultCurrency: "NGN",
contacts: [
{
name: "Finance",
email: "finance@leadway.example",
isBillingPrimary: true,
ccOnInvoices: false,
},
{
name: "CFO",
email: "cfo@leadway.example",
isBillingPrimary: false,
ccOnInvoices: true,
},
],
}),
});
console.log(response.status, await response.json());import os
import requests
response = requests.post(
f"{os.environ['FLUX_BASE_URL']}/api/v1/customers",
headers={
"Authorization": f"ApiKey {os.environ['FLUX_API_KEY']}",
"Idempotency-Key": "create-customer-ws_42",
},
json={
"customerType": "company",
"companyName": "Leadway Group",
"legalName": "Leadway Group Plc",
"email": "finance@leadway.example",
"phone": "+2348012345678",
"address": "121 Funso Williams Ave, Lagos",
"taxId": "12345678-0001",
"vatNumber": "VAT-001",
"rcNumber": "RC123456",
"externalRef": "ws_42",
"regulatedEntityCount": 3,
"defaultCurrency": "NGN",
"contacts": [
{
"name": "Finance",
"email": "finance@leadway.example",
"isBillingPrimary": True,
"ccOnInvoices": False,
},
{
"name": "CFO",
"email": "cfo@leadway.example",
"isBillingPrimary": False,
"ccOnInvoices": True,
},
],
},
timeout=30,
)
print(response.status_code, response.json())<?php
$body = <<<'JSON'
{
"customerType": "company",
"companyName": "Leadway Group",
"legalName": "Leadway Group Plc",
"email": "finance@leadway.example",
"phone": "+2348012345678",
"address": "121 Funso Williams Ave, Lagos",
"taxId": "12345678-0001",
"vatNumber": "VAT-001",
"rcNumber": "RC123456",
"externalRef": "ws_42",
"regulatedEntityCount": 3,
"defaultCurrency": "NGN",
"contacts": [
{
"name": "Finance",
"email": "finance@leadway.example",
"isBillingPrimary": true,
"ccOnInvoices": false
},
{
"name": "CFO",
"email": "cfo@leadway.example",
"isBillingPrimary": false,
"ccOnInvoices": true
}
]
}
JSON;
$ch = curl_init(getenv('FLUX_BASE_URL') . '/api/v1/customers');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Authorization: ApiKey ' . getenv('FLUX_API_KEY'),
'Content-Type: application/json',
'Idempotency-Key: create-customer-ws_42',
],
CURLOPT_POSTFIELDS => $body,
CURLOPT_RETURNTRANSFER => true,
]);
$response = curl_exec($ch);
echo curl_getinfo($ch, CURLINFO_HTTP_CODE), ' ', $response, PHP_EOL;using System.Net.Http.Headers;
using System.Text;
var baseUrl = Environment.GetEnvironmentVariable("FLUX_BASE_URL");
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("ApiKey", Environment.GetEnvironmentVariable("FLUX_API_KEY"));
using var request = new HttpRequestMessage(HttpMethod.Post, $"{baseUrl}/api/v1/customers");
request.Headers.Add("Idempotency-Key", "create-customer-ws_42");
request.Content = new StringContent("""
{
"customerType": "company",
"companyName": "Leadway Group",
"legalName": "Leadway Group Plc",
"email": "finance@leadway.example",
"phone": "+2348012345678",
"address": "121 Funso Williams Ave, Lagos",
"taxId": "12345678-0001",
"vatNumber": "VAT-001",
"rcNumber": "RC123456",
"externalRef": "ws_42",
"regulatedEntityCount": 3,
"defaultCurrency": "NGN",
"contacts": [
{
"name": "Finance",
"email": "finance@leadway.example",
"isBillingPrimary": true,
"ccOnInvoices": false
},
{
"name": "CFO",
"email": "cfo@leadway.example",
"isBillingPrimary": false,
"ccOnInvoices": true
}
]
}
""", Encoding.UTF8, "application/json");
using var response = await http.SendAsync(request);
Console.WriteLine($"{(int)response.StatusCode} {await response.Content.ReadAsStringAsync()}");package main
import (
"fmt"
"io"
"net/http"
"os"
"strings"
)
func main() {
body := strings.NewReader(`{
"customerType": "company",
"companyName": "Leadway Group",
"legalName": "Leadway Group Plc",
"email": "finance@leadway.example",
"phone": "+2348012345678",
"address": "121 Funso Williams Ave, Lagos",
"taxId": "12345678-0001",
"vatNumber": "VAT-001",
"rcNumber": "RC123456",
"externalRef": "ws_42",
"regulatedEntityCount": 3,
"defaultCurrency": "NGN",
"contacts": [
{
"name": "Finance",
"email": "finance@leadway.example",
"isBillingPrimary": true,
"ccOnInvoices": false
},
{
"name": "CFO",
"email": "cfo@leadway.example",
"isBillingPrimary": false,
"ccOnInvoices": true
}
]
}`)
req, err := http.NewRequest("POST", os.Getenv("FLUX_BASE_URL")+"/api/v1/customers", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "ApiKey "+os.Getenv("FLUX_API_KEY"))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Idempotency-Key", "create-customer-ws_42")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
out, _ := io.ReadAll(resp.Body)
fmt.Println(resp.StatusCode, string(out))
}Responses 201 Created{
"id" : 812 ,
"externalRef" : "ws_42" ,
"customerType" : "company" ,
"name" : "Leadway Group Plc" ,
"legalName" : "Leadway Group Plc" ,
"companyName" : "Leadway Group" ,
"firstName" : null ,
"lastName" : null ,
"email" : "finance@leadway.example" ,
"phone" : "+2348012345678" ,
"address" : "121 Funso Williams Ave, Lagos" ,
"taxId" : "12345678-0001" ,
"vatNumber" : "VAT-001" ,
"rcNumber" : "RC123456" ,
"parentCustomerId" : null ,
"regulatedEntityCount" : 3 ,
"defaultCurrency" : "NGN" ,
"defaultSettlementBankId" : null ,
"contacts" : [
{
"name" : "Finance" ,
"email" : "finance@leadway.example" ,
"phone" : null ,
"isBillingPrimary" : true ,
"ccOnInvoices" : false
},
{
"name" : "CFO" ,
"email" : "cfo@leadway.example" ,
"phone" : null ,
"isBillingPrimary" : false ,
"ccOnInvoices" : true
}
],
"createdAt" : "2026-11-01T10:20:00" ,
"updatedAt" : null
}8 possible errors Status Code When 400invalid_requestValidation failed. The message says what, such as Add at least one invoice item . 409conflictA uniqueness rule failed, such as another customer having the same externalRef. 400invalid_idempotency_keyIdempotency-Key is longer than 255 characters.409idempotency_in_progressA request with the same Idempotency-Key is still running. 422idempotency_key_reusedThe same Idempotency-Key was sent with a different request. 401unauthorizedNo API key, an unknown key or a revoked key. 403insufficient_scopeThe key lacks the scope. details names it: { "required": "invoices:write" }. 429rate_limitedToo many requests for this key. Wait for the Retry-After seconds.
Update a customer# PATCH /api/v1/customers/{id}customers:write
Changes only the fields you send. Sending contacts replaces the whole list ; leave it out to keep the current contacts.
Path parameters Field Description id integer required The customer's id.
Request body Field Description customerType string optional individual or company. Defaults to individual on create.email string optional A valid email address. Required on create.firstName string optional Required for individuals.lastName string optional Required for individuals.phone string optional Required and must be valid for individuals. Optional for companies, but must be valid if sent.companyName string optional Required for companies.legalName string optional Registered legal name. Used as the billing name when set.address string optional Postal address.taxId string optional TIN. Another customer in the organization can't have the same one.vatNumber string optional VAT registration number.rcNumber string optional CAC registration (RC) number.externalRef string optional Your id for the customer. At most 100 characters, unique within the organization.parentCustomerId integer optional A customer in the same organization. Can't be the customer itself, or a customer whose parent is this one.regulatedEntityCount integer optional 0 or more.defaultCurrency string optional A supported currency code. One of NGN, USD, CAD, EUR, GBP.defaultSettlementBankId integer optional One of the organization's bank account ids, from the Flux app.contacts array of Billing contact (request) optional At most 20, each with a valid email, and at most one primary. On update, sending contacts replaces the whole list . Leave it out to keep the current contacts.
Request cURL Node.js Python PHP C# Go
Copy curl -X PATCH "$FLUX_BASE_URL/api/v1/customers/812" \
-H "Authorization: ApiKey $FLUX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone": "+2348098765432",
"regulatedEntityCount": 4
}'// Node.js 18+ (built-in fetch). Save as an .mjs file.
const response = await fetch(`${process.env.FLUX_BASE_URL}/api/v1/customers/812`, {
method: "PATCH",
headers: {
Authorization: `ApiKey ${process.env.FLUX_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
phone: "+2348098765432",
regulatedEntityCount: 4,
}),
});
console.log(response.status, await response.json());import os
import requests
response = requests.patch(
f"{os.environ['FLUX_BASE_URL']}/api/v1/customers/812",
headers={"Authorization": f"ApiKey {os.environ['FLUX_API_KEY']}"},
json={
"phone": "+2348098765432",
"regulatedEntityCount": 4,
},
timeout=30,
)
print(response.status_code, response.json())<?php
$body = <<<'JSON'
{
"phone": "+2348098765432",
"regulatedEntityCount": 4
}
JSON;
$ch = curl_init(getenv('FLUX_BASE_URL') . '/api/v1/customers/812');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_HTTPHEADER => [
'Authorization: ApiKey ' . getenv('FLUX_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => $body,
CURLOPT_RETURNTRANSFER => true,
]);
$response = curl_exec($ch);
echo curl_getinfo($ch, CURLINFO_HTTP_CODE), ' ', $response, PHP_EOL;using System.Net.Http.Headers;
using System.Text;
var baseUrl = Environment.GetEnvironmentVariable("FLUX_BASE_URL");
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("ApiKey", Environment.GetEnvironmentVariable("FLUX_API_KEY"));
using var request = new HttpRequestMessage(HttpMethod.Patch, $"{baseUrl}/api/v1/customers/812");
request.Content = new StringContent("""
{
"phone": "+2348098765432",
"regulatedEntityCount": 4
}
""", Encoding.UTF8, "application/json");
using var response = await http.SendAsync(request);
Console.WriteLine($"{(int)response.StatusCode} {await response.Content.ReadAsStringAsync()}");package main
import (
"fmt"
"io"
"net/http"
"os"
"strings"
)
func main() {
body := strings.NewReader(`{
"phone": "+2348098765432",
"regulatedEntityCount": 4
}`)
req, err := http.NewRequest("PATCH", os.Getenv("FLUX_BASE_URL")+"/api/v1/customers/812", body)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "ApiKey "+os.Getenv("FLUX_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
out, _ := io.ReadAll(resp.Body)
fmt.Println(resp.StatusCode, string(out))
}Responses 200 OK{
"id" : 812 ,
"externalRef" : "ws_42" ,
"customerType" : "company" ,
"name" : "Leadway Group Plc" ,
"legalName" : "Leadway Group Plc" ,
"companyName" : "Leadway Group" ,
"firstName" : null ,
"lastName" : null ,
"email" : "finance@leadway.example" ,
"phone" : "+2348098765432" ,
"address" : "121 Funso Williams Ave, Lagos" ,
"taxId" : "12345678-0001" ,
"vatNumber" : "VAT-001" ,
"rcNumber" : "RC123456" ,
"parentCustomerId" : null ,
"regulatedEntityCount" : 4 ,
"defaultCurrency" : "NGN" ,
"defaultSettlementBankId" : null ,
"contacts" : [
{
"name" : "Finance" ,
"email" : "finance@leadway.example" ,
"phone" : null ,
"isBillingPrimary" : true ,
"ccOnInvoices" : false
},
{
"name" : "CFO" ,
"email" : "cfo@leadway.example" ,
"phone" : null ,
"isBillingPrimary" : false ,
"ccOnInvoices" : true
}
],
"createdAt" : "2026-11-01T10:20:00" ,
"updatedAt" : "2026-11-08T16:45:00"
}6 possible errors Status Code When 400invalid_requestValidation failed. The message says what, such as Add at least one invoice item . 404not_foundUnknown id, or an id that belongs to another organization. 409conflictA uniqueness rule failed, such as another customer having the same externalRef. 401unauthorizedNo API key, an unknown key or a revoked key. 403insufficient_scopeThe key lacks the scope. details names it: { "required": "invoices:write" }. 429rate_limitedToo many requests for this key. Wait for the Retry-After seconds.
Get a customer# GET /api/v1/customers/{id}customers:read
Returns the customer with its billing contacts.
Path parameters Field Description id integer required The customer's id.
Request cURL Node.js Python PHP C# Go
Copy curl "$FLUX_BASE_URL/api/v1/customers/812" \
-H "Authorization: ApiKey $FLUX_API_KEY"// Node.js 18+ (built-in fetch). Save as an .mjs file.
const response = await fetch(`${process.env.FLUX_BASE_URL}/api/v1/customers/812`, {
headers: {
Authorization: `ApiKey ${process.env.FLUX_API_KEY}`,
},
});
console.log(response.status, await response.json());import os
import requests
response = requests.get(
f"{os.environ['FLUX_BASE_URL']}/api/v1/customers/812",
headers={"Authorization": f"ApiKey {os.environ['FLUX_API_KEY']}"},
timeout=30,
)
print(response.status_code, response.json())<?php
$ch = curl_init(getenv('FLUX_BASE_URL') . '/api/v1/customers/812');
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => [
'Authorization: ApiKey ' . getenv('FLUX_API_KEY'),
],
CURLOPT_RETURNTRANSFER => true,
]);
$response = curl_exec($ch);
echo curl_getinfo($ch, CURLINFO_HTTP_CODE), ' ', $response, PHP_EOL;using System.Net.Http.Headers;
var baseUrl = Environment.GetEnvironmentVariable("FLUX_BASE_URL");
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("ApiKey", Environment.GetEnvironmentVariable("FLUX_API_KEY"));
using var request = new HttpRequestMessage(HttpMethod.Get, $"{baseUrl}/api/v1/customers/812");
using var response = await http.SendAsync(request);
Console.WriteLine($"{(int)response.StatusCode} {await response.Content.ReadAsStringAsync()}");package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", os.Getenv("FLUX_BASE_URL")+"/api/v1/customers/812", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "ApiKey "+os.Getenv("FLUX_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
out, _ := io.ReadAll(resp.Body)
fmt.Println(resp.StatusCode, string(out))
}Responses 200 OK{
"id" : 812 ,
"externalRef" : "ws_42" ,
"customerType" : "company" ,
"name" : "Leadway Group Plc" ,
"legalName" : "Leadway Group Plc" ,
"companyName" : "Leadway Group" ,
"firstName" : null ,
"lastName" : null ,
"email" : "finance@leadway.example" ,
"phone" : "+2348012345678" ,
"address" : "121 Funso Williams Ave, Lagos" ,
"taxId" : "12345678-0001" ,
"vatNumber" : "VAT-001" ,
"rcNumber" : "RC123456" ,
"parentCustomerId" : null ,
"regulatedEntityCount" : 3 ,
"defaultCurrency" : "NGN" ,
"defaultSettlementBankId" : null ,
"contacts" : [
{
"name" : "Finance" ,
"email" : "finance@leadway.example" ,
"phone" : null ,
"isBillingPrimary" : true ,
"ccOnInvoices" : false
},
{
"name" : "CFO" ,
"email" : "cfo@leadway.example" ,
"phone" : null ,
"isBillingPrimary" : false ,
"ccOnInvoices" : true
}
],
"createdAt" : "2026-11-01T10:20:00" ,
"updatedAt" : null
}4 possible errors Status Code When 404not_foundUnknown id, or an id that belongs to another organization. 401unauthorizedNo API key, an unknown key or a revoked key. 403insufficient_scopeThe key lacks the scope. details names it: { "required": "invoices:write" }. 429rate_limitedToo many requests for this key. Wait for the Retry-After seconds.
List customers# GET /api/v1/customerscustomers:read
Lists customers, newest first. Filter by externalRef to find the customer you created for one of your records. List results have contacts: null; get the customer to read its contacts.
Query parameters Field Description externalRef string Only the customer with this reference. limit integer Items per page, 1 to 100. Default 25. cursor string The nextCursor from the previous page. Leave it out for the first page.
Request cURL Node.js Python PHP C# Go
Copy curl "$FLUX_BASE_URL/api/v1/customers?externalRef=ws_42" \
-H "Authorization: ApiKey $FLUX_API_KEY"// Node.js 18+ (built-in fetch). Save as an .mjs file.
const response = await fetch(`${process.env.FLUX_BASE_URL}/api/v1/customers?externalRef=ws_42`, {
headers: {
Authorization: `ApiKey ${process.env.FLUX_API_KEY}`,
},
});
console.log(response.status, await response.json());import os
import requests
response = requests.get(
f"{os.environ['FLUX_BASE_URL']}/api/v1/customers",
headers={"Authorization": f"ApiKey {os.environ['FLUX_API_KEY']}"},
params={
"externalRef": "ws_42",
},
timeout=30,
)
print(response.status_code, response.json())<?php
$ch = curl_init(getenv('FLUX_BASE_URL') . '/api/v1/customers?externalRef=ws_42');
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => [
'Authorization: ApiKey ' . getenv('FLUX_API_KEY'),
],
CURLOPT_RETURNTRANSFER => true,
]);
$response = curl_exec($ch);
echo curl_getinfo($ch, CURLINFO_HTTP_CODE), ' ', $response, PHP_EOL;using System.Net.Http.Headers;
var baseUrl = Environment.GetEnvironmentVariable("FLUX_BASE_URL");
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("ApiKey", Environment.GetEnvironmentVariable("FLUX_API_KEY"));
using var request = new HttpRequestMessage(HttpMethod.Get, $"{baseUrl}/api/v1/customers?externalRef=ws_42");
using var response = await http.SendAsync(request);
Console.WriteLine($"{(int)response.StatusCode} {await response.Content.ReadAsStringAsync()}");package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", os.Getenv("FLUX_BASE_URL")+"/api/v1/customers?externalRef=ws_42", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "ApiKey "+os.Getenv("FLUX_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
out, _ := io.ReadAll(resp.Body)
fmt.Println(resp.StatusCode, string(out))
}Responses 200 OKA page of customers. An empty data array means no match.
{
"data" : [
{
"id" : 812 ,
"externalRef" : "ws_42" ,
"customerType" : "company" ,
"name" : "Leadway Group Plc" ,
"legalName" : "Leadway Group Plc" ,
"companyName" : "Leadway Group" ,
"firstName" : null ,
"lastName" : null ,
"email" : "finance@leadway.example" ,
"phone" : "+2348012345678" ,
"address" : "121 Funso Williams Ave, Lagos" ,
"taxId" : "12345678-0001" ,
"vatNumber" : "VAT-001" ,
"rcNumber" : "RC123456" ,
"parentCustomerId" : null ,
"regulatedEntityCount" : 3 ,
"defaultCurrency" : "NGN" ,
"defaultSettlementBankId" : null ,
"contacts" : null ,
"createdAt" : "2026-11-01T10:20:00" ,
"updatedAt" : null
}
],
"nextCursor" : null ,
"hasMore" : false
}3 possible errors Status Code When 401unauthorizedNo API key, an unknown key or a revoked key. 403insufficient_scopeThe key lacks the scope. details names it: { "required": "invoices:write" }. 429rate_limitedToo many requests for this key. Wait for the Retry-After seconds.
List a customer's enrollments# GET /api/v1/customers/{id}/enrollmentscustomers:read
The services the customer is enrolled in: their current plan. Returns an array, newest first, not a page.
Path parameters Field Description id integer required The customer's id.
This endpoint doesn't return billingCycle or nextBillingDate yet. The enrollment webhook object does. See Known limitations .
Request cURL Node.js Python PHP C# Go
Copy curl "$FLUX_BASE_URL/api/v1/customers/812/enrollments" \
-H "Authorization: ApiKey $FLUX_API_KEY"// Node.js 18+ (built-in fetch). Save as an .mjs file.
const response = await fetch(`${process.env.FLUX_BASE_URL}/api/v1/customers/812/enrollments`, {
headers: {
Authorization: `ApiKey ${process.env.FLUX_API_KEY}`,
},
});
console.log(response.status, await response.json());import os
import requests
response = requests.get(
f"{os.environ['FLUX_BASE_URL']}/api/v1/customers/812/enrollments",
headers={"Authorization": f"ApiKey {os.environ['FLUX_API_KEY']}"},
timeout=30,
)
print(response.status_code, response.json())<?php
$ch = curl_init(getenv('FLUX_BASE_URL') . '/api/v1/customers/812/enrollments');
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => [
'Authorization: ApiKey ' . getenv('FLUX_API_KEY'),
],
CURLOPT_RETURNTRANSFER => true,
]);
$response = curl_exec($ch);
echo curl_getinfo($ch, CURLINFO_HTTP_CODE), ' ', $response, PHP_EOL;using System.Net.Http.Headers;
var baseUrl = Environment.GetEnvironmentVariable("FLUX_BASE_URL");
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("ApiKey", Environment.GetEnvironmentVariable("FLUX_API_KEY"));
using var request = new HttpRequestMessage(HttpMethod.Get, $"{baseUrl}/api/v1/customers/812/enrollments");
using var response = await http.SendAsync(request);
Console.WriteLine($"{(int)response.StatusCode} {await response.Content.ReadAsStringAsync()}");package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", os.Getenv("FLUX_BASE_URL")+"/api/v1/customers/812/enrollments", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "ApiKey "+os.Getenv("FLUX_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
out, _ := io.ReadAll(resp.Body)
fmt.Println(resp.StatusCode, string(out))
}Responses 200 OK[
{
"id" : 31 ,
"serviceId" : 7 ,
"serviceName" : "Subscription" ,
"amount" : 250000.00 ,
"enrolledFrom" : "2026-10-01T00:00:00" ,
"enrolledTo" : null ,
"active" : true
}
]4 possible errors Status Code When 404not_foundUnknown id, or an id that belongs to another organization. 401unauthorizedNo API key, an unknown key or a revoked key. 403insufficient_scopeThe key lacks the scope. details names it: { "required": "invoices:write" }. 429rate_limitedToo many requests for this key. Wait for the Retry-After seconds.
Get a customer's statement# GET /api/v1/customers/{id}/statementcustomers:read
Open, overdue and paid totals per currency, for a billing page or a credit check. Counts approved and paid invoices; voided ones are excluded.
Path parameters Field Description id integer required The customer's id.
Request cURL Node.js Python PHP C# Go
Copy curl "$FLUX_BASE_URL/api/v1/customers/812/statement" \
-H "Authorization: ApiKey $FLUX_API_KEY"// Node.js 18+ (built-in fetch). Save as an .mjs file.
const response = await fetch(`${process.env.FLUX_BASE_URL}/api/v1/customers/812/statement`, {
headers: {
Authorization: `ApiKey ${process.env.FLUX_API_KEY}`,
},
});
console.log(response.status, await response.json());import os
import requests
response = requests.get(
f"{os.environ['FLUX_BASE_URL']}/api/v1/customers/812/statement",
headers={"Authorization": f"ApiKey {os.environ['FLUX_API_KEY']}"},
timeout=30,
)
print(response.status_code, response.json())<?php
$ch = curl_init(getenv('FLUX_BASE_URL') . '/api/v1/customers/812/statement');
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => [
'Authorization: ApiKey ' . getenv('FLUX_API_KEY'),
],
CURLOPT_RETURNTRANSFER => true,
]);
$response = curl_exec($ch);
echo curl_getinfo($ch, CURLINFO_HTTP_CODE), ' ', $response, PHP_EOL;using System.Net.Http.Headers;
var baseUrl = Environment.GetEnvironmentVariable("FLUX_BASE_URL");
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("ApiKey", Environment.GetEnvironmentVariable("FLUX_API_KEY"));
using var request = new HttpRequestMessage(HttpMethod.Get, $"{baseUrl}/api/v1/customers/812/statement");
using var response = await http.SendAsync(request);
Console.WriteLine($"{(int)response.StatusCode} {await response.Content.ReadAsStringAsync()}");package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("GET", os.Getenv("FLUX_BASE_URL")+"/api/v1/customers/812/statement", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "ApiKey "+os.Getenv("FLUX_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
out, _ := io.ReadAll(resp.Body)
fmt.Println(resp.StatusCode, string(out))
}Responses 200 OK{
"customerId" : 812 ,
"currencies" : [
{
"currency" : "NGN" ,
"open" : 500000.00 ,
"overdue" : 250000.00 ,
"paid" : 1250000.00 ,
"openCount" : 2 ,
"overdueCount" : 1 ,
"paidCount" : 5
}
]
}4 possible errors Status Code When 404not_foundUnknown id, or an id that belongs to another organization. 401unauthorizedNo API key, an unknown key or a revoked key. 403insufficient_scopeThe key lacks the scope. details names it: { "required": "invoices:write" }. 429rate_limitedToo many requests for this key. Wait for the Retry-After seconds.