CentraPoint

API

Credit notes API

Issue credit notes, apply credit to invoices, and pay credit back against a payment, by payout or manually.

On this page

Overview#

A credit note records money you owe a customer: a return, an overcharge or goodwill, optionally against one of their invoices. Once issued, its balance can be used in any mix of ways: applied to another invoice, refunded against one of the customer's payments, paid out to their bank account by Netcash payout, or recorded as paid back outside CentraPoint. Requires a plan that includes Invoicing.

Credit note endpoints
EndpointPurpose
POST /api/v1/credit-notesCreate (draft or issued)
GET /api/v1/credit-notesList, filter by status, customer or invoice
GET /api/v1/credit-notes/{id}Get one credit note
POST /api/v1/credit-notes/{id}/issueIssue a draft
POST /api/v1/credit-notes/{id}/voidVoid an unused credit note
POST /api/v1/credit-notes/{id}/applyApply credit to an invoice
POST /api/v1/credit-notes/{id}/refundPay credit back
GET /api/v1/credit-notes/{id}/pdfBranded credit note PDF

Wherever a path takes {id}, you can also use the credit note number (e.g. CN-000008).

The credit note object#

The same object is returned by every credit note endpoint and sent as data in credit_note.* webhooks.

Credit note
{
  "object": "credit_note",
  "id": "cmg3c7d8e0002crn0001abcd",
  "number": "CN-000008",
  "status": "issued",
  "issueDate": "2026-09-27T09:10:00.000Z",
  "periodStart": "2026-09-01",
  "periodEnd": "2026-09-30",
  "reason": "Hosting downtime 12-14 September",
  "currency": "ZAR",
  "taxInclusive": false,
  "subtotal": 200,
  "taxAmount": 30,
  "total": 230,
  "amountApplied": 100,
  "amountRefunded": 0,
  "balance": 130,
  "customer": {
    "id": "cmg2c0s7t0003cust0001abcd",
    "externalReference": "CRM-1001",
    "email": "[email protected]"
  },
  "invoice": {
    "id": "cmg2i9n0v0005inv0001abcd",
    "number": "INV-000042",
    "externalReference": "ORDER-1001"
  },
  "lineItems": [
    {
      "description": "Service credit - downtime",
      "details": "Outage 12-14 September (3 days)",
      "quantity": 1,
      "unitPrice": 200,
      "amount": 200,
      "taxRate": 15,
      "periodStart": "2026-09-12",
      "periodEnd": "2026-09-14"
    }
  ],
  "history": [
    {
      "at": "2026-09-27T09:20:00.000Z",
      "kind": "applied",
      "amount": 100,
      "ref": "INV-000051"
    }
  ],
  "refunds": [],
  "payouts": [],
  "issuedAt": "2026-09-27T09:10:00.000Z",
  "voidedAt": null,
  "createdAt": "2026-09-27T09:10:00.000Z",
  "updatedAt": "2026-09-27T09:20:00.000Z"
}
Credit note fields
FieldTypeDescription
objectrequiredstringAlways credit_note.
idrequiredstringCentraPoint credit note ID.
numberrequiredstringSequential number, e.g. CN-000008.
statusrequiredstringSee Statuses.
issueDaterequiredstringISO 8601 UTC timestamp.
periodStart, periodEndrequiredstring | nullPeriod being credited (YYYY-MM-DD, inclusive), or null. See Billing periods and line details.
reasonrequiredstring | nullWhy the credit was given (printed on the PDF).
currencyrequiredstringISO 4217 code (the invoice's currency when created against an invoice).
taxInclusiverequiredbooleanWhether line prices include tax.
subtotal, taxAmount, totalrequirednumberTotals excluding VAT, VAT, and including VAT.
amountAppliedrequirednumberApplied to invoices.
amountRefundedrequirednumberPaid back to the customer, including scheduled payouts that have not gone out yet (released again if the payout is cancelled or fails).
balancerequirednumbertotal − amountApplied − amountRefunded: credit still available.
customerrequiredobject{ id, externalReference, email }
invoicerequiredobject | null{ id, number, externalReference } of the invoice being credited.
lineItemsrequiredobject[]description, details (string | null), quantity, unitPrice, amount, taxRate (%), periodStart / periodEnd (YYYY-MM-DD | null).
historyrequiredobject[]How the credit was used: { at, kind, amount, ref, note? } with kind applied (ref = invoice number), refund (ref = payment reference), payout (ref = payout reference) or manual.
refundsrequiredobject[]Refunds recorded against payments: { id, number, amount, transactionId }. See the refund object.
payoutsrequiredobject[]Payouts: { id, reference, status, amount, actionDate, paidAt }. See the payout object.
issuedAt, voidedAtrequiredstring | null
createdAt, updatedAtrequiredstring

Statuses#

Credit note statuses
statusMeaning
draftCreated, not issued. The credit can't be used yet.
issuedIssued with a balance available.
appliedFully used, mostly applied to invoices.
refundedFully used, mostly paid back to the customer.
voidVoided before any of it was used.

Create a credit note#

POST/api/v1/credit-notes
Create credit note fields
FieldTypeDescription
customerIdoptionalstringThe customer's CentraPoint ID. Send at most one of customerId or customerExternalReference; one is required unless you send invoiceId.
customerExternalReferenceoptionalstringYour reference of an existing customer. An unknown customer returns 400.
invoiceIdoptionalstringCredit against this invoice. The customer defaults to the invoice's (and must match), the currency is the invoice's, and the default tax rate is the invoice's rate. Credit notes on one invoice can't add up to more than its total.
lineItemsrequiredobject[]1–200 lines, same rules as invoice lines, including optional details and periodStart / periodEnd. Without an invoice, the default taxRate is your organisation's tax rate.
currencyoptionalstringISO 4217 code, default ZAR (ignored in favour of the invoice's currency; a different one returns 400).
taxInclusiveoptionalbooleanDefault false.
periodStart, periodEndoptionalstring (YYYY-MM-DD)Period being credited, inclusive. Send both or neither; periodEnd must be on or after periodStart. Default: the invoice's period when you send invoiceId, else none.
reasonoptionalstringUp to 1000 chars.
notesoptionalstringUp to 4000 chars.
issueoptionalbooleanDefault false (draft). true issues it immediately.
curl -X POST "https://app.centrapoint.co.za/api/v1/credit-notes" \
  -H "Authorization: Bearer $CENTRAPOINT_API_KEY" \
  -H "Idempotency-Key: 4e8a2c6f-1d3b-4f9a-b7e5-8c0d2a4f6b19" \
  -H "Content-Type: application/json" \
  -d '{
    "invoiceId": "cmg2i9n0v0005inv0001abcd",
    "reason": "Hosting downtime 12-14 September",
    "lineItems": [
      {
        "description": "Service credit - downtime",
        "quantity": 1,
        "unitPrice": 200
      }
    ],
    "issue": true
  }'

Returns 201 with the credit note object. Send an Idempotency-Key so a retry doesn't create a second credit note.

List credit notes#

GET/api/v1/credit-notes
List query parameters
FieldTypeDescription
statusoptionalstringdraft, issued, applied, refunded or void.
customerIdoptionalstringOnly this customer's credit notes.
invoiceIdoptionalstringOnly credit notes against this invoice.
limit, startingAfteroptionalKeyset pagination: the response is { data, hasMore, nextCursor }, newest first.
curl -X GET "https://app.centrapoint.co.za/api/v1/credit-notes?status=issued" \
  -H "Authorization: Bearer $CENTRAPOINT_API_KEY"

Get a credit note#

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

Issue a credit note#

POST/api/v1/credit-notes/{id}/issue

Issues a draft so its credit can be used. No body is needed. Other statuses return 400. Emits credit_note.issued.

Void a credit note#

POST/api/v1/credit-notes/{id}/void

Voids a draft or issued credit note that hasn't been used (anything applied or refunded returns 400). Optional body { "reason": "…" } (up to 500 chars) is added to the notes. Voiding a void credit note returns it unchanged. Emits credit_note.voided.

Apply credit to an invoice#

POST/api/v1/credit-notes/{id}/apply
Apply fields
FieldTypeDescription
invoiceIdrequiredstringAn unpaid invoice of the same customer, in the same currency.
amountrequirednumberGreater than 0, at most the credit balance and the invoice's outstanding balance.
curl -X POST "https://app.centrapoint.co.za/api/v1/credit-notes/cmg3c7d8e0002crn0001abcd/apply" \
  -H "Authorization: Bearer $CENTRAPOINT_API_KEY" \
  -H "Idempotency-Key: a3c5e7f9-2b4d-4f6a-8c1e-3d5f7a9b1c02" \
  -H "Content-Type: application/json" \
  -d '{
    "invoiceId": "cmg2i9n0v0005inv0051abcd",
    "amount": 100
  }'

Records an invoice payment with method credit_note (the invoice gets invoice.paid or invoice.partially_paid as usual) and returns the updated credit note. Emits credit_note.applied.

Pay credit back#

POST/api/v1/credit-notes/{id}/refund

Pays some or all of the balance back to the customer. Every request has a method and an amount (greater than 0, at most the balance); the other fields depend on the method. Returns the updated credit note and emits credit_note.refunded. The credit note must be issued.

Against a payment#

method: payment
FieldTypeDescription
methodrequiredstringpayment
amountrequirednumberAt most what is left to refund on that payment.
transactionReferencerequiredstringReference of one of the customer's complete or partially_refunded payments (see the Transactions API).
referenceoptionalstringThe gateway's refund reference, kept on the refund.

Records a refund on the payment (which becomes refunded or partially_refunded and sends the matching payment.* webhook). CentraPoint does not move the money: process the refund in the gateway's own portal.

curl -X POST "https://app.centrapoint.co.za/api/v1/credit-notes/cmg3c7d8e0002crn0001abcd/refund" \
  -H "Authorization: Bearer $CENTRAPOINT_API_KEY" \
  -H "Idempotency-Key: b7d9f1a3-4c6e-4a8b-9d2f-5e7a9c1b3d46" \
  -H "Content-Type: application/json" \
  -d '{
    "method": "payment",
    "amount": 130,
    "transactionReference": "CP-20260925-9F3A1C7B",
    "reference": "PF-REFUND-88121"
  }'

By payout#

method: payout
FieldTypeDescription
methodrequiredstringpayout
amountrequirednumberZAR credit notes only.
actionDaterequiredstring (YYYY-MM-DD)When Netcash should pay. Not in the past.
bankrequiredobjectaccountHolder, accountNumber, branchCode, accountType (current, savings or transmission), optional bankName. Validated like the dashboard; stored encrypted and never returned.
beneficiaryNameoptionalstringUp to 50 chars. Default the account holder.
beneficiaryEmailoptionalstringOptional.
providerIdoptionalstringYour Netcash Creditor & Salary Payments gateway. Default: the first enabled one (400 if none).

Schedules a payout of kind refund linked to the credit note (it appears in payouts). The amount is reserved immediately and released again if the payout is cancelled or fails.

curl -X POST "https://app.centrapoint.co.za/api/v1/credit-notes/cmg3c7d8e0002crn0001abcd/refund" \
  -H "Authorization: Bearer $CENTRAPOINT_API_KEY" \
  -H "Idempotency-Key: c1e3a5b7-6d8f-4b0a-a2c4-7e9b1d3f5a68" \
  -H "Content-Type: application/json" \
  -d '{
    "method": "payout",
    "amount": 130,
    "actionDate": "2026-10-01",
    "bank": {
      "accountHolder": "T Nkosi",
      "accountNumber": "62000000000",
      "branchCode": "250655",
      "accountType": "current",
      "bankName": "FNB"
    },
    "beneficiaryEmail": "[email protected]"
  }'

Recorded manually#

method: manual
FieldTypeDescription
methodrequiredstringmanual
amountrequirednumber
manualMethodoptionalstringHow it was paid, e.g. eft (default) or cash. Up to 30 chars.
referenceoptionalstringE.g. your bank statement reference.

Records credit you paid back outside CentraPoint, for example an EFT from your business bank account.

Download the credit note PDF#

GET/api/v1/credit-notes/{id}/pdf

Returns the branded credit note PDF (application/pdf, as an attachment, Cache-Control: private, no-store) or 404.

Download a credit note PDF
curl -o credit-note.pdf \
  -H "Authorization: Bearer $CENTRAPOINT_API_KEY" \
  "https://app.centrapoint.co.za/api/v1/credit-notes/cmg3c7d8e0002crn0001abcd/pdf"

Webhook events#

credit_note.created, credit_note.issued, credit_note.applied, credit_note.refunded (any pay-back method) and credit_note.voided are sent to your webhook endpoints with the credit note object as data, whether the change came from the API or the dashboard. Creating with issue: true sends both created and issued. When a payout for a credit note is cancelled or fails, you receive payout.cancelled / payout.failed; fetch the credit note for its restored balance.

Errors#

Credit note errors
StatuserrorWhen
400invalid_requestValidation failed; customer, invoice or payment not found or belonging to another customer; credit above the invoice total; only one of periodStart/periodEnd, or periodEnd before periodStart; currency mismatch; not issued; amount above the balance; payment not refundable; invalid bank details; no payout gateway; non-ZAR payout; action date in the past; voiding a used credit note.
403plan_restricted / account_restrictedPlan lacks the API or Invoicing, or the account is read-only (writes).
404not_foundNo credit note with this ID or number in your organisation.
409idempotency_conflictIdempotency-Key reused with a different body.
401 / 429 / 500unauthorized / rate_limited / internal_errorSee Errors