Idempotency
Debitura uses endpoint-specific idempotency mechanisms rather than a universal Idempotency-Key header. This article explains how each API handles repeated requests and what you should do to safely retry operations.
How Debitura Handles Idempotency
Different Debitura APIs use different approaches to prevent duplicate operations:
| API | Operation | Mechanism | Key Field |
|---|---|---|---|
| Referral Partner API | Client creation | Natural key lookup | ExternalTenantId |
| Customer API | Case creation | Reference uniqueness | CreditorReference |
| All APIs | Webhook consumption | Event ID tracking | id field in payload |
Debitura does not support a standard Idempotency-Key request header. Instead, idempotency is achieved through business-level identifiers that you control.
Referral Partner API
Client Creation
The POST /clients endpoint is fully idempotent based on your ExternalTenantId:
POST /v1/clients
Content-Type: application/json
{
"externalTenantId": "your-unique-client-id",
"company": { ... }
}
Behavior on repeated calls:
- First call creates the client and returns
201 Createdor202 Accepted - Subsequent calls with the same
ExternalTenantIdreturn the existing client's current status - No duplicate clients or links are created
The response code may change between calls as onboarding progresses:
| Client State | Response |
|---|---|
| Fully onboarded | 201 Created |
| Onboarding incomplete | 202 Accepted |
| Exists, needs manual linking | 409 Conflict |
This design allows you to safely retry client creation requests without tracking request state yourself.
Case Creation via Clients Endpoint
When creating cases through the Referral Partner API's client onboarding flow, case creation is not idempotent in the same way:
- If you include a
casesarray when creating a client, cases are created only on the first successful call - Repeated calls for an already-linked client return an
IdempotencyViolationerror for the cases portion - The client data itself remains idempotent
Recommendation: Create clients first, then create cases separately using CreditorReference for duplicate prevention.
Customer API
Case Creation
Case creation uses CreditorReference as a uniqueness constraint:
POST /v1/cases
Content-Type: application/json
{
"creditorReference": "INV-2024-001",
"debtor": { ... },
"amount": 1500.00
}
Behavior:
CreditorReferencemust be unique per creditor- Attempting to create a case with a duplicate reference returns
400 Bad Request - This prevents accidental duplicate case creation
Important: This is duplicate prevention, not true idempotency. If your first request times out, you should:
- Query for existing cases with that
CreditorReference - Only retry if no case exists
Webhook Consumption
When receiving webhooks from Debitura, use the id field for idempotency:
{
"id": "evt_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"type": "case.created",
"timestamp": "2024-01-15T10:30:00Z",
"data": { ... }
}
Implementation pattern:
- Extract the
idfield from the webhook payload - Check if you've already processed this event ID
- If processed, return
200 OKwithout taking action - If new, process the event and store the ID
Debitura retries failed webhook deliveries up to 8 times with exponential backoff. Your endpoint may receive the same event multiple times, so idempotent handling is essential.
See Webhook Best Practices for implementation examples.
Safe Retry Strategies
Since Debitura doesn't use a universal idempotency key, follow these patterns for safe retries:
For Client Operations (Referral Partner API)
Safe to retry directly—the API handles idempotency via ExternalTenantId.
For Case Operations
- Include a unique
CreditorReferencein every request - If a request fails:
- Query for cases with that reference
- Only retry if no case exists
- Handle
400responses for duplicate references gracefully
For Webhook Processing
- Store processed event IDs (the
idfield) - Check before processing
- Return
200 OKfor already-processed events
Summary
| Operation | Safe to Retry? | How to Handle |
|---|---|---|
| Create client (Referral Partner API) | ✅ Yes | API handles via ExternalTenantId |
| Create case | ⚠️ With care | Use unique CreditorReference, check before retry |
| Process webhook | ✅ Yes | Track id field, deduplicate locally |
For case creation, implement a check-then-act pattern: query for existing cases with your CreditorReference before retrying failed requests.