CentraPoint

API

Mandates API

Create, list, retrieve and update Netcash debit order mandates, and issue debit order agreements for online signing.

On this page

Overview#

A mandate is a customer's authority to debit their bank account through your Netcash debit order account. Read the Debit orders guide for how mandates are authorised, approved, batched and collected. Batches, batch approval, unpaids and debit order settings stay in the dashboard.

Mandate endpoints
EndpointPurpose
POST /api/v1/mandatesCreate a mandate
GET /api/v1/mandatesList mandates
GET /api/v1/mandates/{id}Get a mandate
PATCH /api/v1/mandates/{id}Change amount or debit day; pause, resume or cancel
POST /api/v1/mandates/{id}/agreementIssue an agreement for online signing

The mandate object#

Mandate
{
  "id": "cmg4m3n4o0006mdt0001abcd",
  "object": "mandate",
  "accountReference": "DO7F3A1C9B2E",
  "status": "pending",
  "stage": "awaiting_signature",
  "customerId": "cmg2c0s7t0003cust0001abcd",
  "productId": null,
  "subscriptionId": null,
  "description": "Monthly service fee",
  "amount": 499,
  "currency": "ZAR",
  "frequency": "monthly",
  "debitDay": 1,
  "startDate": "2026-10-01",
  "endDate": null,
  "nextDebitDate": null,
  "bank": {
    "name": "FNB",
    "branchCode": "250655",
    "accountType": "current",
    "accountHolder": "T Nkosi",
    "accountNumberLast4": "6789"
  },
  "idNumberLast4": null,
  "eMandateUrl": null,
  "authorisedAt": null,
  "approvedAt": null,
  "rejectedAt": null,
  "rejectionReason": null,
  "failureCount": 0,
  "lastCollectedAt": null,
  "agreement": {
    "signed": false,
    "signedAt": null,
    "latest": {
      "id": "cmg4a7g8r0007agr0001abcd",
      "status": "open"
    }
  },
  "createdAt": "2026-09-28T08:20:00.000Z",
  "updatedAt": "2026-09-28T08:20:00.000Z"
}
Mandate fields
FieldTypeDescription
accountReferencerequiredstringDO + 10 hex characters. Debit order transactions use {accountReference}-{YYYYMMDD} as their reference.
status, stagerequiredstringStatus and stage
customerId, productId, subscriptionIdrequiredstring | nullThe customer, an optional product and the customer subscription the mandate collects.
amount, currencyrequirednumber, stringAmount per debit; always ZAR.
frequency, debitDayrequiredstring, integermonthly, quarterly, biannually or annually; day of the month (days past month-end use the last day).
startDate, endDate, nextDebitDate, lastCollectedAtrequiredstring (date) | nullBusiness dates (YYYY-MM-DD).
bankrequiredobject{ name, branchCode, accountType, accountHolder, accountNumberLast4 }. The full account number is never returned.
idNumberLast4requiredstring | nullLast 4 digits of the ID number, if given.
eMandateUrlrequiredstring | nullNetcash e-mandate URL while waiting for the customer to sign it.
authorisedAt, approvedAt, rejectedAt, rejectionReasonrequiredstring | nullWhen the customer authorised it, and your team's approval or rejection.
failureCountrequiredintegerConsecutive unpaids; the mandate is paused automatically at 3.
agreementrequiredobject{ signed, signedAt, latest: { id, status } }; latest.status is open, signed, cancelled or expired.

Status and stage#

Mandate stages
statusstageMeaning
pendingawaiting_signatureWaiting for the customer to sign the agreement or e-mandate.
pendingawaiting_approvalSigned; your debit order settings require a staff member to approve it.
pendingpendingAuthorised and approved, about to activate.
activeactiveIncluded in batches when due.
pausedpausedSkipped until resumed (manually, with its subscription, or after 3 unpaids).
cancelledcancelled or rejectedStopped permanently; rejected by your team, or cancelled.

Create a mandate#

POST/api/v1/mandates
Create mandate fields
FieldTypeDescription
customerId or customerrequiredstring | objectExactly one: the ID, or { "id" } / { "externalReference" }.
bank.branchCoderequiredstring6 digits.
bank.accountNumberrequiredstringDigits (spaces and dashes are removed); validated for live Netcash accounts.
bank.accountHolderrequiredstring2–30 characters.
bank.accountTypeoptionalstringcurrent (default), savings or transmission.
bank.nameoptionalstringBank name, up to 60 characters.
amountrequirednumberGreater than 0, up to 1 000 000 (ZAR).
frequencyoptionalstringDefault monthly.
debitDayoptionalinteger1–31; default from your debit order settings.
startDate, endDateoptionalstring (date)YYYY-MM-DD. Start today or later (default today); end after start.
providerIdoptionalstringNetcash provider; default your first enabled one.
productId, subscriptionIdoptionalstringLink a product, or the customer subscription to collect.
descriptionoptionalstringUp to 500 characters; defaults to the product name.
idNumberoptionalstringAccount holder's ID number (up to 20 characters).
notesoptionalstringInternal notes, up to 2000 characters.
authorityoptionalstringagreement (default), emandate or offline. See below.
confirmOfflineMandateoptionalbooleanMust be true with authority: "offline".
curl -X POST "https://app.centrapoint.co.za/api/v1/mandates" \
  -H "Authorization: Bearer $CENTRAPOINT_API_KEY" \
  -H "Idempotency-Key: 0b7c9e2d-4f1a-4c8e-a6d3-9e5f2b1c7a40" \
  -H "Content-Type: application/json" \
  -d '{
    "customer": {
      "externalReference": "CRM-1001"
    },
    "description": "Monthly service fee",
    "bank": {
      "name": "FNB",
      "branchCode": "250655",
      "accountNumber": "62123456789",
      "accountType": "current",
      "accountHolder": "T Nkosi"
    },
    "amount": 499,
    "frequency": "monthly",
    "debitDay": 1,
    "startDate": "2026-10-01"
  }'

Returns 201 with the mandate plus warnings (non-blocking bank validation messages) and, for agreement authority, agreementSent: { id, emailed, expiresAt }. Supports the Idempotency-Key header.

Authority: agreement, e-mandate or offline#

Mandate authorities
authorityWhat happens
agreementCentraPoint emails the customer your debit order agreement (Debit orders → Settings) to sign online. The signing URL is not in the create response; issue one with the agreement endpoint if you want to show it yourself.
emandateNetcash creates an electronic mandate for the customer to sign; its link is returned as eMandateUrl. Netcash reports the signature back to CentraPoint.
offlineYou already hold a signed mandate. It is marked authorised and becomes active at once, unless your settings require mandate approval.

List mandates#

GET/api/v1/mandates
List query parameters
FieldTypeDescription
customerIdoptionalstringFilter by customer.
statusoptionalstringpending, active, paused or cancelled.
accountReferenceoptionalstringExact match (case-insensitive).
limitoptionalinteger1–100, default 20.

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

curl -X GET "https://app.centrapoint.co.za/api/v1/mandates?customerId=cmg2c0s7t0003cust0001abcd" \
  -H "Authorization: Bearer $CENTRAPOINT_API_KEY"

Get a mandate#

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

Update a mandate#

PATCH/api/v1/mandates/{id}
Update mandate fields
FieldTypeDescription
amountoptionalnumberNew debit amount.
debitDayoptionalinteger1–31.
statusoptionalstringpaused stops debits, active resumes a paused mandate, cancelled is permanent.
curl -X PATCH "https://app.centrapoint.co.za/api/v1/mandates/cmg4m3n4o0006mdt0001abcd" \
  -H "Authorization: Bearer $CENTRAPOINT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "paused"
  }'

Send at least one field. A pending mandate can't be set active (409): it activates once authorised and approved. The Idempotency-Key header is not used.

Issue an agreement for signing#

POST/api/v1/mandates/{id}/agreement
Agreement fields
FieldTypeDescription
emailoptionalbooleanDefault true: email the signing link to the customer. false only returns it.
notesoptionalstringUp to 2000 characters.
curl -X POST "https://app.centrapoint.co.za/api/v1/mandates/cmg4m3n4o0006mdt0001abcd/agreement" \
  -H "Authorization: Bearer $CENTRAPOINT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": false
  }'
201 response
{
  "id": "cmg4a7g8r0007agr0001abcd",
  "object": "mandate_agreement",
  "mandateId": "cmg4m3n4o0006mdt0001abcd",
  "status": "pending",
  "signUrl": "https://app.centrapoint.co.za/sign-mandate/3q9…",
  "expiresAt": "2026-10-12T08:20:00.000Z",
  "emailed": false
}

Renders your agreement template for this mandate and withdraws any agreement still open. The signUrl works for 14 days; treat it as a secret. This endpoint is never replayed from an Idempotency-Key, so each call issues a new link.

Errors#

Mandate errors
StatuserrorWhen
400invalid_requestValidation failed: bank details, start date in the past, unknown customer/product/subscription, no Netcash provider, Netcash rejected the e-mandate, offline without confirmOfflineMandate.
403plan_restrictedNo REST API or Debit orders in your plan.
403plan_limit / account_restrictedMandate limit reached, or the account is read-only.
404not_foundNo mandate with this ID in your organisation.
409invalid_requestPATCH status: "active" on a mandate that isn't paused.
409idempotency_conflictIdempotency-Key reused with a different body (create).
401 / 429 / 500unauthorized / rate_limited / internal_errorSee Errors