Create, list, retrieve and update Netcash debit order mandates, and issue debit order agreements for online signing.
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.
Note
Needs the REST API and Debit orders in your plan (403 plan_restricted otherwise), and a Netcash debit order provider. Creating a mandate counts towards your plan's active mandate limit (403 plan_limit).
Mandate endpoints Endpoint Purpose 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# {
"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 Field Type Description accountReferencerequired string DO + 10 hex characters. Debit order transactions use {accountReference}-{YYYYMMDD} as their reference.status, stagerequired string Status and stage customerId, productId, subscriptionIdrequired string | null The customer, an optional product and the customer subscription the mandate collects. amount, currencyrequired number, string Amount per debit; always ZAR. frequency, debitDayrequired string, integer monthly, quarterly, biannually or annually; day of the month (days past month-end use the last day).startDate, endDate, nextDebitDate, lastCollectedAtrequired string (date) | null Business dates (YYYY-MM-DD). bankrequired object { name, branchCode, accountType, accountHolder, accountNumberLast4 }. The full account number is never returned.idNumberLast4required string | null Last 4 digits of the ID number, if given. eMandateUrlrequired string | null Netcash e-mandate URL while waiting for the customer to sign it. authorisedAt, approvedAt, rejectedAt, rejectionReasonrequired string | null When the customer authorised it, and your team's approval or rejection. failureCountrequired integer Consecutive unpaids; the mandate is paused automatically at 3. agreementrequired object { signed, signedAt, latest: { id, status } }; latest.status is open, signed, cancelled or expired.
Status and stage# Mandate stages status stage Meaning 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 Field Type Description customerId or customerrequired string | object Exactly one: the ID, or { "id" } / { "externalReference" }. bank.branchCoderequired string 6 digits. bank.accountNumberrequired string Digits (spaces and dashes are removed); validated for live Netcash accounts. bank.accountHolderrequired string 2–30 characters. bank.accountTypeoptional string current (default), savings or transmission.bank.nameoptional string Bank name, up to 60 characters. amountrequired number Greater than 0, up to 1 000 000 (ZAR). frequencyoptional string Default monthly. debitDayoptional integer 1–31; default from your debit order settings. startDate, endDateoptional string (date) YYYY-MM-DD. Start today or later (default today); end after start. providerIdoptional string Netcash provider; default your first enabled one. productId, subscriptionIdoptional string Link a product, or the customer subscription to collect. descriptionoptional string Up to 500 characters; defaults to the product name. idNumberoptional string Account holder's ID number (up to 20 characters). notesoptional string Internal notes, up to 2000 characters. authorityoptional string agreement (default), emandate or offline. See below.confirmOfflineMandateoptional boolean Must be true with authority: "offline".
cURL Node.js PHP Python C# .NET
Copy 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 authority What 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.
Important
Both the API and the dashboard's new mandate form default to agreement. If your settings require a signed agreement, only mandates with a signed CentraPoint agreement are included in batches, so an e-mandate or offline mandate is then only collected once a CentraPoint agreement has also been signed for it.
List mandates# GET /api/v1/mandates
List query parameters Field Type Description customerIdoptional string Filter by customer. statusoptional string pending, active, paused or cancelled.accountReferenceoptional string Exact match (case-insensitive). limitoptional integer 1–100, default 20.
Returns { "data": [ … ] }, newest first.
cURL Node.js PHP Python C# .NET
Copy 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 Node.js PHP Python C# .NET
Copy 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 Field Type Description amountoptional number New debit amount. debitDayoptional integer 1–31. statusoptional string paused stops debits, active resumes a paused mandate, cancelled is permanent.
cURL Node.js PHP Python C# .NET
Copy 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 Field Type Description emailoptional boolean Default true: email the signing link to the customer. false only returns it. notesoptional string Up to 2000 characters.
cURL Node.js PHP Python C# .NET
Copy 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
}'{
"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 Status error When 400 invalid_requestValidation failed: bank details, start date in the past, unknown customer/product/subscription, no Netcash provider, Netcash rejected the e-mandate, offline without confirmOfflineMandate. 403 plan_restrictedNo REST API or Debit orders in your plan. 403 plan_limit / account_restrictedMandate limit reached, or the account is read-only. 404 not_foundNo mandate with this ID in your organisation. 409 invalid_requestPATCH status: "active" on a mandate that isn't paused. 409 idempotency_conflictIdempotency-Key reused with a different body (create). 401 / 429 / 500 unauthorized / rate_limited / internal_errorSee Errors