CentraPoint

API

Customers API

Create, upsert, list, retrieve and update customers, keyed by your own externalReference.

On this page

Overview#

Customers are the people and businesses you invoice and take payments from. Keep them in sync with your own system by sending your ID as externalReference: creating with the same reference again updates the existing customer instead of duplicating it. Available on every plan that includes the REST API.

Customer endpoints
EndpointPurpose
POST /api/v1/customersCreate, or upsert by externalReference
GET /api/v1/customersList, filter by externalReference or email
GET /api/v1/customers/{id}Get one customer
PATCH /api/v1/customers/{id}Update fields

The customer object#

Customer
{
  "id": "cmg2c0s7t0003cust0001abcd",
  "accountCode": "CUS-00042",
  "externalReference": "CRM-1001",
  "email": "[email protected]",
  "firstName": "Thandi",
  "lastName": "Nkosi",
  "company": "Nkosi Trading (Pty) Ltd",
  "vatNumber": "4123456789",
  "phone": "+27821234567",
  "address": "12 Long Street, Cape Town, 8001",
  "active": true,
  "metadata": {
    "crmId": "0061x00000AbCdE"
  },
  "createdAt": "2026-09-25T08:00:00.000Z",
  "updatedAt": "2026-09-25T08:00:00.000Z"
}
Customer fields
FieldTypeDescription
idrequiredstringCentraPoint customer ID.
accountCoderequiredstringAccount code assigned by CentraPoint (shown on invoices and in accounting exports).
externalReferencerequiredstring | nullYour ID for the customer.
emailrequiredstringStored in lower case.
firstNamerequiredstring
lastName, company, vatNumber, phone, addressrequiredstring | nullOptional details, printed on invoices where relevant.
activerequiredbooleanInactive customers are kept for history.
metadatarequiredobjectYour key/value data; {} when empty. See metadata.
createdAt, updatedAtrequiredstringISO 8601 UTC timestamps.

Create or upsert a customer#

POST/api/v1/customers
Create customer fields
FieldTypeDescription
externalReferenceoptionalstring1–190 characters. Your ID; makes the request an upsert.
emailrequiredstring (email)Up to 200 characters.
firstNamerequiredstring1–100 characters.
lastNameoptionalstring | nullUp to 100 characters.
companyoptionalstring | nullUp to 200 characters.
vatNumberoptionalstring | nullUp to 30 characters.
phoneoptionalstring | nullUp to 30 characters.
addressoptionalstring | nullUp to 1000 characters.
metadataoptionalobjectKey/value data (rules).
curl -X POST "https://app.centrapoint.co.za/api/v1/customers" \
  -H "Authorization: Bearer $CENTRAPOINT_API_KEY" \
  -H "Idempotency-Key: 3f6c2a4e-8d1b-4f7a-9c2e-5b1d0a7e6f31" \
  -H "Content-Type: application/json" \
  -d '{
    "externalReference": "CRM-1001",
    "email": "[email protected]",
    "firstName": "Thandi",
    "lastName": "Nkosi",
    "company": "Nkosi Trading (Pty) Ltd",
    "vatNumber": "4123456789",
    "phone": "+27821234567",
    "metadata": {
      "crmId": "0061x00000AbCdE"
    }
  }'

Returns the customer object. Supports the Idempotency-Key header.

Upsert rules#

Create versus upsert outcomes
RequestSituationResult
No externalReference–201 new customer (even if the email already exists)
With externalReferenceA customer has this reference200 that customer updated with the sent fields
With externalReferenceNo match, but a customer with the same email has no reference200 that customer is adopted: the reference is set and fields updated
With externalReferenceNo match201 new customer

On update, fields you omit keep their values. Concurrent upserts with the same reference are serialised, so they never create two customers. Creating a customer counts towards your plan's customer limit (403 plan_limit).

List customers#

GET/api/v1/customers
List query parameters
FieldTypeDescription
externalReferenceoptionalstringExact match.
emailoptionalstringExact match, case-insensitive.
limitoptionalinteger1–100, default 20.

Returns { "data": [ … ] }, newest first.

curl -X GET "https://app.centrapoint.co.za/api/v1/customers?externalReference=CRM-1001" \
  -H "Authorization: Bearer $CENTRAPOINT_API_KEY"

Get a customer#

GET/api/v1/customers/{id}
curl -X GET "https://app.centrapoint.co.za/api/v1/customers/cmg2c0s7t0003cust0001abcd" \
  -H "Authorization: Bearer $CENTRAPOINT_API_KEY"

Update a customer#

PATCH/api/v1/customers/{id}

Partial update: send only the fields to change. null clears an optional field. metadata replaces the whole map (send null to clear it). active: false deactivates the customer. You can also set or change externalReference (it must not belong to another customer). Unknown fields are rejected with 400. The Idempotency-Key header is not used on PATCH, which is safe to repeat.

curl -X PATCH "https://app.centrapoint.co.za/api/v1/customers/cmg2c0s7t0003cust0001abcd" \
  -H "Authorization: Bearer $CENTRAPOINT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+27829876543",
    "company": null
  }'

Errors#

Customer errors
StatuserrorWhen
400invalid_requestValidation failed, invalid metadata, unknown field (PATCH), or externalReference already used by another customer (PATCH).
401unauthorizedMissing or invalid API key.
403plan_restricted / plan_limit / account_restrictedNo API access, customer limit reached, or account read-only (writes).
404not_foundNo customer with this ID in your organisation.
409idempotency_conflictIdempotency-Key reused with a different body (POST).
429 / 500rate_limited / internal_errorSee Errors