Build a Starter Integration with an AI agent
Build a “Send to collection” button: send one invoice from your server, open the returned link, then read current progress. Debitura hosts setup and correction. Pricing preview is optional.
Give your agent this brief
Start at llms.txt. Append .md to any documentation URL for its Markdown copy, including this recipe. Use the collection-request reference and OpenAPI schemas for the complete contract.
Build a small server-side Debitura Starter Integration using this recipe
and its linked docs. Use test hosts, fictional clients and isTest invoices.
Keep credentials on the server, outside prompts, code, browser bundles and logs.
Implement one-invoice POST, a user-clicked returned solutionUrl, current GET,
and a signature-verified collection_request.updated handler with safe deduplication.
Recover after return, repeated/missing events, failed reads and uncertain POSTs.
Record actual request/case progress; redirects and submitted are not proof of
active collection. Exercise the checks below and record friction and cleanup.
1. Prepare test access
Set your server’s DEBITURA_API_KEY to a test partner key. Call https://testreferral-api.debitura.com with XApiKey; check access with GET /me. Arrange an allowlisted test email and verification-code access with your partnership contact. Use unique fictional identities. See Environments and test data.
The public 123456 demo is a simulation. A demo partner alone does not enable that code for API-created clients. Use their real test verification codes; never update agreement state in the database to claim completion.
2. Send one invoice from your server
Use one stable externalTenantId per client and creditorReference per invoice. Replace the test email placeholders with the arranged address and RUN_ID with your unique run identifier:
POST https://testreferral-api.debitura.com/collection-requests
XApiKey: YOUR_TEST_API_KEY
Idempotency-Key: starter-RUN_ID-001
Content-Type: application/json
{
"externalTenantId": "starter-RUN_ID",
"client": {
"name": "Starter Recipe Test Ltd",
"country": "GB",
"supportEmail": "YOUR_TEST_EMAIL"
},
"user": { "name": "Recipe Test User", "email": "YOUR_TEST_EMAIL" },
"invoices": [{
"creditorReference": "STARTER-RUN_ID-001",
"debtor": {
"type": "Company",
"name": "Fictional 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
}]
}
invoices has exactly one item. Client/user fields initialise new accounts only. Configure return navigation on your partner account; omit returnUrl and never construct hosted URLs. For bulk sending, reuse Sending several invoices: independent calls/results, deterministic current-action selection and retained partial failures.
Store request id, client/reference and original key/body in your existing server records. Authorise ownership on every browser-facing read; browsers cannot choose another client’s request or credentials.
3. Open the returned action and read again
A new client returns 202 / awaiting_onboarding, solutionType: "onboarding" and a solutionUrl. Show a user-clicked Continue link; asynchronous popups can be blocked. Open only the current returned HTTPS URL, without adding parameters.
Current status | Your integration does |
|---|---|
awaiting_onboarding | Open onboarding; complete company/user details and agreements. |
awaiting_approval | Open approval. Existing clients must consent before case creation; Debitura emails the submitting user. |
awaiting_signature | Open the agreement link; solutionType identifies sdca, sdca_update, power_of_attorney or jurisdiction_pricing_appendix. |
awaiting_kyc | Open KYC. Submission releases eligible cases; reconciliation can take time. |
needs_fixing | Open correction. Saving leaves a draft; explicit submission creates the case. |
submitted | Show the case and caseStatus; ordinary verification can remain. |
processing | Wait and refresh, without navigation. |
rejected / expired | Show reason/issues without navigation. A fresh request can seek approval after expiry. |
Refresh null URLs and handle unknown actions explicitly. Agreements can be reused; another collector/jurisdiction can require more signing. Only approvals expire, normally after seven days. See the complete action guide.
Read current state after every return, on manual recheck while pending, and after a verified update:
GET https://testreferral-api.debitura.com/collection-requests/{requestId}
XApiKey: YOUR_TEST_API_KEY
If the original response was lost, look up the newest request for that client and invoice; URL-encode both values:
GET https://testreferral-api.debitura.com/collection-requests?externalTenantId=starter-RUN_ID&creditorReference=STARTER-RUN_ID-001
XApiKey: YOUR_TEST_API_KEY
GET defines progress; redirects do not. After shared setup, refresh all known selected request IDs. Clear Continue during refresh; failed reads retain the last result with an error and withhold stale navigation.
4. Handle updates and recovery
Register a webhook on the test Referral Partner API (POST /v1/Webhooks), with your HTTPS endpoint, events: ["collection_request.updated"] and isTestMode: true. Save its returned signing secret on the server. Normal request updates can reach both Test and Production subscriptions regardless of the invoice's isTest; explicit test deliveries target Test subscriptions only.
Implement this handler using the signature verification and deduplication guidance:
- Verify
X-Debitura-Signaturebefore parsing or acting. Sign{timestamp}.{raw_json_body}with HMAC-SHA256 using the Base64-decoded secret; compare lowercase hex in constant time. Reject invalid signatures, timestamps older than 300 seconds or more than 30 seconds ahead. - Parse the verified body: type
event.event, identityevent.id, request IDevent.data.id. Resolve your own client/request mapping; fetch from your configured API, never a supplied URL. - Deduplicate
event.idin your existing job/store. Durably enqueue before acknowledging, or complete GET/update before marking done and returning2xx. Failed work stays retryable. Return within 10 seconds; queue longer work. - GET with the matching server-side partner key and update only that invoice row. Duplicates create no case/payment; current reads prevent out-of-order events regressing state.
SDCA → PoA can change GET without an event. Deliveries can repeat or be missed: retain return/manual GET recovery, with no exactly-once or zero-loss assumption.
| Failure | Recovery |
|---|---|
Timeout / 5xx during POST | Look up by client/reference, or retry the original body and key within the 24-hour replay window. Keep an uncertain outcome visible. |
| Same-key replay shows old action | GET current state; replay returns the original receipt, not progress. Changed body with the same key is refused. |
400 / unstructured HTTP error | Show the failure for that invoice. Fix malformed requests; do not treat them as stored requests. |
422 with a collection-request body | Handle its returned status and invoice reason; a structured rejection is a result. Other 422 errors can be idempotency conflicts, not receipts. |
| Failed read or dependency | Keep pending/error state, retry the read/work, and report no success until observed. |
5. Verify, clean up and go live
Record HTTP status, request ID, invoice result and actual case status, without keys, signing links, verification codes or personal payloads. Exercise each check with fictional test fixtures:
- New client → actual onboarding/signing → current GET; existing client → approval before processing.
- Additional signature and KYC where required; corrected draft stays
needs_fixingafter save and creates a case only after explicit submit; rejected invoice retains its reason. - Identical keyed retry and changed-body conflict; reference lookup after an uncertain POST; current GET after return/missing event and stale replay; no duplicate case.
- Valid signed update, repeated delivery, invalid signature/raw body, stale/future timestamp, failed GET followed by retry. Local signed fixtures prove your handler, not actual Debitura delivery; test delivery separately.
- Invalid key, empty/two-item invoice array, another partner's request/tenant and unavailable dependency are refused or surfaced without leaking secrets or claiming success.
Use the supported test reset, inspecting blockers and closing active owned test cases first. Complete the Starter go-live checklist: production credentials/hosts and subscriptions, branding/return configuration, every status and recovery path. Real production invoices omit isTest or set it to false; this recipe performs no production calls.
Add Full endpoints later: mint a client bearer with the same externalTenantId, without new onboarding. Starter finds existing cases by client, invoice reference and test/live classification whichever route created them. The Full AI recipe remains available.