AP bills

Vendor bills. Lines go in the same request - see Conventions on nested writes.

The object#

FieldTypeDescription
idread-onlyintegerNolaPro id.
invoicenumberstring(20)The vendor’s own invoice number. Required and never generated - it is how duplicate bills are spotted.
cancelbooleanCancelled. Always a boolean on the wire, whatever integer width the column uses (D23).
completeread-onlyinteger1 when the bill is fully paid.
paynoneinteger1 puts the bill on payment hold; payment runs set to skip held bills exclude it.
totalmoneystring(4dp)Stored as decimal(19,4).
descriptionstring(50)Bill description.
dateofinvoicestringDate on the vendor’s invoice - the accounting date the bill posts under.
duedatestringDate payment is due.
discountamountmoneystring(4dp)Stored as decimal(19,4).
discountdatestringLast date the early-payment discount applies.
vendoridintegerReference to vendors, by id. Write either this or vendor.
vendorstring(30)Code for the referenced vendor, instead of the id.
commenttextComment. Stored as text, no practical length limit.
wherefromintegerModule that raised the bill: 1 = entered in AP.
entrydatestringWhen the record was created.
lastchangedateread-onlystringLast modification. Drives modifiedsince.
approved_paydatestringPay date approved in the pre-approval workflow.
preapproved_useridread-onlyintegerUser who pre-approved the bill for payment.
preapproved_userstring(50)The name of the referenced genusers, instead of the id. Send this or preapproved_userid, not both unless they agree.
preapproved_statusintegerPre-approval workflow status: 0 = pending, 1 = approved.
preapproved_checkacctidintegerChecking account chosen for the bill during pre-approval.
preapproved_checkacctstring(30)The name of the referenced checkaccounts, instead of the id. Send this or preapproved_checkacctid, not both unless they agree.
preapproved_amountmoneystring(6dp)Stored as decimal(15,6).
preapproved_interestmoneystring(6dp)Stored as decimal(15,6).
old_idread-onlystring(255)Bill id in the system this record was imported from.
ccpurchaseinteger1 when the bill is a credit-card purchase (shown on the CC purchases tab).
apglaccountidintegerReference to glaccounts, by id. Write either this or apglaccount.
apglaccountstring(20)The name of the referenced glaccounts, instead of the id. Send this or apglaccountid, not both unless they agree.
chargebackinteger1 when the bill is charged back to another party.
recurringinteger1 when the bill is a recurring template that generates future bills.
payplan_dayofmonthintegerDay of the month the recurring bill generates on.
payplan_daysintegerInterval in days between generated bills, when not monthly.
payplan_nextstringNext date the recurring bill generates.
payplan_numtimesintegerRemaining number of bills the recurrence will generate; -1 repeats indefinitely.
isretainerinteger1 when the bill holds retainage withheld from another bill.
retainer_apbillidintegerRetainer apbillid. Id only.
drawidintegerDrawid. Id only.
currencystring(10)Currency the bill is payable in.
curratenumberstring(10dp)Numeric string, 10 decimal places. Not money - do not apply currency rounding.
alternate_paytonamestring(255)Pay To name printed on the check when it differs from the vendor name.
non_negotiableinteger1 prints the payment check as Non-Negotiable, recording a payment made outside AP.
costcodeidintegerCost code.
costcodestring(20)Code for the referenced costcode, instead of the id.
voucheridintegerVoucherid. Id only.
voucherstring(50)The voucher of the referenced gltransactions, instead of the id. Send this or voucherid, not both unless they agree.
frommanualinteger1 when the bill came from Manual Checks entry.
glcategoryidintegerGlcategoryid. Id only.
glcategorystring(20)The code of the referenced glcategories, instead of the id. Send this or glcategoryid, not both unless they agree.
jobidintegerJobid. Id only.
altglpostdatestringAlternate GL posting date, when the bill posts to a different period than the invoice date.
frompayrollinteger1 when the bill was generated by payroll (tax and deduction remittances).
highpriorityinteger1 marks the bill High Priority in payment runs.
invoicetermsidintegerReference to invoiceterms, by id. Write either this or invoiceterms.
invoicetermsstring(30)The verbal of the referenced invoiceterms, instead of the id. Send this or invoicetermsid, not both unless they agree.
prepaidintegerPrepaid. Id only.
invpodepositidread-onlyintegerPurchase-order deposit this bill settles. Read-only: the link is made by NolaPro's own PO deposit flow, and no /invpodeposits resource exists to name or supply the id.
externalidstring(100)Your own key. Scoped to your company.

Endpoints#

GET/apbills/{id}/payments 200422

Payments applied to a vendor bill.

What paid this bill, when, and through which voucher. A customer payment against an invoice is a first-class resource (/payments). Its counterpart on the payables side lives here, against the bill it settles. Anyone reconciling accounts payable needs it to close the loop between a bill and the money that left. A voided cheque keeps its row and carries checkvoid with a reversing voucher, rather than disappearing.

Requires scope bills:read.

Parameters
NameInTypeNotes
idrequiredpathintegerThe bill id.
When it fails
StatusCodeMeaning
422unknown_valueNo such parent record in this company. The same answer whether it does not exist or belongs to someone else, so a caller cannot probe another company's ids.
curl \
  'https://acme.nolapro.com/!/api/v2/apbills/104/payments' \
  -H 'Authorization: Bearer $NP_TOKEN'
POST/apbills/batch 207400422

Create many.

Requires scope bills:write.

Parameters
NameInTypeNotes
Body array
FieldTypeDescription
vendoridrequiredintegerWho the bill is from.
numberrequiredstring(20)The VENDOR's invoice number. Required - it is how a duplicate bill is spotted, and NolaPro has no counter to fall back on because the number is theirs.
datestringBill date. Defaults to today.
duedatestringPayment due date.
totalmoneystringWhat is owed. Must equal the sum of the distribution lines. Decimal STRING, not a JSON number.
externalidstring(100)Your own identifier for this record. Stored verbatim and returned on reads; GET /<resource>?externalid=... finds it again.
linesrequiredarray of objectThe GL DISTRIBUTION, not products: each line says which account the expense lands in and for how much. Together they must equal the bill total.
postbooleanPost the invoice to the general ledger. Defaults to true. Send false to create it as a DRAFT: no GL voucher is written, so lines can still be added with POST /invoicelines or changed with PATCH /invoicelines/{id}. Post it later by cancelling and re-raising, or build it fully before posting. Once an invoice carries a voucher its lines are closed to further change.
When it fails
StatusCodeMeaning
400invalid_requestThe request was malformed.
422gl_set_unbalancedThe signed amounts do not sum to zero.
422period_closedThe GL period containing the date is closed.
422unknown_valueA reference did not resolve in this company.
curl -X POST \
  'https://acme.nolapro.com/!/api/v2/apbills/batch' \
  -H 'Authorization: Bearer $NP_TOKEN' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: your-unique-key' \
  -d '[
    {
        "vendorid": 104,
        "number": "INV-88421",
        "date": "2026-08-02",
        "duedate": "2026-08-02",
        "total": "125.0000",
        "externalid": "crm-8842",
        "lines": [
            {
                "amount": "125.0000"
            }
        ],
        "post": false
    }
]'
Response 207
{
    "results": [
        {
            "index": 1,
            "status": 1
        }
    ]
}
GET/apbills 200403

List ap bills.

Requires scope bills:read.

Parameters
NameInTypeNotes
completequerystringRestrict to one complete.
vendoridquerystringRestrict to one vendorid.
jobidquerystringRestrict to one jobid.
invoicenumberquerystringinvoicenumber. Partial match, case-insensitive.
descriptionquerystringdescription. Partial match, case-insensitive.
cancelquerystringDefaults to false. Pass true or any.
modifiedsincequerystringRFC 3339 UTC timestamp. Returns only records changed since then, including cancelled ones - so cancel defaults to any rather than false when this is used. The response carries _meta.synced_through; store it and send it back next time.
externalidquerystringExact match on your own key.
includequerystringComma-separated extras to embed. Only custom_fields is available: the extra fields this install has defined on the record. Off by default, and an unrecognised value is refused rather than ignored. See Conventions.
When it fails
StatusCodeMeaning
403insufficient_scopeToken lacks read scope.
curl \
  'https://acme.nolapro.com/!/api/v2/apbills' \
  -H 'Authorization: Bearer $NP_TOKEN'
POST/apbills 201400422

Create.

Requires scope bills:write.

Parameters
NameInTypeNotes
Body
FieldTypeDescription
vendoridrequiredintegerWho the bill is from.
numberrequiredstring(20)The VENDOR's invoice number. Required - it is how a duplicate bill is spotted, and NolaPro has no counter to fall back on because the number is theirs.
datestringBill date. Defaults to today.
duedatestringPayment due date.
totalmoneystringWhat is owed. Must equal the sum of the distribution lines. Decimal STRING, not a JSON number.
externalidstring(100)Your own identifier for this record. Stored verbatim and returned on reads; GET /<resource>?externalid=... finds it again.
linesrequiredarray of objectThe GL DISTRIBUTION, not products: each line says which account the expense lands in and for how much. Together they must equal the bill total.
postbooleanPost the invoice to the general ledger. Defaults to true. Send false to create it as a DRAFT: no GL voucher is written, so lines can still be added with POST /invoicelines or changed with PATCH /invoicelines/{id}. Post it later by cancelling and re-raising, or build it fully before posting. Once an invoice carries a voucher its lines are closed to further change.
When it fails
StatusCodeMeaning
400invalid_requestA required field was missing.
422gl_set_unbalancedThe signed amounts do not sum to zero.
422period_closedThe GL period containing the date is closed.
422unknown_valueA reference did not resolve in this company.
curl -X POST \
  'https://acme.nolapro.com/!/api/v2/apbills' \
  -H 'Authorization: Bearer $NP_TOKEN' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: your-unique-key' \
  -d '{
    "vendorid": 104,
    "number": "INV-88421",
    "date": "2026-08-02",
    "duedate": "2026-08-02",
    "total": "125.0000",
    "externalid": "crm-8842",
    "lines": [
        {
            "amount": "125.0000"
        }
    ],
    "post": false
}'
Response 201
{
    "vendorid": 104,
    "number": "INV-88421",
    "total": "125.0000",
    "posted": false,
    "voucherid": 104
}
GET/apbills/{id} 200404

Retrieve one record.

Requires scope bills:read.

Parameters
NameInTypeNotes
idrequiredpathintegerThe record id.
includequerystringComma-separated extras to embed. Only custom_fields is available: the extra fields this install has defined on the record. Off by default, and an unrecognised value is refused rather than ignored. See Conventions.
When it fails
StatusCodeMeaning
404not_foundNo record with that id.
curl \
  'https://acme.nolapro.com/!/api/v2/apbills/104' \
  -H 'Authorization: Bearer $NP_TOKEN'
Response 200
{
    "invoicenumber": "INV-88421",
    "paynone": 1,
    "total": "125.0000",
    "description": "Example description",
    "dateofinvoice": "2026-08-01",
    "duedate": "2026-08-01"
}
PATCH/apbills/{id} 200400404409422

Update.

Requires scope bills:write.

Parameters
NameInTypeNotes
idrequiredpathintegerThe record id.
Body
FieldTypeDescription
numberstring(20)The vendor's invoice number.
duedatestringWhen payment or delivery is expected.
datestringDocument date.
descriptionstring(255)Free text.
externalidstring(100)Your own identifier for this record.
When it fails
StatusCodeMeaning
400invalid_requestThe request was malformed.
404not_foundNo such record, or it belongs to another company.
409apbill_already_postedThe bill already carries a voucherid.
409stale_recordIf-Match did not match; someone else changed it first.
422rule_violationNolaPro refused the change. message carries its reason.
curl -X PATCH \
  'https://acme.nolapro.com/!/api/v2/apbills/104' \
  -H 'Authorization: Bearer $NP_TOKEN' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: your-unique-key' \
  -d '{
    "number": "INV-88421",
    "duedate": "2026-08-01",
    "date": "2026-08-01",
    "description": "Example description"
}'
DELETE/apbills/{id} 200400409422

Cancel.

Requires scope bills:cancel.

Parameters
NameInTypeNotes
idrequiredpathintegerThe record id.
When it fails
StatusCodeMeaning
400invalid_requestThe request was malformed.
409cannot_cancelSomething already depends on this document - a payment, a shipment, an invoice.
422period_closedThe current GL period is closed, so a reversal has nowhere to post.
422unknown_valueNo such record in this company.
curl -X DELETE \
  'https://acme.nolapro.com/!/api/v2/apbills/104' \
  -H 'Authorization: Bearer $NP_TOKEN'
POST/apbills/{id}/post 200404409422

Post this bill to the general ledger.

Writes the GL voucher for a DRAFT bill - one created with post: false. A draft bill's distribution can still be changed with POST /apbilllines and PATCH /apbilllines/{id}. Posting runs billpost(), which builds the voucher from that distribution, so the lines must already sum to the bill total - otherwise the voucher would not represent the liability it is filed against. An already-posted bill answers 409.

Requires scope bills:write.

Parameters
NameInTypeNotes
idrequiredpathinteger
When it fails
StatusCodeMeaning
404not_foundNo bill with that id in this company.
409apbill_already_postedAlready posted. Nothing was written a second time.
422rule_violationNolaPro refused the document. message carries its reason.
422unknown_valueA reference did not resolve in this company.
422period_closedThe GL period the document posts into is closed, so the voucher has nowhere to go.
422gl_set_unbalancedThe distribution lines do not sum to the bill total, so the voucher would not represent the liability it is filed against.
curl -X POST \
  'https://acme.nolapro.com/!/api/v2/apbills/104/post' \
  -H 'Authorization: Bearer $NP_TOKEN'
GET/apbills/checks 200

Re-print an AP cheque as a PDF

Re-draws a cheque that has already been written. Nothing is recorded — no cheque number is consumed and no record changes; this renders what is already in the books. Answers application/pdf, not JSON. Because the body is binary it cannot be carried inside a /batch results array; asking for it there returns 415 not_batchable.

Requires scope bills:read.

Parameters
NameInTypeNotes
checknbrrequiredquerystringThe cheque to draw.
curl \
  'https://acme.nolapro.com/!/api/v2/apbills/checks' \
  -H 'Authorization: Bearer $NP_TOKEN'