Skip to content
AccountFUNDocs

Prepayments

The prepayments endpoints cover money that changes hands before an invoice or bill exists — a supplier deposit, a customer advance, an overpayment. A prepayment is created as a draft, posted through an approval step, then applied to the documents it belongs to (or refunded) later.

Two directions exist:

TypeWhoSide of the booksSettles
spendMoney paid to a supplier as an advancePurchasesBills
receiveMoney received from a customer as an advanceSalesInvoices

Reading requires prepayments:read; creating and submitting require prepayments:write (an opt-in on the consent screen). Approving and voiding post to the ledger and need prepayments:approve (opt-in; the role needs Approve Documents). Allocating, un-allocating, refunding and reversing a refund move money and need prepayments:settle (opt-in; the role needs Record Payments). The role must see the prepayment’s side of the books, and a list returns only the directions the role can see. See Authentication.

MethodPathScopeDescription
GET/api/v1/prepaymentsprepayments:readList prepayments (paginated, searchable).
POST/api/v1/prepaymentsprepayments:writeCreate a draft prepayment.
GET/api/v1/prepayments/{id}prepayments:readFetch one prepayment with lines, allocations and refunds.
POST/api/v1/prepayments/{id}/submitprepayments:writeMove a draft to SUBMITTED.
POST/api/v1/prepayments/{id}/approveprepayments:approveApprove (post) a draft or submitted prepayment.
POST/api/v1/prepayments/{id}/voidprepayments:approveVoid a prepayment (reversing a posted one first).
POST/api/v1/prepayments/{id}/allocateprepayments:settleApply the prepayment to invoices or bills.
DELETE/api/v1/prepayments/{id}/allocations/{allocationId}prepayments:settleUn-allocate one application.
POST/api/v1/prepayments/{id}/refundprepayments:settleRefund the prepayment from a bank account.
POST/api/v1/prepayments/{id}/refunds/{refundId}/reverseprepayments:settleReverse a refund recorded by mistake.

Related lookups you will usually need: contacts (the supplier or customer), the chart of accounts (the bank account and each line’s account), tax rates, and the documents being settled — invoices or bills. AI assistants can use all of this through the MCP server.


StatusMeaning
DRAFTCreated but not yet posted.
SUBMITTEDSubmitted for approval.
APPROVEDPosted to the ledger — the advance exists and can be applied or refunded.
ALLOCATEDFully applied to invoices or bills.
VOIDEDCancelled; a posted prepayment is reversed out of the ledger.

Returns a paginated list for the token’s organization, newest first. Only the directions the caller’s role can see are returned.

Terminal window
curl "https://app.accountfun.com/api/v1/prepayments?prepaymentType=receive&search=deposit" \
-H "Authorization: Bearer $ACCESS_TOKEN"
ParameterTypeDefaultDescription
statusstring—Filter by status: DRAFT, SUBMITTED, APPROVED, ALLOCATED or VOIDED.
prepaymentTypestring—spend (supplier advances) or receive (customer advances).
contactIdstring—Filter to prepayments for a specific contact.
searchstring—Case-insensitive match on the prepayment number, reference or contact name.
pageinteger1Page number (1-based, max 10000).
limitinteger25Page size (max 200).
{
"prepayments": [
{
"id": "a1b2c3d4-...",
"prepaymentNumber": "PP-0003",
"prepaymentType": "receive",
"status": "APPROVED",
"reference": "DEPOSIT-1042",
"currency": "USD",
"total": "1000.00",
"amountApplied": "0.00",
"balanceRemaining": "1000.00",
"date": "2026-10-08",
"contact": { "id": "...", "name": "Northwind Traders", "email": "ap@northwind.example" },
"createdAt": "2026-10-08T09:30:00.120Z"
}
],
"pagination": { "page": 1, "limit": 25, "total": 1, "totalPages": 1 }
}
FieldDescription
prepayments[].totalPrepayment total including tax.
prepayments[].amountAppliedAmount allocated or refunded so far.
prepayments[].balanceRemainingUnapplied amount (total − amountApplied).

Creates a DRAFT prepayment. The bank account must be a Bank account in the prepayment’s currency. Posting it is a separate step (submit and approve, or approve a draft directly).

Terminal window
curl -X POST https://app.accountfun.com/api/v1/prepayments \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: deposit-order-11" \
-d '{
"prepaymentType": "receive",
"contactId": "00000000-0000-0000-0000-000000000001",
"bankAccountId": "00000000-0000-0000-0000-00000000000b",
"date": "2026-10-08",
"reference": "DEPOSIT-1042",
"currency": "USD",
"taxMode": "none",
"lines": [
{
"description": "Deposit for order #1042",
"quantity": "1",
"unitAmount": "1000.00",
"accountId": "00000000-0000-0000-0000-00000000000a",
"taxRateId": null
}
]
}'
FieldTypeRequiredDescription
prepaymentTypestringYesspend (a supplier advance) or receive (a customer advance).
contactIdstringYesThe supplier or customer. Must be active and belong to the token’s organization.
bankAccountIdstringYesThe Bank account the cash is paid from / received into.
datedate (YYYY-MM-DD)YesThe prepayment date.
linesarrayYesOne or more lines (see below).
referencestringNoFree-text reference.
currencystringNo3-letter ISO 4217 code. Defaults to the bank account’s currency.
exchangeRatestringNoCustom rate to the base currency. Omit for the prevailing rate.
taxModestringNonone, exclusive or inclusive — how line amounts relate to tax.
prepaymentNumberstringNoOverride the organization’s numbering (e.g. PP-0003).
projectIdstringNoGroup the prepayment under an open project.
FieldTypeRequiredDescription
quantitystringYesNumeric string, e.g. "1".
unitAmountstringYesNumeric string, e.g. "1000.00".
accountIdstringYesThe account the line names.
descriptionstringNoLine description.
taxRateIdstringNoA tax rate from GET /api/v1/tax-rates. Omit for no tax.
discountstringNoA flat amount ("5.00") or a percentage ("10%").
{
"prepayment": {
"id": "a1b2c3d4-...",
"prepaymentNumber": "PP-0003",
"prepaymentType": "receive",
"status": "DRAFT",
"reference": "DEPOSIT-1042",
"currency": "USD",
"subtotal": "1000.00",
"taxTotal": "0.00",
"total": "1000.00",
"amountApplied": "0.00",
"balanceRemaining": "1000.00",
"date": "2026-10-08",
"projectId": null,
"journalEntryId": null,
"bankAccountId": "00000000-0000-0000-0000-00000000000b",
"postedAt": null,
"voidedAt": null,
"contact": { "id": "...", "name": "Northwind Traders", "email": "ap@northwind.example" },
"bankAccount": { "id": "...", "code": "090", "name": "Business Account", "currency": null },
"lines": [ "…" ],
"allocations": [],
"refunds": []
}
}
StatusCause
400Invalid body — the details object names each bad field.
400The bank account isn’t a Bank account, isn’t in the prepayment’s currency, or the contact can’t be used for this type.
403The contact, bank account or an account does not belong to this organization, or the role can’t see this side of the books.
403The date falls on or before the organization’s lock date.
409A prepayment rule was violated (for example a duplicate prepayment number).

Terminal window
curl https://app.accountfun.com/api/v1/prepayments/a1b2c3d4-... \
-H "Authorization: Bearer $ACCESS_TOKEN"

Returns { "prepayment": { … } } with its contact, bank account and lines, the allocations (each with amount, appliedAt, isReversed and the invoice or bill it reduced) and any refunds (each with amount, date and isReversed). An un-allocated row is kept as history and shows isReversed: true rather than disappearing.


Moves a DRAFT prepayment to SUBMITTED so it can be posted. Needs the prepayments:write scope.

Terminal window
curl -X POST https://app.accountfun.com/api/v1/prepayments/a1b2c3d4-.../submit \
-H "Authorization: Bearer $ACCESS_TOKEN"

Response — 200 OK: { "success": true }.


Posts a DRAFT or SUBMITTED prepayment to the ledger — the prepayment asset/liability against the bank account. Requires the prepayments:approve scope and the Approve Documents permission.

Terminal window
curl -X POST https://app.accountfun.com/api/v1/prepayments/a1b2c3d4-.../approve \
-H "Authorization: Bearer $ACCESS_TOKEN"
{
"prepaymentId": "a1b2c3d4-...",
"status": "APPROVED",
"journalEntryId": "je-11ee22"
}

journalEntryId is null for a zero-value prepayment.

StatusCause
400The prepayment can’t be approved in its current state.
403insufficient_scope — the token doesn’t carry prepayments:approve, or the role lacks Approve Documents or this side of the books.
403The date falls on or before the lock date.
404No prepayment with that id in the token’s organization.

Voids a prepayment. A posted (APPROVED) one is reversed; a draft or submitted one is simply marked voided. A prepayment that has been applied to invoices or bills must have its allocations reversed first. Requires the prepayments:approve scope.

Terminal window
curl -X POST https://app.accountfun.com/api/v1/prepayments/a1b2c3d4-.../void \
-H "Authorization: Bearer $ACCESS_TOKEN"
{
"prepaymentId": "a1b2c3d4-...",
"voided": true,
"reversalEntryId": "je-33ff44"
}

reversalEntryId is null when the prepayment was never posted.


Applies an APPROVED prepayment to invoices (receive) or bills (spend), fully or in part. Requires the prepayments:settle scope and the Record Payments permission. Supports Idempotency-Key.

Terminal window
curl -X POST https://app.accountfun.com/api/v1/prepayments/a1b2c3d4-.../allocate \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: pp-0003-allocate" \
-d '{
"allocations": [
{ "invoiceId": "1a2b3c4d-...", "amount": "1000.00" }
],
"date": "2026-10-15"
}'
FieldTypeRequiredDescription
allocationsarrayYesOne or more applications to documents (see below).
datedate (YYYY-MM-DD)NoDate the allocation applies. Defaults to today.
exchangeRatestringNoRate to the base currency when applying across currencies.
Allocation fieldTypeDescription
invoiceIdstringThe invoice to apply to (receive prepayments only).
billIdstringThe bill to apply to (spend prepayments only).
amountstringAmount applied, in the prepayment currency.
{
"prepaymentId": "a1b2c3d4-...",
"prepaymentStatus": "ALLOCATED",
"allocations": [
{ "prepaymentId": "a1b2c3d4-...", "invoiceId": "1a2b3c4d-...", "billId": null, "amount": "1000.00" }
],
"documentUpdates": [
{
"documentId": "1a2b3c4d-...",
"documentType": "invoice",
"amountPaid": "1000.00",
"balanceDue": "0.00",
"status": "PAID"
}
]
}
StatusCause
400Invalid body, the prepayment isn’t approved, an allocation exceeds the remaining balance or the document’s balance, or the document can’t be settled.
403Missing prepayments:settle or the Record Payments permission, or an invoice/bill is outside the organization.
404The prepayment doesn’t exist in the token’s organization.

Undoes one application of an APPROVED / ALLOCATED prepayment: posts the mirror entry dated the organization’s today, restores the document’s balance and the prepayment’s remaining balance, and keeps the allocation row as reversed history. Requires the prepayments:settle scope.

DELETE /api/v1/prepayments/{id}/allocations/{allocationId}

No body.

Terminal window
curl -X DELETE "https://app.accountfun.com/api/v1/prepayments/a1b2c3d4-.../allocations/66aa77bb-..." \
-H "Authorization: Bearer $ACCESS_TOKEN"
{
"prepaymentId": "a1b2c3d4-...",
"allocationId": "66aa77bb-...",
"journalEntryId": "je-88cc99",
"prepaymentStatus": "APPROVED",
"amountApplied": "0.00",
"balanceRemaining": "1000.00"
}
StatusCause
400The allocation can’t be reversed (already reversed, or the prepayment isn’t in an allocatable state).
403Missing prepayments:settle or the Record Payments permission.
404The prepayment or allocation doesn’t exist in the token’s organization.

Records a cash refund of an APPROVED / ALLOCATED prepayment from a Bank account — money moving back to the customer (receive) or coming back from the supplier (spend). Requires the prepayments:settle scope and the Record Payments permission. Supports Idempotency-Key.

Terminal window
curl -X POST https://app.accountfun.com/api/v1/prepayments/a1b2c3d4-.../refund \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: pp-0003-refund" \
-d '{
"bankAccountId": "00000000-0000-0000-0000-00000000000b",
"amount": "1000.00",
"currency": "USD",
"date": "2026-10-20",
"appliedAmount": "1000.00",
"reference": "REFUND-DEPOSIT-1042"
}'
FieldTypeRequiredDescription
bankAccountIdstringYesThe Bank account the refund is paid from / received into.
amountstringYesRefund amount.
currencystringYesISO 4217 code; must match the bank account’s currency.
datedate (YYYY-MM-DD)YesRefund date.
appliedAmountstringYesPrepayment balance consumed, in the prepayment currency.
exchangeRatestringNoRate to the base currency. Defaults to 1.
referencestringNoFree-text reference.
{
"refundId": "rf-77ee88",
"journalEntryId": "je-aabbcc",
"prepaymentStatus": "ALLOCATED",
"amountApplied": "1000.00",
"balanceRemaining": "0.00"
}
StatusCause
400Invalid body, the prepayment isn’t approved, the refund currency doesn’t match the bank account, or the refund exceeds the available balance.
403Missing prepayments:settle or the Record Payments permission.
404The prepayment or bank account doesn’t exist in the token’s organization.

Undoes an incorrectly recorded prepayment refund: posts the mirror entry dated the refund date, restores the prepayment’s remaining balance and marks the refund reversed. Requires the prepayments:settle scope.

POST /api/v1/prepayments/{id}/refunds/{refundId}/reverse

No body.

Terminal window
curl -X POST "https://app.accountfun.com/api/v1/prepayments/a1b2c3d4-.../refunds/rf-77ee88/reverse" \
-H "Authorization: Bearer $ACCESS_TOKEN"
{
"refundId": "rf-77ee88",
"reversalEntryId": "je-ddeeff",
"prepaymentId": "a1b2c3d4-...",
"prepaymentStatus": "APPROVED",
"amountApplied": "0.00",
"balanceRemaining": "1000.00"
}
StatusCause
400The refund can’t be reversed (already reversed, or the prepayment state changed).
403Missing prepayments:settle or the Record Payments permission.
404The prepayment or refund doesn’t exist in the token’s organization.

Everything your integration changes is recorded as the user who authorized it, via your app, with the time and where the request came from (IP address and user agent). This covers prepayments created, submitted, approved, voided, allocated, un-allocated, refunded and reversed — the ledger postings name your app too. These entries appear in the organization’s Audit History. Every API request is also logged, and the logs are kept for 30 days.

  1. Maya’s customer pays a $1,000 deposit for work that hasn’t been invoiced yet. Record it: POST /api/v1/prepayments with prepaymentType: "receive", the customer, the bank account and one line.
  2. Submit and approve it — POST …/submit, then POST …/approve with prepayments:approve — so the money is in the books.
  3. When the invoice is issued, apply the deposit: POST …/allocate with { "allocations": [{ "invoiceId": "…", "amount": "1000.00" }] }. The invoice’s balanceDue drops by the applied amount.
  4. If the work is cancelled instead, refund the deposit: POST …/refund with the bank account, amount and appliedAmount. If the refund was a mistake, POST …/refunds/{refundId}/reverse restores the balance.