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.

EndpointWhat it does
POST /api/v1/customersCreate a customer
PATCH /api/v1/customers/{id}Update a customer
GET /api/v1/customers/{id}Get a customer
GET /api/v1/customersList customers
GET /api/v1/customers/{id}/enrollmentsList a customer's enrollments
GET /api/v1/customers/{id}/statementGet a customer's statement

The customer object#

Someone the organization bills: an individual or a company.

FieldDescription
idintegerFlux's id for the customer.
externalRefstring · nullableYour id for the customer, such as a workspace id. Unique within the organization.
customerTypestringindividual or company.
namestringThe billing name. For a company, the legal name, else the company name. For an individual, their name.
legalNamestring · nullableRegistered legal name.
companyNamestring · nullableTrading name. Set for companies.
firstNamestring · nullableSet for individuals.
lastNamestring · nullableSet for individuals.
emailstringThe customer's email. Gets invoices when there's no primary contact.
phonestring · nullableIn international format.
addressstring · nullablePostal address.
taxIdstring · nullableTax identification number (TIN). Unique within the organization.
vatNumberstring · nullableVAT registration number.
rcNumberstring · nullableCAC registration (RC) number.
parentCustomerIdinteger · nullableThe group company this customer belongs to, in the same organization.
regulatedEntityCountinteger · nullableNumber of regulated entities. 0 or more.
defaultCurrencystring · nullablePre-fills the currency when someone raises an invoice for this customer in the Flux app. One of NGN, USD, CAD, EUR, GBP.
defaultSettlementBankIdinteger · nullableThe organization's bank account that this customer's payments settle into. Ids come from the Flux app.
contactsarray of Billing contact · nullableBilling contacts. Returned by get, create and update. Always null in list results.
createdAttimestampWhen the customer was created. Server time, no offset.
updatedAttimestamp · nullableWhen the customer last changed. null if never.
Customer
{
  "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
}

The billing contact object#

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.

FieldDescription
namestring · nullableLabel or person's name.
emailstringReceives invoices and receipts.
phonestring · nullablePhone number.
isBillingPrimarybooleanThe primary billing contact. At most one per customer.
ccOnInvoicesbooleanCopied 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.

FieldDescription
idintegerEnrollment id.
serviceIdintegerThe service in the organization's catalogue.
serviceNamestring · nullableThe service's name.
amountnumber (decimal)The agreed amount, else the service's price. Major units.
enrolledFromdateStart date.
enrolledTodate · nullableEnd date. null if open-ended.
activebooleanActive and within its dates today.
Enrollment
{
  "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.

FieldDescription
customerIdintegerThe customer.
currenciesarray of Currency totalsOne entry per currency the customer has invoices in. Empty if none.

Each entry in currencies:

FieldDescription
currencystringISO currency code. One of NGN, USD, CAD, EUR, GBP.
opennumber (decimal)Total of approved, unpaid invoices. Includes the overdue ones.
overduenumber (decimal)Total of open invoices past their due date.
paidnumber (decimal)Total of paid invoices.
openCountintegerNumber of open invoices.
overdueCountintegerNumber of overdue invoices.
paidCountintegerNumber of paid invoices.
Statement
{
  "customerId": 812,
  "currencies": [
    {
      "currency": "NGN",
      "open": 500000.00,
      "overdue": 250000.00,
      "paid": 1250000.00,
      "openCount": 2,
      "overdueCount": 1,
      "paidCount": 5
    }
  ]
}

Create a customer#

POST/api/v1/customerscustomers:writeIdempotency-Key

Creates a customer. Send an Idempotency-Key so a retry can't create a second one.

Request body

FieldDescription
customerTypestringoptional individual or company. Defaults to individual on create.
emailstringrequired A valid email address. Required on create.
firstNamestringoptional Required for individuals.
lastNamestringoptional Required for individuals.
phonestringoptional Required and must be valid for individuals. Optional for companies, but must be valid if sent.
companyNamestringoptional Required for companies.
legalNamestringoptional Registered legal name. Used as the billing name when set.
addressstringoptional Postal address.
taxIdstringoptional TIN. Another customer in the organization can't have the same one.
vatNumberstringoptional VAT registration number.
rcNumberstringoptional CAC registration (RC) number.
externalRefstringoptional Your id for the customer. At most 100 characters, unique within the organization.
parentCustomerIdintegeroptional A customer in the same organization. Can't be the customer itself, or a customer whose parent is this one.
regulatedEntityCountintegeroptional 0 or more.
defaultCurrencystringoptional A supported currency code. One of NGN, USD, CAD, EUR, GBP.
defaultSettlementBankIdintegeroptional One of the organization's bank account ids, from the Flux app.
contactsarray 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 -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
    }
  ]
}'

Responses

201 Created
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
StatusCodeWhen
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

FieldDescription
idintegerrequired The customer's id.

Request body

FieldDescription
customerTypestringoptional individual or company. Defaults to individual on create.
emailstringoptional A valid email address. Required on create.
firstNamestringoptional Required for individuals.
lastNamestringoptional Required for individuals.
phonestringoptional Required and must be valid for individuals. Optional for companies, but must be valid if sent.
companyNamestringoptional Required for companies.
legalNamestringoptional Registered legal name. Used as the billing name when set.
addressstringoptional Postal address.
taxIdstringoptional TIN. Another customer in the organization can't have the same one.
vatNumberstringoptional VAT registration number.
rcNumberstringoptional CAC registration (RC) number.
externalRefstringoptional Your id for the customer. At most 100 characters, unique within the organization.
parentCustomerIdintegeroptional A customer in the same organization. Can't be the customer itself, or a customer whose parent is this one.
regulatedEntityCountintegeroptional 0 or more.
defaultCurrencystringoptional A supported currency code. One of NGN, USD, CAD, EUR, GBP.
defaultSettlementBankIdintegeroptional One of the organization's bank account ids, from the Flux app.
contactsarray 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 -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
}'

Responses

200 OK
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
StatusCodeWhen
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

FieldDescription
idintegerrequired The customer's id.

Request

curl "$FLUX_BASE_URL/api/v1/customers/812" \
  -H "Authorization: ApiKey $FLUX_API_KEY"

Responses

200 OK
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
StatusCodeWhen
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

FieldDescription
externalRefstringOnly the customer with this reference.
limitintegerItems per page, 1 to 100. Default 25.
cursorstringThe nextCursor from the previous page. Leave it out for the first page.

Request

curl "$FLUX_BASE_URL/api/v1/customers?externalRef=ws_42" \
  -H "Authorization: ApiKey $FLUX_API_KEY"

Responses

200 OK

A page of customers. An empty data array means no match.

200 OK
{
  "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
StatusCodeWhen
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

FieldDescription
idintegerrequired The customer's id.

This endpoint doesn't return billingCycle or nextBillingDate yet. The enrollment webhook object does. See Known limitations.

Request

curl "$FLUX_BASE_URL/api/v1/customers/812/enrollments" \
  -H "Authorization: ApiKey $FLUX_API_KEY"

Responses

200 OK
200 OK
[
  {
    "id": 31,
    "serviceId": 7,
    "serviceName": "Subscription",
    "amount": 250000.00,
    "enrolledFrom": "2026-10-01T00:00:00",
    "enrolledTo": null,
    "active": true
  }
]
4 possible errors
StatusCodeWhen
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

FieldDescription
idintegerrequired The customer's id.

Request

curl "$FLUX_BASE_URL/api/v1/customers/812/statement" \
  -H "Authorization: ApiKey $FLUX_API_KEY"

Responses

200 OK
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
StatusCodeWhen
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.