Clients¶
A client starts as a prospect the moment you create it. It can receive invoices immediately; it can only receive money once onboarding is complete and underwriting has approved it.
Lifecycle¶
| Status | Meaning | Can send invoices | Can be financed |
|---|---|---|---|
pending_approval |
Created, or in onboarding, or awaiting underwriting | Yes | No |
active |
Approved, limit assigned | Yes | Yes |
suspended |
Temporarily blocked | Yes | No |
inactive |
Deactivated, relationship dormant | Yes | No |
archived |
Closed | No | No |
These five values are the complete set — status is never anything else. A newly created client is pending_approval and additionally carries isProspect: true until it has a financing relationship. There is no prospect status: prospect is the flag, not the state. Where the client sits inside onboarding is a separate field — read onboarding state, not the client status.
Invoices are accepted in every state except archived. Those flagged for financing before the client is active wait, and are picked up automatically the moment approval lands — no resubmission.
Status transitions arrive as client.status_changed webhooks.
Create a client¶
Registers one of your users as a Noja prospect and returns a ready-to-use onboarding URL in the same response.
Request¶
| Field | Type | Notes | |
|---|---|---|---|
countryCode |
string | Required | NL |
registrationNumber |
string | Required | Company registration number — see formats |
companyName |
string | Required | Replaced by the registry name once we enrich |
contact |
object | Required | firstName, lastName, email, phone |
consent |
object | Optional | Required before financial data is accepted. Omit it and Noja records consent when the client signs — see Consent |
tradeName |
string | Optional | Handelsnaam, when it differs from the registered name |
partnerReference |
string | Optional | Your own user or tenant ID, echoed back everywhere |
language |
string | Optional | nl (default), en or fi |
{
"countryCode": "NL",
"registrationNumber": "68123456",
"companyName": "Van Dijk Installatietechniek",
"contact": {
"firstName": "Sanne",
"lastName": "van Dijk",
"email": "sanne@vandijk-installatie.nl",
"phone": "+31612345678"
},
"consent": {
"obtainedAt": "2026-09-14T09:31:04Z",
"method": "in_product_checkbox",
"evidenceRef": "ptr-consent-4471a9"
},
"partnerReference": "ptr-user-88213"
}
Response · 201¶
{
"clientId": "0193f2a1-8c4e-7b21-9d3f-1a2b3c4d5e6f",
"countryCode": "NL",
"registrationNumber": "68123456",
"companyName": "Van Dijk Installatietechniek B.V.",
"status": "pending_approval",
"isProspect": true,
"partnerReference": "ptr-user-88213",
"onboarding": {
"mode": "hosted",
"url": "https://aanvraag.noja.nl/?partnerAccess=p_7f2a91&ref=0193f2a1",
"expiresAt": "2026-10-14T09:31:04Z"
},
"createdAt": "2026-09-14T09:31:04Z"
}
The onboarding.url is the Mode B hand-off. Ignore it if you are collecting the data yourself.
Errors¶
| Status | Code | When |
|---|---|---|
| 409 | client_exists |
That registration number is already registered. The body carries the existing clientId — treat it as success and continue. |
| 422 | validation_failed |
Registration number does not match its country's format, or the contact is incomplete. |
Read a client¶
Current state of one client: status, onboarding progress, and a headline capacity figure once approved.
{
"clientId": "0193f2a1-8c4e-7b21-9d3f-1a2b3c4d5e6f",
"registrationNumber": "68123456",
"companyName": "Van Dijk Installatietechniek B.V.",
"status": "active",
"isProspect": false,
"partnerReference": "ptr-user-88213",
"onboarding": {
"state": "signed",
"completedAt": "2026-09-18T14:02:55Z",
"signing": { "state": "signed", "provider": "scrive" }
},
"capacity": {
"availableCredit": { "amount": 1840000, "currency": "EUR" },
"creditUsedPercentage": 26.4
}
}
capacity is null until the client is active. It is a summary for showing headroom in a list view; for the full commercial picture use credit conditions.
History coverage¶
How much trading history we hold, and whether it is enough to price the client. Poll this after a bulk upload instead of guessing.
Three months is the minimum that produces a limit. Twelve months gives materially better pricing, because payment-behaviour variance is what narrows the rate. Below three months sufficientForPricing stays false and no terms are issued.
{
"monthsCovered": 11,
"invoiceCount": 284,
"earliestIssueDate": "2025-10-02",
"latestIssueDate": "2026-09-11",
"distinctDebtors": 37,
"sufficientForPricing": true,
"qualityTier": "good",
"recommendation": "Send one more month to reach the 12-month tier."
}
qualityTier |
Meaning |
|---|---|
insufficient |
Under three months. No limit can be issued. |
minimal |
Three to six months. Limit issued, conservative pricing. |
good |
Six to twelve months. |
complete |
Twelve months or more. Best available pricing. |
Limit and fees¶
The full commercial terms — limit, utilisation, pricing, and effective APR.
Terms appear as soon as there is enough history to price them, which is usually before the client is approved. state tells you how much weight to give them:
state |
Meaning | Safe to show as a firm offer |
|---|---|---|
indicative |
Priced from history, not yet underwritten | No — label it an estimate |
pending_approval |
Submitted, in underwriting | No |
approved |
Underwritten and live | Yes |
declined |
Underwriting declined the client | No |
Before there is enough history to price anything, the endpoint returns 409 terms_not_available with a reason of insufficient_history.
Response¶
| Field | Type | Meaning |
|---|---|---|
state |
enum | indicative, pending_approval, approved, declined |
updatedAt |
timestamp | When these terms last changed |
totalCreditLimit |
money | Assigned limit |
temporaryCreditLimit |
money | Uplift, when one is active |
temporaryCreditLimitFrom |
date | Start of the uplift window |
temporaryCreditLimitTo |
date | End of the uplift window |
usedCredit |
money | Drawn and not yet repaid |
outstandingCredit |
money | Financed invoices awaiting debtor settlement |
effectiveCreditLimit |
money | Total including any temporary uplift |
availableCredit |
money | Effective limit minus used |
creditUsedPercentage |
number | Utilisation, 0–100 |
financingRate |
string | Headline financing rate |
pricing |
string | Pricing band label |
additionalFinancingPrice |
string | Surcharge beyond the base term |
effectiveAprBase |
number | Effective APR at the base rate |
effectiveAprAdditional |
number | Effective APR including surcharge |
openingFee |
money | One-off fee charged at activation |
averagePaymentTermCurrent |
integer | Debtors' current average days-to-pay |
averagePaymentTermHistory |
integer | The same figure across full history |
conditionsDetails |
array | Label/value pairs for display |
{
"state": "approved",
"updatedAt": "2026-09-19T08:40:12Z",
"totalCreditLimit": { "amount": 2500000, "currency": "EUR" },
"temporaryCreditLimit": null,
"usedCredit": { "amount": 660000, "currency": "EUR" },
"outstandingCredit": { "amount": 660000, "currency": "EUR" },
"effectiveCreditLimit": { "amount": 2500000, "currency": "EUR" },
"availableCredit": { "amount": 1840000, "currency": "EUR" },
"creditUsedPercentage": 26.4,
"financingRate": "2.4% / 30 days",
"pricing": "Band B",
"additionalFinancingPrice": "0.8% / 15 days",
"effectiveAprBase": 28.1,
"effectiveAprAdditional": 34.6,
"openingFee": { "amount": 50000, "currency": "EUR" },
"averagePaymentTermCurrent": 41,
"averagePaymentTermHistory": 38,
"conditionsDetails": [
{ "label": "Invoice minimum", "value": "€250" },
{ "label": "Maximum term", "value": "90 days" }
]
}
Surfacing this to the user
availableCredit and financingRate are the two figures a user acts on. The APR fields exist because Dutch consumer-facing credit disclosure expects them — show them where a user is deciding, not in a settings page.
Changes to any of these arrive as client.credit_conditions_updated.