Creating and managing customers

A Customer record is the anchor for everything that follows—mandate setup, invoice issuance, and payment collection. Keep one Adfin customer.id per real-world payer and reuse it.

Resources at a glance

Field

Purpose

id

Immutable Adfin identifier, returned on creation of the customer

name

Legal name of the customer (business or individual)

people[]

Optional contacts (each can have a name, email, and phone). Can be allocated as primary contact, and if to include in communications

Addresses[]

A list of addresses for the customer. Currently, only one address is supported.

externalData[]

Key value pairs to connect with Accounting platforms.


Create a customer

Endpoint: POST /customers

Typical request:

{
  "name": "John Doe Ltd",
  "people": [
    { "name": "John Doe", "email": "[email protected]" }
  ],
  "addresses": [
    { "line1": "2 Catherine Pl", "city": "London", "postCode": "SW1E 6HF" }
  ],
  "externalData": { "xeroContactId": "abc-123" }
}

Full API docs: [https://docs.adfin.com/v2.0/reference/postinvoice#/versions]

Key rules:

  • Idempotency by body hash – sending the same payload again has no side effects.
  • Validation first – you’ll get 422 for malformed email, missing name, or array size > 1.
  • You will be returned a direct debit URL as part of the response, if you want to include the direct debit link for the customer or distribute it on your side.

The response echoes a populated CustomerResponse object, including the customer ID and direct debit.


Direct debits for customers

Endpoint: GET /customers/[id]/directdebitmandates

  1. Call GET /customers/[id]/directdebitmandates with a JSON body containing a redirectUrl to bring the user back to your app (it is also returned in the create customer response).
  2. We return a URL — send the customer there to sign the mandate.
  3. Listen for the dd-mandate. Updated webhook to know when status moves to ACTIVE.

If you ever need to void a mandate (e.g., customer changed bank), call
PUT /customers/directdebitmandates/[id]: cancel.


Retrieve or update a customer

Action

Method & Path

Get by ID

GET /customers/[id] – add includeCustomerFinancialDetails=true to embed ageing & balance.

Update

PUT /customers with the full object, including id; only changed fields are persisted.

As per the PUT standard, this will not append data, but totally replace it.

If you are performing PUT customer updates, it is recommended to get the latest response from GET and merge your new fields to avoid overwriting changes in Adfin or Xero.

Delete

DELETE /customers/[id] to hard remove a customer


List & search customers

Endpoint: GET /customers

Supports rich server-side filtering so you rarely need client-side joins.


Query ParameterExample use
searchTextFuzzy search on name, email
onlyCustomersWithActivity=trueShow customers who have invoices or mandates
ddMandateStatuses=ACTIVEPre-filter by mandate status
financialStatus=OVERDUESurface at-risk customers as part of credit control
PaginationPage & Size

Best practices

  1. Create once, reuse forever – keep the Adfin customer ID in your DB.
  2. Attach mandate ASAP – trigger mandate creation right after sign-up so future invoices auto-collect.
  3. Sync contacts – push updated emails or addresses with PUT /customers whenever they change.
  4. Stay event-driven – subscribe to customer, updated, and dd-mandate. Updated to mirror state instantly.

What’s Next

Now you're ready to create invoices for customers