Source: https://docs.debitura.com/api/customer-api/cases

# Cases — Customer API

Base URL: `https://customer-api.debitura.com`

Authentication: `XApiKey` API key; see [authentication](https://docs.debitura.com/developer-concepts/authentication.md).

Generated from [OpenAPI](https://docs.debitura.com/openapi/customer-api.json). Examples are schema illustrations, not observed responses. Complete schemas, including recursive types, are in OpenAPI.

<a id="list-collection-cases"></a>

## List collection cases

`GET /cases`

Returns a paginated list of collection cases for your account.

**Pagination:**
- page (default: 1) - Page number, starting from 1
- pageSize (default: 10, max: 100) - Number of results per page

**Filters:**
- statuses - Filter by case lifecycle status (comma-separated list)
  Valid values: PendingContractSigning, PendingVerificationInternal, PendingVerification,
  NeedsAdditionalDetails, Leads, LeadsQuoteGiven, Active, Paused, Closed, Merged
  (case-insensitive; both name and description forms accepted)
- divisionIds - Filter by creditor division IDs (comma-separated GUIDs, for multi-division creditors)
- debtorIds - Filter by specific debtor IDs (comma-separated GUIDs)
- ids - Filter by specific case IDs (comma-separated GUIDs)

**Sorting:**
- sort - Sort field and direction (format: 'field:direction')
  Valid sort fields: DateCreated, DateUpdated, DateFinished, DateCollectionStarted,
  DueDate, Date, GrossAmount, Remainder, InterestFees, CollectionFees, ReminderFees,
  Lifecycle, CloseCode, ClaimType, Reference, CreditorReference, CollectionPartnerReference,
  Type, Classification, Debtor, Creditor, Country, ExclusivityEndDate, ActiveCollectionPeriodEndDate,
  PaymentTotalSum, CurrentPhase, CollectionPartner, Jurisdiction,
  ManagedByPartner, CreditorDivision, AssignedCollectorUser, AssignedCreditorUser,
  AssignedManagingPartnerUser, ReferralPartner
  Examples: 'DateCreated:desc', 'DueDate:asc', 'GrossAmount:desc'
  Unknown fields return HTTP 400. Equal values are ordered by case ID in the last requested direction.

**Response:**
- Returns InvoiceListApiDTO with page metadata and cases array
- Page metadata includes: totalResults, currentPage, skipped, pageSize

### Query parameters

- `Page` (integer): 
- `PageSize` (integer): 
- `DebtorIds` (array of uuids): 
- `Ids` (array of uuids): 
- `Statuses` (array of strings): Filter by case lifecycle status. Valid values: PendingContractSigning, PendingVerificationInternal,
PendingVerification, NeedsAdditionalDetails, Leads, LeadsQuoteGiven, Active, Paused, Closed, Merged
(case-insensitive; both name and description forms accepted).
- `DivisionIds` (array of uuids): Optional list of division IDs to filter by
- `Sort` (string): Optional sorting string "Field[:asc|desc][,Field2[:asc|desc]]…".
Valid sort fields: DateCreated, DateUpdated, DateFinished, DateCollectionStarted,
DueDate, Date, GrossAmount, Remainder, InterestFees, CollectionFees, ReminderFees,
Lifecycle, CloseCode. Examples: 'DateCreated:desc', 'DueDate:asc'. Unknown fields are silently ignored.

### Response 200

List returned

- `page` (object, required): Stable v1 pagination metadata shared by public list responses.
- `page.totalResults` (integer): 
- `page.pageSize` (integer): 
- `page.currentPage` (integer): 
- `page.responseCount` (integer): 
- `page.totalPages` (integer): 
- `cases` (array of objects, nullable): V1 Invoice DTO for external partner APIs
- `cases[].id` (uuid): 
- `cases[].dateCreated` (datetime): 
- `cases[].dateUpdated` (datetime, nullable): 
- `cases[].reference` (string, nullable): 
- `cases[].creditorReference` (string, nullable): 
- `cases[].creditorComments` (string, nullable): 
- `cases[].claimDescription` (string, nullable): 
- `cases[].grossAmount` (number): 
- `cases[].remainder` (number): 
- `cases[].interestFees` (number): 
- `cases[].reminderFees` (number): 
- `cases[].collectionFees` (number): 
- `cases[].totalAddedFees` (number): 
- `cases[].currency` (string, nullable): 
- `cases[].isTestCase` (boolean): 
- `cases[].lifecycle` (string, nullable): 
- `cases[].dueDate` (datetime): 
- `cases[].date` (datetime): 
- `cases[].dateFinished` (datetime, nullable): 
- `cases[].dateCollectionStarted` (datetime, nullable): 
- `cases[].closeCode` (string, nullable): 
- `cases[].currentEngagementPhase` (string, nullable): The current phase of the case's engagement: "Pre-legal", "Legal", or "Enforcement".
A different axis from Lifecycle/CloseCode — an Active case can be
in any of the three phases.
            
Null means "no active engagement" (e.g. lead / quoting / pre-contract-signing / unassigned, or
a data-consistency gap) — this is a distinct third state, NOT a synonym for Pre-legal. Most
cases legitimately read Pre-legal; phase only leaves Pre-legal on legal/enforcement quote flows.
            
Not guaranteed to be monotonic: an admin correction can move phase backwards (e.g. Legal back
to Pre-legal).
            
Persists after case closure — reflects the case's last-known engagement phase, not the current
Lifecycle. Note: this is a different field from a lead quote's own offered phase (the phase a
partner's quote proposes to work the case at, if this case ever went through a quote flow) —
this field is the case-level phase of its actual engagement, not a quote's terms.
- `cases[].claimType` (string, nullable): The type of claim for this case (e.g. "Unpaid Invoice", "Loan Repayment", "Breach of Contract").
Null if not set.
- `cases[].creditorDivisionId` (uuid, nullable): 
- `cases[].debtor` (object): V1 Debtor DTO for external partner APIs.
The debtor is the party that owes the debt.
- `cases[].debtor.type` (string, required): Debtor type. Valid values: "Company" or "Private" (case-insensitive)
- `cases[].debtor.name` (string, required): Debtor name (company name or person's full name)
- `cases[].debtor.contactPerson` (string, nullable): Contact person at the company (required for companies, not used for persons)
- `cases[].debtor.companyRegistrationNumber` (string, nullable): Company registration number (VAT number, CVR, org number, etc.)
- `cases[].debtor.address` (string, nullable): Street address
- `cases[].debtor.zipCode` (string, nullable): Postal/ZIP code
- `cases[].debtor.city` (string, nullable): City name
- `cases[].debtor.state` (string, nullable): State/region/province name
- `cases[].debtor.stateAlpha2` (string, nullable): US state: two-letter code (e.g., "CA"), ISO 3166-2 format (e.g., "US-CA"), or full name (e.g., "California")
- `cases[].debtor.countryAlpha2` (string, nullable): Country code (ISO 3166-1 alpha-2 format)
- `cases[].debtor.country` (string, nullable): Country name
- `cases[].debtor.email` (string, nullable): Email address for debtor contact
- `cases[].debtor.phone` (string, nullable): Phone number (include country code)
- `cases[].collectionPartner` (object): V1 Collection Partner DTO for external partner APIs
- `cases[].collectionPartner.name` (string, nullable): 
- `cases[].collectionPartner.officeEmail` (string, nullable): 
- `cases[].collectionPartner.officePhone` (string, nullable): 
- `cases[].collectionPartner.publicSite` (string, nullable): 
- `cases[].collectionPartner.surveyCadenceMode` (enum, deprecated): Deprecated: kept as a number and never removed, but not extended. Survey-generation cadence: 0 = Standard
(rolling monthly survey), 1 = DecisionPointOnly (no rolling surveys).
  Values: `0`, `1`.
- `cases[].creditor` (object): Creditor (client) information for external partner APIs.
Represents the party that the debtor owes money to.
- `cases[].creditor.id` (uuid): Unique identifier for the creditor
- `cases[].creditor.companyName` (string, nullable): Company name of the creditor
- `cases[].creditor.companyRegistrationNumber` (string, nullable): Company registration number (CVR, VAT number, etc.)
- `cases[].creditor.officeEmail` (string, nullable): Primary office email address
- `cases[].creditor.officePhone` (string, nullable): Primary office phone number
- `cases[].creditor.address` (string, nullable): Street address
- `cases[].creditor.city` (string, nullable): City
- `cases[].creditor.zipCode` (string, nullable): Postal/ZIP code
- `cases[].creditor.state` (string, nullable): State or region (if applicable)
- `cases[].creditor.country` (string, nullable): Country name
- `cases[].creditor.division` (object): Creditor division information for external partner APIs.
Represents a specific division or department within a creditor organization.
- `cases[].creditor.division.id` (uuid): Unique identifier for the division
- `cases[].creditor.division.name` (string, nullable): Name of the division
- `cases[].bankAccount` (object): Bank account information for partner API.
Full details provided as partners need this to:
1. Provide payment instructions to debtors (when debtor pays client directly)
2. Execute payouts to clients (when partner receives payment and pays out remainder)
- `cases[].bankAccount.id` (integer): Bank account identifier
- `cases[].bankAccount.label` (string, nullable): User-friendly label (e.g., "Main EUR Account")
- `cases[].bankAccount.scheme` (string, nullable): Account scheme: IBAN, SWIFT, or LOCAL
- `cases[].bankAccount.currencyCode` (string, nullable): Currency code (ISO 4217)
- `cases[].bankAccount.bankCountryCode` (string, nullable): Bank country code (ISO Alpha-2)
- `cases[].bankAccount.accountHolderName` (string, nullable): Account holder name (beneficiary)
- `cases[].bankAccount.iban` (string, nullable): IBAN (for IBAN scheme accounts)
- `cases[].bankAccount.bic` (string, nullable): BIC/SWIFT code (for IBAN and SWIFT scheme accounts)
- `cases[].bankAccount.accountNumber` (string, nullable): Account number (for SWIFT and LOCAL scheme accounts)
- `cases[].bankAccount.localIdentifier` (string, nullable): Local identifier (for LOCAL scheme accounts, e.g., sort code + account number)
- `cases[].bankAccount.localIdentifierType` (string, nullable): Type of local identifier (e.g., "Sort Code", "Routing Number")
- `cases[].bankAccount.bankName` (string, nullable): Bank name (optional)
- `cases[].bankAccount.bankAddress` (string, nullable): Bank address (optional)
- `cases[].bankAccount.bankCity` (string, nullable): Bank city (optional)
- `cases[].bankAccount.bankZipCode` (string, nullable): Bank zip/postal code (optional)
- `cases[].bankAccount.bankState` (string, nullable): Bank state/region (optional)
- `cases[].blendedAgeUpliftPoints` (number, nullable): MULTI-INVOICE AGE BUCKET PRICING
Calculated blended age uplift percentage points (0-20) for multi-invoice cases.
Shows the additional fee percentage added due to invoice age.
Formula: ((A12-A24)×10 + A24×20) / Total Principal
Null for single-invoice cases (age uplift is calculated from due date instead).
- `cases[].preLegalSuccessFee` (number, nullable): PRE-LEGAL SUCCESS FEE
The total pre-legal success fee percentage for this case.
Includes base fee + age-based uplift (blended or single-invoice).
Null if pricing has not been calculated yet or if case is not in pre-legal phase.
Example: 20.5 represents 20.5% success fee.
- `cases[].solutionUrl` (string, nullable, deprecated): When the case is created with allowPendingContracts=true and required contracts are unsigned,
this URL points to the signing page. Null when contracts are already signed or not applicable.
- `cases[].signingHandoff` (object): Partner-facing handoff metadata for a creditor's pending signing chain.
Returned on POST /cases responses (422 with pending-signing errors,
or 200 with AllowPendingContracts=true when signings remain).
            
Designed as an envelope so future fields (expiration, suggested email
copy, etc.) can be added without polluting the parent DTO.
- `cases[].signingHandoff.combinedSigningUrl` (string, nullable): Single signing entry URL that walks the creditor through every
pending step (SDCA upgrade → PoA → JPA → KYC) on the Creditors app
and returns to the partner-supplied returnUrl when done.
- `cases[].exclusivePeriodEndDate` (datetime, nullable): The date the exclusive collection period ends (or ended).
Null if no collection period has been created for this case (e.g. custom-terms cases).
Use GET /cases/{id}/exclusive-period for the full chain including extensions.
- `cases[].disputeStatus` (string, nullable): Whether the claim is disputed by the debtor.
One of: "Yes, the claim is disputed", "No, the claim is not disputed", or "Don't Know".
Null when the dispute status has not been set on the case.
- `cases[].validation` (object): Stable v1 validation summary used by ordinary and list mappings.
- `cases[].validation.needsInfo` (boolean): 
- `cases[].assignedUser` (object): Represents the creditor team member assigned to a case.
- `cases[].assignedUser.email` (string, nullable): The assigned user's email address.
- `cases[].assignedUser.name` (string, nullable): The assigned user's full name.
- `cases[].allocationOutstanding` (object): Outstanding amount per bucket on the case: each bucket's total minus the payments allocated to it.
- `cases[].allocationOutstanding.principal` (number): 
- `cases[].allocationOutstanding.interest` (number): 
- `cases[].allocationOutstanding.reminderFees` (number): 
- `cases[].allocationOutstanding.collectionFees` (number): 

```json
{
  "page": {
    "totalResults": 42,
    "pageSize": 25,
    "currentPage": 1,
    "responseCount": 42,
    "totalPages": 1
  },
  "cases": [
    {
      "id": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
      "dateCreated": "2026-10-01T14:05:00Z",
      "dateUpdated": "2026-10-01T14:05:00Z",
      "reference": "INV-2026-0042",
      "creditorReference": "INV-2026-0042",
      "creditorComments": "Payment plan agreed with the debtor.",
      "claimDescription": "string",
      "grossAmount": 2500,
      "remainder": 1.5,
      "interestFees": 2500,
      "reminderFees": 2500,
      "collectionFees": 2500,
      "totalAddedFees": 2500,
      "currency": "EUR",
      "isTestCase": true,
      "lifecycle": "string",
      "dueDate": "2026-10-01T14:05:00Z",
      "date": "2026-10-01T14:05:00Z",
      "dateFinished": "2026-10-01T14:05:00Z",
      "dateCollectionStarted": "2026-10-01T14:05:00Z",
      "closeCode": "string",
      "currentEngagementPhase": "string",
      "claimType": "string",
      "creditorDivisionId": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
      "debtor": {
        "type": "Company",
        "name": "Pacific Trading LLC",
        "contactPerson": "John Smith",
        "companyRegistrationNumber": "47-1234567",
        "address": "123 Market Street, Suite 400",
        "zipCode": "94105",
        "city": "San Francisco",
        "state": "California",
        "stateAlpha2": "CA",
        "countryAlpha2": "US",
        "country": "United States",
        "email": "accounts@pacifictrading.com",
        "phone": "+1 415 555 0123"
      },
      "collectionPartner": {
        "name": "Muster GmbH",
        "officeEmail": "finance@example.com",
        "officePhone": "+49 30 1234567",
        "publicSite": "string",
        "surveyCadenceMode": 0
      },
      "creditor": {
        "id": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
        "companyName": "Muster GmbH",
        "companyRegistrationNumber": "DE123456789",
        "officeEmail": "finance@example.com",
        "officePhone": "+49 30 1234567",
        "address": "Friedrichstraße 68",
        "city": "Berlin",
        "zipCode": "10115",
        "state": "string",
        "country": "Germany",
        "division": {
          "id": {},
          "name": {}
        }
      },
      "bankAccount": {
        "id": 3,
        "label": "string",
        "scheme": "string",
        "currencyCode": "EUR",
        "bankCountryCode": "DE",
        "accountHolderName": "Muster GmbH",
        "iban": "string",
        "bic": "string",
        "accountNumber": "string",
        "localIdentifier": "string",
        "localIdentifierType": "string",
        "bankName": "Muster GmbH",
        "bankAddress": "Friedrichstraße 68",
        "bankCity": "Berlin",
        "bankZipCode": "10115",
        "bankState": "string"
      },
      "blendedAgeUpliftPoints": 1.5,
      "preLegalSuccessFee": 2500,
      "solutionUrl": "https://app.debitura.com/…",
      "signingHandoff": {
        "combinedSigningUrl": "https://app.debitura.com/…"
      },
      "exclusivePeriodEndDate": "2026-10-01T14:05:00Z",
      "disputeStatus": "string",
      "validation": {
        "needsInfo": true
      },
      "assignedUser": {
        "email": "finance@example.com",
        "name": "Muster GmbH"
      },
      "allocationOutstanding": {
        "principal": 1.5,
        "interest": 1.5,
        "reminderFees": 2500,
        "collectionFees": 2500
      }
    }
  ]
}
```

### Response 400

Invalid query parameters

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

<a id="create-collection-case"></a>

## Create collection case

`POST /cases`

Creates a new collection case for debt collection.

**Test Mode:**
- Set isTest=true to create a test case (case IS created in the database but marked as test data)
- Test cases are excluded from production metrics and can be easily filtered or deleted
- Use test mode for integration testing and development

**Debtor Rules:**
- debtor.type must be "Company" or "Private"
  - Company → debtor.name is mandatory (company name)
  - Private → debtor.name is mandatory (person's full name)

**Geographic Rules:**
- debtor.countryAlpha2 (ISO 3166-1 alpha-2) is always required
- debtor.state is a free-text region description
- For US debtors: debtor.stateAlpha2 (two-letter state code) is also required – debtor.state is ignored in that scenario
- Customer API submissions are limited to cases that match an exclusive pre-legal partner.
  If no eligible partner matches, the API returns 422 and does not create a case. The
  interactive portal's custom-quote/network-lead fallback is not available through this API.

**Claim Amount and Aging — three ways to send it:**
1. `amountToRecover` plus a single `dueDate`
2. `amountToRecover` plus the cumulative `amountToRecoverOver6/12/24Months` buckets
3. `claimLines[]` — send the unpaid invoices and let us do the arithmetic (recommended for multi-invoice claims)

```
"claimLines": [
  { "dueDate": "2024-01-15", "amount": 423.42, "reference": "INV-1001" },
  { "dueDate": "2025-05-02", "amount": 700.87, "reference": "INV-1042" }
]
```

- `amount` is the **outstanding balance** on that invoice — what the debtor still owes on it, already
  net of payments received and credit notes issued. It is not the invoice's original face value.
  Leave fully settled invoices out; every amount must be greater than zero, with at most 2 decimals.
- We derive `amountToRecover` and all three age buckets from the lines, so send `claimLines`
  **instead of** `amountToRecover` and the `amountToRecoverOver6/12/24Months` fields. Sending both is a 400.
- Use `claimLines` whenever the debtor has already part-paid: it is the only way to express an honest
  age profile on a part-paid claim, because the buckets are then computed on the same outstanding
  balances the total is computed on.
- `claimLines` is a pricing input only. It is not stored and is not shown to the collecting partner —
  include a per-invoice breakdown in `comments` if the partner needs to see one.
- Maximum 1000 lines. Per-line errors are returned keyed by index, e.g. `ClaimLines[2].DueDate`.
- If you omit the case-level `dueDate`, it is set to the oldest due date across your lines — so in that
  case `date` must not be later than the earliest `claimLines` due date, or the request is rejected with
  a 400 on `date`. Send an explicit `dueDate` if you need a different case due date.

**Optional Parameters:**
- creditorDivisionId - Assign case to a specific division (for multi-division creditors)
- allowPendingContracts - Accept cases with unsigned contracts in 'PendingContractSigning' status instead of returning 422

**Error Responses:**
- 400: Field validation errors (returns JSON object with field names as keys and error arrays as values)
- 422: Business rule violations (returns BusinessErrorResponseApiDTO with type, message, and solutionUrl)
- 500: Server errors

### Headers

- `Idempotency-Key` (string): Optional non-empty, non-whitespace idempotency key (max 255 characters) for safely retrying this request. If a previous request used the same key with an identical body, the original terminal response is replayed verbatim. Reusing the key with a different body returns 422 with `businessErrors[0].type: "IdempotencyConflict"`. Field-level 400 validation errors are not stored, so you may fix the request and retry with the same key.
  Max 255 characters.

### Request body (application/json)

- `currencyCode` (string, required, nullable): 
- `date` (datetime): 
- `dueDate` (datetime, nullable): 
- `comments` (string, nullable): Optional comments about the case, e.g. payment history or communication context.
  Max 4000 characters.
- `claimDescription` (string, nullable): Client provided description of the claim
  Max 4000 characters.
- `creditorReference` (string, nullable): 
  Max 50 characters.
- `debtor` (object): V1 Debtor DTO for external partner APIs.
The debtor is the party that owes the debt.
- `debtor.type` (string, required): Debtor type. Valid values: "Company" or "Private" (case-insensitive)
- `debtor.name` (string, required): Debtor name (company name or person's full name)
- `debtor.contactPerson` (string, nullable): Contact person at the company (required for companies, not used for persons)
- `debtor.companyRegistrationNumber` (string, nullable): Company registration number (VAT number, CVR, org number, etc.)
- `debtor.address` (string, nullable): Street address
- `debtor.zipCode` (string, nullable): Postal/ZIP code
- `debtor.city` (string, nullable): City name
- `debtor.state` (string, nullable): State/region/province name
- `debtor.stateAlpha2` (string, nullable): US state: two-letter code (e.g., "CA"), ISO 3166-2 format (e.g., "US-CA"), or full name (e.g., "California")
- `debtor.countryAlpha2` (string, nullable): Country code (ISO 3166-1 alpha-2 format)
- `debtor.country` (string, nullable): Country name
- `debtor.email` (string, nullable): Email address for debtor contact
- `debtor.phone` (string, nullable): Phone number (include country code)
- `creditorDivisionId` (uuid, nullable): 
- `amountToRecover` (number): The TOTAL amount to recover for this case.
This represents the full principal amount across all invoices (if multiple invoices are bundled).
            
For multi-invoice cases with different ages, you can optionally provide age breakdown fields
(AmountToRecoverOver12Months and AmountToRecoverOver24Months) to enable blended age-based pricing.
            
If age breakdown fields are omitted, age uplift will be calculated from the invoice due date (single-invoice pricing).
            
Required unless you send ClaimLines, in which case this must be omitted or 0 — the server
derives the total by summing the outstanding balance of every claim line. Sending both a
non-zero AmountToRecover and ClaimLines is rejected, because the two would disagree.
- `amountToRecoverOver6Months` (number, nullable): OPTIONAL - MULTI-INVOICE AGE BUCKET PRICING (PRICING ZONE 180-DAY THRESHOLD)
            
The portion of AmountToRecover that is more than 6 months (180 days) overdue.
This includes amounts that are 12+ and 24+ months overdue.
            
This field is optional and can only be provided alongside AmountToRecoverOver12Months
and AmountToRecoverOver24Months. It enables precise pricing tier selection based on
the 180-day threshold. When omitted, the system falls back to deriving the threshold
from AmountToRecoverOver12Months.
            
Validation rules:
- Must be ≤ AmountToRecover
- Must be ≥ AmountToRecoverOver12Months
- `amountToRecoverOver12Months` (number, nullable): OPTIONAL - MULTI-INVOICE AGE BUCKET PRICING
            
The portion of AmountToRecover that is more than 12 months overdue.
This includes amounts that are 24+ months overdue.
            
If provided, AmountToRecoverOver24Months must also be provided.
Both fields must be provided together or both omitted.
            
Used to calculate blended age uplift for multi-invoice cases:
- Amount under 12 months = AmountToRecover - AmountToRecoverOver12Months
- Amount 12-24 months = AmountToRecoverOver12Months - AmountToRecoverOver24Months
- Amount over 24 months = AmountToRecoverOver24Months
            
Blended uplift formula: ((A12-A24)×10 + A24×20) / AmountToRecover
where A12 = AmountToRecoverOver12Months, A24 = AmountToRecoverOver24Months
            
Validation rules:
- Must be ≤ AmountToRecover
- Must be ≥ AmountToRecoverOver24Months
- `amountToRecoverOver24Months` (number, nullable): OPTIONAL - MULTI-INVOICE AGE BUCKET PRICING
            
The portion of AmountToRecover that is more than 24 months overdue.
            
If provided, AmountToRecoverOver12Months must also be provided.
Both fields must be provided together or both omitted.
            
Used to calculate blended age uplift for multi-invoice cases.
See AmountToRecoverOver12Months for full details on the calculation.
            
Validation rules:
- Must be ≤ AmountToRecoverOver12Months
- Must be ≤ AmountToRecover
- `claimLines` (array of objects, nullable): OPTIONAL - the unpaid invoices making up this claim, one line per invoice, each carrying its
own outstanding balance and payment deadline.
            
When supplied, the server derives AmountToRecover and all three cumulative age buckets from
these lines, so send them instead of — never alongside — AmountToRecover and the
AmountToRecoverOver6/12/24Months fields. Supplying both is rejected with a 400.
            
Use this whenever the debtor has already part-paid the claim: the buckets are then computed
on the same outstanding balances the total is computed on, so the age profile stays honest.
Maximum 1000 lines. When DueDate is omitted on the case, it is derived as the oldest line
due date; an explicit DueDate is honoured.
            
Claim lines are a pricing input only — they are not stored and are never shown to the
collecting partner.
- `claimLines[].dueDate` (datetime, required, nullable): Payment deadline of this invoice. Provide date only without time component.
Must be on or after 2000-01-01 and must not be in the future.
- `claimLines[].amount` (number, required): The outstanding balance on this invoice in the case currency — what the debtor still owes on it,
already net of any payments the debtor has made and net of any credit notes issued against it.
This is not the invoice's original face value.
Must be greater than zero with at most 2 decimal places; omit invoices that are fully settled.
- `claimLines[].reference` (string, nullable): Optional: your own invoice number for this line. Used only to make validation errors readable
and to reject the same invoice being sent twice. It is not stored and not shown to anyone.
- `allowPendingContracts` (boolean): When true, cases with unsigned contracts (SDCA/POA) are accepted in 'PendingContractSigning'
status instead of being rejected with 422. The case transitions automatically once contracts are signed.
Default: false (unsigned contracts return 422).
- `isTest` (boolean): When true, creates a test case that IS persisted to the database but marked as test data.
Test cases are excluded from production metrics and can be easily filtered or deleted.
Use this for integration testing and development.
- `tag` (string, nullable): Optional tag for scoped test data grouping (e.g. "suite-run-{uuid}").
Use this to group test cases created by a single CI pipeline run so they can be
bulk-deleted via DELETE /test/cases?tag={tag} without affecting parallel runs.
Only meaningful when IsTest is true. Max 100 characters.
  Max 100 characters.
- `assignedUserEmail` (string, nullable): Optional: Email address of the creditor team member to assign as the case owner.
When provided, email notifications for this case will be sent only to this user
instead of all team members.
Must correspond to an active member of your team.
  Max 320 characters; Email address.
- `returnUrl` (string, nullable): Optional: URL the creditor user should land on after completing any
pending signing chain (SDCA upgrade / PoA / JPA / KYC) on the
Debitura Creditors app. Embedded, URL-encoded, into
`BusinessErrorResponseApiDTO.SigningHandoff.CombinedSigningUrl`
(on 422 with pending signings) and
`InvoiceDto.SigningHandoff.CombinedSigningUrl` (on 200 when
`AllowPendingContracts=true` with signings remaining).
            
Must be an absolute http(s) URL. Values that fail validation
(relative URLs, non-http schemes, header-injection characters) are
silently dropped — the combined URL is still emitted but without
the returnUrl query parameter, and the Creditors app falls back to
its own safe in-app default landing.
            
Additive. Existing integrations
that omit this field see the same behaviour as before.
  Max 2048 characters.

```json
{
  "currencyCode": "EUR",
  "amountToRecover": 4000,
  "date": "2026-03-01",
  "dueDate": "2026-03-09",
  "claimDescription": "Custom mobile app development services",
  "comments": "Outstanding invoice INV 2024 00789 for custom mobile app development delivered 15 Nov 2024; payment 60 days overdue despite two reminders.",
  "creditorReference": "INV‑2024‑00789",
  "isTest": true,
  "debtor": {
    "type": "Company",
    "name": "Acme Corp",
    "contactPerson": "John Doe",
    "companyRegistrationNumber": "12345678",
    "address": "123 Business Street",
    "zipCode": "1000",
    "city": "Lisbon",
    "state": "Lisbon",
    "countryAlpha2": "PT",
    "email": "billing@acme‑corp.com",
    "phone": "+351 123 456 789"
  }
}
```

### Response 200

Case created

- `id` (uuid): 
- `dateCreated` (datetime): 
- `dateUpdated` (datetime, nullable): 
- `reference` (string, nullable): 
- `creditorReference` (string, nullable): 
- `creditorComments` (string, nullable): 
- `claimDescription` (string, nullable): 
- `grossAmount` (number): 
- `remainder` (number): 
- `interestFees` (number): 
- `reminderFees` (number): 
- `collectionFees` (number): 
- `totalAddedFees` (number): 
- `currency` (string, nullable): 
- `isTestCase` (boolean): 
- `lifecycle` (string, nullable): 
- `dueDate` (datetime): 
- `date` (datetime): 
- `dateFinished` (datetime, nullable): 
- `dateCollectionStarted` (datetime, nullable): 
- `closeCode` (string, nullable): 
- `currentEngagementPhase` (string, nullable): The current phase of the case's engagement: "Pre-legal", "Legal", or "Enforcement".
A different axis from Lifecycle/CloseCode — an Active case can be
in any of the three phases.
            
Null means "no active engagement" (e.g. lead / quoting / pre-contract-signing / unassigned, or
a data-consistency gap) — this is a distinct third state, NOT a synonym for Pre-legal. Most
cases legitimately read Pre-legal; phase only leaves Pre-legal on legal/enforcement quote flows.
            
Not guaranteed to be monotonic: an admin correction can move phase backwards (e.g. Legal back
to Pre-legal).
            
Persists after case closure — reflects the case's last-known engagement phase, not the current
Lifecycle. Note: this is a different field from a lead quote's own offered phase (the phase a
partner's quote proposes to work the case at, if this case ever went through a quote flow) —
this field is the case-level phase of its actual engagement, not a quote's terms.
- `claimType` (string, nullable): The type of claim for this case (e.g. "Unpaid Invoice", "Loan Repayment", "Breach of Contract").
Null if not set.
- `creditorDivisionId` (uuid, nullable): 
- `debtor` (object): V1 Debtor DTO for external partner APIs.
The debtor is the party that owes the debt.
- `debtor.type` (string, required): Debtor type. Valid values: "Company" or "Private" (case-insensitive)
- `debtor.name` (string, required): Debtor name (company name or person's full name)
- `debtor.contactPerson` (string, nullable): Contact person at the company (required for companies, not used for persons)
- `debtor.companyRegistrationNumber` (string, nullable): Company registration number (VAT number, CVR, org number, etc.)
- `debtor.address` (string, nullable): Street address
- `debtor.zipCode` (string, nullable): Postal/ZIP code
- `debtor.city` (string, nullable): City name
- `debtor.state` (string, nullable): State/region/province name
- `debtor.stateAlpha2` (string, nullable): US state: two-letter code (e.g., "CA"), ISO 3166-2 format (e.g., "US-CA"), or full name (e.g., "California")
- `debtor.countryAlpha2` (string, nullable): Country code (ISO 3166-1 alpha-2 format)
- `debtor.country` (string, nullable): Country name
- `debtor.email` (string, nullable): Email address for debtor contact
- `debtor.phone` (string, nullable): Phone number (include country code)
- `collectionPartner` (object): V1 Collection Partner DTO for external partner APIs
- `collectionPartner.name` (string, nullable): 
- `collectionPartner.officeEmail` (string, nullable): 
- `collectionPartner.officePhone` (string, nullable): 
- `collectionPartner.publicSite` (string, nullable): 
- `collectionPartner.surveyCadenceMode` (enum, deprecated): Deprecated: kept as a number and never removed, but not extended. Survey-generation cadence: 0 = Standard
(rolling monthly survey), 1 = DecisionPointOnly (no rolling surveys).
  Values: `0`, `1`.
- `creditor` (object): Creditor (client) information for external partner APIs.
Represents the party that the debtor owes money to.
- `creditor.id` (uuid): Unique identifier for the creditor
- `creditor.companyName` (string, nullable): Company name of the creditor
- `creditor.companyRegistrationNumber` (string, nullable): Company registration number (CVR, VAT number, etc.)
- `creditor.officeEmail` (string, nullable): Primary office email address
- `creditor.officePhone` (string, nullable): Primary office phone number
- `creditor.address` (string, nullable): Street address
- `creditor.city` (string, nullable): City
- `creditor.zipCode` (string, nullable): Postal/ZIP code
- `creditor.state` (string, nullable): State or region (if applicable)
- `creditor.country` (string, nullable): Country name
- `creditor.division` (object): Creditor division information for external partner APIs.
Represents a specific division or department within a creditor organization.
- `creditor.division.id` (uuid): Unique identifier for the division
- `creditor.division.name` (string, nullable): Name of the division
- `bankAccount` (object): Bank account information for partner API.
Full details provided as partners need this to:
1. Provide payment instructions to debtors (when debtor pays client directly)
2. Execute payouts to clients (when partner receives payment and pays out remainder)
- `bankAccount.id` (integer): Bank account identifier
- `bankAccount.label` (string, nullable): User-friendly label (e.g., "Main EUR Account")
- `bankAccount.scheme` (string, nullable): Account scheme: IBAN, SWIFT, or LOCAL
- `bankAccount.currencyCode` (string, nullable): Currency code (ISO 4217)
- `bankAccount.bankCountryCode` (string, nullable): Bank country code (ISO Alpha-2)
- `bankAccount.accountHolderName` (string, nullable): Account holder name (beneficiary)
- `bankAccount.iban` (string, nullable): IBAN (for IBAN scheme accounts)
- `bankAccount.bic` (string, nullable): BIC/SWIFT code (for IBAN and SWIFT scheme accounts)
- `bankAccount.accountNumber` (string, nullable): Account number (for SWIFT and LOCAL scheme accounts)
- `bankAccount.localIdentifier` (string, nullable): Local identifier (for LOCAL scheme accounts, e.g., sort code + account number)
- `bankAccount.localIdentifierType` (string, nullable): Type of local identifier (e.g., "Sort Code", "Routing Number")
- `bankAccount.bankName` (string, nullable): Bank name (optional)
- `bankAccount.bankAddress` (string, nullable): Bank address (optional)
- `bankAccount.bankCity` (string, nullable): Bank city (optional)
- `bankAccount.bankZipCode` (string, nullable): Bank zip/postal code (optional)
- `bankAccount.bankState` (string, nullable): Bank state/region (optional)
- `blendedAgeUpliftPoints` (number, nullable): MULTI-INVOICE AGE BUCKET PRICING
Calculated blended age uplift percentage points (0-20) for multi-invoice cases.
Shows the additional fee percentage added due to invoice age.
Formula: ((A12-A24)×10 + A24×20) / Total Principal
Null for single-invoice cases (age uplift is calculated from due date instead).
- `preLegalSuccessFee` (number, nullable): PRE-LEGAL SUCCESS FEE
The total pre-legal success fee percentage for this case.
Includes base fee + age-based uplift (blended or single-invoice).
Null if pricing has not been calculated yet or if case is not in pre-legal phase.
Example: 20.5 represents 20.5% success fee.
- `solutionUrl` (string, nullable, deprecated): When the case is created with allowPendingContracts=true and required contracts are unsigned,
this URL points to the signing page. Null when contracts are already signed or not applicable.
- `signingHandoff` (object): Partner-facing handoff metadata for a creditor's pending signing chain.
Returned on POST /cases responses (422 with pending-signing errors,
or 200 with AllowPendingContracts=true when signings remain).
            
Designed as an envelope so future fields (expiration, suggested email
copy, etc.) can be added without polluting the parent DTO.
- `signingHandoff.combinedSigningUrl` (string, nullable): Single signing entry URL that walks the creditor through every
pending step (SDCA upgrade → PoA → JPA → KYC) on the Creditors app
and returns to the partner-supplied returnUrl when done.
- `exclusivePeriodEndDate` (datetime, nullable): The date the exclusive collection period ends (or ended).
Null if no collection period has been created for this case (e.g. custom-terms cases).
Use GET /cases/{id}/exclusive-period for the full chain including extensions.
- `disputeStatus` (string, nullable): Whether the claim is disputed by the debtor.
One of: "Yes, the claim is disputed", "No, the claim is not disputed", or "Don't Know".
Null when the dispute status has not been set on the case.
- `validation` (object): Stable v1 validation summary used by ordinary and list mappings.
- `validation.needsInfo` (boolean): 
- `assignedUser` (object): Represents the creditor team member assigned to a case.
- `assignedUser.email` (string, nullable): The assigned user's email address.
- `assignedUser.name` (string, nullable): The assigned user's full name.
- `allocationOutstanding` (object): Outstanding amount per bucket on the case: each bucket's total minus the payments allocated to it.
- `allocationOutstanding.principal` (number): 
- `allocationOutstanding.interest` (number): 
- `allocationOutstanding.reminderFees` (number): 
- `allocationOutstanding.collectionFees` (number): 

```json
{
  "id": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
  "dateCreated": "2026-10-01T14:05:00Z",
  "dateUpdated": "2026-10-01T14:05:00Z",
  "reference": "INV-2026-0042",
  "creditorReference": "INV-2026-0042",
  "creditorComments": "Payment plan agreed with the debtor.",
  "claimDescription": "string",
  "grossAmount": 2500,
  "remainder": 1.5,
  "interestFees": 2500,
  "reminderFees": 2500,
  "collectionFees": 2500,
  "totalAddedFees": 2500,
  "currency": "EUR",
  "isTestCase": true,
  "lifecycle": "string",
  "dueDate": "2026-10-01T14:05:00Z",
  "date": "2026-10-01T14:05:00Z",
  "dateFinished": "2026-10-01T14:05:00Z",
  "dateCollectionStarted": "2026-10-01T14:05:00Z",
  "closeCode": "string",
  "currentEngagementPhase": "string",
  "claimType": "string",
  "creditorDivisionId": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
  "debtor": {
    "type": "Company",
    "name": "Pacific Trading LLC",
    "contactPerson": "John Smith",
    "companyRegistrationNumber": "47-1234567",
    "address": "123 Market Street, Suite 400",
    "zipCode": "94105",
    "city": "San Francisco",
    "state": "California",
    "stateAlpha2": "CA",
    "countryAlpha2": "US",
    "country": "United States",
    "email": "accounts@pacifictrading.com",
    "phone": "+1 415 555 0123"
  },
  "collectionPartner": {
    "name": "Muster GmbH",
    "officeEmail": "finance@example.com",
    "officePhone": "+49 30 1234567",
    "publicSite": "string",
    "surveyCadenceMode": 0
  },
  "creditor": {
    "id": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
    "companyName": "Muster GmbH",
    "companyRegistrationNumber": "DE123456789",
    "officeEmail": "finance@example.com",
    "officePhone": "+49 30 1234567",
    "address": "Friedrichstraße 68",
    "city": "Berlin",
    "zipCode": "10115",
    "state": "string",
    "country": "Germany",
    "division": {
      "id": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
      "name": "Muster GmbH"
    }
  },
  "bankAccount": {
    "id": 3,
    "label": "string",
    "scheme": "string",
    "currencyCode": "EUR",
    "bankCountryCode": "DE",
    "accountHolderName": "Muster GmbH",
    "iban": "string",
    "bic": "string",
    "accountNumber": "string",
    "localIdentifier": "string",
    "localIdentifierType": "string",
    "bankName": "Muster GmbH",
    "bankAddress": "Friedrichstraße 68",
    "bankCity": "Berlin",
    "bankZipCode": "10115",
    "bankState": "string"
  },
  "blendedAgeUpliftPoints": 1.5,
  "preLegalSuccessFee": 2500,
  "solutionUrl": "https://app.debitura.com/…",
  "signingHandoff": {
    "combinedSigningUrl": "https://app.debitura.com/…"
  },
  "exclusivePeriodEndDate": "2026-10-01T14:05:00Z",
  "disputeStatus": "string",
  "validation": {
    "needsInfo": true
  },
  "assignedUser": {
    "email": "finance@example.com",
    "name": "Muster GmbH"
  },
  "allocationOutstanding": {
    "principal": 1.5,
    "interest": 1.5,
    "reminderFees": 2500,
    "collectionFees": 2500
  }
}
```

### Response 400

Invalid request

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

### Response 422

Business rule violation

- `businessErrors` (array of objects, nullable): List of business errors that must be resolved before the case can be created.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.
- `signingHandoff` (object): Partner-facing handoff metadata for a creditor's pending signing chain.
Returned on POST /cases responses (422 with pending-signing errors,
or 200 with AllowPendingContracts=true when signings remain).
            
Designed as an envelope so future fields (expiration, suggested email
copy, etc.) can be added without polluting the parent DTO.
- `signingHandoff.combinedSigningUrl` (string, nullable): Single signing entry URL that walks the creditor through every
pending step (SDCA upgrade → PoA → JPA → KYC) on the Creditors app
and returns to the partner-supplied returnUrl when done.

```json
{
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ],
  "signingHandoff": {
    "combinedSigningUrl": "https://app.debitura.com/…"
  }
}
```

### Response 500

Server error

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

<a id="preview-case-eligibility-and-requirements"></a>

## Preview case eligibility and requirements

`POST /cases/preview`

Preview what would happen if you submitted a case, without actually creating it.

**What This Endpoint Returns:**
- IsEligible - Whether the case can be submitted (partner available)
- PartnerAssignment - Which collection partner would handle the case
- RequiredActions - What contracts/documents need to be signed before submission
  - Standard Debt Collection Agreement (SDCA)
  - Power of Attorney (PoA) for the assigned partner
- PricingPreview - Estimated success fee with age-based surcharges
- Jurisdiction - Geographic details

**Use This To:**
1. Check if a jurisdiction is supported before submitting
2. Determine which documents need signing before case creation
3. Get signing URLs to guide users through required actions
4. Estimate pricing including age surcharges

**Required Fields:**
- AmountToRecover - Total principal amount
- CurrencyCode - ISO 4217 currency code (e.g., 'DKK', 'EUR', 'USD')
- Debtor.Type - 'Company' or 'Private'
- Debtor.CountryAlpha2 - ISO 3166-1 alpha-2 country code
- Debtor.StateAlpha2 - Required for US cases only (e.g., 'CA', 'NY')

**Optional Fields (Multi-Invoice Age Pricing):**
- AmountToRecoverOver12Months - Portion over 12 months overdue
- AmountToRecoverOver24Months - Portion over 24 months overdue
(Both must be provided together if used)
- AmountToRecoverOver6Months - Portion over 6 months overdue (optional, improves pricing tier accuracy at the 180-day threshold; requires Over12/Over24)

**Optional Fields (Claim Lines — recommended for multi-invoice claims):**
Instead of totalling the claim and computing the buckets yourself, send the unpaid invoices:

```
"claimLines": [
  { "dueDate": "2024-01-15", "amount": 423.42, "reference": "INV-1001" },
  { "dueDate": "2025-05-02", "amount": 700.87, "reference": "INV-1042" }
]
```

- `amount` is the **outstanding balance** on that invoice, already net of payments and credit notes.
- We derive `amountToRecover` and all three age buckets from the lines and price on them, so send
  `claimLines` **instead of** `amountToRecover`, the `amountToRecoverOver6/12/24Months` fields, and
  `dueDate`. Combining any of those with `claimLines` is a 400.
- Use `claimLines` whenever the debtor has already part-paid: it is the only way to express an honest
  age profile on a part-paid claim.
- Maximum 1000 lines. Per-line errors are returned keyed by index, e.g. `ClaimLines[2].DueDate`.
- The same ledger produces the same quote here and on POST /cases.

**Solution URLs Are Context-Aware:**
- Bearer token (referral partner) → referral onboarding URLs
- XApiKey (creditor) → standard creditor app URLs

**Important Notes:**
- This endpoint does NOT create a case - it only previews what would happen
- A matched preview applies the same monetary admission rules as POST /cases; create revalidates all rules
- Monetary refusals return AmountBelowMinimum and admissionMinimum (rule, USD amount, request-currency amount and currency code)
- amountCheckUnavailable means monetary eligibility is provisional because a required conversion was unavailable
- Unmatched cases remain ineligible at every amount; this API does not offer network/custom-quote submission
- If multiple partners match (system limitation), the first match is returned
- All required actions must be completed before calling POST /cases

**Example Workflow:**
```
1. POST /cases/preview → Check eligibility and get signing URLs
2. User completes required actions (signs SDCA, signs PoA)
3. POST /cases → Create the actual case
```

### Request body (application/json)

- `amountToRecover` (number): The TOTAL amount to recover for this case.
This represents the full principal amount across all invoices (if multiple invoices are bundled).
            
For multi-invoice cases with different ages, you can optionally provide age breakdown fields
(AmountToRecoverOver12Months and AmountToRecoverOver24Months) to enable blended age-based pricing.
            
If age breakdown fields are omitted, the preview will show base pricing without age surcharge calculation.
            
Required unless you send ClaimLines, in which case this must be omitted or 0 — the server
derives the total by summing the outstanding balance of every claim line. Sending both a
non-zero AmountToRecover and ClaimLines is rejected, because the two would disagree.
- `currencyCode` (string, required): ISO 4217 currency code for the amount (e.g., "DKK", "EUR", "USD")
  3–3 characters.
- `debtor` (object, required): Simplified debtor information for case preview.
Only includes the minimum fields required for partner routing and eligibility checking.
- `debtor.type` (string, required): Debtor type. Valid values: "Company" or "Private"
This affects partner selection as different partners may specialize in B2B vs B2C collection.
- `debtor.countryAlpha2` (string, required): Country code (ISO 3166-1 alpha-2 format, e.g., "DK", "US", "PL")
Used to determine jurisdiction and available collection partners.
  2–2 characters.
- `debtor.stateAlpha2` (string, nullable): US state code (e.g., "CA", "NY")
REQUIRED for United States cases only, as US partner coverage is state-specific.
Optional for other countries.
  2–2 characters.
- `amountToRecoverOver6Months` (number, nullable): OPTIONAL - MULTI-INVOICE AGE BUCKET PRICING (PRICING ZONE 180-DAY THRESHOLD)
            
The portion of AmountToRecover that is more than 6 months (180 days) overdue.
This includes amounts that are 12+ and 24+ months overdue.
            
This field is optional and can only be provided alongside AmountToRecoverOver12Months
and AmountToRecoverOver24Months. It enables precise pricing tier selection based on
the 180-day threshold. When omitted, the system falls back to deriving the threshold
from AmountToRecoverOver12Months.
            
Validation rules:
- Must be ≤ AmountToRecover
- Must be ≥ AmountToRecoverOver12Months
- `amountToRecoverOver12Months` (number, nullable): OPTIONAL - MULTI-INVOICE AGE BUCKET PRICING
            
The portion of AmountToRecover that is more than 12 months overdue.
This includes amounts that are 24+ months overdue.
            
If provided, AmountToRecoverOver24Months must also be provided.
Both fields must be provided together or both omitted.
            
Used to calculate blended age uplift for multi-invoice cases:
- Amount under 12 months = AmountToRecover - AmountToRecoverOver12Months
- Amount 12-24 months = AmountToRecoverOver12Months - AmountToRecoverOver24Months
- Amount over 24 months = AmountToRecoverOver24Months
            
Blended uplift formula: ((A12-A24)×10 + A24×20) / AmountToRecover
where A12 = AmountToRecoverOver12Months, A24 = AmountToRecoverOver24Months
            
Validation rules:
- Must be ≤ AmountToRecover
- Must be ≥ AmountToRecoverOver24Months
- `amountToRecoverOver24Months` (number, nullable): OPTIONAL - MULTI-INVOICE AGE BUCKET PRICING
            
The portion of AmountToRecover that is more than 24 months overdue.
            
If provided, AmountToRecoverOver12Months must also be provided.
Both fields must be provided together or both omitted.
            
Used to calculate blended age uplift for multi-invoice cases.
See AmountToRecoverOver12Months for full details on the calculation.
            
Validation rules:
- Must be ≤ AmountToRecoverOver12Months
- Must be ≤ AmountToRecover
- `claimLines` (array of objects, nullable): OPTIONAL - the unpaid invoices making up this claim, one line per invoice, each carrying its
own outstanding balance and payment deadline.
            
When supplied, the server derives AmountToRecover and all three cumulative age buckets from
these lines and prices on them, so send them instead of — never alongside — AmountToRecover,
the AmountToRecoverOver6/12/24Months fields, or DueDate. Supplying any of those together
with ClaimLines is rejected with a 400.
            
Use this whenever the debtor has already part-paid the claim: the buckets are then computed
on the same outstanding balances the total is computed on, so the age profile stays honest.
Maximum 1000 lines. Claim lines are a pricing input only and are never stored.
- `claimLines[].dueDate` (datetime, required, nullable): Payment deadline of this invoice. Provide date only without time component.
Must be on or after 2000-01-01 and must not be in the future.
- `claimLines[].amount` (number, required): The outstanding balance on this invoice in the case currency — what the debtor still owes on it,
already net of any payments the debtor has made and net of any credit notes issued against it.
This is not the invoice's original face value.
Must be greater than zero with at most 2 decimal places; omit invoices that are fully settled.
- `claimLines[].reference` (string, nullable): Optional: your own invoice number for this line. Used only to make validation errors readable
and to reject the same invoice being sent twice. It is not stored and not shown to anyone.
- `dueDate` (datetime, nullable): Optional invoice due date. Mutually exclusive with age bucket fields and with ClaimLines.
If provided, Debitura computes the age surcharge internally — no need to calculate age buckets.
Cannot be a future date.
- `returnUrl` (string, nullable): Optional: URL the creditor user should land on after completing any
pending signing chain (SDCA upgrade / PoA / JPA / KYC) on the
Debitura Creditors app. Embedded, URL-encoded, into
`PreviewCaseResponseApiViewModel.Result.SigningHandoff.CombinedSigningUrl`
(when at least one signing-related required action is present) and into
`BusinessErrorResponseApiDTO.SigningHandoff.CombinedSigningUrl` /
`InvoiceDto.SigningHandoff.CombinedSigningUrl` on POST `/cases`.
            
Must be an absolute http(s) URL. Values that fail validation
(relative URLs, non-http schemes, header-injection characters) are
silently dropped — the combined URL is still emitted but without
the returnUrl query parameter, and the Creditors app falls back to
its own safe in-app default landing.
            
Additive. Existing integrations
that omit this field see the same behaviour as before.
  Max 2048 characters.

```json
{
  "amountToRecover": 50000,
  "currencyCode": "USD",
  "amountToRecoverOver12Months": 30000,
  "amountToRecoverOver24Months": 15000,
  "debtor": {
    "type": "Company",
    "countryAlpha2": "US",
    "stateAlpha2": "CA"
  }
}
```

### Response 200

Preview completed

- `result` (object): Detailed preview result for a case submission.
- `result.isEligible` (boolean): Whether a collection partner is available and submit's monetary admission checks pass.
If false, check IneligibilityReason for details.
- `result.ineligibilityReason` (string, nullable): Explanation of why the case is not eligible (only present when IsEligible = false).
Branch on IneligibilityReasonCode rather than on this text, which may be reworded.
- `result.ineligibilityReasonCode` (string, nullable): Stable machine-readable reason, present whenever IneligibilityReason is
One of: NoGeographicCoverage, AmountBelowMinimum, AmountAboveMaximum,
DebtorTypeNotCovered, NotCoveredByPartnerRules, ExcludedForClient, EligibilityUndetermined.

Only NoGeographicCoverage means we have no partner in the jurisdiction. AmountBelowMinimum
means the geography IS covered and only the claim amount fell short. EligibilityUndetermined
is a transient failure on our side, not a statement about coverage — retry rather than
telling the client their address is wrong.
- `result.admissionMinimum` (object): Safe, additive metadata for a monetary admission refusal. Recheck preview after changing the claim.
- `result.admissionMinimum.rule` (string, nullable): PlatformMinimum (configured client/partner/platform floor) or UnitedStatesMinimum.
- `result.admissionMinimum.amountUsd` (number): The minimum principal in USD.
- `result.admissionMinimum.amount` (number): The minimum principal in the request currency, rounded upward to two decimals.
- `result.admissionMinimum.currencyCode` (string, nullable): ISO currency code of Amount.
- `result.applicableMinimumAmount` (number, nullable): What this claim would have to reach to be accepted, in the currency of the request; never below
the platform minimum of 100 USD. Only present when no partner was matched. Withheld when the
client's own routing exclusions mean the number would not be reachable for them, and when the
request currency cannot be priced. Null when no partner covering this case declares a minimum.
- `result.applicableMinimumCurrencyCode` (string, nullable): ISO code that ApplicableMinimumAmount is expressed in.
- `result.marketMinimumAmount` (number, nullable): The smallest claim the marketplace takes for this jurisdiction and debtor type, in the currency of
the request: the lowest partner floor, never below the platform minimum of 100 USD. A statement
about the market, not about this claim: it is returned whether or not a partner was selected, and
does not depend on the claim amount or on the caller. It is not the admission rules applied when a
case is created. Null when no partner covers the market or the amount cannot be priced.
- `result.marketMinimumCurrencyCode` (string, nullable): ISO code that MarketMinimumAmount is expressed in.
- `result.amountCheckUnavailable` (boolean): True when a currency conversion needed to evaluate the claim amount was unavailable, so the
amount-based part of matching or monetary admission was NOT actually checked. It can be true on an
eligible answer: a partner matched only because amount conditions failed open while rates were
down. Treat such an answer as provisional and retry rather than relying on the floor having
been applied.
- `result.partnerAssignment` (object): Information about the collection partner assigned to this case.
- `result.partnerAssignment.collectionPartnerId` (uuid): Unique identifier for the collection partner.
- `result.partnerAssignment.partnerName` (string, nullable): Display name of the collection partner company.
- `result.partnerAssignment.partnerCountry` (string, nullable): ISO 3166-1 alpha-2 country code for the partner's primary country.
- `result.requiredActions` (array of objects, nullable): List of actions required before the case can be submitted (e.g., sign contracts).
Empty if no actions are required.
Each action includes a solution URL to complete the requirement.
- `result.requiredActions[].type` (string, nullable): The type of action required.
Common values: "MissingDebtCollectionContract", "MissingPowerOfAttorney"
- `result.requiredActions[].message` (string, nullable): Human-readable description of what is required.
- `result.requiredActions[].solutionUrl` (string, nullable): URL where the user can complete this <i>specific</i> action (e.g., contract signing page).
The URL is context-aware: referral partner tokens get referral onboarding URLs,
regular API keys get standard creditor app URLs.
            

Partners who want a <b>single URL</b> that walks the user through every pending
action in one chain — instead of forwarding one URL per `RequiredActionDto` —
should use SigningHandoff's
`CombinedSigningUrl`. The two are complementary: `SolutionUrl` is granular
per-action; `CombinedSigningUrl` is the chain-walking alternative for
signing-related actions.
- `result.requiredActions[].isBlocking` (boolean): Whether this action must be completed before case submission.
Currently all returned actions are blocking (true).
- `result.jurisdiction` (object): Geographic jurisdiction information for the case.
- `result.jurisdiction.id` (integer): Internal jurisdiction identifier.
- `result.jurisdiction.name` (string, nullable): Display name of the jurisdiction (e.g., "Denmark", "United States - California").
- `result.jurisdiction.countryAlpha2` (string, nullable): ISO 3166-1 alpha-2 country code.
- `result.jurisdiction.stateAlpha2` (string, nullable): ISO 3166-2 state/region code (only for countries with state-level routing like the US).
- `result.pricingPreview` (object): Estimated pricing for the case, including age-based surcharges.
- `result.pricingPreview.baseSuccessFeePercentage` (number): Base success fee percentage before age surcharges.
This is the standard rate for cases under 12 months overdue.
- `result.pricingPreview.ageSurchargePercentage` (number): Additional percentage points added for aged invoices.
Calculated based on invoice age:
- 12-24 months overdue: +8 percentage points
- 24+ months overdue: +15 percentage points
- Multi-invoice with mixed ages: blended rate (0-15 percentage points)
- `result.pricingPreview.totalSuccessFeePercentage` (number): Total success fee percentage (base + age surcharge).
This is the percentage of the recovered amount that will be charged as a success fee.
- `result.pricingPreview.currencyCode` (string, nullable): ISO 4217 currency code for the case.
- `result.pricingPreview.pricingSource` (string, nullable): Which pricing rule determined the fee.
Possible values: "Standard agreement", "Creditor custom pricing",
"Managing partner custom pricing", "Jurisdiction custom pricing",
"Partner custom pricing", "Accepted quote".
- `result.pricingPreview.pricingSourceDescription` (string, nullable): Human-readable explanation of why this pricing was applied.
Example: "9.5% success fee — BD Legal custom collection rates (EU zone, $1,000–$7,999 tier)"
- `result.requiresKycVerification` (boolean): Whether the resolved collection partner requires KYC verification before cases can be submitted.
When true, the creditor must complete KYC verification before case creation will succeed.
- `result.hasKycOnFile` (boolean): Whether the creditor already has KYC verification on file with Debitura.
When RequiresKycVerification is true and HasKycOnFile is false, a MissingKycVerification
required action will be present in the RequiredActions list.
- `result.signingHandoff` (object): Partner-facing handoff metadata for a creditor's pending signing chain.
Returned on POST /cases responses (422 with pending-signing errors,
or 200 with AllowPendingContracts=true when signings remain).
            
Designed as an envelope so future fields (expiration, suggested email
copy, etc.) can be added without polluting the parent DTO.
- `result.signingHandoff.combinedSigningUrl` (string, nullable): Single signing entry URL that walks the creditor through every
pending step (SDCA upgrade → PoA → JPA → KYC) on the Creditors app
and returns to the partner-supplied returnUrl when done.

```json
{
  "result": {
    "isEligible": true,
    "ineligibilityReason": null,
    "ineligibilityReasonCode": null,
    "admissionMinimum": {
      "rule": "string",
      "amountUsd": 2500,
      "amount": 2500,
      "currencyCode": "EUR"
    },
    "applicableMinimumAmount": 2500,
    "applicableMinimumCurrencyCode": "EUR",
    "marketMinimumAmount": 2500,
    "marketMinimumCurrencyCode": "EUR",
    "amountCheckUnavailable": true,
    "partnerAssignment": {
      "collectionPartnerId": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
      "partnerName": "Muster GmbH",
      "partnerCountry": "string"
    },
    "requiredActions": [
      {
        "type": "string",
        "message": "Payment plan agreed with the debtor.",
        "solutionUrl": "https://app.debitura.com/…",
        "isBlocking": true
      }
    ],
    "jurisdiction": {
      "id": 3,
      "name": "Muster GmbH",
      "countryAlpha2": "DE",
      "stateAlpha2": null
    },
    "pricingPreview": {
      "baseSuccessFeePercentage": 2500,
      "ageSurchargePercentage": 1.5,
      "totalSuccessFeePercentage": 2500,
      "currencyCode": "EUR",
      "pricingSource": "string",
      "pricingSourceDescription": "string"
    },
    "requiresKycVerification": true,
    "hasKycOnFile": true,
    "signingHandoff": {
      "combinedSigningUrl": "https://app.debitura.com/…"
    }
  }
}
```

### Response 400

Invalid request (validation errors)

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

### Response 500

Internal server error

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

<a id="fetch-case-by-id"></a>

## Fetch case by ID

`GET /cases/{id}`

Returns case details for the provided Debitura case ID (a GUID).

### Path parameters

- `id` (uuid, required): 

### Response 200

Case found

- `id` (uuid): 
- `dateCreated` (datetime): 
- `dateUpdated` (datetime, nullable): 
- `reference` (string, nullable): 
- `creditorReference` (string, nullable): 
- `creditorComments` (string, nullable): 
- `claimDescription` (string, nullable): 
- `grossAmount` (number): 
- `remainder` (number): 
- `interestFees` (number): 
- `reminderFees` (number): 
- `collectionFees` (number): 
- `totalAddedFees` (number): 
- `currency` (string, nullable): 
- `isTestCase` (boolean): 
- `lifecycle` (string, nullable): 
- `dueDate` (datetime): 
- `date` (datetime): 
- `dateFinished` (datetime, nullable): 
- `dateCollectionStarted` (datetime, nullable): 
- `closeCode` (string, nullable): 
- `currentEngagementPhase` (string, nullable): The current phase of the case's engagement: "Pre-legal", "Legal", or "Enforcement".
A different axis from Lifecycle/CloseCode — an Active case can be
in any of the three phases.
            
Null means "no active engagement" (e.g. lead / quoting / pre-contract-signing / unassigned, or
a data-consistency gap) — this is a distinct third state, NOT a synonym for Pre-legal. Most
cases legitimately read Pre-legal; phase only leaves Pre-legal on legal/enforcement quote flows.
            
Not guaranteed to be monotonic: an admin correction can move phase backwards (e.g. Legal back
to Pre-legal).
            
Persists after case closure — reflects the case's last-known engagement phase, not the current
Lifecycle. Note: this is a different field from a lead quote's own offered phase (the phase a
partner's quote proposes to work the case at, if this case ever went through a quote flow) —
this field is the case-level phase of its actual engagement, not a quote's terms.
- `claimType` (string, nullable): The type of claim for this case (e.g. "Unpaid Invoice", "Loan Repayment", "Breach of Contract").
Null if not set.
- `creditorDivisionId` (uuid, nullable): 
- `debtor` (object): V1 Debtor DTO for external partner APIs.
The debtor is the party that owes the debt.
- `debtor.type` (string, required): Debtor type. Valid values: "Company" or "Private" (case-insensitive)
- `debtor.name` (string, required): Debtor name (company name or person's full name)
- `debtor.contactPerson` (string, nullable): Contact person at the company (required for companies, not used for persons)
- `debtor.companyRegistrationNumber` (string, nullable): Company registration number (VAT number, CVR, org number, etc.)
- `debtor.address` (string, nullable): Street address
- `debtor.zipCode` (string, nullable): Postal/ZIP code
- `debtor.city` (string, nullable): City name
- `debtor.state` (string, nullable): State/region/province name
- `debtor.stateAlpha2` (string, nullable): US state: two-letter code (e.g., "CA"), ISO 3166-2 format (e.g., "US-CA"), or full name (e.g., "California")
- `debtor.countryAlpha2` (string, nullable): Country code (ISO 3166-1 alpha-2 format)
- `debtor.country` (string, nullable): Country name
- `debtor.email` (string, nullable): Email address for debtor contact
- `debtor.phone` (string, nullable): Phone number (include country code)
- `collectionPartner` (object): V1 Collection Partner DTO for external partner APIs
- `collectionPartner.name` (string, nullable): 
- `collectionPartner.officeEmail` (string, nullable): 
- `collectionPartner.officePhone` (string, nullable): 
- `collectionPartner.publicSite` (string, nullable): 
- `collectionPartner.surveyCadenceMode` (enum, deprecated): Deprecated: kept as a number and never removed, but not extended. Survey-generation cadence: 0 = Standard
(rolling monthly survey), 1 = DecisionPointOnly (no rolling surveys).
  Values: `0`, `1`.
- `creditor` (object): Creditor (client) information for external partner APIs.
Represents the party that the debtor owes money to.
- `creditor.id` (uuid): Unique identifier for the creditor
- `creditor.companyName` (string, nullable): Company name of the creditor
- `creditor.companyRegistrationNumber` (string, nullable): Company registration number (CVR, VAT number, etc.)
- `creditor.officeEmail` (string, nullable): Primary office email address
- `creditor.officePhone` (string, nullable): Primary office phone number
- `creditor.address` (string, nullable): Street address
- `creditor.city` (string, nullable): City
- `creditor.zipCode` (string, nullable): Postal/ZIP code
- `creditor.state` (string, nullable): State or region (if applicable)
- `creditor.country` (string, nullable): Country name
- `creditor.division` (object): Creditor division information for external partner APIs.
Represents a specific division or department within a creditor organization.
- `creditor.division.id` (uuid): Unique identifier for the division
- `creditor.division.name` (string, nullable): Name of the division
- `bankAccount` (object): Bank account information for partner API.
Full details provided as partners need this to:
1. Provide payment instructions to debtors (when debtor pays client directly)
2. Execute payouts to clients (when partner receives payment and pays out remainder)
- `bankAccount.id` (integer): Bank account identifier
- `bankAccount.label` (string, nullable): User-friendly label (e.g., "Main EUR Account")
- `bankAccount.scheme` (string, nullable): Account scheme: IBAN, SWIFT, or LOCAL
- `bankAccount.currencyCode` (string, nullable): Currency code (ISO 4217)
- `bankAccount.bankCountryCode` (string, nullable): Bank country code (ISO Alpha-2)
- `bankAccount.accountHolderName` (string, nullable): Account holder name (beneficiary)
- `bankAccount.iban` (string, nullable): IBAN (for IBAN scheme accounts)
- `bankAccount.bic` (string, nullable): BIC/SWIFT code (for IBAN and SWIFT scheme accounts)
- `bankAccount.accountNumber` (string, nullable): Account number (for SWIFT and LOCAL scheme accounts)
- `bankAccount.localIdentifier` (string, nullable): Local identifier (for LOCAL scheme accounts, e.g., sort code + account number)
- `bankAccount.localIdentifierType` (string, nullable): Type of local identifier (e.g., "Sort Code", "Routing Number")
- `bankAccount.bankName` (string, nullable): Bank name (optional)
- `bankAccount.bankAddress` (string, nullable): Bank address (optional)
- `bankAccount.bankCity` (string, nullable): Bank city (optional)
- `bankAccount.bankZipCode` (string, nullable): Bank zip/postal code (optional)
- `bankAccount.bankState` (string, nullable): Bank state/region (optional)
- `blendedAgeUpliftPoints` (number, nullable): MULTI-INVOICE AGE BUCKET PRICING
Calculated blended age uplift percentage points (0-20) for multi-invoice cases.
Shows the additional fee percentage added due to invoice age.
Formula: ((A12-A24)×10 + A24×20) / Total Principal
Null for single-invoice cases (age uplift is calculated from due date instead).
- `preLegalSuccessFee` (number, nullable): PRE-LEGAL SUCCESS FEE
The total pre-legal success fee percentage for this case.
Includes base fee + age-based uplift (blended or single-invoice).
Null if pricing has not been calculated yet or if case is not in pre-legal phase.
Example: 20.5 represents 20.5% success fee.
- `solutionUrl` (string, nullable, deprecated): When the case is created with allowPendingContracts=true and required contracts are unsigned,
this URL points to the signing page. Null when contracts are already signed or not applicable.
- `signingHandoff` (object): Partner-facing handoff metadata for a creditor's pending signing chain.
Returned on POST /cases responses (422 with pending-signing errors,
or 200 with AllowPendingContracts=true when signings remain).
            
Designed as an envelope so future fields (expiration, suggested email
copy, etc.) can be added without polluting the parent DTO.
- `signingHandoff.combinedSigningUrl` (string, nullable): Single signing entry URL that walks the creditor through every
pending step (SDCA upgrade → PoA → JPA → KYC) on the Creditors app
and returns to the partner-supplied returnUrl when done.
- `exclusivePeriodEndDate` (datetime, nullable): The date the exclusive collection period ends (or ended).
Null if no collection period has been created for this case (e.g. custom-terms cases).
Use GET /cases/{id}/exclusive-period for the full chain including extensions.
- `disputeStatus` (string, nullable): Whether the claim is disputed by the debtor.
One of: "Yes, the claim is disputed", "No, the claim is not disputed", or "Don't Know".
Null when the dispute status has not been set on the case.
- `validation` (object): Stable v1 validation summary used by ordinary and list mappings.
- `validation.needsInfo` (boolean): 
- `assignedUser` (object): Represents the creditor team member assigned to a case.
- `assignedUser.email` (string, nullable): The assigned user's email address.
- `assignedUser.name` (string, nullable): The assigned user's full name.
- `allocationOutstanding` (object): Outstanding amount per bucket on the case: each bucket's total minus the payments allocated to it.
- `allocationOutstanding.principal` (number): 
- `allocationOutstanding.interest` (number): 
- `allocationOutstanding.reminderFees` (number): 
- `allocationOutstanding.collectionFees` (number): 

```json
{
  "id": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
  "dateCreated": "2026-10-01T14:05:00Z",
  "dateUpdated": "2026-10-01T14:05:00Z",
  "reference": "INV-2026-0042",
  "creditorReference": "INV-2026-0042",
  "creditorComments": "Payment plan agreed with the debtor.",
  "claimDescription": "string",
  "grossAmount": 2500,
  "remainder": 1.5,
  "interestFees": 2500,
  "reminderFees": 2500,
  "collectionFees": 2500,
  "totalAddedFees": 2500,
  "currency": "EUR",
  "isTestCase": true,
  "lifecycle": "string",
  "dueDate": "2026-10-01T14:05:00Z",
  "date": "2026-10-01T14:05:00Z",
  "dateFinished": "2026-10-01T14:05:00Z",
  "dateCollectionStarted": "2026-10-01T14:05:00Z",
  "closeCode": "string",
  "currentEngagementPhase": "string",
  "claimType": "string",
  "creditorDivisionId": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
  "debtor": {
    "type": "Company",
    "name": "Pacific Trading LLC",
    "contactPerson": "John Smith",
    "companyRegistrationNumber": "47-1234567",
    "address": "123 Market Street, Suite 400",
    "zipCode": "94105",
    "city": "San Francisco",
    "state": "California",
    "stateAlpha2": "CA",
    "countryAlpha2": "US",
    "country": "United States",
    "email": "accounts@pacifictrading.com",
    "phone": "+1 415 555 0123"
  },
  "collectionPartner": {
    "name": "Muster GmbH",
    "officeEmail": "finance@example.com",
    "officePhone": "+49 30 1234567",
    "publicSite": "string",
    "surveyCadenceMode": 0
  },
  "creditor": {
    "id": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
    "companyName": "Muster GmbH",
    "companyRegistrationNumber": "DE123456789",
    "officeEmail": "finance@example.com",
    "officePhone": "+49 30 1234567",
    "address": "Friedrichstraße 68",
    "city": "Berlin",
    "zipCode": "10115",
    "state": "string",
    "country": "Germany",
    "division": {
      "id": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
      "name": "Muster GmbH"
    }
  },
  "bankAccount": {
    "id": 3,
    "label": "string",
    "scheme": "string",
    "currencyCode": "EUR",
    "bankCountryCode": "DE",
    "accountHolderName": "Muster GmbH",
    "iban": "string",
    "bic": "string",
    "accountNumber": "string",
    "localIdentifier": "string",
    "localIdentifierType": "string",
    "bankName": "Muster GmbH",
    "bankAddress": "Friedrichstraße 68",
    "bankCity": "Berlin",
    "bankZipCode": "10115",
    "bankState": "string"
  },
  "blendedAgeUpliftPoints": 1.5,
  "preLegalSuccessFee": 2500,
  "solutionUrl": "https://app.debitura.com/…",
  "signingHandoff": {
    "combinedSigningUrl": "https://app.debitura.com/…"
  },
  "exclusivePeriodEndDate": "2026-10-01T14:05:00Z",
  "disputeStatus": "string",
  "validation": {
    "needsInfo": true
  },
  "assignedUser": {
    "email": "finance@example.com",
    "name": "Muster GmbH"
  },
  "allocationOutstanding": {
    "principal": 1.5,
    "interest": 1.5,
    "reminderFees": 2500,
    "collectionFees": 2500
  }
}
```

### Response 400

ID missing, empty, or ID is not a collection case

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

### Response 404

Case not found, deleted, or does not belong to your account

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

<a id="fetch-case-by-creditor-reference"></a>

## Fetch case by creditor reference

`GET /cases/by-creditor-reference/{creditorReference}`

Returns case details for the provided creditor reference. The creditor reference is your own unique identifier for the case, as provided when the case was created.

### Path parameters

- `creditorReference` (string, required): 

### Response 200

Case found

- `id` (uuid): 
- `dateCreated` (datetime): 
- `dateUpdated` (datetime, nullable): 
- `reference` (string, nullable): 
- `creditorReference` (string, nullable): 
- `creditorComments` (string, nullable): 
- `claimDescription` (string, nullable): 
- `grossAmount` (number): 
- `remainder` (number): 
- `interestFees` (number): 
- `reminderFees` (number): 
- `collectionFees` (number): 
- `totalAddedFees` (number): 
- `currency` (string, nullable): 
- `isTestCase` (boolean): 
- `lifecycle` (string, nullable): 
- `dueDate` (datetime): 
- `date` (datetime): 
- `dateFinished` (datetime, nullable): 
- `dateCollectionStarted` (datetime, nullable): 
- `closeCode` (string, nullable): 
- `currentEngagementPhase` (string, nullable): The current phase of the case's engagement: "Pre-legal", "Legal", or "Enforcement".
A different axis from Lifecycle/CloseCode — an Active case can be
in any of the three phases.
            
Null means "no active engagement" (e.g. lead / quoting / pre-contract-signing / unassigned, or
a data-consistency gap) — this is a distinct third state, NOT a synonym for Pre-legal. Most
cases legitimately read Pre-legal; phase only leaves Pre-legal on legal/enforcement quote flows.
            
Not guaranteed to be monotonic: an admin correction can move phase backwards (e.g. Legal back
to Pre-legal).
            
Persists after case closure — reflects the case's last-known engagement phase, not the current
Lifecycle. Note: this is a different field from a lead quote's own offered phase (the phase a
partner's quote proposes to work the case at, if this case ever went through a quote flow) —
this field is the case-level phase of its actual engagement, not a quote's terms.
- `claimType` (string, nullable): The type of claim for this case (e.g. "Unpaid Invoice", "Loan Repayment", "Breach of Contract").
Null if not set.
- `creditorDivisionId` (uuid, nullable): 
- `debtor` (object): V1 Debtor DTO for external partner APIs.
The debtor is the party that owes the debt.
- `debtor.type` (string, required): Debtor type. Valid values: "Company" or "Private" (case-insensitive)
- `debtor.name` (string, required): Debtor name (company name or person's full name)
- `debtor.contactPerson` (string, nullable): Contact person at the company (required for companies, not used for persons)
- `debtor.companyRegistrationNumber` (string, nullable): Company registration number (VAT number, CVR, org number, etc.)
- `debtor.address` (string, nullable): Street address
- `debtor.zipCode` (string, nullable): Postal/ZIP code
- `debtor.city` (string, nullable): City name
- `debtor.state` (string, nullable): State/region/province name
- `debtor.stateAlpha2` (string, nullable): US state: two-letter code (e.g., "CA"), ISO 3166-2 format (e.g., "US-CA"), or full name (e.g., "California")
- `debtor.countryAlpha2` (string, nullable): Country code (ISO 3166-1 alpha-2 format)
- `debtor.country` (string, nullable): Country name
- `debtor.email` (string, nullable): Email address for debtor contact
- `debtor.phone` (string, nullable): Phone number (include country code)
- `collectionPartner` (object): V1 Collection Partner DTO for external partner APIs
- `collectionPartner.name` (string, nullable): 
- `collectionPartner.officeEmail` (string, nullable): 
- `collectionPartner.officePhone` (string, nullable): 
- `collectionPartner.publicSite` (string, nullable): 
- `collectionPartner.surveyCadenceMode` (enum, deprecated): Deprecated: kept as a number and never removed, but not extended. Survey-generation cadence: 0 = Standard
(rolling monthly survey), 1 = DecisionPointOnly (no rolling surveys).
  Values: `0`, `1`.
- `creditor` (object): Creditor (client) information for external partner APIs.
Represents the party that the debtor owes money to.
- `creditor.id` (uuid): Unique identifier for the creditor
- `creditor.companyName` (string, nullable): Company name of the creditor
- `creditor.companyRegistrationNumber` (string, nullable): Company registration number (CVR, VAT number, etc.)
- `creditor.officeEmail` (string, nullable): Primary office email address
- `creditor.officePhone` (string, nullable): Primary office phone number
- `creditor.address` (string, nullable): Street address
- `creditor.city` (string, nullable): City
- `creditor.zipCode` (string, nullable): Postal/ZIP code
- `creditor.state` (string, nullable): State or region (if applicable)
- `creditor.country` (string, nullable): Country name
- `creditor.division` (object): Creditor division information for external partner APIs.
Represents a specific division or department within a creditor organization.
- `creditor.division.id` (uuid): Unique identifier for the division
- `creditor.division.name` (string, nullable): Name of the division
- `bankAccount` (object): Bank account information for partner API.
Full details provided as partners need this to:
1. Provide payment instructions to debtors (when debtor pays client directly)
2. Execute payouts to clients (when partner receives payment and pays out remainder)
- `bankAccount.id` (integer): Bank account identifier
- `bankAccount.label` (string, nullable): User-friendly label (e.g., "Main EUR Account")
- `bankAccount.scheme` (string, nullable): Account scheme: IBAN, SWIFT, or LOCAL
- `bankAccount.currencyCode` (string, nullable): Currency code (ISO 4217)
- `bankAccount.bankCountryCode` (string, nullable): Bank country code (ISO Alpha-2)
- `bankAccount.accountHolderName` (string, nullable): Account holder name (beneficiary)
- `bankAccount.iban` (string, nullable): IBAN (for IBAN scheme accounts)
- `bankAccount.bic` (string, nullable): BIC/SWIFT code (for IBAN and SWIFT scheme accounts)
- `bankAccount.accountNumber` (string, nullable): Account number (for SWIFT and LOCAL scheme accounts)
- `bankAccount.localIdentifier` (string, nullable): Local identifier (for LOCAL scheme accounts, e.g., sort code + account number)
- `bankAccount.localIdentifierType` (string, nullable): Type of local identifier (e.g., "Sort Code", "Routing Number")
- `bankAccount.bankName` (string, nullable): Bank name (optional)
- `bankAccount.bankAddress` (string, nullable): Bank address (optional)
- `bankAccount.bankCity` (string, nullable): Bank city (optional)
- `bankAccount.bankZipCode` (string, nullable): Bank zip/postal code (optional)
- `bankAccount.bankState` (string, nullable): Bank state/region (optional)
- `blendedAgeUpliftPoints` (number, nullable): MULTI-INVOICE AGE BUCKET PRICING
Calculated blended age uplift percentage points (0-20) for multi-invoice cases.
Shows the additional fee percentage added due to invoice age.
Formula: ((A12-A24)×10 + A24×20) / Total Principal
Null for single-invoice cases (age uplift is calculated from due date instead).
- `preLegalSuccessFee` (number, nullable): PRE-LEGAL SUCCESS FEE
The total pre-legal success fee percentage for this case.
Includes base fee + age-based uplift (blended or single-invoice).
Null if pricing has not been calculated yet or if case is not in pre-legal phase.
Example: 20.5 represents 20.5% success fee.
- `solutionUrl` (string, nullable, deprecated): When the case is created with allowPendingContracts=true and required contracts are unsigned,
this URL points to the signing page. Null when contracts are already signed or not applicable.
- `signingHandoff` (object): Partner-facing handoff metadata for a creditor's pending signing chain.
Returned on POST /cases responses (422 with pending-signing errors,
or 200 with AllowPendingContracts=true when signings remain).
            
Designed as an envelope so future fields (expiration, suggested email
copy, etc.) can be added without polluting the parent DTO.
- `signingHandoff.combinedSigningUrl` (string, nullable): Single signing entry URL that walks the creditor through every
pending step (SDCA upgrade → PoA → JPA → KYC) on the Creditors app
and returns to the partner-supplied returnUrl when done.
- `exclusivePeriodEndDate` (datetime, nullable): The date the exclusive collection period ends (or ended).
Null if no collection period has been created for this case (e.g. custom-terms cases).
Use GET /cases/{id}/exclusive-period for the full chain including extensions.
- `disputeStatus` (string, nullable): Whether the claim is disputed by the debtor.
One of: "Yes, the claim is disputed", "No, the claim is not disputed", or "Don't Know".
Null when the dispute status has not been set on the case.
- `validation` (object): Stable v1 validation summary used by ordinary and list mappings.
- `validation.needsInfo` (boolean): 
- `assignedUser` (object): Represents the creditor team member assigned to a case.
- `assignedUser.email` (string, nullable): The assigned user's email address.
- `assignedUser.name` (string, nullable): The assigned user's full name.
- `allocationOutstanding` (object): Outstanding amount per bucket on the case: each bucket's total minus the payments allocated to it.
- `allocationOutstanding.principal` (number): 
- `allocationOutstanding.interest` (number): 
- `allocationOutstanding.reminderFees` (number): 
- `allocationOutstanding.collectionFees` (number): 

```json
{
  "id": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
  "dateCreated": "2026-10-01T14:05:00Z",
  "dateUpdated": "2026-10-01T14:05:00Z",
  "reference": "INV-2026-0042",
  "creditorReference": "INV-2026-0042",
  "creditorComments": "Payment plan agreed with the debtor.",
  "claimDescription": "string",
  "grossAmount": 2500,
  "remainder": 1.5,
  "interestFees": 2500,
  "reminderFees": 2500,
  "collectionFees": 2500,
  "totalAddedFees": 2500,
  "currency": "EUR",
  "isTestCase": true,
  "lifecycle": "string",
  "dueDate": "2026-10-01T14:05:00Z",
  "date": "2026-10-01T14:05:00Z",
  "dateFinished": "2026-10-01T14:05:00Z",
  "dateCollectionStarted": "2026-10-01T14:05:00Z",
  "closeCode": "string",
  "currentEngagementPhase": "string",
  "claimType": "string",
  "creditorDivisionId": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
  "debtor": {
    "type": "Company",
    "name": "Pacific Trading LLC",
    "contactPerson": "John Smith",
    "companyRegistrationNumber": "47-1234567",
    "address": "123 Market Street, Suite 400",
    "zipCode": "94105",
    "city": "San Francisco",
    "state": "California",
    "stateAlpha2": "CA",
    "countryAlpha2": "US",
    "country": "United States",
    "email": "accounts@pacifictrading.com",
    "phone": "+1 415 555 0123"
  },
  "collectionPartner": {
    "name": "Muster GmbH",
    "officeEmail": "finance@example.com",
    "officePhone": "+49 30 1234567",
    "publicSite": "string",
    "surveyCadenceMode": 0
  },
  "creditor": {
    "id": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
    "companyName": "Muster GmbH",
    "companyRegistrationNumber": "DE123456789",
    "officeEmail": "finance@example.com",
    "officePhone": "+49 30 1234567",
    "address": "Friedrichstraße 68",
    "city": "Berlin",
    "zipCode": "10115",
    "state": "string",
    "country": "Germany",
    "division": {
      "id": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
      "name": "Muster GmbH"
    }
  },
  "bankAccount": {
    "id": 3,
    "label": "string",
    "scheme": "string",
    "currencyCode": "EUR",
    "bankCountryCode": "DE",
    "accountHolderName": "Muster GmbH",
    "iban": "string",
    "bic": "string",
    "accountNumber": "string",
    "localIdentifier": "string",
    "localIdentifierType": "string",
    "bankName": "Muster GmbH",
    "bankAddress": "Friedrichstraße 68",
    "bankCity": "Berlin",
    "bankZipCode": "10115",
    "bankState": "string"
  },
  "blendedAgeUpliftPoints": 1.5,
  "preLegalSuccessFee": 2500,
  "solutionUrl": "https://app.debitura.com/…",
  "signingHandoff": {
    "combinedSigningUrl": "https://app.debitura.com/…"
  },
  "exclusivePeriodEndDate": "2026-10-01T14:05:00Z",
  "disputeStatus": "string",
  "validation": {
    "needsInfo": true
  },
  "assignedUser": {
    "email": "finance@example.com",
    "name": "Muster GmbH"
  },
  "allocationOutstanding": {
    "principal": 1.5,
    "interest": 1.5,
    "reminderFees": 2500,
    "collectionFees": 2500
  }
}
```

### Response 400

Creditor reference missing or empty

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

### Response 404

No case found with this creditor reference

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

<a id="get-contract-signing-status-for-a-case"></a>

## Get contract signing status for a case

`GET /cases/{id}/contract-status`

Returns the signing status of the SDCA (Standard Debt Collection Agreement), PoA (Power of Attorney), and Jurisdiction Pricing Appendix for a case.

**Use case:** When a case is stuck in PendingContractSigning, use this endpoint to determine which contract is missing and get the signing URL.

**Response:**
- sdca: Always present — shows whether the debt collection agreement is signed
- poa: Present only if a collection partner is assigned — shows whether the power of attorney is signed for that partner
- NeedsPoaSigning: true when the case is blocked because a required PoA or Jurisdiction Pricing Appendix has not been signed
- Each contract item includes a solutionUrl if signing or re-signing is needed
- The solutionUrl is context-aware: referral partner bearer tokens get referral onboarding URLs, API keys get creditor app URLs

### Path parameters

- `id` (uuid, required): 

### Response 200

Contract status returned

- `sdca` (object): Status of an individual contract (SDCA, PoA, or Pricing Appendix).
- `sdca.signed` (boolean): Whether the contract has been signed.
- `sdca.requiresResigning` (boolean): Whether the contract needs to be re-signed (e.g., due to contract template updates).
- `sdca.solutionUrl` (string, nullable): URL where the creditor can sign or re-sign the contract.
Null if the contract is signed and current.
The URL is context-aware: referral partner tokens get referral onboarding URLs,
regular API keys get standard creditor app URLs.
- `poa` (object): Status of an individual contract (SDCA, PoA, or Pricing Appendix).
- `poa.signed` (boolean): Whether the contract has been signed.
- `poa.requiresResigning` (boolean): Whether the contract needs to be re-signed (e.g., due to contract template updates).
- `poa.solutionUrl` (string, nullable): URL where the creditor can sign or re-sign the contract.
Null if the contract is signed and current.
The URL is context-aware: referral partner tokens get referral onboarding URLs,
regular API keys get standard creditor app URLs.
- `pricingAppendix` (object): Status of an individual contract (SDCA, PoA, or Pricing Appendix).
- `pricingAppendix.signed` (boolean): Whether the contract has been signed.
- `pricingAppendix.requiresResigning` (boolean): Whether the contract needs to be re-signed (e.g., due to contract template updates).
- `pricingAppendix.solutionUrl` (string, nullable): URL where the creditor can sign or re-sign the contract.
Null if the contract is signed and current.
The URL is context-aware: referral partner tokens get referral onboarding URLs,
regular API keys get standard creditor app URLs.
- `collectionPartnerName` (string, nullable): Name of the assigned collection partner, if any.
- `needsPoaSigning` (boolean): Whether the creditor needs to sign (or re-sign) a Power of Attorney.
True when: POA is missing or stale, OR the debtor's country has an active jurisdiction pricing zone
and the Jurisdiction Pricing Appendix (presented as POA) is missing or stale.

```json
{
  "sdca": {
    "signed": true,
    "requiresResigning": true,
    "solutionUrl": "https://app.debitura.com/…"
  },
  "poa": {
    "signed": true,
    "requiresResigning": true,
    "solutionUrl": "https://app.debitura.com/…"
  },
  "pricingAppendix": {
    "signed": true,
    "requiresResigning": true,
    "solutionUrl": "https://app.debitura.com/…"
  },
  "collectionPartnerName": "Muster GmbH",
  "needsPoaSigning": true
}
```

### Response 400

ID missing, empty, or not a collection case

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

### Response 404

Case not found, deleted, or does not belong to your account

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

<a id="fetch-case-by-reference"></a>

## Fetch case by reference

`GET /cases/case-reference/{caseReference}`

Returns case details for the provided Debitura case reference (example: Q8OAXF3W).

### Path parameters

- `caseReference` (string, required): 

### Response 200

Case found

- `id` (uuid): 
- `dateCreated` (datetime): 
- `dateUpdated` (datetime, nullable): 
- `reference` (string, nullable): 
- `creditorReference` (string, nullable): 
- `creditorComments` (string, nullable): 
- `claimDescription` (string, nullable): 
- `grossAmount` (number): 
- `remainder` (number): 
- `interestFees` (number): 
- `reminderFees` (number): 
- `collectionFees` (number): 
- `totalAddedFees` (number): 
- `currency` (string, nullable): 
- `isTestCase` (boolean): 
- `lifecycle` (string, nullable): 
- `dueDate` (datetime): 
- `date` (datetime): 
- `dateFinished` (datetime, nullable): 
- `dateCollectionStarted` (datetime, nullable): 
- `closeCode` (string, nullable): 
- `currentEngagementPhase` (string, nullable): The current phase of the case's engagement: "Pre-legal", "Legal", or "Enforcement".
A different axis from Lifecycle/CloseCode — an Active case can be
in any of the three phases.
            
Null means "no active engagement" (e.g. lead / quoting / pre-contract-signing / unassigned, or
a data-consistency gap) — this is a distinct third state, NOT a synonym for Pre-legal. Most
cases legitimately read Pre-legal; phase only leaves Pre-legal on legal/enforcement quote flows.
            
Not guaranteed to be monotonic: an admin correction can move phase backwards (e.g. Legal back
to Pre-legal).
            
Persists after case closure — reflects the case's last-known engagement phase, not the current
Lifecycle. Note: this is a different field from a lead quote's own offered phase (the phase a
partner's quote proposes to work the case at, if this case ever went through a quote flow) —
this field is the case-level phase of its actual engagement, not a quote's terms.
- `claimType` (string, nullable): The type of claim for this case (e.g. "Unpaid Invoice", "Loan Repayment", "Breach of Contract").
Null if not set.
- `creditorDivisionId` (uuid, nullable): 
- `debtor` (object): V1 Debtor DTO for external partner APIs.
The debtor is the party that owes the debt.
- `debtor.type` (string, required): Debtor type. Valid values: "Company" or "Private" (case-insensitive)
- `debtor.name` (string, required): Debtor name (company name or person's full name)
- `debtor.contactPerson` (string, nullable): Contact person at the company (required for companies, not used for persons)
- `debtor.companyRegistrationNumber` (string, nullable): Company registration number (VAT number, CVR, org number, etc.)
- `debtor.address` (string, nullable): Street address
- `debtor.zipCode` (string, nullable): Postal/ZIP code
- `debtor.city` (string, nullable): City name
- `debtor.state` (string, nullable): State/region/province name
- `debtor.stateAlpha2` (string, nullable): US state: two-letter code (e.g., "CA"), ISO 3166-2 format (e.g., "US-CA"), or full name (e.g., "California")
- `debtor.countryAlpha2` (string, nullable): Country code (ISO 3166-1 alpha-2 format)
- `debtor.country` (string, nullable): Country name
- `debtor.email` (string, nullable): Email address for debtor contact
- `debtor.phone` (string, nullable): Phone number (include country code)
- `collectionPartner` (object): V1 Collection Partner DTO for external partner APIs
- `collectionPartner.name` (string, nullable): 
- `collectionPartner.officeEmail` (string, nullable): 
- `collectionPartner.officePhone` (string, nullable): 
- `collectionPartner.publicSite` (string, nullable): 
- `collectionPartner.surveyCadenceMode` (enum, deprecated): Deprecated: kept as a number and never removed, but not extended. Survey-generation cadence: 0 = Standard
(rolling monthly survey), 1 = DecisionPointOnly (no rolling surveys).
  Values: `0`, `1`.
- `creditor` (object): Creditor (client) information for external partner APIs.
Represents the party that the debtor owes money to.
- `creditor.id` (uuid): Unique identifier for the creditor
- `creditor.companyName` (string, nullable): Company name of the creditor
- `creditor.companyRegistrationNumber` (string, nullable): Company registration number (CVR, VAT number, etc.)
- `creditor.officeEmail` (string, nullable): Primary office email address
- `creditor.officePhone` (string, nullable): Primary office phone number
- `creditor.address` (string, nullable): Street address
- `creditor.city` (string, nullable): City
- `creditor.zipCode` (string, nullable): Postal/ZIP code
- `creditor.state` (string, nullable): State or region (if applicable)
- `creditor.country` (string, nullable): Country name
- `creditor.division` (object): Creditor division information for external partner APIs.
Represents a specific division or department within a creditor organization.
- `creditor.division.id` (uuid): Unique identifier for the division
- `creditor.division.name` (string, nullable): Name of the division
- `bankAccount` (object): Bank account information for partner API.
Full details provided as partners need this to:
1. Provide payment instructions to debtors (when debtor pays client directly)
2. Execute payouts to clients (when partner receives payment and pays out remainder)
- `bankAccount.id` (integer): Bank account identifier
- `bankAccount.label` (string, nullable): User-friendly label (e.g., "Main EUR Account")
- `bankAccount.scheme` (string, nullable): Account scheme: IBAN, SWIFT, or LOCAL
- `bankAccount.currencyCode` (string, nullable): Currency code (ISO 4217)
- `bankAccount.bankCountryCode` (string, nullable): Bank country code (ISO Alpha-2)
- `bankAccount.accountHolderName` (string, nullable): Account holder name (beneficiary)
- `bankAccount.iban` (string, nullable): IBAN (for IBAN scheme accounts)
- `bankAccount.bic` (string, nullable): BIC/SWIFT code (for IBAN and SWIFT scheme accounts)
- `bankAccount.accountNumber` (string, nullable): Account number (for SWIFT and LOCAL scheme accounts)
- `bankAccount.localIdentifier` (string, nullable): Local identifier (for LOCAL scheme accounts, e.g., sort code + account number)
- `bankAccount.localIdentifierType` (string, nullable): Type of local identifier (e.g., "Sort Code", "Routing Number")
- `bankAccount.bankName` (string, nullable): Bank name (optional)
- `bankAccount.bankAddress` (string, nullable): Bank address (optional)
- `bankAccount.bankCity` (string, nullable): Bank city (optional)
- `bankAccount.bankZipCode` (string, nullable): Bank zip/postal code (optional)
- `bankAccount.bankState` (string, nullable): Bank state/region (optional)
- `blendedAgeUpliftPoints` (number, nullable): MULTI-INVOICE AGE BUCKET PRICING
Calculated blended age uplift percentage points (0-20) for multi-invoice cases.
Shows the additional fee percentage added due to invoice age.
Formula: ((A12-A24)×10 + A24×20) / Total Principal
Null for single-invoice cases (age uplift is calculated from due date instead).
- `preLegalSuccessFee` (number, nullable): PRE-LEGAL SUCCESS FEE
The total pre-legal success fee percentage for this case.
Includes base fee + age-based uplift (blended or single-invoice).
Null if pricing has not been calculated yet or if case is not in pre-legal phase.
Example: 20.5 represents 20.5% success fee.
- `solutionUrl` (string, nullable, deprecated): When the case is created with allowPendingContracts=true and required contracts are unsigned,
this URL points to the signing page. Null when contracts are already signed or not applicable.
- `signingHandoff` (object): Partner-facing handoff metadata for a creditor's pending signing chain.
Returned on POST /cases responses (422 with pending-signing errors,
or 200 with AllowPendingContracts=true when signings remain).
            
Designed as an envelope so future fields (expiration, suggested email
copy, etc.) can be added without polluting the parent DTO.
- `signingHandoff.combinedSigningUrl` (string, nullable): Single signing entry URL that walks the creditor through every
pending step (SDCA upgrade → PoA → JPA → KYC) on the Creditors app
and returns to the partner-supplied returnUrl when done.
- `exclusivePeriodEndDate` (datetime, nullable): The date the exclusive collection period ends (or ended).
Null if no collection period has been created for this case (e.g. custom-terms cases).
Use GET /cases/{id}/exclusive-period for the full chain including extensions.
- `disputeStatus` (string, nullable): Whether the claim is disputed by the debtor.
One of: "Yes, the claim is disputed", "No, the claim is not disputed", or "Don't Know".
Null when the dispute status has not been set on the case.
- `validation` (object): Stable v1 validation summary used by ordinary and list mappings.
- `validation.needsInfo` (boolean): 
- `assignedUser` (object): Represents the creditor team member assigned to a case.
- `assignedUser.email` (string, nullable): The assigned user's email address.
- `assignedUser.name` (string, nullable): The assigned user's full name.
- `allocationOutstanding` (object): Outstanding amount per bucket on the case: each bucket's total minus the payments allocated to it.
- `allocationOutstanding.principal` (number): 
- `allocationOutstanding.interest` (number): 
- `allocationOutstanding.reminderFees` (number): 
- `allocationOutstanding.collectionFees` (number): 

```json
{
  "id": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
  "dateCreated": "2026-10-01T14:05:00Z",
  "dateUpdated": "2026-10-01T14:05:00Z",
  "reference": "INV-2026-0042",
  "creditorReference": "INV-2026-0042",
  "creditorComments": "Payment plan agreed with the debtor.",
  "claimDescription": "string",
  "grossAmount": 2500,
  "remainder": 1.5,
  "interestFees": 2500,
  "reminderFees": 2500,
  "collectionFees": 2500,
  "totalAddedFees": 2500,
  "currency": "EUR",
  "isTestCase": true,
  "lifecycle": "string",
  "dueDate": "2026-10-01T14:05:00Z",
  "date": "2026-10-01T14:05:00Z",
  "dateFinished": "2026-10-01T14:05:00Z",
  "dateCollectionStarted": "2026-10-01T14:05:00Z",
  "closeCode": "string",
  "currentEngagementPhase": "string",
  "claimType": "string",
  "creditorDivisionId": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
  "debtor": {
    "type": "Company",
    "name": "Pacific Trading LLC",
    "contactPerson": "John Smith",
    "companyRegistrationNumber": "47-1234567",
    "address": "123 Market Street, Suite 400",
    "zipCode": "94105",
    "city": "San Francisco",
    "state": "California",
    "stateAlpha2": "CA",
    "countryAlpha2": "US",
    "country": "United States",
    "email": "accounts@pacifictrading.com",
    "phone": "+1 415 555 0123"
  },
  "collectionPartner": {
    "name": "Muster GmbH",
    "officeEmail": "finance@example.com",
    "officePhone": "+49 30 1234567",
    "publicSite": "string",
    "surveyCadenceMode": 0
  },
  "creditor": {
    "id": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
    "companyName": "Muster GmbH",
    "companyRegistrationNumber": "DE123456789",
    "officeEmail": "finance@example.com",
    "officePhone": "+49 30 1234567",
    "address": "Friedrichstraße 68",
    "city": "Berlin",
    "zipCode": "10115",
    "state": "string",
    "country": "Germany",
    "division": {
      "id": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
      "name": "Muster GmbH"
    }
  },
  "bankAccount": {
    "id": 3,
    "label": "string",
    "scheme": "string",
    "currencyCode": "EUR",
    "bankCountryCode": "DE",
    "accountHolderName": "Muster GmbH",
    "iban": "string",
    "bic": "string",
    "accountNumber": "string",
    "localIdentifier": "string",
    "localIdentifierType": "string",
    "bankName": "Muster GmbH",
    "bankAddress": "Friedrichstraße 68",
    "bankCity": "Berlin",
    "bankZipCode": "10115",
    "bankState": "string"
  },
  "blendedAgeUpliftPoints": 1.5,
  "preLegalSuccessFee": 2500,
  "solutionUrl": "https://app.debitura.com/…",
  "signingHandoff": {
    "combinedSigningUrl": "https://app.debitura.com/…"
  },
  "exclusivePeriodEndDate": "2026-10-01T14:05:00Z",
  "disputeStatus": "string",
  "validation": {
    "needsInfo": true
  },
  "assignedUser": {
    "email": "finance@example.com",
    "name": "Muster GmbH"
  },
  "allocationOutstanding": {
    "principal": 1.5,
    "interest": 1.5,
    "reminderFees": 2500,
    "collectionFees": 2500
  }
}
```

### Response 400

Reference missing or reference is not a collection case

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

### Response 404

Reference not found or case does not belong to your account

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

<a id="fetch-case-timeline"></a>

## Fetch case timeline

`GET /cases/{id}/timeline`

Returns the full event timeline for the case along with the current engagement phase.

**Response shape:**
- `items` — chronological list of timeline events
- `currentEngagementPhase` — current phase of the active engagement: "Pre-legal", "Legal", or "Enforcement". Null when no active engagement exists.

### Path parameters

- `id` (uuid, required): 

### Response 200

Timeline returned

- `items` (array of objects, required, nullable): Chronological list of events on the case.
- `items[].date` (datetime): 
- `items[].type` (string, required, nullable): 
- `items[].title` (string, required, nullable): 
- `items[].description` (string, required, nullable): 
- `items[].relatedCases` (array of objects, nullable): Related cases that the authenticated timeline viewer may open. Merge timeline entries
use these safe references instead of exposing persisted case identifiers in text.
- `items[].relatedCases[].id` (uuid): 
- `items[].relatedCases[].reference` (string, required, nullable): 
- `items[].actor` (object): Represents the actor (person or system) that performed a timeline action.
- `items[].actor.type` (string, required, nullable): The type of actor. One of: "System", "Creditor user", "Partner user".
- `items[].actor.name` (string, nullable): Display name of the actor, if available.
- `currentEngagementPhase` (string, nullable): The current engagement phase of the case, sourced from CaseEngagement.CurrentPhase.
Possible values: "Pre-legal", "Legal", "Enforcement".
Null when no active engagement exists (e.g. case not yet assigned to a partner).

```json
{
  "items": [
    {
      "date": "2026-10-01T14:05:00Z",
      "type": "string",
      "title": "string",
      "description": "string",
      "relatedCases": [
        {
          "id": {},
          "reference": {}
        }
      ],
      "actor": {
        "type": "string",
        "name": "Muster GmbH"
      }
    }
  ],
  "currentEngagementPhase": "string"
}
```

### Response 400

ID missing

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

### Response 404

Case not found

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

<a id="fetch-case-chats"></a>

## Fetch case chats

`GET /cases/{id}/chats`

Returns all chat messages attached to the case.

### Path parameters

- `id` (uuid, required): 

### Response 200

Chats returned

- `id` (uuid): 
- `dateCreated` (datetime): 
- `dateUpdated` (datetime, nullable): 
- `role` (enum, deprecated): Deprecated: kept as a number and never removed, but not extended — read `roleLabel` instead.
Sender role: 0 = Partner, 1 = Creditor, 2 = ManagedByPartner.
  Values: `0`, `1`, `2`.
- `roleLabel` (string, nullable): The sender role, readable. Always one of "Partner", "Creditor" or "Managed by partner" — these
values are stable.
- `message` (string, nullable): 
- `isSeen` (boolean): 
- `user` (object): 
- `user.id` (integer): 
- `user.dateCreated` (datetime, nullable): 
- `user.dateUpdated` (datetime, nullable): 
- `user.firstName` (string, nullable): 
- `user.lastName` (string, nullable): 
- `user.email` (string, required, nullable): 

```json
[
  {
    "id": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
    "dateCreated": "2026-10-01T14:05:00Z",
    "dateUpdated": "2026-10-01T14:05:00Z",
    "role": 0,
    "roleLabel": "string",
    "message": "Payment plan agreed with the debtor.",
    "isSeen": true,
    "user": {
      "id": 3,
      "dateCreated": "2026-10-01T14:05:00Z",
      "dateUpdated": "2026-10-01T14:05:00Z",
      "firstName": "Anna",
      "lastName": "Schmidt",
      "email": "finance@example.com"
    }
  }
]
```

### Response 400

ID missing

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

### Response 404

Case not found

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

<a id="send-a-chat-message"></a>

## Send a chat message

`POST /cases/{id}/chats`

Posts a new chat message on a case, visible to both you and the collection partner.

**Message Details:**
- The message is attributed to the team member identified by `userId`
- The collection partner will receive an email notification about the new message
- Messages appear in the case chat timeline in chronological order

**Prerequisites:**
- The case must exist and belong to your account
- The `userId` must be a valid user ID from `GET /users` belonging to your team

**Use Case:**
Use this endpoint to communicate with collection partners about case progress, provide additional information, or respond to partner questions. Messages sent via this endpoint are equivalent to messages sent through the creditor portal chat.

### Path parameters

- `id` (uuid, required): 

### Request body (application/json)

- `message` (string, required): The chat message content to send.
  Max 10000 characters.
- `userId` (uuid, nullable, deprecated): ID of the team member sending this message.
Must be a valid user ID from GET /users belonging to your team.
Deprecated: use UserEmail instead. At least one of UserId or UserEmail must be provided.
- `userEmail` (string, nullable): Email address of the team member sending this message.
Must correspond to an active member of your team (same account as the API key).
Preferred over UserId. At least one of UserEmail or UserId must be provided.
  Email address.

```json
{
  "message": "Please provide the signed contract for this case.",
  "userId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "userEmail": "john.doe@example.com"
}
```

### Response 200

Chat message sent successfully

- `id` (uuid): 
- `dateCreated` (datetime): 
- `dateUpdated` (datetime, nullable): 
- `role` (enum, deprecated): Deprecated: kept as a number and never removed, but not extended — read `roleLabel` instead.
Sender role: 0 = Partner, 1 = Creditor, 2 = ManagedByPartner.
  Values: `0`, `1`, `2`.
- `roleLabel` (string, nullable): The sender role, readable. Always one of "Partner", "Creditor" or "Managed by partner" — these
values are stable.
- `message` (string, nullable): 
- `isSeen` (boolean): 
- `user` (object): 
- `user.id` (integer): 
- `user.dateCreated` (datetime, nullable): 
- `user.dateUpdated` (datetime, nullable): 
- `user.firstName` (string, nullable): 
- `user.lastName` (string, nullable): 
- `user.email` (string, required, nullable): 

```json
{
  "id": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
  "dateCreated": "2026-10-01T14:05:00Z",
  "dateUpdated": "2026-10-01T14:05:00Z",
  "role": 0,
  "roleLabel": "string",
  "message": "Payment plan agreed with the debtor.",
  "isSeen": true,
  "user": {
    "id": 3,
    "dateCreated": "2026-10-01T14:05:00Z",
    "dateUpdated": "2026-10-01T14:05:00Z",
    "firstName": "Anna",
    "lastName": "Schmidt",
    "email": "finance@example.com"
  }
}
```

### Response 400

Validation error — missing fields, invalid userId, or invalid request body

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

### Response 404

Case not found

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

### Response 500

Internal server error

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

<a id="fetch-case-payments"></a>

## Fetch case payments

`GET /cases/{id}/payments`

Returns every payment recorded on the case.

### Path parameters

- `id` (uuid, required): 

### Response 200

Payments returned

- `id` (uuid): 
- `dateCreated` (datetime): 
- `dateUpdated` (datetime, nullable): 
- `date` (datetime): 
- `grossAmount` (number): 
- `recipient` (string, required, nullable): 
- `method` (string, required, nullable): 
- `currency` (string, required, nullable): 
- `invoice` (object, required): 
- `invoice.status` (string, required, nullable): 
- `invoice.reference` (string, required, nullable): 
- `invoice.invoiceId` (uuid): 

```json
[
  {
    "id": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
    "dateCreated": "2026-10-01T14:05:00Z",
    "dateUpdated": "2026-10-01T14:05:00Z",
    "date": "2026-10-01T14:05:00Z",
    "grossAmount": 2500,
    "recipient": "string",
    "method": "string",
    "currency": "EUR",
    "invoice": {
      "status": "string",
      "reference": "INV-2026-0042",
      "invoiceId": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31"
    }
  }
]
```

### Response 400

ID missing

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

### Response 404

Case not found

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

<a id="get-case-files"></a>

## Get case files

`GET /cases/{id}/files`

Returns all files associated with the specified case.

### Path parameters

- `id` (uuid, required): 

### Response 200

Files retrieved successfully

- `id` (uuid): 
- `dateCreated` (datetime): 
- `dateUpdated` (datetime): 
- `caseId` (uuid): 
- `entityType` (string, nullable): 
- `entityId` (uuid): 
- `fileName` (string, nullable): 
- `url` (string, nullable): 
- `description` (string, nullable): 
- `documentType` (string, nullable): 

```json
[
  {
    "id": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
    "dateCreated": "2026-10-01T14:05:00Z",
    "dateUpdated": "2026-10-01T14:05:00Z",
    "caseId": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
    "entityType": "string",
    "entityId": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
    "fileName": "Muster GmbH",
    "url": "https://app.debitura.com/…",
    "description": "string",
    "documentType": "string"
  }
]
```

### Response 400

Invalid case ID

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

### Response 404

Case not found

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

### Response 500

Server error

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

<a id="upload-a-file-to-a-case"></a>

## Upload a file to a case

`POST /cases/{id}/files`

Uploads a file and associates it with a case.

File requirements:
- Maximum file size: 25MB
- Allowed file types: PDF (.pdf), Excel (.xls, .xlsx), CSV (.csv), Text (.TXT), Images (.jpg, .jpeg, .png, .gif)

The file will be stored securely and associated with the specified case.

Document type (optional, case-insensitive). Omit it when you do not know it; the file is then stored as not specified.
- OriginalInvoice - Invoice or credit note
- AccountStatement - Statement of account
- Contract - Contract or agreement
- TermsAndConditions - Terms and conditions
- ProofOfDelivery - Order or proof of delivery
- DemandLetter - Reminder or demand letter
- Correspondence - Correspondence with the debtor
- PaymentProof - Proof of payment
- CourtDocument - Court or legal document
- IdentityDocument - Identity document
- Miscellaneous - Other

Still accepted for existing integrations: DebtorDocuments, CreditorDocuments, PartnerDocuments.
Any other value is rejected with 400 and error InvalidDocumentType.

### Path parameters

- `id` (uuid, required): 

### Request body (multipart/form-data)

- `Description` (string): 
- `DocumentType` (string): 
- `File` (file, required): 

### Response 200

File uploaded successfully

- `id` (uuid): 
- `dateCreated` (datetime): 
- `dateUpdated` (datetime): 
- `caseId` (uuid): 
- `entityType` (string, nullable): 
- `entityId` (uuid): 
- `fileName` (string, nullable): 
- `url` (string, nullable): 
- `description` (string, nullable): 
- `documentType` (string, nullable): 

```json
{
  "id": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
  "dateCreated": "2026-10-01T14:05:00Z",
  "dateUpdated": "2026-10-01T14:05:00Z",
  "caseId": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
  "entityType": "string",
  "entityId": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
  "fileName": "Muster GmbH",
  "url": "https://app.debitura.com/…",
  "description": "string",
  "documentType": "string"
}
```

### Response 400

Invalid request

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

### Response 404

Case not found

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

### Response 413

File too large

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

### Response 415

Unsupported file type

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

### Response 500

Server error

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

<a id="list-quote-requests-for-a-case"></a>

## List quote requests for a case

`GET /cases/{id}/quote-requests`

Returns all quote requests for the specified case. Multiple quote requests can exist per case.

### Path parameters

- `id` (uuid, required): 

### Response 200

Quote requests returned

- `quoteRequests` (array of objects, required, nullable): V1 Lead DTO for external customer APIs (summary view)
- `quoteRequests[].quoteRequestId` (uuid): 
- `quoteRequests[].caseId` (uuid): 
- `quoteRequests[].status` (string, required, nullable): 
- `quoteRequests[].leadFlowStatus` (string, required, nullable): 
- `quoteRequests[].quoteType` (string, required, nullable): 
- `quoteRequests[].maxQuotes` (integer): 
- `quoteRequests[].currentQuotesCount` (integer): 
- `quoteRequests[].outcome` (string, nullable): 
- `quoteRequests[].purpose` (string, nullable): Why this lead exists: PhaseChange (legal/enforcement escalation that advances the case
phase) or AdditionalService (in-phase add-on). Null for legacy leads created before the field existed.
- `quoteRequests[].dateCreated` (datetime): 
- `quoteRequests[].dateQualified` (datetime, nullable): 
- `quoteRequests[].leadsDoneOffered` (datetime, nullable): 
- `quoteRequests[].dateReminderSent` (datetime, nullable): 
- `quoteRequests[].dateReminderTwoSent` (datetime, nullable): 
- `quoteRequests[].dateOutcomeSelected` (datetime, nullable): 

```json
{
  "quoteRequests": [
    {
      "quoteRequestId": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
      "caseId": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
      "status": "string",
      "leadFlowStatus": "string",
      "quoteType": "string",
      "maxQuotes": 3,
      "currentQuotesCount": 42,
      "outcome": "string",
      "purpose": "string",
      "dateCreated": "2026-10-01T14:05:00Z",
      "dateQualified": "2026-10-01T14:05:00Z",
      "leadsDoneOffered": "2026-10-01T14:05:00Z",
      "dateReminderSent": "2026-10-01T14:05:00Z",
      "dateReminderTwoSent": "2026-10-01T14:05:00Z",
      "dateOutcomeSelected": "2026-10-01T14:05:00Z"
    }
  ]
}
```

### Response 400

Invalid case ID

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

### Response 404

Case not found

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

<a id="get-quote-request-details"></a>

## Get quote request details

`GET /cases/{id}/quote-requests/{quoteRequestId}`

Returns detailed information for a specific quote request including computed properties.

### Path parameters

- `id` (uuid, required): 
- `quoteRequestId` (uuid, required): 

### Response 200

Quote request found

- `quoteRequestId` (uuid): 
- `caseId` (uuid): 
- `status` (string, required, nullable): 
- `leadFlowStatus` (string, required, nullable): 
- `quoteType` (string, required, nullable): 
- `maxQuotes` (integer): 
- `currentQuotesCount` (integer): 
- `isMaxBidCountReached` (boolean): 
- `outcome` (string, nullable): 
- `request` (string, nullable): 
- `existingFees` (string, nullable): 
- `dateCreated` (datetime): 
- `dateQualified` (datetime, nullable): 
- `leadsDoneOffered` (datetime, nullable): 
- `dateReminderSent` (datetime, nullable): 
- `dateReminderTwoSent` (datetime, nullable): 
- `dateOutcomeSelected` (datetime, nullable): 

```json
{
  "quoteRequestId": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
  "caseId": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
  "status": "string",
  "leadFlowStatus": "string",
  "quoteType": "string",
  "maxQuotes": 3,
  "currentQuotesCount": 42,
  "isMaxBidCountReached": true,
  "outcome": "string",
  "request": "string",
  "existingFees": "string",
  "dateCreated": "2026-10-01T14:05:00Z",
  "dateQualified": "2026-10-01T14:05:00Z",
  "leadsDoneOffered": "2026-10-01T14:05:00Z",
  "dateReminderSent": "2026-10-01T14:05:00Z",
  "dateReminderTwoSent": "2026-10-01T14:05:00Z",
  "dateOutcomeSelected": "2026-10-01T14:05:00Z"
}
```

### Response 400

Invalid ID

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

### Response 404

Quote request or case not found

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

<a id="list-quotes-for-a-quote-request"></a>

## List quotes for a quote request

`GET /cases/{id}/quote-requests/{quoteRequestId}/quotes`

Returns all partner quotes received for the specified quote request.

### Path parameters

- `id` (uuid, required): 
- `quoteRequestId` (uuid, required): 

### Response 200

Quotes returned

- `quotes` (array of objects, required, nullable): V1 Lead Quote DTO for external customer APIs (summary view)
- `quotes[].quoteId` (uuid): 
- `quotes[].quoteRequestId` (uuid): 
- `quotes[].partnerId` (uuid): 
- `quotes[].partnerName` (string, required, nullable): 
- `quotes[].status` (string, required, nullable): 
- `quotes[].agreementType` (string, required, nullable): 
- `quotes[].hourlyRate` (number, nullable): 
- `quotes[].hourlyEstimated` (number, nullable): 
- `quotes[].flatFeeEstimate` (number, nullable): 
- `quotes[].successFee` (number, nullable): 
- `quotes[].hybridEstimate` (number, nullable): 
- `quotes[].proposedSolution` (string, nullable): 
- `quotes[].partnerWhyUsSection` (string, nullable): 
- `quotes[].phase` (string, nullable): The case phase this quote offers to work in (Pre-legal / Legal / Enforcement). Null = unspecified.
- `quotes[].offerNature` (string, nullable): Whether declining stops the case (Recommendation / Required). v1: display only. Null = unspecified.
- `quotes[].currency` (string, required, nullable): 
- `quotes[].dateCreated` (datetime): 

```json
{
  "quotes": [
    {
      "quoteId": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
      "quoteRequestId": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
      "partnerId": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
      "partnerName": "Muster GmbH",
      "status": "string",
      "agreementType": "string",
      "hourlyRate": 1.5,
      "hourlyEstimated": 1.5,
      "flatFeeEstimate": 2500,
      "successFee": 2500,
      "hybridEstimate": 1.5,
      "proposedSolution": "string",
      "partnerWhyUsSection": "string",
      "phase": "string",
      "offerNature": "string",
      "currency": "EUR",
      "dateCreated": "2026-10-01T14:05:00Z"
    }
  ]
}
```

### Response 400

Invalid ID

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

### Response 404

Quote request or case not found

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

<a id="get-quote-details"></a>

## Get quote details

`GET /cases/{id}/quote-requests/{quoteRequestId}/quotes/{quoteId}`

Returns complete details for a specific quote including full pricing breakdown.

### Path parameters

- `id` (uuid, required): 
- `quoteRequestId` (uuid, required): 
- `quoteId` (uuid, required): 

### Response 200

Quote found

- `quoteId` (uuid): 
- `quoteRequestId` (uuid): 
- `partnerId` (uuid): 
- `partnerName` (string, required, nullable): 
- `status` (string, required, nullable): 
- `agreementType` (string, required, nullable): 
- `pricing` (object, required): Nested pricing details for a lead quote
- `pricing.hourlyRate` (number, nullable): 
- `pricing.hourlyEstimated` (number, nullable): 
- `pricing.flatFeeEstimate` (number, nullable): 
- `pricing.successFeeFee` (number, nullable): 
- `pricing.hybridEstimate` (number, nullable): 
- `pricing.costProcessMisc` (number): 
- `currency` (string, required, nullable): 
- `proposedSolution` (string, nullable): 
- `feeComments` (string, nullable): 
- `partnerWhyUsSection` (string, nullable): 
- `fullQuoteLink` (string, nullable): 
- `dateCreated` (datetime): 
- `dateUpdated` (datetime, nullable): 

```json
{
  "quoteId": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
  "quoteRequestId": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
  "partnerId": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
  "partnerName": "Muster GmbH",
  "status": "string",
  "agreementType": "string",
  "pricing": {
    "hourlyRate": 1.5,
    "hourlyEstimated": 1.5,
    "flatFeeEstimate": 2500,
    "successFeeFee": 2500,
    "hybridEstimate": 1.5,
    "costProcessMisc": 1.5
  },
  "currency": "EUR",
  "proposedSolution": "string",
  "feeComments": "Payment plan agreed with the debtor.",
  "partnerWhyUsSection": "string",
  "fullQuoteLink": "https://app.debitura.com/…",
  "dateCreated": "2026-10-01T14:05:00Z",
  "dateUpdated": "2026-10-01T14:05:00Z"
}
```

### Response 400

Invalid ID

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

### Response 404

Quote, quote request, or case not found

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

### Response 500

Internal server error

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

<a id="get-exclusive-collection-period-chain"></a>

## Get exclusive collection period chain

`GET /cases/{id}/exclusive-period`

Returns the full exclusive collection period chain for a case, including the initial period and any extensions triggered by debtor actions (promise to pay, payment agreement, or actual payment).

### Path parameters

- `id` (uuid, required): 

### Response 200

Chain returned

- `engagementStartDate` (datetime): Start date of the initial exclusivity engagement.
- `currentEndDate` (datetime): Current end date of the exclusive period (after any extensions).
- `daysRemaining` (integer): Days remaining until the period ends. Negative when the period has naturally expired.
Zero when the engagement was terminated early (partner change or withdrawal),
regardless of the original end date.
- `status` (string, nullable): Current status of the exclusive period: Active, Expired, or Terminated.
Active — partner has exclusive rights.
Expired — period ended naturally (time elapsed or case resolved).
Terminated — period was ended early (partner change, withdrawal, etc.).
- `extensions` (array of objects, nullable): Each extension event that occurred within the current engagement, in chronological order.
Empty for cases that have never had an extension triggered.
- `extensions[].type` (string, nullable): What triggered this extension: PromiseToPay, PaymentAgreement, Payment, or Manual.
- `extensions[].eventDate` (datetime): When the extension period started (i.e. when the trigger event occurred).
- `extensions[].newEndDate` (datetime): The new period end date after this extension was applied.

```json
{
  "engagementStartDate": "2026-10-01T14:05:00Z",
  "currentEndDate": "2026-10-01T14:05:00Z",
  "daysRemaining": 3,
  "status": "string",
  "extensions": [
    {
      "type": "string",
      "eventDate": "2026-10-01T14:05:00Z",
      "newEndDate": "2026-10-01T14:05:00Z"
    }
  ]
}
```

### Response 400

ID missing or empty

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

### Response 404

Case not found, does not belong to your account, or no collection period exists

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

<a id="get-full-validation-detail-for-a-case"></a>

## Get full validation detail for a case

`GET /cases/{id}/validation`

Returns the full creditor-facing validation status for a case, including the resolution area and description for each outstanding item.

**When to call:** Check `validation.needsInfo` on `GET /cases/{id}`. If `true`, call this endpoint to retrieve the item-level breakdown of what the creditor must supply.

**Safety:** Only creditor-facing resolution areas are returned. Internal areas (InternalReview, AdminReview) and sensitive fields (Rationale, Confidence) are never exposed.

### Path parameters

- `id` (uuid, required): 

### Response 200

Full validation status returned

- `needsInfo` (boolean): 
- `creditorRespondedAt` (datetime, nullable): 
- `items` (array of objects, nullable): 
- `items[].resolutionArea` (string, nullable): 
- `items[].description` (string, nullable): 

```json
{
  "needsInfo": true,
  "creditorRespondedAt": "2026-10-01T14:05:00Z",
  "items": [
    {
      "resolutionArea": "string",
      "description": "string"
    }
  ]
}
```

### Response 400

ID missing, empty, or not a collection case

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

### Response 404

Case not found or does not belong to your account

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

<a id="list-tasks-for-a-case"></a>

## List tasks for a case

`GET /cases/{id}/tasks`

Returns every open task (action-item) attached to this specific case. Same data as GET /tasks, scoped to one case — use this when you're already working a specific case and want just its outstanding tasks.

**Note:** account-level tasks that aren't tied to a single case (e.g. SignContract, AssignBankAccount — these block your whole account, not one case) never appear here; call GET /tasks to see those. The same goes for lead-scoped tasks (e.g. SelectQuoteWinner), which are attached to a lead rather than a case.

**Note:** the quote-review tasks (IncumbentLegalQuotePending, ReviewQuotes) DO appear here — they are attached to the case — but they are decided on the lead behind it, so they normally carry a `leadId` and their solutionUrl points at that lead rather than this case. On the rare row with no lead recorded, `leadId` is null and solutionUrl falls back to this case's page.

**Filtering:**
- status (default: Open) — Open or Solved
- type (repeatable, e.g. ?type=ReplyToChat) — restrict to specific task types

No pagination — a single case has few tasks.

### Path parameters

- `id` (uuid, required): 

### Query parameters

- `status` (string): 
- `type` (array of strings): 

### Response 200

Tasks returned

- `id` (uuid): The task's unique ID.
- `type` (string, nullable): Stable string code for the task type (e.g. `"ReplyToChat"`). This is the public,
additive-safe contract — it does NOT track the internal integer enum used in storage.
- `typeLabel` (string, nullable): Human-readable label for Type (e.g. "Reply to chat").
- `title` (string, nullable): Short task title, as shown in the Creditor app.
- `description` (string, nullable): Optional longer description of what the task requires.
- `status` (string, nullable): Either `"Open"` or `"Solved"`.
- `caseId` (uuid, nullable): The case (collection case / invoice) this task belongs to, when applicable.
Null for account-level tasks not tied to a single case (e.g. SignContract, AssignBankAccount).
- `caseReference` (string, nullable): Your reference for CaseId, if any.
- `leadId` (uuid, nullable): The lead this task belongs to, if any. Populated for lead-scoped tasks, and for the
quote-review tasks (`IncumbentLegalQuotePending`, `ReviewQuotes`) — which are
attached to a case but decided on the lead, so those carry both `caseId` and
`leadId`, and their `solutionUrl` points at the lead. Null for every other
task type. On the rare quote-review row with no lead recorded, `leadId` is null and
`solutionUrl` falls back to the case page — the two never disagree.
- `deadline` (datetime, nullable): When this task is due, if a deadline is set.
- `dateCreated` (datetime): When the task was created.
- `dateSolved` (datetime, nullable): When the task was resolved, if it has been.
- `solutionUrl` (string, nullable): Absolute URL — identical to the one the Creditor app itself links to — where a human can
resolve this task. Always present, regardless of whether Action is populated.
- `action` (object): A machine-readable hint pointing at the existing API call that resolves a task, e.g.
`{ "method": "POST", "path": "/cases/{caseId}/chats" }` for a chat-driven task.
            
Path uses the same `{param}` placeholder style as this API's own
documented routes — substitute in the real IDs before calling.
- `action.method` (string, nullable): HTTP method to use, e.g. `"POST"`.
- `action.path` (string, nullable): Path template for the resolving call, e.g. `"/cases/{caseId}/chats"`.
Relative to the API's base URL.

```json
[
  {
    "id": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
    "type": "string",
    "typeLabel": "string",
    "title": "string",
    "description": "string",
    "status": "string",
    "caseId": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
    "caseReference": "INV-2026-0042",
    "leadId": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
    "deadline": "2026-10-01T14:05:00Z",
    "dateCreated": "2026-10-01T14:05:00Z",
    "dateSolved": "2026-10-01T14:05:00Z",
    "solutionUrl": "https://app.debitura.com/…",
    "action": {
      "method": "string",
      "path": "string"
    }
  }
]
```

### Response 400

ID missing, or invalid status/type filter

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

### Response 404

Case not found

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```
