Skip to main content

Workflow: Handle 409 Conflicts

Learn how to handle conflicts when linking clients who already exist in Debitura's system through other channels.

Understanding 409 Conflicts

A 409 Conflict response occurs when you attempt to link a client that already has a relationship with Debitura through another channel:

  • Direct customer account
  • Another referral partner
  • Collection partner relationship
  • Legacy system migration

When Conflicts Occur

Conflicts can happen during:

  1. Client Linking - Attempting to create a new linked client
  2. Case Creation - Creating a case for a debtor already known to Debitura
  3. Onboarding - Customer already completed onboarding elsewhere

Conflict Response Structure

When a conflict occurs, you'll receive a 409 Conflict response with detailed information:

HTTP/1.1 409 Conflict
Content-Type: application/json
{
"error": {
"type": "conflict_error",
"message": "Client already exists in Debitura system",
"conflict_type": "existing_client",
"details": {
"client_id": "cli_existing_123",
"relationship_type": "direct_customer",
"created_at": "2023-06-15T08:30:00Z",
"can_claim": false,
"claim_deadline": null
}
}
}

Conflict Types

1. Existing Direct Customer

Scenario: Company already has a direct Debitura account.

Response:

{
"error": {
"type": "conflict_error",
"conflict_type": "existing_direct_customer",
"details": {
"client_id": "cli_abc123",
"relationship_type": "direct_customer",
"can_claim": false
}
}
}

Resolution:

  • Contact Debitura support to discuss migration
  • Customer must approve transfer to referral model
  • Existing cases remain with direct relationship

2. Existing Referral Partner

Scenario: Company already linked to a different referral partner.

Response:

{
"error": {
"type": "conflict_error",
"conflict_type": "existing_referral_partner",
"details": {
"client_id": "cli_abc123",
"relationship_type": "referral_partner",
"partner_name": "Other Platform AB",
"can_claim": false
}
}
}

Resolution:

  • Cannot claim clients from other partners
  • Customer must terminate existing relationship first
  • Debitura support can facilitate if needed

3. Claimable Client

Scenario: Company exists but is in an inactive or transitional state that allows claiming.

Response:

{
"error": {
"type": "conflict_error",
"conflict_type": "claimable_client",
"details": {
"client_id": "cli_abc123",
"relationship_type": "inactive",
"can_claim": true,
"claim_deadline": "2024-02-15T23:59:59Z"
}
}
}

Resolution: Use the claim endpoint (see below).

Claiming Clients

When can_claim: true is indicated, you can claim the client:

Claim Request

POST /v1/referral-partners/clients/{client_id}/claim

Request:

{
"external_id": "your_customer_id_123",
"acknowledge_terms": true,
"metadata": {
"claim_reason": "customer_migrated",
"migration_date": "2024-01-15"
}
}

Response:

{
"client_id": "cli_abc123",
"external_id": "your_customer_id_123",
"status": "active",
"bearer_token": "tok_new_xyz789",
"claimed_at": "2024-01-15T10:00:00Z",
"previous_relationship": "inactive"
}

Claim Conditions

You can claim a client when:

  • Client is marked as can_claim: true
  • Claim deadline has not passed
  • You acknowledge attribution terms
  • No active referral partner relationship exists

What Happens After Claiming

  1. Attribution Changes

    • Future cases attributed to you
    • Existing case attribution unchanged
    • Clear separation of old vs new cases
  2. Bearer Token Issued

    • New bearer token for case creation
    • Old credentials (if any) remain for historical access
  3. Audit Trail

    • Claim recorded in client history
    • Previous relationship noted
    • Revenue attribution adjusted

Handling Strategies

Strategy 1: Graceful Degradation

Provide degraded functionality when client cannot be linked:

async function linkOrDegrade(customerData) {
try {
const client = await linkClient(customerData);
return {
linked: true,
bearer_token: client.bearer_token,
features: ['case_creation', 'revenue_share']
};
} catch (error) {
if (error.status === 409) {
// Client exists, but we can't link them
return {
linked: false,
features: ['manual_referral'], // Limited functionality
message: 'Contact support to complete setup'
};
}
throw error;
}
}

Strategy 2: Support-Assisted Resolution

Direct customer to support when conflicts arise:

async function handleConflict(error, customerData) {
if (error.conflict_type === 'existing_direct_customer') {
// Generate support ticket
const ticket = await createSupportTicket({
type: 'client_migration',
customer: customerData,
conflict_details: error.details
});

return {
action: 'contact_support',
ticket_id: ticket.id,
message: 'We need to migrate your existing Debitura account. Support will contact you within 24 hours.'
};
}
}

Strategy 3: Claim When Possible

Automatically claim when permitted:

async function linkOrClaim(customerData) {
try {
// Attempt normal linking
return await linkClient(customerData);
} catch (error) {
if (error.status === 409 && error.details.can_claim) {
// Automatically claim if allowed
return await claimClient(
error.details.client_id,
customerData.external_id
);
}
throw error;
}
}

Preventing Conflicts

Pre-Flight Validation

Check if a client exists before attempting to link:

GET /v1/referral-partners/validate-client?vat_number=SE123456789001

Response:

{
"exists": true,
"available_for_linking": false,
"conflict_type": "existing_direct_customer",
"recommendations": [
"contact_support",
"customer_approval_required"
]
}

Validation Workflow

  1. Before Linking: Call validation endpoint
  2. If Available: Proceed with linking
  3. If Conflict: Show appropriate message to user
  4. If Claimable: Offer claim option

Error Response Reference

Common Conflict Scenarios

Scenarioconflict_typecan_claimAction
Direct customerexisting_direct_customerfalseContact support
Other partnerexisting_referral_partnerfalseCannot link
Inactive accountclaimable_clienttrueUse claim endpoint
Pending onboardingpending_onboardingtrueComplete or claim
Terminated accountterminated_accounttrueClaim within deadline

Best Practices

User Experience

  • Clearly communicate conflict situations
  • Provide actionable next steps
  • Avoid technical jargon in error messages
  • Offer support contact information

Technical Implementation

  • Implement pre-flight validation
  • Handle 409s gracefully
  • Log conflict occurrences
  • Monitor conflict patterns

Business Process

  • Document conflict resolution process
  • Train support team on migration
  • Set customer expectations
  • Track time-to-resolution

Examples

async function safelyLinkClient(customerData) {
// Pre-flight check
const validation = await validateClient({
vat_number: customerData.vat_number,
email: customerData.email
});

if (!validation.available_for_linking) {
// Handle conflict proactively
return {
success: false,
reason: validation.conflict_type,
action_required: validation.recommendations
};
}

// Safe to link
return await linkClient(customerData);
}

Example 2: Automatic Claim Flow

async function linkWithAutoClaim(customerData) {
try {
return await linkClient(customerData);
} catch (error) {
if (error.status === 409) {
const { can_claim, client_id } = error.details;

if (can_claim) {
// Automatically claim
console.log('Client exists but is claimable, claiming...');
return await claimClient(client_id, {
external_id: customerData.external_id,
acknowledge_terms: true
});
}

// Cannot claim - escalate
throw new Error(
`Cannot link client: ${error.conflict_type}. Please contact support.`
);
}
throw error;
}
}

Support Escalation

When conflicts cannot be resolved automatically:

  1. Gather Information

    • Client details from your system
    • Conflict error response
    • Customer's intent/preference
  2. Contact Debitura Support

  3. Customer Communication

    • Inform customer of situation
    • Set expectations on timeline
    • Provide tracking information

Next Steps