Invoices¶
One endpoint for everything. An invoice is an invoice — whether it is trading history from last February, a payable your client owes, or a receivable they want financed today.
Two fields do all the work¶
| Field | Values | What it changes |
|---|---|---|
direction |
receivable · payable |
Whether your client issued the invoice or received it. Receivables can be financed; payables build the cash-flow picture that informs the limit. |
financingRequested |
true · false |
false (default) files the invoice as history. true queues it for scoring and a decision. |
credited |
true · false |
false (default) is an invoice. true marks it a credit note. |
There is no separate history endpoint and no separate financing endpoint. Send everything the same way and set the flag when — or if — financing is wanted.
The flag is not a decision you have to make at send time. An invoice sent as history sits at recorded; flipping financingRequested to true later moves that same invoice into review without resending it. That is the path behind an in-product trigger — see Ask for financing on an invoice you already sent.
Send an invoice¶
Request¶
| Field | Type | Notes | |
|---|---|---|---|
client |
object | Required | countryCode + registrationNumber |
invoiceNumber |
string | Required | Your number. Unique per client; resending updates. |
direction |
enum | Required | receivable or payable |
counterparty |
object | Required | The debtor for receivables, the supplier for payables |
counterparty.name |
string | Required | Always required |
counterparty.type |
enum | Required | company, association, public_institution or person |
counterparty.registrationNumber |
string | Optional | Company registration number when you have it — materially improves scoring |
counterparty.countryCode |
string | Optional | Defaults to the client's country |
amount |
money | Required | Gross, minor units |
issueDate |
date | Required | |
dueDate |
date | Required | |
financingRequested |
boolean | Optional | Defaults to false |
credited |
boolean | Optional | true if this document is a credit note. Defaults to false |
partnerStatus |
string | Optional | Your own status label — stored, echoed back, never interpreted |
document |
object | Optional | The invoice PDF or image — see Attaching the document |
vatAmount |
money | Optional | |
paymentStatus |
enum | Optional | open, paid, partially_paid, credited, written_off |
paymentDate |
date | Optional | Required when paymentStatus is paid |
paidAmount |
money | Optional | Required when paymentStatus is partially_paid |
reference |
string | Optional | Payment reference as printed on the invoice |
currency |
string | Optional | Defaults to EUR; carried inside each money object |
lineItems |
array | Optional | See Line items |
{
"client": { "countryCode": "NL", "registrationNumber": "68123456" },
"invoiceNumber": "2026-0417",
"direction": "receivable",
"financingRequested": true,
"counterparty": {
"name": "Bouwgroep Rotterdam B.V.",
"type": "company",
"registrationNumber": "24398871",
"countryCode": "NL"
},
"amount": { "amount": 424250, "currency": "EUR" },
"vatAmount": { "amount": 73625, "currency": "EUR" },
"issueDate": "2026-08-30",
"dueDate": "2026-09-29",
"paymentStatus": "open",
"credited": false,
"reference": "0417 2026 VDI",
"partnerStatus": "sent"
}
{
"client": { "countryCode": "NL", "registrationNumber": "68123456" },
"invoiceNumber": "INK-2026-0912",
"direction": "payable",
"counterparty": {
"name": "Technische Unie B.V.",
"type": "company",
"registrationNumber": "30031444"
},
"amount": { "amount": 187300, "currency": "EUR" },
"issueDate": "2026-09-01",
"dueDate": "2026-09-15",
"paymentStatus": "paid",
"paymentDate": "2026-09-12"
}
Response · 201¶
{
"invoiceId": "0193f31a-77bd-7c02-bb14-9e0f2a4c8d31",
"invoiceNumber": "2026-0417",
"direction": "receivable",
"paymentStatus": "open",
"credited": false,
"partnerStatus": "sent",
"financing": {
"state": "pending",
"amountFinanceable": { "amount": 339400, "currency": "EUR" },
"expectedDecisionBy": "2026-09-14T10:05:00Z"
},
"createdAt": "2026-09-14T09:47:12Z"
}
amountFinanceable is the invoice amount multiplied by the client's assigned financing percentage. It is an estimate until a decision lands, at which point amountApproved is authoritative.
Line items¶
Optional, but they improve scoring on financed invoices and are what a reviewer looks at when an invoice is queued for manual attention.
| Field | Type | Notes | |
|---|---|---|---|
description |
string | Required | What was sold |
quantity |
number | Optional | Decimals allowed |
unitPrice |
money | Optional | Minor units, excluding VAT |
vatRate |
number | Optional | Percentage, e.g. 21 |
unit |
string | Optional | Free text, e.g. hour, piece |
productCode |
string | Optional | Your article or SKU code |
{
"lineItems": [
{
"description": "Installation labour",
"quantity": 18.5,
"unitPrice": { "amount": 8500, "currency": "EUR" },
"vatRate": 21,
"unit": "hour"
},
{
"description": "Heat pump — model WP-240",
"quantity": 1,
"unitPrice": { "amount": 268000, "currency": "EUR" },
"vatRate": 21,
"productCode": "WP-240"
}
]
}
Line items are not reconciled against amount. If they disagree, amount wins — it is the figure financing is calculated from.
Attaching the document¶
Send the invoice PDF or image inline. Optional, and only worth doing for invoices you may want financed — a reviewer can then see the document without asking you for it.
| Field | Type | Notes | |
|---|---|---|---|
document.contentBase64 |
string | Required | Base64-encoded file bytes |
document.mediaType |
string | Required | application/pdf, image/jpeg, image/png or image/tiff |
document.filename |
string | Optional | Shown to reviewers |
{
"document": {
"filename": "2026-0417.pdf",
"mediaType": "application/pdf",
"contentBase64": "JVBERi0xLjQKJeLjz9MKMyAwIG9iago8PC9..."
}
}
Maximum 10 MB decoded. A base64 payload inflates by roughly a third, so keep the encoded string under about 13 MB and stay inside the 256 KB body cap by sending documents on the single-invoice endpoint rather than in a batch.
Credit notes¶
Set credited: true and send the credit note as its own invoice, with amount as a positive number. Link it to what it credits with creditsInvoiceNumber:
{
"invoiceNumber": "2026-0417-CN",
"credited": true,
"creditsInvoiceNumber": "2026-0417",
"amount": { "amount": 42425, "currency": "EUR" },
"direction": "receivable"
}
A credit note against a financed invoice reduces the amount outstanding. Credit notes cannot themselves be financed — financingRequested: true on one returns 422 validation_failed.
Invoice states¶
An invoice carries two independent statuses. Keeping them apart matters: an invoice can be overdue and financed at the same time.
paymentStatus — the debtor payment lifecycle. You set it; Noja also updates it from bank reconciliation once an invoice is financed.
| Value | Meaning |
|---|---|
open |
Issued, not yet paid |
partially_paid |
Part of the amount received |
paid |
Paid in full |
overdue |
Past due and not settled |
credited |
Cancelled by a credit note |
written_off |
Abandoned |
financing.state — the financing lifecycle. Noja owns it entirely.
| Value | Meaning |
|---|---|
not_requested |
Stored as history. The default. |
pending |
Financing requested, decision not yet made. Covers both scoring in progress and waiting on client approval. |
financing_approved |
Approved. financing.amountApproved is payable. |
financing_rejected |
Declined for this invoice. financing.reason explains why. |
financed |
Paid out to the client. |
rejected |
Declined terminally — do not resubmit. |
Settlement is not a financing state. Once the debtor pays a financed invoice, paymentStatus becomes paid and financing.settledAt is stamped.
Payables are never financed
A payable invoice stays at financing.state: not_requested for life. Setting financingRequested: true on one returns 422 validation_failed. Payables exist so the limit reflects real net cash flow rather than gross receivables.
Bulk history¶
The call you use once per client to send twelve months in one go. Up to 1,000 invoices per request, processed asynchronously. Partial success is normal: valid rows land, invalid rows are reported individually.
{
"client": { "countryCode": "NL", "registrationNumber": "68123456" },
"invoices": [
{ "invoiceNumber": "2026-0388", "direction": "receivable", "...": "..." },
{ "invoiceNumber": "2026-0389", "direction": "receivable", "...": "..." }
]
}
{
"jobId": "0193f33c-1a02-7d55-8e77-4b1c9f0a2e88",
"status": "processing",
"received": 284,
"pollAfter": "2026-09-14T09:33:00Z"
}
Batched invoices default to financingRequested: false — history is the point.
Check a batch¶
{
"jobId": "0193f33c-1a02-7d55-8e77-4b1c9f0a2e88",
"status": "completed",
"received": 284,
"accepted": 281,
"rejected": 3,
"errors": [
{
"invoiceNumber": "2026-0402",
"code": "validation_failed",
"fields": { "dueDate": "before_issue_date" }
}
],
"completedAt": "2026-09-14T09:34:48Z"
}
Fix and resend only the rejected rows. Accepted rows are already stored.
Update an invoice¶
Two uses. Flip an existing invoice to financing, or correct the payment outcome of a historical one.
Ask for financing on an invoice you already sent¶
This is the in-product trigger: an invoice ages past term, you surface the option, the user taps it, and one PATCH moves the invoice into review.
The invoice must still be open. Financing a settled, credited, or already-financed invoice returns 409 not_financeable.
Update your own status¶
Free text. Noja stores it, returns it, and lets you filter on it, but never acts on it.
Attach the document later¶
Send the same document object accepted on create. Useful when the PDF is generated after the invoice record.
Correct a historical invoice¶
{
"paymentStatus": "paid",
"paymentDate": "2026-09-08",
"paidAmount": { "amount": 424250, "currency": "EUR" }
}
Optional. We treat history as a snapshot, so a stale payment status on a closed invoice degrades scoring only marginally — keeping it current is a refinement, not an obligation.
What you cannot change
financing.state, the decision fields, and every credit field are Noja-owned and read-only. Attempting to set them returns 422 naming the field.
You also cannot change amount, issueDate, or counterparty on an invoice that has already been financed — send a credit note as a new invoice instead.
List invoices¶
Filters¶
| Parameter | Accepts | Example |
|---|---|---|
client |
country and registration number | NL/68123456 |
direction |
receivable, payable |
receivable |
paymentStatus |
any payment status, repeatable | overdue |
financingState |
any financing state, repeatable | financing_approved |
financingRequested |
true, false |
true |
credited |
true, false |
false |
counterpartyType |
company, association, public_institution, person |
company |
counterpartyRegistrationNumber |
exact match | 24398871 |
partnerStatus |
exact match on your own label | sent |
issuedFrom / issuedTo |
dates | 2026-01-01 |
dueFrom / dueTo |
dates | 2026-09-30 |
updatedSince |
timestamp | 2026-09-14T00:00:00Z |
Repeatable parameters are OR-ed within themselves and AND-ed across: ?paymentStatus=open&paymentStatus=overdue&direction=receivable returns open or overdue receivables.
Pagination¶
Cursor-based. Follow nextCursor until hasMore is false; page size is fixed by us and may change, so never assume a count.
cursor=""
while :; do
page=$(curl -s -H "Authorization: Bearer $TOKEN" \
"https://api.noja.fi/partner/v1/invoices?client=NL/68123456&cursor=$cursor")
echo "$page" | jq -r '.invoices[].invoiceNumber'
[ "$(echo "$page" | jq -r .hasMore)" = "true" ] || break
cursor=$(echo "$page" | jq -r .nextCursor)
done
A cursor is valid for one hour and encodes the filters it was created with — changing a filter mid-walk invalidates it. Use this to reconcile, not to poll: webhooks carry changes as they happen.
Read one invoice¶
{
"invoiceId": "0193f31a-77bd-7c02-bb14-9e0f2a4c8d31",
"invoiceNumber": "2026-0417",
"client": { "countryCode": "NL", "registrationNumber": "68123456" },
"direction": "receivable",
"paymentStatus": "open",
"credited": false,
"partnerStatus": "sent",
"amount": { "amount": 424250, "currency": "EUR" },
"issueDate": "2026-08-30",
"dueDate": "2026-09-29",
"daysOverdue": 0,
"counterparty": {
"name": "Bouwgroep Rotterdam B.V.",
"type": "company",
"registrationNumber": "24398871"
},
"hasDocument": true,
"financing": {
"state": "financing_approved",
"decidedAt": "2026-09-14T10:02:47Z",
"amountApproved": { "amount": 339400, "currency": "EUR" },
"fee": { "amount": 10182, "currency": "EUR" },
"expectedPayoutAt": "2026-09-14T16:00:00Z"
}
}
You can also fetch by your own number: GET /invoices?client=NL/68123456&invoiceNumber=2026-0417.