Skip to main content

Build the collection button

The Starter Integration puts a "Send to collection" button beside an unpaid invoice. Your server sends the invoice to Debitura in one request. Debitura works out what the client still has to do (sign up, approve the connection, sign an agreement, verify identity or fix the invoice) and returns one link to open. You follow the request until it becomes a case.

Use this when: you want collection in your product without building onboarding, agreement or error-handling screens. You'll build: one server call, a button that opens a link, and one webhook handler. New to Starter? Do the quickstart first.

How it works​

Every time the client finishes a step, the request moves on and, if more is needed, carries a new solutionUrl. Your button always does the same thing: open the current solutionUrl.

1. Send one invoice​

Call POST /collection-requests from your server with your API key. Never call it from browser code. The API reference lists every field.

POST https://testreferral-api.debitura.com/collection-requests
XApiKey: <your-test-partner-key>
Idempotency-Key: collection-example-inv-0042
Content-Type: application/json

{
"externalTenantId": "example-client-42",
"client": {
"name": "Example Client Ltd",
"country": "GB",
"supportEmail": "accounts@example.invalid"
},
"user": {
"name": "Example User",
"email": "accounts@example.invalid"
},
"invoices": [{
"creditorReference": "EXAMPLE-INV-0042",
"debtor": {
"type": "Company",
"name": "Example Debtor Ltd",
"countryAlpha2": "GB",
"address": "10 Example Street",
"city": "London"
},
"amountToRecover": 1500.00,
"currencyCode": "GBP",
"date": "2026-06-01T00:00:00Z",
"dueDate": "2026-06-30T00:00:00Z",
"isTest": true
}]
}

What to know about the request:

  • One invoice per request. invoices is an array with exactly one item. If your user selects several invoices, send one request each.
  • Your identifiers. externalTenantId is your stable ID for the client, and creditorReference is the invoice number. You use both to look a request up later.
  • Client details are used once. client and user set up a new account. They never overwrite an account that already exists.
  • Retries are safe when you reuse the same Idempotency-Key. For 24 hours, the same key returns the original response; a changed payload with that key is refused. Because it is the original response, it can show an earlier step than where the client is now, so use a current read to check progress.
  • Return navigation after the hosted pages is set on your partner account, not per request. Never build onboarding or signing URLs yourself.

2. Open the next action​

The response says where the request stands and, if the client has something to do, gives you the link. For a new client:

{
"id": "33333333-3333-4333-8333-000000000042",
"status": "awaiting_onboarding",
"solutionType": "onboarding",
"solutionUrl": "https://testreferral.debitura.com/Onboarding/CompanyDetails/55555555-5555-4555-8555-555555555555",
"externalTenantId": "example-client-42"
}

Store the request id, then open solutionUrl from your button. What each status means for your user:

statusWhat the client does nextWhat your app shows
awaiting_onboardingSets up their Debitura accountOpens solutionUrl
awaiting_approvalApproves the connection to your platform (they already have a Debitura account)Opens solutionUrl; Debitura has also emailed them the invitation
awaiting_signatureSigns the agreement named in solutionTypeOpens solutionUrl
awaiting_kycSubmits identity detailsOpens solutionUrl
needs_fixingCorrects the invoice details and submits the draftOpens solutionUrl. Saving alone creates no case
submittedNothing; the invoice is a caseOpens solutionUrl to show the case
processingNothing yetShows "in progress" and reads again; there may be no link
rejected, expiredNothingShows the returned reason; there is no link, so don't make one

Details that matter:

  • Signatures. solutionType tells you which agreement: sdca, sdca_update, power_of_attorney or jurisdiction_pricing_appendix.
  • Existing clients. When the matched account isn't linked to you yet, nothing is created until the client approves. Debitura emails one approval invitation to the submitting user, and the same link is your solutionUrl. Until they approve, the response doesn't reveal which account matched. Only approvals expire (normally after 7 days); onboarding, signing and drafts have no deadline from the request.
  • KYC. The case waits while identity details are missing. Submitting them releases it; the collecting partner's review of those details is a separate, later step.
  • submitted is not "collecting". The invoice's caseStatus can still show verification or another early case stage.
  • HTTP codes. 201 means submitted, 202 means action or processing remains, and 422 can mean rejected. Branch on the body's status, not on the HTTP code alone.

Business context: see Case eligibility for which invoices Debitura accepts.

3. Follow progress​

Read the current state by request ID, or find the newest request for a client and invoice:

GET https://testreferral-api.debitura.com/collection-requests/{requestId}
XApiKey: <your-test-partner-key>
GET https://testreferral-api.debitura.com/collection-requests?externalTenantId=example-client-42&creditorReference=EXAMPLE-INV-0042
XApiKey: <your-test-partner-key>

To hear about changes without polling, subscribe to collection_request.updated. It fires when the request status or the invoice outcome changes, and carries the current request. Case events (case.created, case.updated, case.closed) keep working as usual. Verify signatures and deduplicate as for every Debitura webhook.

Two things to plan for:

  • Delivery is best effort and can repeat. If a webhook seems missing, read the request. Never create a new case because a callback didn't arrive.
  • Webhooks and test data. Request updates reach your active subscriptions in both Test and Production; an invoice's isTest does not decide where they go. A webhook test with collectionRequestId reaches Test subscriptions only, and only in the test environment.

4. Handle failures​

What happensWhat it meansWhat to do
400The request itself is unreadable: malformed JSON, wrong types, missing externalTenantId or creditorReference, more than one invoice, or size limitsFix your request; nothing was stored
needs_fixingThe invoice is readable but needs correctingOpen solutionUrl; the client fixes it on Debitura
rejectedDebitura can't take this invoice, e.g. the country isn't covered or the amount is below the minimumShow the returned reason
Timeout or 5xxA dependency failedRetry with the same Idempotency-Key, or read the request first. Don't tell your user it worked

5. Add Full endpoints when you need them​

Starter and Full share the same client relationship. With the same externalTenantId, you can mint a bearer token and use Customer API operations for this client at any time, with no new onboarding. Typical next steps:

A new Starter request recognises an existing case for the same client, invoice reference and test/live classification, whichever route created it. It returns that case and leaves the case's origin, attribution and rate unchanged. Starter doesn't change how the Full endpoints respond.

Try it without code​

The Ledgerline demo shows the button in a fictional accounting product. Turn on Developer view to see example requests and responses for each step. The demo sends no API traffic, so it doesn't prove your own integration works; verify that against test before production.

What's next​