{
"openapi": "3.0.4",
"info": {
"title": "Debitura Collection Partner API",
"description": "Welcome to the Debitura Collection Partner API, your gateway to automating debt collection workflows on the world's leading platform for cross-border debt recovery.\n\nAs a trusted partner in Debitura's network of 500+ collection agencies and law firms across 183 jurisdictions, this API provides the following capabilities:\n\n**Managing Assigned Cases** - For exclusive partners with designated jurisdictions:\n- Retrieve and manage cases assigned to your agency\n- Track case details, timelines, and communications\n- Update case status and payment information\n\n**Submitting Cases to the Network** - Available to all partners:\n- Submit new cases on behalf of your clients to our global network\n- Track status of cases submitted to partners worldwide\n- Provide global coverage to your existing clients and earn a 20% revenue share\n- Manage cross-border debt collection through one unified platform\n\nAll operations follow our standardized Debt Collection Agreement and no-cure-no-pay model. The API provides the same functionality available through our user-friendly partner portal at https://partner.debitura.com.\n\nFor support or inquiries, please reach out to us at contact@debitura.com. To obtain your API key, log into the partner portal and navigate to: https://partner.debitura.com/CollectionPartnerApiKey/Index\n\nš Full documentation, guides, and integration walkthroughs: https://docs.debitura.com/collection-partners\n\nNOTE: Authentication requires the XApiKey header with your partner-specific API key. Available features depend on your partnership agreement.",
"contact": {
"name": "Debitura Support",
"url": "https://www.debitura.com/integration",
"email": "contact@debitura.com"
},
"version": "v1"
},
"servers": [
{
"url": "https://collectionpartner-api.debitura.com",
"description": "Production"
}
],
"paths": {
"/cases": {
"get": {
"tags": [
"Cases"
],
"summary": "List collection cases.",
"description": "Returns a paginated list of cases where you are the **collection partner** (actively collecting the debt).\n\n**What is a Collection Partner?**\nA collection partner is an agency or law firm that performs the actual debt recovery work. When you appear as the collection partner on a case, you are responsible for:\n- Contacting the debtor and attempting recovery\n- Managing the case lifecycle and status updates\n- Recording payments and fees\n- Uploading documents and evidence\n- Communicating with the creditor through the case chat\n\n**Note:** This endpoint shows cases where you are collecting. For cases you submitted on behalf of your own clients (where you are the managing partner), use the `/managed-cases` endpoint instead.\n\n**Pagination:**\n- page (default: 1) - Page number, starting from 1\n- pageSize (default: 10, max: 100) - Number of results per page\n\n**Filters:**\n- statuses - Filter by case lifecycle status (comma-separated list)\n Valid values: PendingVerification, NeedsAdditionalDetails, Leads, LeadsQuoteGiven, Active, Paused, Closed\n **Note:** Partner-specific statuses only. Internal platform statuses like 'PendingContractSigning' or 'PendingVerificationInternal' are not available here ā cases in those stages are hidden from every collection-partner-facing endpoint until Debitura's internal verification clears, regardless of assignment.\n- divisionIds - Filter by creditor division IDs (comma-separated GUIDs)\n- debtorIds - Filter by specific debtor IDs (comma-separated GUIDs)\n- ids - Filter by specific case IDs (comma-separated GUIDs)\n- includeTestCases - When true, includes test/demo cases owned by the caller. Defaults to false.\n\n**Sorting:**\n- sort - Sort field and direction (format: 'field:direction')\n Examples: 'date:desc', 'amount:asc', 'debtorName:asc'\n\n**Response:**\n- Returns InvoiceListApiDTO with page metadata and cases array\n- Page metadata includes: totalResults, currentPage, skipped, pageSize",
"parameters": [
{
"name": "Page",
"in": "query",
"schema": {
"type": "integer",
"format": "int32"
}
},
{
"name": "PageSize",
"in": "query",
"schema": {
"type": "integer",
"format": "int32"
}
},
{
"name": "DebtorIds",
"in": "query",
"schema": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
}
}
},
{
"name": "Ids",
"in": "query",
"schema": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
}
}
},
{
"name": "Statuses",
"in": "query",
"description": "Filter by case lifecycle status. Valid values: PendingContractSigning, PendingVerificationInternal,\nPendingVerification, NeedsAdditionalDetails, Leads, LeadsQuoteGiven, Active, Paused, Closed, Merged\n(case-insensitive; both name and description forms accepted).",
"schema": {
"type": "array",
"items": {
"type": "string"
}
}
},
{
"name": "DivisionIds",
"in": "query",
"description": "Optional list of division IDs to filter by",
"schema": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
}
}
},
{
"name": "Sort",
"in": "query",
"description": "Optional sorting string \"Field[:asc|desc][,Field2[:asc|desc]]ā¦\".\nValid sort fields: DateCreated, DateUpdated, DateFinished, DateCollectionStarted,\nDueDate, Date, GrossAmount, Remainder, InterestFees, CollectionFees, ReminderFees,\nLifecycle, CloseCode. Examples: 'DateCreated:desc', 'DueDate:asc'. Unknown fields are silently ignored.",
"schema": {
"type": "string"
}
},
{
"name": "includeTestCases",
"in": "query",
"description": "When true, includes test/demo cases where the caller is the owner (either as collection partner\nor as managing partner). Defaults to false.\n \nImplementation note: the spec sets CollectionPartnerIds = [callerPartnerId] as an AND filter.\nSelf-managed test cases are still returned because routing isolation guarantees\nCollectionPartnerId == ManagedByPartnerId for cases submitted by the managing partner to themselves.\nTestCaseOwnerManagedByPartnerId provides the OR-leg for non-self-routed test cases.",
"schema": {
"type": "boolean",
"default": false
}
}
],
"responses": {
"200": {
"description": "List returned",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceListDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceListDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceListDto"
}
}
}
},
"400": {
"description": "Invalid query parameters (returns specific validation errors)",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/cases/{id}": {
"get": {
"tags": [
"Cases"
],
"summary": "Fetch case by ID",
"description": "Returns detailed case information for a specific case ID (GUID).\n\n**Access Control:**\nOnly returns cases where you are the collection partner, or test/demo cases where you are the managing partner. For managed production cases, use `/managed-cases/{id}` instead.\n\n**Response Includes:**\n- Case details (reference, amount, currency, status, lifecycle stage)\n- Debtor information (name, address, contact details, company/private type)\n- Creditor information\n- Collection partner assignment details\n- Financial breakdown (principal, interest, fees)\n- Important dates (creation, assignment, due dates)\n- Geographic information (jurisdiction, country)",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "Case found",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceDto"
}
}
}
},
"400": {
"description": "ID missing, empty, or ID is not a collection case",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"404": {
"description": "Case not found, deleted, or not assigned to you as collection partner",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/cases/case-reference/{caseReference}": {
"get": {
"tags": [
"Cases"
],
"summary": "Fetch case by reference",
"description": "Returns detailed case information using the Debitura case reference (e.g., 'Q8OAXF3W').\n\n**Use Case:**\nUse this endpoint when you have the Debitura case reference (visible in the partner portal and emails) but not the GUID. This is helpful for customer service integrations or when referencing cases in communications.\n\n**Access Control:**\nOnly returns cases where you are the collection partner, or test/demo cases where you are the managing partner. For managed production cases, use `/managed-cases/case-reference/{reference}`.",
"parameters": [
{
"name": "caseReference",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Case found",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceDto"
}
}
}
},
"400": {
"description": "Reference missing or reference is not a collection case",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"404": {
"description": "Reference not found or not assigned to you as collection partner",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/cases/by-partner-reference/{reference}": {
"get": {
"tags": [
"Cases"
],
"summary": "Fetch a single case by the collection partner's own reference ID.",
"description": "Returns detailed case information using the collection partner's own reference (the `CollectionPartnerReference` field set during case activation).\n\n**Use Case:**\nUse this endpoint when you have your own internal case reference and want to look up the corresponding Debitura case. This is useful for integrating your case management system with Debitura.\n\n**Matching:**\nExact string match only. Combined references like '112179442 & 112179443' must be queried with the full combined string.\n\n**Access Control:**\nOnly returns cases where you are the collection partner and the case is a production collection case.",
"parameters": [
{
"name": "reference",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Case found",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceDto"
}
}
}
},
"400": {
"description": "Reference missing or empty",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"404": {
"description": "No case found with this partner reference",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/cases/by-partner-reference": {
"get": {
"tags": [
"Cases"
],
"summary": "Batch lookup of cases by the collection partner's own reference IDs.",
"description": "Returns a dictionary mapping each partner reference to its corresponding case details.\n\n**Use Case:**\nUse this endpoint to look up multiple cases at once using your own internal reference IDs. This is more efficient than making individual calls for each reference.\n\n**Parameters:**\n- references (required) - Comma-separated list of partner reference strings (max 100)\n\n**Matching:**\nExact string match only. References not found or not assigned to you are omitted from the response (no error).\n\n**Response:**\nA dictionary where keys are the partner reference strings and values are the case details. Missing references are silently omitted.",
"parameters": [
{
"name": "references",
"in": "query",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Dictionary of reference to case",
"content": {
"text/plain": {
"schema": {
"type": "object",
"additionalProperties": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceDto"
}
}
},
"application/json": {
"schema": {
"type": "object",
"additionalProperties": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceDto"
}
}
},
"text/json": {
"schema": {
"type": "object",
"additionalProperties": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceDto"
}
}
}
}
},
"400": {
"description": "References parameter missing, empty, or exceeds maximum",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/cases/by-creditor-reference": {
"get": {
"tags": [
"Cases"
],
"summary": "Fetch a single case by creditor reference, scoped to a specific creditor and partner.",
"description": "Returns detailed case information using the creditor's own reference (`CreditorReference`) scoped to a specific creditor.\n\n**Use Case:**\nUse this endpoint when you have the creditor's reference (e.g. from an invoice file or payment import) and need to look up the corresponding Debitura case. Because `CreditorReference` is only unique within a single creditor, you must also supply `creditorId` to make the lookup unambiguous.\n\n**Matching:**\nExact string match on `CreditorReference`. The case must also belong to the specified creditor and be assigned to the calling partner.\n\n**Access Control:**\nOnly returns production collection cases where you are the collection partner. The `creditorId` parameter scopes the lookup to a specific creditor ā you can only retrieve cases for creditors whose cases are assigned to you.",
"parameters": [
{
"name": "reference",
"in": "query",
"schema": {
"type": "string"
}
},
{
"name": "creditorId",
"in": "query",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "Case found",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceDto"
}
}
}
},
"400": {
"description": "Reference or creditorId missing or empty",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"404": {
"description": "No case found for this reference + creditor combination, or not assigned to you",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/cases/{id}/timeline": {
"get": {
"tags": [
"Cases"
],
"summary": "Fetch case timeline",
"description": "Returns the complete chronological event history for a case along with the current engagement phase.\n\n**Timeline Events Include:**\n- Case assignment to collection partner\n- Status changes and lifecycle transitions\n- Payment recordings\n- Document uploads\n- Communication events\n- Fee additions\n- Manual updates and notes\n- System-generated events\n\n**Response shape:**\n- `items` ā chronological list of timeline events\n- `currentEngagementPhase` ā current phase of the active engagement: \"Pre-legal\", \"Legal\", or \"Enforcement\". Null when no active engagement exists.\n\n**Use Case:**\nUse this to track case progress, understand case history, audit actions, or display activity to users. Timeline events are ordered chronologically and include timestamps, event types, titles, and descriptions.\n\n**Note:** Timeline is filtered to show partner-relevant events only.",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "Timeline returned",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.CaseTimelineResponse"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.CaseTimelineResponse"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.CaseTimelineResponse"
}
}
}
},
"400": {
"description": "Case ID missing or empty",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"404": {
"description": "Case not found or not assigned to you as collection partner",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/cases/{id}/chats": {
"get": {
"tags": [
"Cases"
],
"summary": "Fetch case chats",
"description": "Returns all chat messages for a case in chronological order.\n\n**Chat Participants:**\n- Collection partner (you) - Messages from your team\n- Creditor - Messages from the client who owns the debt\n- Debitura support - System notifications and support messages\n- Managing partner (if applicable) - Messages from the partner who submitted the case\n\n**Message Details Include:**\n- Message content and timestamp\n- Sender information (name, role)\n- Message type (text, system notification, file attachment reference)\n- Read status and delivery information\n\n**Use Case:**\nUse this endpoint to build case communication interfaces, retrieve conversation history, or integrate case discussions into your systems. Perfect for customer service tools or partner portals.\n\n**Note:** If the case has no thread or messages, an empty array is returned.",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "Chats returned (empty array if no messages)",
"content": {
"text/plain": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Chats.ChatDto"
}
}
},
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Chats.ChatDto"
}
}
},
"text/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Chats.ChatDto"
}
}
}
}
},
"400": {
"description": "Case ID missing or empty",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"404": {
"description": "Case not found or not assigned to you as collection partner",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
},
"post": {
"tags": [
"Cases"
],
"summary": "Send a chat message on a case",
"description": "Posts a new chat message on a case, visible to both the collection partner and the creditor.\n\n**Message Details:**\n- The message is attributed to the team member identified by `userId`\n- The creditor will receive an email notification about the new message\n- A task is created in the Debitura platform for the creditor to review the message\n- Messages appear in the case chat timeline in chronological order\n\n**Prerequisites:**\n- The case must exist and be assigned to you as collection partner\n- The `userId` must be a valid user ID from `GET /users` belonging to your team\n\n**Use Case:**\nUse this endpoint to communicate with creditors about case progress, request additional information, or provide status updates. Messages sent via this endpoint are equivalent to messages sent through the partner portal chat.",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "Idempotency-Key",
"in": "header",
"description": "Optional idempotency key (max 255 characters). If the same key is reused with an identical message body within 24 hours, the originally created chat message is returned instead of posting a duplicate. The key is scoped per partner, case, and message body ā reusing it with a different body posts a new message rather than returning a conflict.",
"schema": {
"maxLength": 255,
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json-patch+json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Chats.SendChatRequest"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Chats.SendChatRequest"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Chats.SendChatRequest"
}
},
"application/*+json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Chats.SendChatRequest"
}
}
}
},
"responses": {
"200": {
"description": "Chat message sent successfully (or duplicate idempotency key ā existing response returned)",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Chats.ChatDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Chats.ChatDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Chats.ChatDto"
}
}
}
},
"400": {
"description": "Validation error ā missing fields, invalid userId, or invalid request body",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"404": {
"description": "Case not found or not assigned to this collection partner",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/cases/{id}/payments": {
"get": {
"tags": [
"Cases"
],
"summary": "Fetch case payments",
"description": "Returns all payments recorded on a specific case.\n\n**Payment Information Includes:**\n- Payment amount and currency\n- Payment date (when received)\n- Payment type (full payment, partial payment, settlement)\n- Payment method (bank transfer, card, cash, etc.)\n- Payment status (pending, confirmed, reconciled)\n- Reference information\n- Allocation breakdown (principal, interest, fees)\n\n**Use Case:**\nUse this endpoint to:\n- Track payment history for a case\n- Reconcile payments with your records\n- Display payment status to users\n- Calculate outstanding balances\n- Generate financial reports\n\n**Note:** Only payments associated with this specific case are returned. All payments are returned in reverse chronological order (newest first).",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "Payments returned (may be empty array)",
"content": {
"text/plain": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.PaymentDto"
}
}
},
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.PaymentDto"
}
}
},
"text/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.PaymentDto"
}
}
}
}
},
"400": {
"description": "Case ID missing or empty",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"404": {
"description": "Case not found or not assigned to you as collection partner",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
},
"post": {
"tags": [
"Cases"
],
"summary": "Create a payment on a case",
"description": "Records a payment received for a collection case.\n\n**Use Case:**\nUse this endpoint when you receive a payment from the debtor. Provide the payment amount and, in the normal case, nothing else for the split ā **omit both PayoutCreditor and PayoutCollectionPartner** and Debitura computes the creditor/partner split server-side from the case's pricing terms (success fee). This is the default and recommended usage for almost every integration.\n\n**Advanced override ā PayoutCreditor / PayoutCollectionPartner:**\nSupplying both fields lets you dictate the split explicitly instead of using the computed one. This is an **advanced, opt-in override** for legitimate edge cases (e.g. a negotiated split where the collection partner already holds funds) ā it is not the normal path and most integrations should never set it. When supplied:\n- Both fields are required together, and MUST sum to PaymentAmount (within 0.01 tolerance).\n- The response's `Warnings` array surfaces (without blocking the request) if the split allocates zero to the creditor, or if the case had no outstanding balance before this payment ā both are signs of a misconfigured or duplicate payment and should be reviewed.\n\n**Currency:** Payment must be in the same currency as the invoice. The currency is automatically determined from the case.\n\n**PaymentRecipient Options:**\n- **Creditor** - Payment was received by the creditor (your client). When using this option, you MUST also specify CommissionPaymentStatus.\n- **CollectionPartner** - Payment was received by you (the collection partner). Commission is automatically marked as Paid since you already have the funds.\n\n**CommissionPaymentStatus:**\nThis field tracks whether the collection partner's commission has been paid. It's only required when PaymentRecipient is 'Creditor'.\n- **Paid** - The creditor has already paid your commission\n- **Unpaid** - The creditor has not yet paid your commission\n\nNote: When PaymentRecipient is 'CollectionPartner', this field is automatically set to 'Paid' since you already have the money.\n\n**Critical Validation:**\n- PayoutCreditor and PayoutCollectionPartner are optional but must be supplied together. When supplied, they MUST equal PaymentAmount (within 0.01 tolerance). When omitted (recommended), the split is computed from the case terms.\n- An explicit split that zeroes the creditor, or that is supplied on an already-settled (zero-remainder) case, is accepted but surfaced as a warning in the response ā not blocked.\n- CommissionPaymentStatus is required only if PaymentRecipient is 'Creditor'\n\n**Payment Flow:**\n1. Full Payment (payment >= outstanding):\n - If CloseCase=true ā closes case with 'Paid' status\n - If CloseCase=false ā case remains open\n\n2. Partial Payment (payment < outstanding):\n - The payment is recorded regardless of CloseCase. The case is NOT closed (CloseCase is honoured only when the payment fully settles the balance) and no error is returned.\n - To close on a partial payment, use the close endpoint with the PartiallyPaid close code.",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "Idempotency-Key",
"in": "header",
"description": "Optional 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 `Type: \"IdempotencyConflict\"`. Field-level 400 validation errors are not stored, so you may fix the request and retry with the same key.",
"schema": {
"maxLength": 255,
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json-patch+json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.CreatePaymentRequest"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.CreatePaymentRequest"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.CreatePaymentRequest"
}
},
"application/*+json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.CreatePaymentRequest"
}
}
}
},
"responses": {
"200": {
"description": "Payment created successfully (or duplicate Idempotency-Key ā the original response is replayed). Check the Warnings array for non-blocking advisory notices (e.g. about an explicit payout-split override).",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.CreatePaymentResponse"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.CreatePaymentResponse"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.CreatePaymentResponse"
}
}
}
},
"400": {
"description": "Invalid request (validation errors)",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"404": {
"description": "Case not found or not assigned to you",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"409": {
"description": "A request with this Idempotency-Key is already in progress. Retry after the indicated delay.",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"422": {
"description": "The Idempotency-Key has already been used with a different request body.",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"500": {
"description": "Server error occurred",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/cases/{id}/files": {
"get": {
"tags": [
"Cases"
],
"summary": "Get case files",
"description": "Returns all documents and files attached to a case.\n\n**File Types Include:**\n- OriginalInvoice - The initial invoice/claim document\n- ProofOfDelivery - Delivery confirmations\n- Contract - Agreements and contracts\n- Correspondence - Email and letter communications\n- PaymentProof - Payment receipts and confirmations\n- CourtDocuments - Legal filings and court papers\n- Other - Miscellaneous supporting documents\n\n**File Information Includes:**\n- File ID and case ID\n- File name and description/label\n- Document type classification\n- Upload timestamps (created, updated)\n- Download URL (temporary, signed link)\n- File metadata\n\n**Use Case:**\nUse this endpoint to:\n- Retrieve evidence and supporting documents\n- Display case files in partner portals\n- Download documents for offline review\n- Build document management interfaces\n- Audit document completeness\n\n**Note:** File URLs are temporary signed links that expire after a period. Generate new URLs by calling this endpoint again if links expire.",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "Files retrieved successfully (may be empty array)",
"content": {
"text/plain": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Files.CaseFileDto"
}
}
},
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Files.CaseFileDto"
}
}
},
"text/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Files.CaseFileDto"
}
}
}
}
},
"400": {
"description": "Case ID missing or empty",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"404": {
"description": "Case not found or not assigned to you as collection partner",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"500": {
"description": "Server error occurred while retrieving files",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
},
"post": {
"tags": [
"Cases"
],
"summary": "Upload a file to a case",
"description": "Uploads a file and attaches it to a case. Mirrors the file upload action available in the Partner portal.\n\n**Access:** Collection partners only. Managing partners are rejected.\n\n**Status gate:** Allowed on all non-Merged statuses, including Closed. Only Merged cases are rejected.\n\n**File requirements:**\n- Maximum size: 25 MB\n- Allowed extensions: `.pdf` `.doc` `.docx` `.xls` `.xlsx` `.jpg` `.jpeg` `.png` `.txt` `.zip` `.csv` `.eml`\n\n**DocumentType (optional):**\n- `OriginalInvoice` ā the original invoice document\n- `DebtorDocuments` ā documents provided by the debtor\n- `CreditorDocuments` ā documents provided by the creditor\n- `PartnerDocuments` ā documents provided by the collection partner\n- `DemandLetter` ā formal demand letter\n- `Miscellaneous` ā other supporting documents\n\nThe file is immediately visible to the creditor.",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"requestBody": {
"content": {
"multipart/form-data": {
"schema": {
"type": "object",
"properties": {
"File": {
"type": "string",
"description": "The file to upload. Required.\nAllowed extensions: .pdf .doc .docx .xls .xlsx .jpg .jpeg .png .txt .zip .csv .eml\nMaximum size: 25 MB.",
"format": "binary"
},
"DocumentType": {
"type": "string",
"description": "Optional document type / category. Omit (or pass null) to leave uncategorised.\nValid values: DebtorDocuments, CreditorDocuments, PartnerDocuments, OriginalInvoice, DemandLetter, Miscellaneous."
},
"Description": {
"type": "string",
"description": "Optional free-text description / label for the file (max 500 characters)."
}
}
},
"encoding": {
"File": {
"style": "form"
},
"DocumentType": {
"style": "form"
},
"Description": {
"style": "form"
}
}
}
}
},
"responses": {
"200": {
"description": "File uploaded successfully",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Files.CaseFileDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Files.CaseFileDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Files.CaseFileDto"
}
}
}
},
"400": {
"description": "Invalid request ā missing file, unsupported extension, or request validation error",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"404": {
"description": "Case not found or not assigned to this collection partner",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"409": {
"description": "Case is Merged and cannot accept new files",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"413": {
"description": "File exceeds the 25 MB size limit",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"415": {
"description": "Unsupported file extension",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/cases/{id}/notes": {
"post": {
"tags": [
"Cases"
],
"summary": "Create a note on a case",
"description": "Creates a new note/comment on a collection case.\n\n**Use Case:**\nUse this endpoint to document activities, record conversations, add reminders, or log any relevant information about the case. Notes are automatically shared with the creditor.\n\n**Validation:**\n- Description is required (max 10000 characters)\n- EventDate must not be in the future (if provided)\n\n**EventDate:**\nSupply EventDate to back-date the note to the time the event actually occurred. For example, if a phone call happened three days ago, pass that date so the timeline reflects the real event order. Omit for real-time notes.",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"requestBody": {
"content": {
"application/json-patch+json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Notes.CreateNoteRequest"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Notes.CreateNoteRequest"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Notes.CreateNoteRequest"
}
},
"application/*+json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Notes.CreateNoteRequest"
}
}
}
},
"responses": {
"200": {
"description": "Note created successfully",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Notes.NoteDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Notes.NoteDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Notes.NoteDto"
}
}
}
},
"400": {
"description": "Invalid request (missing required fields, EventDate in the future, or validation errors)",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"404": {
"description": "Case not found or not assigned to you",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"500": {
"description": "Server error occurred",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/cases/{id}/payments/{paymentId}": {
"put": {
"tags": [
"Cases"
],
"summary": "Edit a payment on a case",
"description": "Edits an existing payment on a collection case. Mirrors the payout-split semantics of the create-payment endpoint.\n\n**Payout Split:** supply both PayoutCreditor and PayoutCollectionPartner to set the split explicitly (they must sum to PaymentAmount), or omit both to have it recomputed from the case's pricing terms.\n\n**Invoiced payments are frozen:** a payment whose payout has already been invoiced (Stripe/QBO) cannot be edited and returns **422 Unprocessable Entity**. This protects the issued accounting entry from silent drift.\n\n**Reopen consent:** if the edit lowers the payment so a previously closed (Paid) case is left with a positive outstanding balance, the case must be reopened. By default this returns **409 Conflict**; resend with `reopenCaseIfNeeded: true` to confirm ā the case is reopened to Active and a `case.updated` webhook fires.",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "paymentId",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"requestBody": {
"content": {
"application/json-patch+json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.UpdatePaymentRequest"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.UpdatePaymentRequest"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.UpdatePaymentRequest"
}
},
"application/*+json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.UpdatePaymentRequest"
}
}
}
},
"responses": {
"200": {
"description": "Payment updated successfully",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.PaymentDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.PaymentDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.PaymentDto"
}
}
}
},
"400": {
"description": "Invalid request (validation errors)",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"404": {
"description": "Case or payment not found / not assigned to you",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"409": {
"description": "Edit would reopen the case; resend with reopenCaseIfNeeded=true",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"422": {
"description": "Payment has already been invoiced and cannot be edited",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"500": {
"description": "Server error occurred",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
},
"delete": {
"tags": [
"Cases"
],
"summary": "Delete a payment on a case",
"description": "Deletes a payment from a collection case, reverting its effect on the case balance and cascading the payout deletion. A durable audit record of the deletion is retained.\n\n**Invoiced payments are frozen:** a payment whose payout has already been invoiced (Stripe/QBO) cannot be deleted and returns **422 Unprocessable Entity**.\n\n**Reopen consent:** if deleting the payment leaves a previously closed (Paid) case with a positive outstanding balance, the case must be reopened. By default this returns **409 Conflict**; resend with `reopenCaseIfNeeded=true` to confirm ā the case is reopened to Active and a `case.updated` webhook fires.",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "paymentId",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "reopenCaseIfNeeded",
"in": "query",
"schema": {
"type": "boolean",
"default": false
}
}
],
"responses": {
"204": {
"description": "Payment deleted successfully"
},
"400": {
"description": "Invalid request",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"404": {
"description": "Case or payment not found / not assigned to you",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"409": {
"description": "Deletion would reopen the case; resend with reopenCaseIfNeeded=true",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"422": {
"description": "Payment has already been invoiced and cannot be deleted",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"500": {
"description": "Server error occurred",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/cases/{id}/close": {
"post": {
"tags": [
"Cases"
],
"summary": "Close a case",
"description": "Closes a collection case with a specified close code.\n\n**Use Case:**\nUse this endpoint to formally close a case when collection is complete or cannot continue. The close code determines the reason and impacts reporting.\n\n**Close Code Validation:**\n- **Paid**: Requires at least one payment AND total payments >= outstanding amount\n- **PartiallyPaid**: Requires at least one payment AND total payments < outstanding amount\n- **All other codes**: No payment requirements\n\n**Valid Close Codes:**\n- **Paid** - Full payment received from debtor\n- **PartiallyPaid** - Some payment received but not full amount\n- **DebtorInsolventBankrupt** - Debtor declared bankruptcy or insolvent\n- **DebtorUntraceable** - Unable to locate or contact debtor\n- **DisputedLegalActionDeclinedByClient** - Debt disputed, creditor declined legal action\n- **WithdrawnByClient** - Creditor requested case withdrawal\n- **PreLegalExhaustedNoPayment** - All pre-legal attempts exhausted without payment\n- **StatuteOfLimitationsExpired** - Legal time limit to collect has passed\n- **SettlementRejectedByClient** - Proposed settlement rejected by creditor\n- **UnresponsiveClient** - Creditor not responding to collection partner\n- **Other** - Other reason (please provide comment)",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"requestBody": {
"content": {
"application/json-patch+json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.Requests.CloseCaseRequest"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.Requests.CloseCaseRequest"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.Requests.CloseCaseRequest"
}
},
"application/*+json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.Requests.CloseCaseRequest"
}
}
}
},
"responses": {
"200": {
"description": "Case closed successfully",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.CloseCaseResponse"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.CloseCaseResponse"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.CloseCaseResponse"
}
}
}
},
"400": {
"description": "Invalid request (validation errors)",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"404": {
"description": "Case not found or not assigned to you",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"500": {
"description": "Server error occurred",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/cases/{id}/start": {
"post": {
"tags": [
"Cases"
],
"summary": "Activate a case from PendingVerification",
"description": "Transitions a case from `PendingVerification` ā `Active`, officially accepting it for debt collection.\n\n**Prerequisites:**\n- The case must be in `PendingVerification` status (returns 400 otherwise)\n- The case must not require custom terms (non-standard agreement). Cases outside the standard pre-legal scope ā where the claim type is not an unpaid invoice or loan repayment, or where a dispute exists ā require negotiation in the partner portal and cannot be activated via this API (returns 400 with a descriptive error).\n- The `userId` must be a valid user ID from `GET /users` belonging to your team (returns 400 if not found)\n- The `assignedUserId`, if provided, must also be a valid user ID from `GET /users` belonging to your team (returns 400 if not found)\n\n**What happens on activation:**\n1. Case lifecycle transitions to Active\n2. A welcome message is sent to the creditor via email notification, attributed to the user identified by `userId`\n3. The welcome message is posted as a chat message in the case thread, attributed to the user identified by `userId`\n4. Any pending verification tasks are automatically resolved\n\n**Fee fields:**\nThe `interestFees`, `reminderFees`, and `collectionFees` fields update the corresponding fee amounts on the case, in the case currency. Default to 0.00 if not provided.\n\n**userId vs assignedUserId:**\n`userId` is required and identifies who is sending the welcome message (the actor). `assignedUserId` is optional and identifies who the case is assigned to for ongoing handling. They can be the same person or different team members. Use `GET /users` to retrieve valid user IDs.",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"requestBody": {
"content": {
"application/json-patch+json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.Requests.StartCaseRequest"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.Requests.StartCaseRequest"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.Requests.StartCaseRequest"
}
},
"application/*+json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.Requests.StartCaseRequest"
}
}
}
},
"responses": {
"200": {
"description": "Case activated successfully",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.StartCaseResponse"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.StartCaseResponse"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.StartCaseResponse"
}
}
}
},
"400": {
"description": "Validation error ā case not in PendingVerification, requires custom terms, invalid assignedUserId, or invalid request body",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"404": {
"description": "Case not found or not assigned to this collection partner",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/cases/{id}/fees": {
"put": {
"tags": [
"Cases"
],
"summary": "Update case fees and/or principal",
"description": "Updates the interest, reminder, and collection fees ā and optionally the principal (GrossAmount) ā on a case.\n\nAll provided values replace the current values. The `grossAmount` field is optional and backward-compatible: omitting it leaves the principal unchanged.\n\nFees typically change over time as collection activity progresses ā for example due to legal costs, attorney fees, investigation charges, or other events.\n\n**When `grossAmount` is supplied:**\n- Both increases and decreases are allowed (no restriction on direction)\n- The pre-legal success fee (commission) is silently recalculated and returned in the response\n- The outstanding remainder is recalculated to reflect the new principal\n- A timeline audit event is written recording the change (From/To principal and fees)\n\n**Prerequisites:**\n- The case must be assigned to this collection partner\n- The case must **not** be Closed or Merged (returns 400 otherwise)\n- All amounts must be ā„ 0 (negative values rejected)",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"requestBody": {
"content": {
"application/json-patch+json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.Requests.UpdateCaseFeesRequest"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.Requests.UpdateCaseFeesRequest"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.Requests.UpdateCaseFeesRequest"
}
},
"application/*+json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.Requests.UpdateCaseFeesRequest"
}
}
}
},
"responses": {
"200": {
"description": "Fees updated successfully",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.UpdateCaseFeesResponse"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.UpdateCaseFeesResponse"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.UpdateCaseFeesResponse"
}
}
}
},
"400": {
"description": "Validation error ā invalid values, case is Closed or Merged, or confirmPriceChange=true was sent on a deliberately-set rate (accepted quote / manual override), which is preserve-only on this API ā resubmit with keepIntentionalRate=true instead.",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"404": {
"description": "Case not found or not assigned to this collection partner",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"409": {
"description": "Price-change confirmation required ā the principal edit would move the success fee by >0.1%. For a standard rate, resubmit with confirmPriceChange=true to re-price. For a deliberately-set rate (accepted quote / manual override) the rate is preserve-only: resubmit with keepIntentionalRate=true to apply the edit and keep the special rate ā partners cannot override it (sending confirmPriceChange=true on such a case is rejected with 400).",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.PriceChangeConfirmationResponse"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.PriceChangeConfirmationResponse"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.PriceChangeConfirmationResponse"
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/cases/{id}/exclusive-period": {
"get": {
"tags": [
"Cases"
],
"summary": "Get exclusive collection period chain",
"description": "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).",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "Chain returned",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.ExclusivePeriodDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.ExclusivePeriodDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.ExclusivePeriodDto"
}
}
}
},
"400": {
"description": "ID missing, empty, or ID is not a collection case",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"404": {
"description": "Case not found, not assigned to you, or no collection period exists",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/cases/{id}/validation": {
"get": {
"tags": [
"Cases"
],
"summary": "Get full validation detail for a case",
"description": "Returns the full creditor-facing validation status for a case, including the resolution area and description for each outstanding item.\n\n**When to call:** Check `validation.needsInfo` on `GET /cases/{id}`. If `true`, call this endpoint to retrieve the item-level breakdown of what must be supplied.\n\n**Access Control:** Same as `GET /cases/{id}` ā only accessible when you are the collection partner (or managing partner on test cases).\n\n**Safety:** Only creditor-facing resolution areas are returned. Internal areas (InternalReview, AdminReview) and sensitive fields (Rationale, Confidence) are never exposed.",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "Full validation status returned",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Domain.Services.CaseValidation.CaseValidationStatusDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Domain.Services.CaseValidation.CaseValidationStatusDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Domain.Services.CaseValidation.CaseValidationStatusDto"
}
}
}
},
"400": {
"description": "ID missing, empty, or not a collection case",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"404": {
"description": "Case not found or not accessible",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/ingestion-jobs": {
"post": {
"tags": [
"IngestionJobs"
],
"summary": "Enqueue a batch of partner ingest events (notes, payments, status updates).",
"description": "Creates one AsyncJob of type PartnerIngestDispatch and one AsyncJobOperation per row.\nThe job is processed asynchronously; poll GET /ingestion-jobs/{jobId} for progress.\n \nCurrently supported row types: Note (type = 0).\nPayment and StatusUpdate types are reserved for future use and will return 400 if submitted.",
"parameters": [
{
"name": "Idempotency-Key",
"in": "header",
"description": "Optional 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 `Type: \"IdempotencyConflict\"`. Field-level 400 validation errors are not stored, so you may fix the request and retry with the same key.",
"schema": {
"maxLength": 255,
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json-patch+json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.CollectionPartnerApi.Controllers.CreateIngestionJobRequest"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.CollectionPartnerApi.Controllers.CreateIngestionJobRequest"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.CollectionPartnerApi.Controllers.CreateIngestionJobRequest"
}
},
"application/*+json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.CollectionPartnerApi.Controllers.CreateIngestionJobRequest"
}
}
}
},
"responses": {
"202": {
"description": "Job accepted",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.CollectionPartnerApi.Controllers.CreateIngestionJobResponse"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.CollectionPartnerApi.Controllers.CreateIngestionJobResponse"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.CollectionPartnerApi.Controllers.CreateIngestionJobResponse"
}
}
}
},
"400": {
"description": "Invalid request",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/ingestion-jobs/{jobId}": {
"get": {
"tags": [
"IngestionJobs"
],
"summary": "Poll the status of a previously submitted ingestion job.",
"description": "Returns current status and per-operation counts for the job.",
"parameters": [
{
"name": "jobId",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "Job found",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.CollectionPartnerApi.Controllers.IngestionJobStatusResponse"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.CollectionPartnerApi.Controllers.IngestionJobStatusResponse"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.CollectionPartnerApi.Controllers.IngestionJobStatusResponse"
}
}
}
},
"404": {
"description": "Job not found or not owned by this partner",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/managed-cases": {
"post": {
"tags": [
"ManagedCases"
],
"summary": "Create case as managing partner",
"description": "Creates a collection case on behalf of your client (or yourself) through the Debitura platform.\n\n**Understanding the Creditor Field:**\nThe creditor is the party that the debtor owes money to. This can be:\n- **Your client's company** - When you're submitting cases on behalf of clients you represent\n- **Your own company** - When you're submitting your own debt collection cases\n\n**How It Works:**\n1. You provide the creditor's basic information (company name + country)\n2. Debitura creates a creditor record (if one doesn't exist)\n3. The collection case is created under that creditor\n4. You are set as the managing partner\n5. The case is automatically assigned to a collection partner based on jurisdiction\n\n**Managing Partner Benefits:**\n- Submit cases on behalf of your clients via API\n- Maintain your client relationships\n- Leverage Debitura's global partner network\n- Monitor case progress through read-only access\n- Provide full-service debt recovery to your clients\n\n**Required Fields:**\n- CreditorCompanyName - The company name of who the debtor owes money to\n- CreditorCountryAlpha2 OR CreditorCountry - Creditor's country (provide either code or name)\n- CurrencyCode - Case currency (e.g., 'USD', 'EUR', 'DKK')\n- Date - Invoice issue date\n- AmountToRecover - Claim amount\n- Debtor - Complete debtor information with jurisdiction\n\n**Debtor Rules:**\n- debtor.type must be \"Company\" or \"Person\"\n - Company ā debtor.name is mandatory (company name)\n - Person ā debtor.name is mandatory (person's full name)\n- For Company debtors, debtor.contactPerson is required\n- debtor.country (or debtor.countryAlpha2) is always required\n- debtor.stateAlpha2 is **required for US cases** - provide the two-letter state code (e.g., \"CA\", \"NY\"). For non-US cases, this field is optional.\n- debtor.state is a general-purpose region field (not used for US jurisdiction resolution)\n\n**Optional Fields:**\n- DueDate - Invoice due date\n- Comments - Additional notes\n- ClaimDescription - Description of the claim\n- CreditorReference - Your client's internal reference\n- CollectionPartnerId - Override automatic partner matching\n- IsTest - Mark as test case (excluded from production metrics)\n\n**Response:**\nReturns the created case details including the case ID, reference number, and assignment information.\n\n**Important Notes:**\n- Creditor records are created fresh each time (no duplicate detection)\n- Contract requirements are automatically bypassed\n- Cases appear in your 'Managed Cases' list\n- You have read-only access to monitor case progress",
"parameters": [
{
"name": "Idempotency-Key",
"in": "header",
"description": "Optional 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 `Type: \"IdempotencyConflict\"`. Field-level 400 validation errors are not stored, so you may fix the request and retry with the same key.",
"schema": {
"maxLength": 255,
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json-patch+json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.Requests.CreateManagedCaseRequest"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.Requests.CreateManagedCaseRequest"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.Requests.CreateManagedCaseRequest"
}
},
"application/*+json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.Requests.CreateManagedCaseRequest"
}
}
}
},
"responses": {
"200": {
"description": "Case created successfully",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceDto"
}
}
}
},
"400": {
"description": "Invalid request data (field validation errors)",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"422": {
"description": "Business rule violation (e.g., no partner available for jurisdiction)",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.BusinessErrorResponseApiDTO"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.BusinessErrorResponseApiDTO"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.BusinessErrorResponseApiDTO"
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
},
"get": {
"tags": [
"ManagedCases"
],
"summary": "List managed cases",
"description": "Returns a paginated list of cases where you are the **managing partner** (submitted on behalf of your clients).\n\n**What is a Managing Partner?**\nA managing partner is a collection partner that submits cases on behalf of their own clients but forwards the actual debt recovery work to another collection partner in Debitura's network. You remain your client's point of contact while leveraging Debitura's global network of 500+ partners across 183 jurisdictions.\n\n**Why Become a Managing Partner?**\n- Serve clients globally without physical presence in every jurisdiction\n- Maintain client relationships while outsourcing collection work\n- Access Debitura's vetted partner network\n- Earn commission on successful recoveries\n- Provide full-service debt recovery to your clients\n\n**Your Role as Managing Partner:**\n- Submit cases on behalf of your clients (via API or partner portal)\n- Monitor case progress and recovery status (read-only access)\n- Communicate with the collection partner through case chat\n- Receive updates on payments and case status\n- Invoice your clients and remit payments\n\n**Note:** This endpoint shows cases YOU submitted. For cases where you are actively collecting, use the `/cases` endpoint instead.\n\n**Partner Portal View:** These cases appear in the 'Cases Submitted' section of the partner portal.\n\n**Pagination:**\n- page (default: 1) - Page number, starting from 1\n- pageSize (default: 10, max: 100) - Number of results per page\n\n**Filters:**\n- statuses - Filter by case lifecycle status (comma-separated list)\n Valid values: PendingContractSigning, PendingVerificationInternal, PendingVerification,\n NeedsAdditionalDetails, Leads, LeadsQuoteGiven, Active, Paused, Closed\n- divisionIds - Filter by your client division IDs (comma-separated GUIDs)\n- debtorIds - Filter by specific debtor IDs (comma-separated GUIDs)\n- ids - Filter by specific case IDs (comma-separated GUIDs)\n\n**Sorting:**\n- sort - Sort field and direction (format: 'field:direction')\n Examples: 'date:desc', 'amount:asc', 'debtorName:asc'\n\n**Response:**\n- Returns InvoiceListApiDTO with page metadata and cases array\n- Each case includes collection partner information (who is actually collecting)\n- Page metadata includes: totalResults, currentPage, skipped, pageSize",
"parameters": [
{
"name": "Page",
"in": "query",
"schema": {
"type": "integer",
"format": "int32"
}
},
{
"name": "PageSize",
"in": "query",
"schema": {
"type": "integer",
"format": "int32"
}
},
{
"name": "DebtorIds",
"in": "query",
"schema": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
}
}
},
{
"name": "Ids",
"in": "query",
"schema": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
}
}
},
{
"name": "Statuses",
"in": "query",
"description": "Filter by case lifecycle status. Valid values: PendingContractSigning, PendingVerificationInternal,\nPendingVerification, NeedsAdditionalDetails, Leads, LeadsQuoteGiven, Active, Paused, Closed, Merged\n(case-insensitive; both name and description forms accepted).",
"schema": {
"type": "array",
"items": {
"type": "string"
}
}
},
{
"name": "DivisionIds",
"in": "query",
"description": "Optional list of division IDs to filter by",
"schema": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
}
}
},
{
"name": "Sort",
"in": "query",
"description": "Optional sorting string \"Field[:asc|desc][,Field2[:asc|desc]]ā¦\".\nValid sort fields: DateCreated, DateUpdated, DateFinished, DateCollectionStarted,\nDueDate, Date, GrossAmount, Remainder, InterestFees, CollectionFees, ReminderFees,\nLifecycle, CloseCode. Examples: 'DateCreated:desc', 'DueDate:asc'. Unknown fields are silently ignored.",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "List returned",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceListDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceListDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceListDto"
}
}
}
},
"400": {
"description": "Invalid query parameters (returns specific validation errors)",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/managed-cases/{id}": {
"get": {
"tags": [
"ManagedCases"
],
"summary": "Fetch managed case by ID",
"description": "Returns detailed information for a case you submitted on behalf of your client (where you are the managing partner).\n\n**Access Control:**\nThis endpoint only returns cases where YOU are the managing partner. If you are the collection partner on a case, use `/cases/{id}` instead.\n\n**Response Includes:**\n- Case details (reference, amount, currency, status)\n- Debtor information\n- Your client information (the creditor)\n- Collection partner details (who is actively collecting this case)\n- Financial breakdown\n- Case progress and timeline summary\n\n**Monitoring Your Cases:**\nAs the managing partner, you have read-only access to monitor progress while the collection partner handles the actual recovery work.",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "Case found",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceDto"
}
}
}
},
"400": {
"description": "ID missing, empty, or ID is not a collection case",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"404": {
"description": "Case not found, deleted, or not submitted by you as managing partner",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/managed-cases/case-reference/{caseReference}": {
"get": {
"tags": [
"ManagedCases"
],
"summary": "Fetch managed case by reference",
"description": "Returns detailed case information using the Debitura case reference (e.g., 'Q8OAXF3W') for cases you submitted.\n\n**Use Case:**\nUse this endpoint when you have the Debitura case reference but not the GUID. Helpful for customer service integrations or when your clients reference cases by the Debitura reference number.\n\n**Access Control:**\nOnly returns cases where you are the managing partner.",
"parameters": [
{
"name": "caseReference",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Case found",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceDto"
}
}
}
},
"400": {
"description": "Reference missing or reference is not a collection case",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"404": {
"description": "Reference not found or not submitted by you as managing partner",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/managed-cases/{id}/timeline": {
"get": {
"tags": [
"ManagedCases"
],
"summary": "Fetch managed case timeline",
"description": "Returns the complete chronological event history for a case you submitted as managing partner.\n\n**Timeline Events Include:**\n- Case submission and acceptance\n- Assignment to collection partner\n- Status changes and lifecycle transitions\n- Payment recordings\n- Communication events between collection partner and creditor\n- Collection partner updates and notes\n\n**Managing Partner Transparency:**\nThe timeline provides full visibility into the collection partner's activities, allowing you to monitor progress and keep your clients informed.\n\n**Response shape:**\n- `items` ā chronological list of timeline events\n- `currentEngagementPhase` ā current phase of the active engagement: \"Pre-legal\", \"Legal\", or \"Enforcement\". Null when no active engagement exists.\n\n**Use Case:**\nUse this to track case progress, update your clients on status, or audit collection partner activities.",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "Timeline returned",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.CaseTimelineResponse"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.CaseTimelineResponse"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.CaseTimelineResponse"
}
}
}
},
"400": {
"description": "Case ID missing or empty",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"404": {
"description": "Case not found or not submitted by you as managing partner",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/managed-cases/{id}/chats": {
"get": {
"tags": [
"ManagedCases"
],
"summary": "Fetch managed case chats",
"description": "Returns all chat messages for a case you submitted, in chronological order.\n\n**Chat Participants (for Managed Cases):**\n- Managing partner (you) - Your messages to the collection partner\n- Collection partner - Messages from the partner actively collecting the case\n- Your client (creditor) - Messages from the client you represent\n- Debitura support - System notifications and support messages\n\n**Communication Flow:**\nAs the managing partner, you can participate in case discussions to:\n- Coordinate with the collection partner\n- Provide additional information about the debtor\n- Relay questions from your client\n- Stay updated on collection progress\n\n**Use Case:**\nMonitor collection partner communications, coordinate case strategy, or extract conversation history to share with your clients.\n\n**Note:** Managing partners have limited write access - you can read and send messages but cannot modify case details or add payments.",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "Chats returned (empty array if no messages)",
"content": {
"text/plain": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Chats.ChatDto"
}
}
},
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Chats.ChatDto"
}
}
},
"text/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Chats.ChatDto"
}
}
}
}
},
"400": {
"description": "Case ID missing or empty",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"404": {
"description": "Case not found or not submitted by you as managing partner",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/managed-cases/{id}/payments": {
"get": {
"tags": [
"ManagedCases"
],
"summary": "Fetch managed case payments",
"description": "Returns all payments recorded on a case you submitted as managing partner.\n\n**Payment Information Includes:**\n- Payment amount, currency, and date\n- Payment type and method\n- Payment status (recorded by collection partner)\n- Allocation breakdown (principal, interest, fees)\n- Payout details (amounts to creditor and collection partner)\n\n**What This Endpoint Shows:**\nAs a managing partner, you can monitor all payment activity on cases you submitted for your clients. This endpoint provides visibility into:\n- What the collection partner has recovered from the debtor\n- How recovered amounts are allocated (principal vs. interest vs. fees)\n- The collection partner's success fee on each payment\n- Payment history and timeline\n\n**Important:** This endpoint is for monitoring and client reporting purposes. Your financial arrangements with your clients (billing, commissions, etc.) are managed outside of Debitura's platform. The payment data shown here represents what the collection partner recovered and their fees, not any commissions or payments to you as the managing partner.\n\n**Use Case:**\nMonitor recovery progress, reconcile payments with your records, track case performance, or provide payment status updates to your clients.\n\n**Note:** On production cases, only the assigned collection partner can record new payments. For test cases (isTestCase: true), managing partners can record payments via `POST /managed-cases/{id}/payments`.",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "Payments returned (may be empty array)",
"content": {
"text/plain": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.PaymentDto"
}
}
},
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.PaymentDto"
}
}
},
"text/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.PaymentDto"
}
}
}
}
},
"400": {
"description": "Case ID missing or empty",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"404": {
"description": "Case not found or not submitted by you as managing partner",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
},
"post": {
"tags": [
"ManagedCases"
],
"summary": "Record a payment on a test case (managing partner)",
"description": "Records a payment on a test case you submitted as managing partner.\n\n**Test-Only Restriction:**\nThis endpoint only works on cases created with `isTestCase: true`. Attempting to record a payment on a production case returns a 400 error. For production cases, the assigned collection partner must use `POST /cases/{id}/payments`.\n\n**Purpose:**\nAllows managing partners (e.g. Get-Systems) to test their full payment integration end-to-end ā including webhook delivery, lifecycle transitions, and remainder updates ā without involving the collection partner.\n\n**Payout Handling:**\nA payout record is created automatically with the full payment amount going to the creditor and zero to the collection partner. CommissionPaymentStatus is set to Unpaid.\n\n**Webhooks:**\nPayment webhooks fire normally, making this useful for end-to-end integration testing.\n\n**CloseCase:**\nIf `closeCase=true` and the payment amount is less than the outstanding balance, a 400 is returned.",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"requestBody": {
"content": {
"application/json-patch+json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.CreateManagedCasePaymentRequest"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.CreateManagedCasePaymentRequest"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.CreateManagedCasePaymentRequest"
}
},
"application/*+json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.CreateManagedCasePaymentRequest"
}
}
}
},
"responses": {
"200": {
"description": "Payment recorded successfully",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.CreateManagedCasePaymentResponse"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.CreateManagedCasePaymentResponse"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.CreateManagedCasePaymentResponse"
}
}
}
},
"400": {
"description": "Invalid request or production case",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"404": {
"description": "Case not found or not submitted by you as managing partner",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"500": {
"description": "Server error",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/managed-cases/{id}/payments/{paymentId}": {
"put": {
"tags": [
"ManagedCases"
],
"summary": "Edit a payment on a test case (managing partner)",
"description": "Edits a payment on a test case you submitted as managing partner.\n\n**Test-Only Restriction:** like recording a payment, this only works on cases created with `isTestCase: true`. Production cases return a 400 ā the assigned collection partner must edit via `PUT /cases/{id}/payments/{paymentId}`.\n\n**Invoiced payments are frozen:** an already-invoiced payment cannot be edited and returns **422**.\n\n**Reopen consent:** if the edit leaves a previously closed (Paid) case with an outstanding balance, the case is reopened only when `reopenCaseIfNeeded: true`; otherwise the request returns **409 Conflict**.",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "paymentId",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"requestBody": {
"content": {
"application/json-patch+json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.UpdatePaymentRequest"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.UpdatePaymentRequest"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.UpdatePaymentRequest"
}
},
"application/*+json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.UpdatePaymentRequest"
}
}
}
},
"responses": {
"200": {
"description": "Payment updated successfully",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.PaymentDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.PaymentDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.PaymentDto"
}
}
}
},
"400": {
"description": "Invalid request or production case",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"404": {
"description": "Case or payment not found / not submitted by you",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"409": {
"description": "Edit would reopen the case; resend with reopenCaseIfNeeded=true",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"422": {
"description": "Payment has already been invoiced and cannot be edited",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"500": {
"description": "Server error",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
},
"delete": {
"tags": [
"ManagedCases"
],
"summary": "Delete a payment on a test case (managing partner)",
"description": "Deletes a payment from a test case you submitted as managing partner, reverting its effect on the case balance and cascading the payout deletion. A durable audit record is retained.\n\n**Test-Only Restriction:** only works on cases created with `isTestCase: true`. Production cases return a 400 ā the assigned collection partner must delete via `DELETE /cases/{id}/payments/{paymentId}`.\n\n**Invoiced payments are frozen:** an already-invoiced payment cannot be deleted and returns **422**.\n\n**Reopen consent:** if the deletion leaves a previously closed (Paid) case with an outstanding balance, the case is reopened only when `reopenCaseIfNeeded=true`; otherwise the request returns **409 Conflict**.",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "paymentId",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "reopenCaseIfNeeded",
"in": "query",
"schema": {
"type": "boolean",
"default": false
}
}
],
"responses": {
"204": {
"description": "Payment deleted successfully"
},
"400": {
"description": "Invalid request or production case",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"404": {
"description": "Case or payment not found / not submitted by you",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"409": {
"description": "Deletion would reopen the case; resend with reopenCaseIfNeeded=true",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"422": {
"description": "Payment has already been invoiced and cannot be deleted",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"500": {
"description": "Server error",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/managed-cases/{id}/files": {
"get": {
"tags": [
"ManagedCases"
],
"summary": "Get managed case files",
"description": "Returns all documents and files attached to a case you submitted as managing partner.\n\n**File Access for Managing Partners:**\nYou have read-only access to all files uploaded by:\n- Your client (the creditor you represent)\n- The collection partner handling the case\n- Debitura support team\n- Yourself (files you uploaded when submitting the case)\n\n**File Types Include:**\n- OriginalInvoice - The initial claim documentation\n- ProofOfDelivery - Delivery confirmations\n- Contract - Agreements between creditor and debtor\n- Correspondence - Email and letter communications\n- PaymentProof - Payment receipts\n- CourtDocuments - Legal filings\n- Other - Miscellaneous supporting documents\n\n**Use Case:**\n- Review evidence and supporting documents\n- Download files to share with your client\n- Verify document completeness before escalation\n- Build client-facing portals showing case documentation\n\n**Note:** File URLs are temporary signed links that expire. Call this endpoint again to generate fresh download links if needed.\n\n**Managing Partner Limitation:** You can view and download files but cannot upload new files directly via this endpoint. File uploads are handled by the collection partner or through the case submission process.",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "Files retrieved successfully (may be empty array)",
"content": {
"text/plain": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Files.CaseFileDto"
}
}
},
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Files.CaseFileDto"
}
}
},
"text/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Files.CaseFileDto"
}
}
}
}
},
"400": {
"description": "Case ID missing or empty",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"404": {
"description": "Case not found or not submitted by you as managing partner",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"500": {
"description": "Server error occurred while retrieving files",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/me": {
"get": {
"tags": [
"Me"
],
"summary": "Verifies the provided API key and returns the collection partner profile",
"description": "Returns the authenticated collection partner's profile information when the `XApiKey` header is valid.\n\nAuthentication\n- Requires a valid API key in the XApiKey header\n- The API key uniquely identifies the collection partner\n\nResponse Data\n- Partner identification (ID, company name, registration details)\n- Contact information (email, phone)\n- Address and location details\n- Billing and invoicing configuration\n- Revenue sharing settings\n- Partner permissions and access levels\n\nUse Cases\n- Verify API key validity and partner identity\n- Retrieve partner profile for display in integrations\n- Access billing and revenue share configuration\n- Check partner permissions and access levels",
"responses": {
"200": {
"description": "Collection partner profile retrieved successfully",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.CollectionPartnerApi.Models.Me.CollectionPartnerMeResponse"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.CollectionPartnerApi.Models.Me.CollectionPartnerMeResponse"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.CollectionPartnerApi.Models.Me.CollectionPartnerMeResponse"
}
}
}
},
"401": {
"description": "Missing or invalid API key",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
}
}
}
},
"404": {
"description": "Collection partner not found",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/test/cases/{id}/advance": {
"post": {
"tags": [
"TestCases"
],
"summary": "Advance a test case to a known lifecycle state.",
"description": "Drives a test case to a well-known lifecycle state in a single call.\n\n**Purpose:**\nEnables CI pipelines and integrators to exercise the full collection lifecycle ā including real webhooks and events ā without manual intervention.\n\n**Target States:**\n- `Active` ā Activates the case from PendingVerification or PendingVerificationInternal. No-op if already Active or Closed.\n- `Closed:Paid` ā Records a payment for `amount` and closes the case as Paid. Activates the case first if needed. `amount` is required.\n- `Closed:NoPayment` ā Closes the case with PreLegalExhaustedNoPayment. Activates the case first if needed.\n\n**Guards:**\n- Returns 400 if the case is not a test case (Classification != Test).\n- Returns 400 if `amount` is missing when `to` is `Closed:Paid`.\n- Returns 400 if `to` is not one of the valid values.\n- Returns 400 if the case is already closed with a different close code (e.g. already Closed:NoPayment when requesting Closed:Paid).\n- Returns 404 if the case is not found or not owned by the calling partner.\n\n**No-op behaviour:**\nIf the case is already at the requested state, the call returns 200 with `advanced: false` and the current state ā no changes are made.\n\n**Webhooks:**\nTransitions use the real internal service pipeline. Webhook delivery per target:\n\n- `ā Active`: fires `case.updated` to Creditor, ReferralPartner, and **Collection Partner** subscriptions.\n- `ā Closed:Paid`: fires `payment.created` to Creditor and **Collection Partner**; fires `case.updated` and `case.closed` to Creditor, ReferralPartner, and **Collection Partner** subscriptions.\n- `ā Closed:NoPayment`: fires `case.updated` and `case.closed` to Creditor, ReferralPartner, and **Collection Partner** subscriptions.\n\n**Note:** `case.closed` is delivered to Collection Partner subscriptions on both close paths.\n\nAll events carry `classification: test` and are only delivered to webhook subscriptions registered with `classification: test`.\n\n**How to Test:**\n\n1. **Create a test case** ā `POST /managed-cases` with `isTest: true` (optionally a `tag` for scoped cleanup). Note the returned `id`.\n\n2. **Register a test webhook subscription** ā subscribe to the events you want to assert on (`case.updated`, `payment.created`, `case.closed`) with `classification: test` and point the URL to your test receiver (e.g. a local ngrok tunnel or a CI webhook sink).\n\n3. **Advance to Active** ā `POST /test/cases/{id}/advance` with `{ \"to\": \"Active\" }`. Expect `{ advanced: true, state: \"Active\" }` and a `case.updated` event on your Collection Partner subscription.\n\n4. **Advance to Closed:Paid** ā `POST /test/cases/{id}/advance` with `{ \"to\": \"Closed:Paid\", \"amount\": 1000.00 }`. Expect `{ advanced: true, state: \"Closed:Paid\" }` and a `payment.created` event on your Collection Partner subscription.\n - Alternatively: advance straight from any pre-active state ā the endpoint activates the case first automatically.\n\n5. **Verify final state** ā `GET /cases/{id}` and assert `lifecycle: Closed` and `closeCode: Paid`.\n\n6. **Test no-op** ā Call the same advance again. Expect `{ advanced: false, state: \"Closed:Paid\" }` and no new webhook events.\n\n7. **Test mismatch error** ā With the case closed as Paid, call `{ \"to\": \"Closed:NoPayment\" }`. Expect 400 with a message describing the conflict.\n\n8. **Test Closed:NoPayment path** ā Create a fresh test case, call `{ \"to\": \"Closed:NoPayment\" }` directly (no amount needed). Expect `case.updated` and `case.closed` on your Collection Partner subscription.\n\n9. **Reset between runs** ā Delete the test case via `DELETE /test/cases/{id}` (or `DELETE /test/cases?tag={tag}` to clear a whole tag) or create a new one per test run to keep assertions clean.",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"requestBody": {
"content": {
"application/json-patch+json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.Requests.AdvanceTestCaseRequest"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.Requests.AdvanceTestCaseRequest"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.Requests.AdvanceTestCaseRequest"
}
},
"application/*+json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.Requests.AdvanceTestCaseRequest"
}
}
}
},
"responses": {
"200": {
"description": "Advance result (advanced=true if state changed, advanced=false if already there)",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.AdvanceTestCaseResponse"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.AdvanceTestCaseResponse"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.AdvanceTestCaseResponse"
}
}
}
},
"400": {
"description": "Validation error ā non-test case, missing amount, or unknown target state",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"404": {
"description": "Case not found or not owned by this collection partner",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/test/cases/{id}": {
"delete": {
"tags": [
"TestCases"
],
"summary": "Hard-delete a single test case by ID.",
"description": "Permanently removes a test case and all its child entities (payments, chats, files, timeline entries, webhook delivery records) from the database.\n\n**This is a hard-delete.** The row is removed entirely ā there is no soft-delete or recovery path. This is intentional for CI environments that create many test cases per day.\n\n**Guards:**\n- Returns 400 if the case is classified as Production. Only Test cases may be deleted via this endpoint.\n- Returns 404 if the case is not found or not owned by the calling partner.\n\n**Idempotent:** Returns 204 even if the case is already deleted (no-op).",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"204": {
"description": "Case deleted (or already absent ā idempotent)"
},
"400": {
"description": "Case is a Production case ā deletion rejected",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"404": {
"description": "Case not found or not owned by this collection partner",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/test/cases": {
"delete": {
"tags": [
"TestCases"
],
"summary": "Hard-delete all test cases with the given tag.",
"description": "Permanently removes all test cases created with the specified tag (and all their child entities) from the database.\n\n**Scoped cleanup:** Each CI pipeline run should create cases with a unique tag (e.g. `suite-run-{uuid}`) and use this endpoint at the end of the run to clean up, without affecting cases from parallel pipeline runs.\n\n**This is a hard-delete.** Rows are removed entirely with no recovery path. This is intentional for CI environments.\n\n**Guards:**\n- Returns 400 if any matched case is classified as Production. The entire operation is rejected and nothing is deleted.\n- Returns 400 if the tag query parameter is missing or blank.\n\n**Idempotent:** Returns 204 even if no cases match the tag ā no error is raised.",
"parameters": [
{
"name": "tag",
"in": "query",
"schema": {
"type": "string"
}
}
],
"responses": {
"204": {
"description": "Cases deleted (or none matched ā idempotent, no response body)"
},
"400": {
"description": "Tag is missing/blank, or matched cases include a Production case",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/test/cases/{id}/replay-last-event": {
"post": {
"tags": [
"TestCases"
],
"summary": "Replay the most recent webhook event for a test case.",
"description": "Collection Partner API only ā this endpoint is a convenience stopgap that existed\n before `GET /webhooks/events` was available. It remains here for backward compatibility\n and because it is a thin wrapper over `POST /webhooks/events/{eventId}/replay`.\n \n Design note: This endpoint was added when the Collection Partner API had no\n delivery-history endpoint (`GET /webhooks/events`), making it impossible to look up\n event IDs for replay. It is a stopgap: \"give me the last event without having to know its ID.\"\n Now that `GET /webhooks/events` exists, integrators can use the full\n history + replay-by-id pattern instead. This endpoint is intentionally not ported\n to the Customer API ā the stopgap only exists because it was needed before history existed.",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "Event re-enqueued for delivery",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.ReplayLastEventResponse"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.ReplayLastEventResponse"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.ReplayLastEventResponse"
}
}
}
},
"400": {
"description": "Validation error ā non-test case or not owned by this partner"
},
"404": {
"description": "Case not found, or no webhook events recorded yet for this case"
}
}
}
},
"/test/webhooks/fire": {
"post": {
"tags": [
"TestWebhooks"
],
"summary": "Fire a named webhook event type for a test case.",
"description": "Fires a real current-state webhook event for any registered Collection Partner event type against a test case ā even if the case hasn't naturally reached the state that would produce that event.\n\n**Purpose:**\nUnblocks testing webhook handlers for rare or hard-to-reach event types (e.g. `case.closed`, `chat.created`) without having to drive the case through its full lifecycle.\n\n**Payload:**\nThe event carries the real current state of the case ā fields are read from the case as it exists now. No payload fabrication or override is supported in this version.\n\n**Event types:**\n- `case.assigned` ā current lifecycle\n- `case.updated` ā current lifecycle (oldLifecycle and newLifecycle both reflect current state)\n- `case.closed` ā current close code and comment (use after case is already closed, or to test your handler regardless)\n- `payment.created` ā most recent payment on the case (returns 422 if no payments exist)\n- `payment.deleted` ā most recently deleted payment on the case (returns 422 if no payments have been deleted)\n- `chat.created` ā most recent chat message on the case (returns 422 if no chats exist)\n\n**Target subscriptions:**\n- If `subscriptionId` is provided, fires only to that subscription. Returns 400 if the subscription is not found, not a test subscription, or not owned by this partner.\n- If omitted, fires to all active test subscriptions registered for the given event type.\n\n**Event log (asynchronous):**\nThe synthetic fire is enqueued into the normal delivery pipeline, exactly like a real dispatch. A successful response (and its `enqueuedCount`) confirms the event was queued ā it does **not** mean a row already exists in the webhook event log. The `WebhookEvent` row appears in `GET /webhooks/events` only after the worker drains the queue and attempts delivery ā usually within a few seconds, but allow up to ~30 seconds, as the queue drain can lag under load. Do not assume the row is present the instant this call returns: poll `GET /webhooks/events?caseId={id}` with a short backoff until the event appears (or a ~30s timeout elapses) rather than reading it once immediately.\n\n**Guards:**\n- Returns 400 if the case is not a test case (`classification != test`), the event type is not valid, or the subscription is not found/not owned.\n- Returns 404 if the case is not found or not owned by this collection partner.\n- Returns 422 if required data is missing (e.g. no payments for `payment.created`, no chats for `chat.created`).",
"requestBody": {
"content": {
"application/json-patch+json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.Requests.FireWebhookRequest"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.Requests.FireWebhookRequest"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.Requests.FireWebhookRequest"
}
},
"application/*+json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.Requests.FireWebhookRequest"
}
}
}
},
"responses": {
"200": {
"description": "Event fired ā delivery jobs enqueued",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.FireWebhookResponse"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.FireWebhookResponse"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.FireWebhookResponse"
}
}
}
},
"400": {
"description": "Validation error ā non-test case, invalid event type, or subscription not found",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"404": {
"description": "Case not found or not owned by this collection partner",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"422": {
"description": "Required data missing (e.g. no payments for payment.created)",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/users": {
"get": {
"tags": [
"Users"
],
"summary": "Lists team members belonging to the authenticated collection partner.",
"description": "Returns a paginated list of users belonging to the authenticated collection partner's team.\n\n**Use Case:**\nUse this endpoint to retrieve valid user IDs for the `assignedUserId` field when activating a case via `POST /cases/{id}/start`.\n\n**Pagination:**\n- `page` (default: 1) ā Page number, starting from 1\n- `pageSize` (default: 50, max: 100) ā Number of results per page\n\n**Response:**\nEach user entry includes:\n- `id` (Guid) ā Use this as `assignedUserId` in `POST /cases/{id}/start`\n- `name` ā Full name of the team member\n- `email` ā Email address of the team member",
"parameters": [
{
"name": "Page",
"in": "query",
"schema": {
"type": "integer",
"format": "int32"
}
},
{
"name": "PageSize",
"in": "query",
"schema": {
"type": "integer",
"format": "int32"
}
}
],
"responses": {
"200": {
"description": "Paginated list of team members returned",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Users.UserListDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Users.UserListDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Users.UserListDto"
}
}
}
},
"400": {
"description": "Invalid pagination parameters",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"401": {
"description": "Missing or invalid API key",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/webhooks/events": {
"get": {
"tags": [
"WebhookEvents"
],
"summary": "List webhook events dispatched for a case.",
"description": "Returns all webhook events dispatched for the given case, scoped to your webhook subscriptions.\nResults are ordered newest-first.\n\n**Use cases:**\n- Verify that a specific event (e.g. `case.updated`) fired after a state transition.\n- Inspect the exact payload delivered on each attempt.\n- Find the event ID to replay via `POST /webhooks/events/{id}/replay`.\n- Part of the CI-loop ASSERT step: after advancing a test case, query this endpoint to confirm the correct events fired.\n\n**Filtering:**\n- `caseId` (required): restricts to events for this case.\n- `since` (optional): only returns events created at or after this ISO 8601 timestamp.\n\n**Note:** Only events for your subscriptions are returned ā events from other collection partners' subscriptions are never exposed.",
"parameters": [
{
"name": "caseId",
"in": "query",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "since",
"in": "query",
"schema": {
"type": "string",
"format": "date-time"
}
}
],
"responses": {
"200": {
"description": "List of webhook events",
"content": {
"text/plain": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Debitura.Web.CollectionPartnerApi.Models.Webhooks.WebhookEventDto"
}
}
},
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Debitura.Web.CollectionPartnerApi.Models.Webhooks.WebhookEventDto"
}
}
},
"text/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Debitura.Web.CollectionPartnerApi.Models.Webhooks.WebhookEventDto"
}
}
}
}
},
"400": {
"description": "Missing or invalid query parameters",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/webhooks/events/{id}/replay": {
"post": {
"tags": [
"WebhookEvents"
],
"summary": "Replay a specific webhook event.",
"description": "Re-enqueues the exact payload from a previously recorded event to its original subscription.\n\nThe event is re-queued as a fresh delivery attempt (attempt 1) using the original payload unchanged.\nDelivery follows the normal retry schedule if the endpoint is unavailable.\n\n**Replay signal:** Replayed deliveries include the header `X-Debitura-Replay: true` so your endpoint can distinguish a replay from a live event and implement idempotency correctly.\n\n**When to use:**\n- Your endpoint was temporarily unavailable and you want to re-deliver a specific event.\n- You want to test idempotency of your event handler.\n- Part of CI-loop ASSERT: confirm an event was dispatched via `GET /webhooks/events`, then replay to a different receiver.\n\n**Relationship to `replay-last-event`:** `POST /test/cases/{id}/replay-last-event` is a convenience wrapper over this endpoint ā it looks up the most recent event ID for you. Use that endpoint when you don't yet know the event ID; use this endpoint when you have the ID from `GET /webhooks/events`.\n\n**Tenant isolation:** Only events belonging to your own subscriptions can be replayed.",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "Event re-enqueued for delivery",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.CollectionPartnerApi.Models.Webhooks.ReplayEventResultDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.CollectionPartnerApi.Models.Webhooks.ReplayEventResultDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.CollectionPartnerApi.Models.Webhooks.ReplayEventResultDto"
}
}
}
},
"400": {
"description": "ID missing or empty",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"404": {
"description": "Event not found or not owned by this collection partner",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/webhooks": {
"get": {
"tags": [
"Webhooks"
],
"summary": "List all webhook subscriptions for the authenticated collection partner.",
"description": "Returns all webhook subscriptions for the authenticated collection partner. Secrets are never returned in list operations.",
"responses": {
"200": {
"description": "List of webhook subscriptions",
"content": {
"text/plain": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Debitura.Domain.Model.Webhooks.Dtos.WebhookDto"
}
}
},
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Debitura.Domain.Model.Webhooks.Dtos.WebhookDto"
}
}
},
"text/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Debitura.Domain.Model.Webhooks.Dtos.WebhookDto"
}
}
}
}
},
"401": {
"description": "API key is missing or invalid"
}
}
},
"post": {
"tags": [
"Webhooks"
],
"summary": "Create a new webhook subscription.",
"description": "Creates a new webhook subscription for receiving real-time event notifications.\n\n**Available Events (assigned/working-partner role):**\n- `case.assigned` - Case validated by Debitura and assigned to your agency\n- `case.updated` - Case lifecycle changed (e.g., Active ā Paused). Does not cover engagement phase\n changes (Pre-legal/Legal/Enforcement) ā poll `GET /cases/{id}` or `GET /cases/{id}/timeline` for\n the current phase; there is no phase-change event today.\n- `case.closed` - Case closed\n- `payment.created` - Payment registered on case\n- `payment.deleted` - Payment reversed (deleted) on case\n- `chat.created` - Chat message created on case\n\n**Security:** Response includes Base64-encoded signing secret (shown only once). Store it to verify HMAC-SHA256 signatures on deliveries.\n\n**Requirements:** HTTPS URL required. Deliveries retry with exponential backoff (8 attempts). Webhook auto-disables after max failures.",
"requestBody": {
"description": "The webhook creation request, including the target URL and event types to subscribe to.",
"content": {
"application/json-patch+json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Domain.Model.Webhooks.Dtos.CreateWebhookRequest"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Domain.Model.Webhooks.Dtos.CreateWebhookRequest"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Domain.Model.Webhooks.Dtos.CreateWebhookRequest"
}
},
"application/*+json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Domain.Model.Webhooks.Dtos.CreateWebhookRequest"
}
}
}
},
"responses": {
"201": {
"description": "Webhook created successfully",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Domain.Model.Webhooks.Dtos.WebhookDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Domain.Model.Webhooks.Dtos.WebhookDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Domain.Model.Webhooks.Dtos.WebhookDto"
}
}
}
},
"400": {
"description": "Invalid request",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"401": {
"description": "API key is missing or invalid"
},
"422": {
"description": "Business rule violation",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
},
"/webhooks/{id}": {
"get": {
"tags": [
"Webhooks"
],
"summary": "Get a specific webhook subscription by ID.",
"description": "Returns details of a specific webhook subscription. Secret is never returned in this operation.",
"parameters": [
{
"name": "id",
"in": "path",
"description": "The unique identifier of the webhook subscription.",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "Webhook subscription found",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Domain.Model.Webhooks.Dtos.WebhookDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Domain.Model.Webhooks.Dtos.WebhookDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Domain.Model.Webhooks.Dtos.WebhookDto"
}
}
}
},
"401": {
"description": "API key is missing or invalid"
},
"404": {
"description": "Webhook not found",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
},
"put": {
"tags": [
"Webhooks"
],
"summary": "Update an existing webhook subscription.",
"description": "Updates webhook URL, events, or active status. Set RegenerateSecret=true to rotate signing secret (returned in response). Use IsActive=true to re-enable auto-disabled webhooks after fixing delivery issues. Secret only included if RegenerateSecret=true.",
"parameters": [
{
"name": "id",
"in": "path",
"description": "The unique identifier of the webhook subscription to update.",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"requestBody": {
"description": "The update request. All fields are optional ā only provided fields are changed.",
"content": {
"application/json-patch+json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Domain.Model.Webhooks.Dtos.UpdateWebhookRequest"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Domain.Model.Webhooks.Dtos.UpdateWebhookRequest"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Domain.Model.Webhooks.Dtos.UpdateWebhookRequest"
}
},
"application/*+json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Domain.Model.Webhooks.Dtos.UpdateWebhookRequest"
}
}
}
},
"responses": {
"200": {
"description": "Webhook updated successfully",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Domain.Model.Webhooks.Dtos.WebhookDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Domain.Model.Webhooks.Dtos.WebhookDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Domain.Model.Webhooks.Dtos.WebhookDto"
}
}
}
},
"400": {
"description": "Invalid request",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
},
"401": {
"description": "API key is missing or invalid"
},
"404": {
"description": "Webhook not found",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
},
"delete": {
"tags": [
"Webhooks"
],
"summary": "Delete a webhook subscription.",
"description": "Permanently deletes webhook subscription. Cannot be undone. Consider setting IsActive=false to temporarily disable instead.",
"parameters": [
{
"name": "id",
"in": "path",
"description": "The unique identifier of the webhook subscription to delete.",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"204": {
"description": "Webhook deleted successfully"
},
"401": {
"description": "API key is missing or invalid"
},
"404": {
"description": "Webhook not found",
"content": {
"text/plain": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto"
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"Debitura.Domain.Model.AsyncJobs.AsyncJobStatus": {
"enum": [
0,
1,
2,
3,
4
],
"type": "integer",
"format": "int32"
},
"Debitura.Domain.Model.Base.PageData": {
"type": "object",
"properties": {
"totalResults": {
"type": "integer",
"format": "int32"
},
"pageSize": {
"type": "integer",
"format": "int32"
},
"currentPage": {
"type": "integer",
"format": "int32"
},
"responseCount": {
"type": "integer",
"format": "int32"
},
"totalPages": {
"type": "integer",
"format": "int32",
"readOnly": true
}
},
"additionalProperties": false
},
"Debitura.Domain.Model.CollectionPartnerLogics.CollectionPartners.SurveyCadenceMode": {
"enum": [
0,
1
],
"type": "integer",
"format": "int32"
},
"Debitura.Domain.Model.CommunicationCenter.Chats.ChatRole": {
"enum": [
0,
1,
2
],
"type": "integer",
"format": "int32"
},
"Debitura.Domain.Model.InvoicePayments.Payouts.CommissionType": {
"enum": [
0,
1
],
"type": "integer",
"format": "int32"
},
"Debitura.Domain.Model.PartnerIngest.PartnerIngestEventType": {
"enum": [
0
],
"type": "integer",
"format": "int32"
},
"Debitura.Domain.Model.Webhooks.Dtos.CreateWebhookRequest": {
"required": [
"events",
"url"
],
"type": "object",
"properties": {
"url": {
"maxLength": 1024,
"minLength": 0,
"type": "string",
"format": "uri"
},
"events": {
"minItems": 1,
"type": "array",
"items": {
"type": "string"
}
},
"isTestMode": {
"type": "boolean"
}
},
"additionalProperties": false
},
"Debitura.Domain.Model.Webhooks.Dtos.UpdateWebhookRequest": {
"type": "object",
"properties": {
"url": {
"maxLength": 1024,
"minLength": 0,
"type": "string",
"format": "uri",
"nullable": true
},
"events": {
"type": "array",
"items": {
"type": "string"
},
"nullable": true
},
"isActive": {
"type": "boolean",
"nullable": true
},
"regenerateSecret": {
"type": "boolean"
},
"isTestMode": {
"type": "boolean",
"nullable": true
}
},
"additionalProperties": false
},
"Debitura.Domain.Model.Webhooks.Dtos.WebhookDto": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"url": {
"type": "string",
"nullable": true
},
"events": {
"type": "array",
"items": {
"type": "string"
},
"nullable": true
},
"isActive": {
"type": "boolean"
},
"createdUtc": {
"type": "string",
"format": "date-time"
},
"updatedUtc": {
"type": "string",
"format": "date-time"
},
"disabledReason": {
"type": "string",
"nullable": true
},
"secret": {
"type": "string",
"nullable": true
},
"isTestMode": {
"type": "boolean"
}
},
"additionalProperties": false
},
"Debitura.Domain.Services.CaseValidation.CaseValidationItemDto": {
"type": "object",
"properties": {
"resolutionArea": {
"type": "string",
"nullable": true
},
"description": {
"type": "string",
"nullable": true
}
},
"additionalProperties": false
},
"Debitura.Domain.Services.CaseValidation.CaseValidationLeanDto": {
"type": "object",
"properties": {
"needsInfo": {
"type": "boolean"
}
},
"additionalProperties": false
},
"Debitura.Domain.Services.CaseValidation.CaseValidationStatusDto": {
"type": "object",
"properties": {
"needsInfo": {
"type": "boolean"
},
"creditorRespondedAt": {
"type": "string",
"format": "date-time",
"nullable": true
},
"items": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Debitura.Domain.Services.CaseValidation.CaseValidationItemDto"
},
"nullable": true
}
},
"additionalProperties": false
},
"Debitura.Web.CollectionPartnerApi.Controllers.CreateIngestionJobRequest": {
"type": "object",
"properties": {
"rows": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Debitura.Web.CollectionPartnerApi.Controllers.IngestionJobRow"
},
"description": "The list of events to enqueue (max recommended: 1000 rows per call).",
"nullable": true
}
},
"additionalProperties": false
},
"Debitura.Web.CollectionPartnerApi.Controllers.CreateIngestionJobResponse": {
"type": "object",
"properties": {
"jobId": {
"type": "string",
"format": "uuid"
},
"rowsQueued": {
"type": "integer",
"format": "int32"
}
},
"additionalProperties": false
},
"Debitura.Web.CollectionPartnerApi.Controllers.IngestionJobRow": {
"type": "object",
"properties": {
"type": {
"$ref": "#/components/schemas/Debitura.Domain.Model.PartnerIngest.PartnerIngestEventType"
},
"caseId": {
"type": "string",
"description": "The case this event belongs to.",
"format": "uuid"
},
"description": {
"type": "string",
"description": "Note text (required for Note events).",
"nullable": true
},
"eventDate": {
"type": "string",
"description": "When the event occurred. Omit to use the current time.",
"format": "date-time",
"nullable": true
},
"externalRef": {
"type": "string",
"description": "Your system's reference for this event (optional, for idempotency tracking).",
"nullable": true
}
},
"additionalProperties": false
},
"Debitura.Web.CollectionPartnerApi.Controllers.IngestionJobStatusResponse": {
"type": "object",
"properties": {
"status": {
"$ref": "#/components/schemas/Debitura.Domain.Model.AsyncJobs.AsyncJobStatus"
},
"rowsTotal": {
"type": "integer",
"format": "int32"
},
"rowsSucceeded": {
"type": "integer",
"format": "int32"
},
"rowsFailed": {
"type": "integer",
"format": "int32"
}
},
"additionalProperties": false
},
"Debitura.Web.CollectionPartnerApi.Models.Me.CollectionPartnerMeResponse": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Unique identifier for the collection partner.",
"format": "uuid"
},
"companyName": {
"type": "string",
"description": "Company name of the collection partner.",
"nullable": true
},
"logoUrl": {
"type": "string",
"description": "URL to the partner's logo image.",
"nullable": true
},
"companyRegistrationNumber": {
"type": "string",
"description": "Company registration number.",
"nullable": true
},
"vatNumber": {
"type": "string",
"description": "Company VAT number.",
"nullable": true
},
"address": {
"type": "string",
"description": "Street address of the company.",
"nullable": true
},
"zipCode": {
"type": "string",
"description": "Zip/postal code.",
"nullable": true
},
"city": {
"type": "string",
"description": "City name.",
"nullable": true
},
"state": {
"type": "string",
"description": "State or region.",
"nullable": true
},
"country": {
"type": "string",
"description": "Country name (not included in automatic mapping).",
"nullable": true
},
"officeEmail": {
"type": "string",
"description": "Office email address.",
"nullable": true
},
"officePhone": {
"type": "string",
"description": "Office phone number.",
"nullable": true
},
"invoiceEmail": {
"type": "string",
"description": "Invoice email address.",
"nullable": true
},
"billingContact": {
"type": "string",
"description": "Billing contact person name.",
"nullable": true
},
"invoiceCurrency": {
"type": "integer",
"description": "Invoice currency ID (nullable - defaults to country currency if not set).",
"format": "int32",
"nullable": true
},
"commissionType": {
"$ref": "#/components/schemas/Debitura.Domain.Model.InvoicePayments.Payouts.CommissionType"
},
"preLegalRevenueShare": {
"type": "number",
"description": "Revenue share percentage for pre-legal cases (decimal, e.g., 0.40 for 40%).",
"format": "double",
"nullable": true
},
"legalRevenueShare": {
"type": "number",
"description": "Revenue share percentage for legal cases (decimal, e.g., 0.20 for 20%).",
"format": "double",
"nullable": true
},
"verifiedProfile": {
"type": "boolean",
"description": "Whether this partner has a verified profile (has verified link or overwrite enabled)."
},
"fullAddress": {
"type": "string",
"description": "Full concatenated address string.",
"nullable": true
},
"surveyCadenceMode": {
"$ref": "#/components/schemas/Debitura.Domain.Model.CollectionPartnerLogics.CollectionPartners.SurveyCadenceMode"
}
},
"additionalProperties": false,
"description": "Response containing collection partner profile information."
},
"Debitura.Web.CollectionPartnerApi.Models.Webhooks.ReplayEventResultDto": {
"type": "object",
"properties": {
"eventId": {
"type": "string",
"description": "The ID of the event that was replayed.",
"format": "uuid"
},
"subscriptionId": {
"type": "string",
"description": "The subscription the event was re-enqueued to.",
"format": "uuid"
},
"eventType": {
"type": "string",
"description": "The event type that was replayed (e.g. \"case.updated\").",
"nullable": true
}
},
"additionalProperties": false,
"description": "Result of replaying a specific webhook event."
},
"Debitura.Web.CollectionPartnerApi.Models.Webhooks.WebhookEventDto": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Unique identifier for this event record.\nUse this ID to replay the event via `POST /webhooks/events/{id}/replay`.",
"format": "uuid"
},
"subscriptionId": {
"type": "string",
"description": "The webhook subscription this event was dispatched to.",
"format": "uuid"
},
"caseId": {
"type": "string",
"description": "The collection case this event relates to.",
"format": "uuid",
"nullable": true
},
"eventType": {
"type": "string",
"description": "The event type (e.g. \"case.assigned\", \"case.updated\", \"case.closed\", \"payment.created\", \"chat.created\").",
"nullable": true
},
"payload": {
"type": "string",
"description": "The full JSON payload that was (or will be) delivered.",
"nullable": true
},
"createdAt": {
"type": "string",
"description": "When this event was first recorded (UTC).",
"format": "date-time"
},
"deliveredAt": {
"type": "string",
"description": "When the event was successfully delivered (UTC).\nNull if delivery has not yet succeeded.",
"format": "date-time",
"nullable": true
},
"attemptCount": {
"type": "integer",
"description": "Number of delivery attempts made so far.",
"format": "int32"
},
"lastResponseCode": {
"type": "integer",
"description": "HTTP status code returned by the subscriber endpoint on the last attempt.",
"format": "int32",
"nullable": true
},
"lastError": {
"type": "string",
"description": "Error message from the last failed delivery attempt. Null on successful delivery.",
"nullable": true
}
},
"additionalProperties": false,
"description": "Represents a recorded webhook delivery event."
},
"Debitura.Web.ExternalApi.Contracts.V1.Cases.AdvanceTestCaseResponse": {
"type": "object",
"properties": {
"advanced": {
"type": "boolean",
"description": "True if the case was advanced in this call; false if it was already at or past the target state (no-op)."
},
"state": {
"type": "string",
"description": "The current state of the case after this call.\nOne of: \"Active\", \"Closed:Paid\", \"Closed:NoPayment\", \"Closed\" (for other close codes).",
"nullable": true
}
},
"additionalProperties": false,
"description": "Response from POST /test/cases/{id}/advance."
},
"Debitura.Web.ExternalApi.Contracts.V1.Cases.AssignedUserDto": {
"type": "object",
"properties": {
"email": {
"type": "string",
"description": "The assigned user's email address.",
"nullable": true
},
"name": {
"type": "string",
"description": "The assigned user's full name.",
"nullable": true
}
},
"additionalProperties": false,
"description": "Represents the creditor team member assigned to a case."
},
"Debitura.Web.ExternalApi.Contracts.V1.Cases.BankAccountDto": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "Bank account identifier",
"format": "int32"
},
"label": {
"type": "string",
"description": "User-friendly label (e.g., \"Main EUR Account\")",
"nullable": true
},
"scheme": {
"type": "string",
"description": "Account scheme: IBAN, SWIFT, or LOCAL",
"nullable": true
},
"currencyCode": {
"type": "string",
"description": "Currency code (ISO 4217)",
"nullable": true
},
"bankCountryCode": {
"type": "string",
"description": "Bank country code (ISO Alpha-2)",
"nullable": true
},
"accountHolderName": {
"type": "string",
"description": "Account holder name (beneficiary)",
"nullable": true
},
"iban": {
"type": "string",
"description": "IBAN (for IBAN scheme accounts)",
"nullable": true
},
"bic": {
"type": "string",
"description": "BIC/SWIFT code (for IBAN and SWIFT scheme accounts)",
"nullable": true
},
"accountNumber": {
"type": "string",
"description": "Account number (for SWIFT and LOCAL scheme accounts)",
"nullable": true
},
"localIdentifier": {
"type": "string",
"description": "Local identifier (for LOCAL scheme accounts, e.g., sort code + account number)",
"nullable": true
},
"localIdentifierType": {
"type": "string",
"description": "Type of local identifier (e.g., \"Sort Code\", \"Routing Number\")",
"nullable": true
},
"bankName": {
"type": "string",
"description": "Bank name (optional)",
"nullable": true
},
"bankAddress": {
"type": "string",
"description": "Bank address (optional)",
"nullable": true
},
"bankCity": {
"type": "string",
"description": "Bank city (optional)",
"nullable": true
},
"bankZipCode": {
"type": "string",
"description": "Bank zip/postal code (optional)",
"nullable": true
},
"bankState": {
"type": "string",
"description": "Bank state/region (optional)",
"nullable": true
}
},
"additionalProperties": false,
"description": "Bank account information for partner API.\nFull details provided as partners need this to:\n1. Provide payment instructions to debtors (when debtor pays client directly)\n2. Execute payouts to clients (when partner receives payment and pays out remainder)"
},
"Debitura.Web.ExternalApi.Contracts.V1.Cases.BusinessErrorApiDTO": {
"type": "object",
"properties": {
"type": {
"type": "string",
"description": "The type of business error (e.g., \"MissingDebtCollectionContract\", \"MissingPowerOfAttorney\", \"NoPartnerAvailable\").",
"nullable": true
},
"message": {
"type": "string",
"description": "A human-readable description of the error.",
"nullable": true
},
"solutionUrl": {
"type": "string",
"description": "A URL where the user can resolve this specific error (e.g., sign a contract).\n \n\nPartners who want a single URL that walks the user through every pending\nsigning in one chain ā instead of forwarding one URL per\n`BusinessErrorApiDTO` ā should use\nDebitura.Web.ExternalApi.Contracts.V1.Cases.BusinessErrorResponseApiDTO.SigningHandoff's `CombinedSigningUrl`.\nThe two are complementary: `SolutionUrl` is granular per-error;\n`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.",
"nullable": true
}
},
"additionalProperties": false,
"description": "Represents a business error in the API response."
},
"Debitura.Web.ExternalApi.Contracts.V1.Cases.BusinessErrorResponseApiDTO": {
"type": "object",
"properties": {
"businessErrors": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.BusinessErrorApiDTO"
},
"description": "List of business errors that must be resolved before the case can be created.",
"nullable": true
},
"signingHandoff": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.SigningHandoffDto"
}
},
"additionalProperties": false,
"description": "Response returned when business rule violations prevent case creation."
},
"Debitura.Web.ExternalApi.Contracts.V1.Cases.CaseTimelineResponse": {
"required": [
"items"
],
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.TimelineItemDto"
},
"description": "Chronological list of events on the case.",
"nullable": true
},
"currentEngagementPhase": {
"type": "string",
"description": "The current engagement phase of the case, sourced from CaseEngagement.CurrentPhase.\nPossible values: \"Pre-legal\", \"Legal\", \"Enforcement\".\nNull when no active engagement exists (e.g. case not yet assigned to a partner).",
"nullable": true
}
},
"additionalProperties": false,
"description": "Response envelope for GET /cases/{id}/timeline.\nWraps the chronological event list with case-level context\nthat cannot be expressed as a single timeline entry."
},
"Debitura.Web.ExternalApi.Contracts.V1.Cases.CloseCaseResponse": {
"required": [
"caseReference",
"closeCode",
"closeCodeDescription"
],
"type": "object",
"properties": {
"caseReference": {
"type": "string",
"nullable": true
},
"closeCode": {
"type": "string",
"nullable": true
},
"closeCodeDescription": {
"type": "string",
"nullable": true
},
"comment": {
"type": "string",
"nullable": true
},
"closedAt": {
"type": "string",
"format": "date-time"
},
"closedBy": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.ClosedByDto"
},
"finalOutstandingAmount": {
"type": "number",
"format": "double"
},
"totalPayments": {
"type": "number",
"format": "double"
},
"totalRecovered": {
"type": "number",
"format": "double"
}
},
"additionalProperties": false,
"description": "Response after closing a case"
},
"Debitura.Web.ExternalApi.Contracts.V1.Cases.ClosedByDto": {
"required": [
"userName"
],
"type": "object",
"properties": {
"userId": {
"type": "integer",
"format": "int32"
},
"userName": {
"type": "string",
"nullable": true
}
},
"additionalProperties": false
},
"Debitura.Web.ExternalApi.Contracts.V1.Cases.CollectionPartnerDto": {
"type": "object",
"properties": {
"name": {
"type": "string",
"nullable": true
},
"officeEmail": {
"type": "string",
"nullable": true
},
"officePhone": {
"type": "string",
"nullable": true
},
"publicSite": {
"type": "string",
"nullable": true
},
"surveyCadenceMode": {
"$ref": "#/components/schemas/Debitura.Domain.Model.CollectionPartnerLogics.CollectionPartners.SurveyCadenceMode"
}
},
"additionalProperties": false,
"description": "V1 Collection Partner DTO for external partner APIs"
},
"Debitura.Web.ExternalApi.Contracts.V1.Cases.CreditorDivisionDto": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Unique identifier for the division",
"format": "uuid"
},
"name": {
"type": "string",
"description": "Name of the division",
"nullable": true
}
},
"additionalProperties": false,
"description": "Creditor division information for external partner APIs.\nRepresents a specific division or department within a creditor organization."
},
"Debitura.Web.ExternalApi.Contracts.V1.Cases.CreditorDto": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Unique identifier for the creditor",
"format": "uuid"
},
"companyName": {
"type": "string",
"description": "Company name of the creditor",
"nullable": true
},
"companyRegistrationNumber": {
"type": "string",
"description": "Company registration number (CVR, VAT number, etc.)",
"nullable": true
},
"officeEmail": {
"type": "string",
"description": "Primary office email address",
"nullable": true
},
"officePhone": {
"type": "string",
"description": "Primary office phone number",
"nullable": true
},
"address": {
"type": "string",
"description": "Street address",
"nullable": true
},
"city": {
"type": "string",
"description": "City",
"nullable": true
},
"zipCode": {
"type": "string",
"description": "Postal/ZIP code",
"nullable": true
},
"state": {
"type": "string",
"description": "State or region (if applicable)",
"nullable": true
},
"country": {
"type": "string",
"description": "Country name",
"nullable": true
},
"division": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.CreditorDivisionDto"
}
},
"additionalProperties": false,
"description": "Creditor (client) information for external partner APIs.\nRepresents the party that the debtor owes money to."
},
"Debitura.Web.ExternalApi.Contracts.V1.Cases.DebtorDto": {
"required": [
"name",
"type"
],
"type": "object",
"properties": {
"type": {
"minLength": 1,
"type": "string",
"description": "Debtor type. Valid values: \"Company\" or \"Person\"",
"example": "Company"
},
"name": {
"minLength": 1,
"type": "string",
"description": "Debtor name (company name or person's full name)",
"example": "Pacific Trading LLC"
},
"contactPerson": {
"type": "string",
"description": "Contact person at the company (required for companies, not used for persons)",
"nullable": true,
"example": "John Smith"
},
"companyRegistrationNumber": {
"type": "string",
"description": "Company registration number (VAT number, CVR, org number, etc.)",
"nullable": true,
"example": "47-1234567"
},
"address": {
"type": "string",
"description": "Street address",
"nullable": true,
"example": "123 Market Street, Suite 400"
},
"zipCode": {
"type": "string",
"description": "Postal/ZIP code",
"nullable": true,
"example": "94105"
},
"city": {
"type": "string",
"description": "City name",
"nullable": true,
"example": "San Francisco"
},
"state": {
"type": "string",
"description": "State/region/province name",
"nullable": true,
"example": "California"
},
"stateAlpha2": {
"type": "string",
"description": "US state: two-letter code (e.g., \"CA\"), ISO 3166-2 format (e.g., \"US-CA\"), or full name (e.g., \"California\")",
"nullable": true,
"example": "CA"
},
"countryAlpha2": {
"type": "string",
"description": "Country code (ISO 3166-1 alpha-2 format)",
"nullable": true,
"example": "US"
},
"country": {
"type": "string",
"description": "Country name",
"nullable": true,
"example": "United States"
},
"email": {
"type": "string",
"description": "Email address for debtor contact",
"nullable": true,
"example": "accounts@pacifictrading.com"
},
"phone": {
"type": "string",
"description": "Phone number (include country code)",
"nullable": true,
"example": "+1 415 555 0123"
}
},
"additionalProperties": false,
"description": "V1 Debtor DTO for external partner APIs.\nThe debtor is the party that owes the debt."
},
"Debitura.Web.ExternalApi.Contracts.V1.Cases.ExclusivePeriodDto": {
"type": "object",
"properties": {
"engagementStartDate": {
"type": "string",
"description": "Start date of the initial exclusivity engagement.",
"format": "date-time"
},
"currentEndDate": {
"type": "string",
"description": "Current end date of the exclusive period (after any extensions).",
"format": "date-time"
},
"daysRemaining": {
"type": "integer",
"description": "Days remaining until the period ends. Negative when the period has naturally expired.\nZero when the engagement was terminated early (partner change or withdrawal),\nregardless of the original end date.",
"format": "int32"
},
"status": {
"type": "string",
"description": "Current status of the exclusive period: Active, Expired, or Terminated.\nActive ā partner has exclusive rights.\nExpired ā period ended naturally (time elapsed or case resolved).\nTerminated ā period was ended early (partner change, withdrawal, etc.).",
"nullable": true
},
"extensions": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.ExclusivePeriodExtensionDto"
},
"description": "Each extension event that occurred within the current engagement, in chronological order.\nEmpty for cases that have never had an extension triggered.",
"nullable": true
}
},
"additionalProperties": false,
"description": "Full exclusive collection period chain for a case.\nReturned by GET /cases/{id}/exclusive-period."
},
"Debitura.Web.ExternalApi.Contracts.V1.Cases.ExclusivePeriodExtensionDto": {
"type": "object",
"properties": {
"type": {
"type": "string",
"description": "What triggered this extension: PromiseToPay, PaymentAgreement, Payment, or Manual.",
"nullable": true
},
"eventDate": {
"type": "string",
"description": "When the extension period started (i.e. when the trigger event occurred).",
"format": "date-time"
},
"newEndDate": {
"type": "string",
"description": "The new period end date after this extension was applied.",
"format": "date-time"
}
},
"additionalProperties": false,
"description": "A single extension event in the exclusive period chain."
},
"Debitura.Web.ExternalApi.Contracts.V1.Cases.FireWebhookResponse": {
"type": "object",
"properties": {
"eventType": {
"type": "string",
"description": "The event type that was fired (e.g. \"case.updated\").",
"nullable": true
},
"caseId": {
"type": "string",
"description": "The case ID the event was fired for.",
"format": "uuid"
},
"enqueuedCount": {
"type": "integer",
"description": "Number of webhook delivery jobs enqueued.\nZero means no active test subscriptions were found for this event type.",
"format": "int32"
}
},
"additionalProperties": false,
"description": "Result of the `POST /test/webhooks/fire` endpoint."
},
"Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceAllocationOutstandingDto": {
"type": "object",
"properties": {
"principal": {
"type": "number",
"format": "double"
},
"interest": {
"type": "number",
"format": "double"
},
"reminderFees": {
"type": "number",
"format": "double"
},
"collectionFees": {
"type": "number",
"format": "double"
}
},
"additionalProperties": false,
"description": "Additive external-API read model. Per-bucket outstanding on the debt ledger, produced by\nthe payment allocation engine (bucket total minus Ī£ active stored allocations ā never re-derived\nfrom a model). Mirrors the internal\n`Debitura.Domain.Model.Receiveables.InvoiceEconomics.EconomicalAllocationOutstanding` shape."
},
"Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceDto": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"dateCreated": {
"type": "string",
"format": "date-time"
},
"dateUpdated": {
"type": "string",
"format": "date-time",
"nullable": true
},
"reference": {
"type": "string",
"nullable": true
},
"creditorReference": {
"type": "string",
"nullable": true
},
"creditorComments": {
"type": "string",
"nullable": true
},
"claimDescription": {
"type": "string",
"nullable": true
},
"grossAmount": {
"type": "number",
"format": "double"
},
"remainder": {
"type": "number",
"format": "double"
},
"interestFees": {
"type": "number",
"format": "double"
},
"reminderFees": {
"type": "number",
"format": "double"
},
"collectionFees": {
"type": "number",
"format": "double"
},
"totalAddedFees": {
"type": "number",
"format": "double"
},
"currency": {
"type": "string",
"nullable": true
},
"isTestCase": {
"type": "boolean"
},
"lifecycle": {
"type": "string",
"nullable": true
},
"dueDate": {
"type": "string",
"format": "date-time"
},
"date": {
"type": "string",
"format": "date-time"
},
"dateFinished": {
"type": "string",
"format": "date-time",
"nullable": true
},
"dateCollectionStarted": {
"type": "string",
"format": "date-time",
"nullable": true
},
"closeCode": {
"type": "string",
"nullable": true
},
"currentEngagementPhase": {
"type": "string",
"description": "The current phase of the case's engagement: \"Pre-legal\", \"Legal\", or \"Enforcement\".\nA different axis from Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceDto.Lifecycle/Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceDto.CloseCode ā an Active case can be\nin any of the three phases.\n \nNull means \"no active engagement\" (e.g. lead / quoting / pre-contract-signing / unassigned, or\na data-consistency gap) ā this is a distinct third state, NOT a synonym for Pre-legal. Most\ncases legitimately read Pre-legal; phase only leaves Pre-legal on legal/enforcement quote flows.\n \nNot guaranteed to be monotonic: an admin correction can move phase backwards (e.g. Legal back\nto Pre-legal).\n \nPersists after case closure ā reflects the case's last-known engagement phase, not the current\nLifecycle. Note: this is a different field from a lead quote's own offered phase (the phase a\npartner's quote proposes to work the case at, if this case ever went through a quote flow) ā\nthis field is the case-level phase of its actual engagement, not a quote's terms.",
"nullable": true
},
"claimType": {
"type": "string",
"description": "The type of claim for this case (e.g. \"Unpaid Invoice\", \"Loan Repayment\", \"Breach of Contract\").\nNull if not set.",
"nullable": true
},
"creditorDivisionId": {
"type": "string",
"format": "uuid",
"nullable": true
},
"debtor": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.DebtorDto"
},
"collectionPartner": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.CollectionPartnerDto"
},
"creditor": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.CreditorDto"
},
"bankAccount": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.BankAccountDto"
},
"blendedAgeUpliftPoints": {
"type": "number",
"description": "MULTI-INVOICE AGE BUCKET PRICING\nCalculated blended age uplift percentage points (0-20) for multi-invoice cases.\nShows the additional fee percentage added due to invoice age.\nFormula: ((A12-A24)Ć10 + A24Ć20) / Total Principal\nNull for single-invoice cases (age uplift is calculated from due date instead).",
"format": "double",
"nullable": true
},
"preLegalSuccessFee": {
"type": "number",
"description": "PRE-LEGAL SUCCESS FEE\nThe total pre-legal success fee percentage for this case.\nIncludes base fee + age-based uplift (blended or single-invoice).\nNull if pricing has not been calculated yet or if case is not in pre-legal phase.\nExample: 20.5 represents 20.5% success fee.",
"format": "double",
"nullable": true
},
"solutionUrl": {
"type": "string",
"description": "When the case is created with allowPendingContracts=true and required contracts are unsigned,\nthis URL points to the signing page. Null when contracts are already signed or not applicable.",
"nullable": true,
"deprecated": true
},
"signingHandoff": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.SigningHandoffDto"
},
"exclusivePeriodEndDate": {
"type": "string",
"description": "The date the exclusive collection period ends (or ended).\nNull if no collection period has been created for this case (e.g. custom-terms cases).\nUse GET /cases/{id}/exclusive-period for the full chain including extensions.",
"format": "date-time",
"nullable": true
},
"disputeStatus": {
"type": "string",
"description": "Whether the claim is disputed by the debtor.\nReturns the description of Debitura.Domain.Model.Receiveables.Invoices.Enums.ClaimDisputeStatus:\n\"Yes, the claim is disputed\", \"No, the claim is not disputed\", or \"Don't Know\".\nNull when the dispute status has not been set on the case.",
"nullable": true
},
"validation": {
"$ref": "#/components/schemas/Debitura.Domain.Services.CaseValidation.CaseValidationLeanDto"
},
"assignedUser": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.AssignedUserDto"
},
"allocationOutstanding": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceAllocationOutstandingDto"
}
},
"additionalProperties": false,
"description": "V1 Invoice DTO for external partner APIs"
},
"Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceListDto": {
"required": [
"page"
],
"type": "object",
"properties": {
"page": {
"$ref": "#/components/schemas/Debitura.Domain.Model.Base.PageData"
},
"cases": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.InvoiceDto"
},
"nullable": true
}
},
"additionalProperties": false
},
"Debitura.Web.ExternalApi.Contracts.V1.Cases.PriceChangeConfirmationResponse": {
"type": "object",
"properties": {
"caseId": {
"type": "string",
"description": "The case ID.",
"format": "uuid"
},
"confirmationRequired": {
"type": "boolean",
"description": "Always `true` on this response. Lets clients branch on the response shape without\ninspecting the HTTP status code."
},
"isIntentionalRate": {
"type": "boolean",
"description": "True when the rate is a deliberately-set rate (accepted quote or manual override) rather than a plain\nbracket crossing. When true the client resolves the 409 with `KeepIntentionalRate = true` only\n(the rate is preserve-only; `ConfirmPriceChange = true` is rejected with 400). When false only\n`ConfirmPriceChange = true` applies (re-price). Lets the consumer branch without parsing\nDebitura.Web.ExternalApi.Contracts.V1.Cases.PriceChangeConfirmationResponse.Message."
},
"currentSuccessFee": {
"type": "number",
"description": "The success fee percentage currently on the case (before the edit).",
"format": "double",
"nullable": true
},
"proposedSuccessFee": {
"type": "number",
"description": "The success fee percentage that would apply if the edit is confirmed.",
"format": "double"
},
"warning": {
"type": "string",
"description": "Optional warning surfaced alongside the confirmation ā e.g. when the principal is lowered on a\ncase that already has payments (partner-rules.md suggests registering a payment instead).\nNull when there is no warning.",
"nullable": true
},
"message": {
"type": "string",
"description": "Human-readable explanation of why confirmation is required.",
"nullable": true
}
},
"additionalProperties": false,
"description": "Returned with HTTP 409 when a principal edit would move the case success fee by more than the\nallowed threshold (>0.1 percentage points), or would affect a deliberately-set rate. The edit is\nNOT applied; the partner reviews the proposed rate change and resubmits the same request to resolve it.\nFor a plain bracket crossing (Debitura.Web.ExternalApi.Contracts.V1.Cases.PriceChangeConfirmationResponse.IsIntentionalRate false) resubmit with\n`ConfirmPriceChange = true` to re-price. For a deliberately-set rate (Debitura.Web.ExternalApi.Contracts.V1.Cases.PriceChangeConfirmationResponse.IsIntentionalRate\ntrue) the rate is preserve-only: resubmit with `KeepIntentionalRate = true` to apply the edit and\nkeep it ā partners cannot override it, and sending `ConfirmPriceChange = true` on such a case is\nrejected with HTTP 400 (DEB-4765 (b)). See partner-rules.md (price-change confirmation) and DEB-4759."
},
"Debitura.Web.ExternalApi.Contracts.V1.Cases.ReplayLastEventResponse": {
"type": "object",
"properties": {
"eventId": {
"type": "string",
"description": "The ID of the webhook event that was re-enqueued.",
"format": "uuid"
},
"subscriptionId": {
"type": "string",
"description": "The subscription the event was re-enqueued to.",
"format": "uuid"
},
"eventType": {
"type": "string",
"description": "The event type that was replayed (e.g. \"case.updated\").",
"nullable": true
}
},
"additionalProperties": false,
"description": "Result of the `POST /test/cases/{id}/replay-last-event` convenience endpoint."
},
"Debitura.Web.ExternalApi.Contracts.V1.Cases.Requests.AdvanceTestCaseRequest": {
"required": [
"to"
],
"type": "object",
"properties": {
"to": {
"type": "string",
"description": "The target state to advance the case to.\nValid values: \"Active\", \"Closed:Paid\", \"Closed:NoPayment\"",
"nullable": true,
"example": "Active"
},
"amount": {
"type": "number",
"description": "Payment amount (required when To is \"Closed:Paid\").\nMust be a positive value in the case currency.",
"format": "double",
"nullable": true,
"example": 1500.00
}
},
"additionalProperties": false,
"description": "Request to advance a test case to a known lifecycle state."
},
"Debitura.Web.ExternalApi.Contracts.V1.Cases.Requests.CloseCaseRequest": {
"required": [
"closeCode"
],
"type": "object",
"properties": {
"closeCode": {
"minLength": 1,
"type": "string",
"description": "Close code/reason for closing the case.\n \n**Valid close codes:**\n- **Paid**: Full payment received from debtor\n- **PartiallyPaid**: Some payment received but not full amount\n- **DebtorInsolventBankrupt**: Debtor declared bankruptcy or insolvent\n- **DebtorUntraceable**: Unable to locate or contact debtor\n- **DisputedLegalActionDeclinedByClient**: Debt disputed, creditor declined legal action\n- **WithdrawnByClient**: Creditor requested case withdrawal\n- **PreLegalExhaustedNoPayment**: All pre-legal attempts exhausted without payment\n- **StatuteOfLimitationsExpired**: Legal time limit to collect has passed\n- **SettlementRejectedByClient**: Proposed settlement rejected by creditor\n- **UnresponsiveClient**: Creditor not responding to collection partner\n- **UneconomicalToPursue**: Recovery cost exceeds claim value\n- **Other**: Other reason (please provide comment)",
"example": "Paid"
},
"comment": {
"maxLength": 2000,
"minLength": 0,
"type": "string",
"description": "Optional comment explaining the closure (recommended for 'Other' close code)",
"nullable": true,
"example": "Case closed after full payment received via bank transfer on 2025-11-19"
}
},
"additionalProperties": false,
"description": "Request to close a case"
},
"Debitura.Web.ExternalApi.Contracts.V1.Cases.Requests.CreateManagedCaseRequest": {
"required": [
"amountToRecover",
"creditorCompanyName",
"currencyCode",
"date",
"debtor"
],
"type": "object",
"properties": {
"creditorCompanyName": {
"minLength": 1,
"type": "string",
"description": "Creditor company name for this case.\nIf you're submitting cases on behalf of your clients, use your client's company name.\nIf you're submitting your own cases, use your own partner company name.",
"example": "Acme Services Inc"
},
"creditorCountryAlpha2": {
"type": "string",
"description": "Creditor country code (ISO 3166-1 alpha-2 format). Either this or CreditorCountry is required.",
"nullable": true,
"example": "US"
},
"creditorCountry": {
"type": "string",
"description": "Creditor country name. Either this or CreditorCountryAlpha2 is required.",
"nullable": true,
"example": "United States"
},
"currencyCode": {
"minLength": 1,
"type": "string",
"description": "Currency code for the case (ISO 4217 format)",
"example": "USD"
},
"date": {
"type": "string",
"description": "Invoice issue date. Provide date only without time component.",
"format": "date-time",
"example": "2024-08-19"
},
"dueDate": {
"type": "string",
"description": "Invoice due date. Provide date only without time component.",
"format": "date-time",
"nullable": true,
"example": "2024-09-02"
},
"comments": {
"maxLength": 4000,
"type": "string",
"description": "Optional comments about the case. Use this to provide context about payment attempts, communication history, or other relevant information.",
"nullable": true,
"example": "Invoice 2024-INV-1234 for custom ERP system development. Payment 90 days overdue despite multiple reminders. Client confirmed services received but cited cash flow issues."
},
"claimDescription": {
"maxLength": 4000,
"type": "string",
"description": "Client provided description of the services or goods delivered",
"nullable": true,
"example": "Software development services - Project Alpha"
},
"creditorReference": {
"maxLength": 50,
"type": "string",
"description": "Client's internal reference for the case (e.g., invoice number)",
"nullable": true,
"example": "INV-2024-1234"
},
"debtor": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.DebtorDto"
},
"amountToRecover": {
"type": "number",
"description": "Total amount to recover from debtor (in the specified currency)",
"format": "double",
"example": 15000.00
},
"isTest": {
"type": "boolean",
"description": "When true, creates a test case that IS persisted to the database but marked as test data.\nTest cases are excluded from production metrics and can be easily filtered or deleted.\nUse this for integration testing and development."
},
"tag": {
"maxLength": 100,
"type": "string",
"description": "Optional tag for scoped test data grouping (e.g. \"suite-run-{uuid}\").\nUse this to group test cases created by a single CI pipeline run so they can be\nbulk-deleted via DELETE /test/cases?tag={tag} without affecting parallel runs.\nOnly meaningful when IsTest is true. Max 100 characters.",
"nullable": true
},
"collectionPartnerId": {
"type": "string",
"description": "Optional: Specify a collection partner ID to handle this case.\nWhen provided, this partner will be used regardless of lead agent matching rules.\nThe partner must be active and have coverage for the debtor's jurisdiction.",
"format": "uuid",
"nullable": true
}
},
"additionalProperties": false,
"description": "Request model for creating a case as a managing partner.\nThe partner submits both creditor information and case details in a single request.",
"example": {
"creditorCompanyName": "Acme Services Inc",
"creditorCountry": "United States",
"currencyCode": "USD",
"amountToRecover": 15000,
"date": "2026-04-22",
"dueDate": "2026-05-06",
"claimDescription": "Software development services - Project Alpha",
"comments": "Invoice INV-2024-1234 for custom ERP system development. Payment 90 days overdue despite multiple reminders. Client confirmed services received but cited cash flow issues.",
"creditorReference": "INV-2024-1234",
"isTest": false,
"debtor": {
"type": "Company",
"name": "Pacific Trading LLC",
"contactPerson": "John Smith",
"companyRegistrationNumber": "47-1234567",
"address": "123 Market Street, Suite 400",
"zipCode": "94105",
"city": "San Francisco",
"stateAlpha2": "CA",
"country": "United States",
"email": "accounts@pacifictrading.com",
"phone": "+1 415 555 0123"
}
}
},
"Debitura.Web.ExternalApi.Contracts.V1.Cases.Requests.FireWebhookRequest": {
"required": [
"caseId",
"event"
],
"type": "object",
"properties": {
"event": {
"type": "string",
"description": "The webhook event type to fire (e.g. \"case.updated\", \"payment.created\").\nMust be a valid event type for the calling API ā refer to each API's documentation\nfor the supported list (Collection Partner and Customer API accept different sets).",
"nullable": true,
"example": "case.updated"
},
"caseId": {
"type": "string",
"description": "The ID of the test case to use as the event source.",
"format": "uuid",
"example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
},
"subscriptionId": {
"type": "string",
"description": "Optional ā the specific subscription ID to fire to.\nIf omitted, fires to all active test subscriptions for the calling API subscriber\nthat are registered for the given event type.",
"format": "uuid",
"nullable": true,
"example": "6b7a1f23-9c48-4e72-a901-1d2b3e4f5a6b"
}
},
"additionalProperties": false,
"description": "Request body for POST /test/webhooks/fire."
},
"Debitura.Web.ExternalApi.Contracts.V1.Cases.Requests.StartCaseRequest": {
"required": [
"welcomeMessage"
],
"type": "object",
"properties": {
"welcomeMessage": {
"maxLength": 5000,
"minLength": 0,
"type": "string",
"description": "Welcome message sent to the creditor upon case activation.\nThis message is included in the email notification sent to the creditor and posted in the case chat.",
"example": "We have received your case and will begin collection proceedings. You will receive regular updates on progress."
},
"userId": {
"type": "string",
"description": "ID of the team member who is sending this welcome message and activating the case.\nUsed to attribute the chat message and email communication.\nMust be a valid user ID from GET /users. Returns 400 if the user is not found in your team.\nDeprecated: use UserEmail instead. At least one of UserId or UserEmail must be provided.",
"format": "uuid",
"nullable": true,
"example": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"deprecated": true
},
"userEmail": {
"type": "string",
"description": "Email address of the team member who is sending this welcome message and activating the case.\nMust correspond to an active member of your team.\nPreferred over UserId. At least one of UserEmail or UserId must be provided.",
"format": "email",
"nullable": true,
"example": "john.doe@example.com"
},
"collectionPartnerReference": {
"maxLength": 128,
"minLength": 0,
"type": "string",
"description": "Your internal reference number for this case (optional).\nStored on the case and visible in the partner portal.",
"nullable": true,
"example": "GET-2025-0042"
},
"assignedUserId": {
"type": "string",
"description": "ID of the team member to assign as the case handler (optional).\nCan be the same as UserId or a different team member.\nMust be a valid user ID from GET /users. Returns 400 if the user is not found in your team.\nDeprecated: use AssignedUserEmail instead.",
"format": "uuid",
"nullable": true,
"deprecated": true
},
"assignedUserEmail": {
"type": "string",
"description": "Email address of the team member to assign as the case handler (optional).\nMust correspond to an active member of your team.\nPreferred over AssignedUserId.",
"format": "email",
"nullable": true,
"example": "jane.smith@example.com"
},
"interestFees": {
"maximum": 1.7976931348623157E+308,
"minimum": 0,
"type": "number",
"description": "Interest fees on this case, in the case currency. Defaults to 0.00 if not provided.",
"format": "double",
"example": 0.00
},
"reminderFees": {
"maximum": 1.7976931348623157E+308,
"minimum": 0,
"type": "number",
"description": "Reminder fees on this case, in the case currency. Defaults to 0.00 if not provided.",
"format": "double",
"example": 100.00
},
"collectionFees": {
"maximum": 1.7976931348623157E+308,
"minimum": 0,
"type": "number",
"description": "Collection fees on this case, in the case currency. Defaults to 0.00 if not provided.",
"format": "double",
"example": 0.00
}
},
"additionalProperties": false,
"description": "Request to activate a case from PendingVerification to Active status.",
"example": {
"userId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"welcomeMessage": "We have received your case and will begin collection proceedings. You will receive regular updates on progress.",
"collectionPartnerReference": "GET-2025-0042",
"assignedUserId": null,
"interestFees": 0,
"reminderFees": 100,
"collectionFees": 0
}
},
"Debitura.Web.ExternalApi.Contracts.V1.Cases.Requests.UpdateCaseFeesRequest": {
"type": "object",
"properties": {
"grossAmount": {
"maximum": 1.7976931348623157E+308,
"minimum": 0,
"type": "number",
"description": "Principal claim amount (gross amount) in the case currency.\nOptional ā omit to leave the principal unchanged (fees-only update, backward-compatible).\nBoth increases and decreases are allowed; must be ā„ 0.",
"format": "double",
"nullable": true,
"example": 1000.00
},
"interestFees": {
"maximum": 1.7976931348623157E+308,
"minimum": 0,
"type": "number",
"description": "Interest fees on this case, in the case currency.",
"format": "double",
"example": 25.50
},
"reminderFees": {
"maximum": 1.7976931348623157E+308,
"minimum": 0,
"type": "number",
"description": "Reminder fees on this case, in the case currency.",
"format": "double",
"example": 10.00
},
"collectionFees": {
"maximum": 1.7976931348623157E+308,
"minimum": 0,
"type": "number",
"description": "Collection fees on this case, in the case currency.",
"format": "double",
"example": 50.00
},
"confirmPriceChange": {
"type": "boolean",
"description": "The \"Change to standard\" resolution. When a principal edit on a standard-rate case would\nmove the success fee by more than 0.1 percentage points (a bracket crossing), the first request\nreturns HTTP 409 with the proposed old/new rate instead of applying the change. Resubmit the same\nrequest with this set to `true` to confirm and apply the re-price. Leaving it `false`\n(the default) on an unaffected edit has no effect. See partner-rules.md (price change confirmation\nrequired if the success fee changes by >0.1%).\n \nIMPORTANT (DEB-4765 (b)): on a case with a deliberately-set rate (an accepted quote or a manual\noverride), partners can never override a special agreement via this API. Sending this flag on such a\ncase is REJECTED with HTTP 400 ā resubmit with Debitura.Web.ExternalApi.Contracts.V1.Cases.Requests.UpdateCaseFeesRequest.KeepIntentionalRate=`true` to apply\nthe edit and keep the special rate. Only the admin (internal) surface can change a special rate.",
"example": false
},
"keepIntentionalRate": {
"type": "boolean",
"description": "The \"Keep special rate\" resolution. When the case carries a deliberately-set rate (an accepted\nquote or a manual override) that the edit would otherwise prompt about, resubmit with this set to\n`true` to apply the edit while preserving the existing rate. On this external Partner API a\nspecial rate is preserve-only: this is the ONLY way to apply an edit to such a case ā sending\nDebitura.Web.ExternalApi.Contracts.V1.Cases.Requests.UpdateCaseFeesRequest.ConfirmPriceChange instead is rejected with HTTP 400. Ignored for a plain bracket\ncrossing on a non-intentional rate (use Debitura.Web.ExternalApi.Contracts.V1.Cases.Requests.UpdateCaseFeesRequest.ConfirmPriceChange there).",
"example": false
}
},
"additionalProperties": false,
"description": "Request to update the fee amounts (and optionally the principal) on an active case."
},
"Debitura.Web.ExternalApi.Contracts.V1.Cases.SigningHandoffDto": {
"type": "object",
"properties": {
"combinedSigningUrl": {
"type": "string",
"description": "Single signing entry URL that walks the creditor through every\npending step (SDCA upgrade ā PoA ā JPA ā KYC) on the Creditors app\nand returns to the partner-supplied returnUrl when done.",
"nullable": true
}
},
"additionalProperties": false,
"description": "Partner-facing handoff metadata for a creditor's pending signing chain.\nReturned on POST /cases responses (422 with pending-signing errors,\nor 200 with AllowPendingContracts=true when signings remain).\n \nDesigned as an envelope so future fields (expiration, suggested email\ncopy, etc.) can be added without polluting the parent DTO."
},
"Debitura.Web.ExternalApi.Contracts.V1.Cases.StartCaseResponse": {
"type": "object",
"properties": {
"caseId": {
"type": "string",
"description": "The case ID.",
"format": "uuid"
},
"caseReference": {
"type": "string",
"description": "The Debitura case reference (e.g. 'Q8OAXF3W').",
"nullable": true
},
"status": {
"type": "string",
"description": "The new lifecycle status of the case.",
"nullable": true
},
"activatedAt": {
"type": "string",
"description": "UTC timestamp when the case was activated.",
"format": "date-time"
},
"collectionPartnerReference": {
"type": "string",
"description": "Your internal reference number for this case, if provided.",
"nullable": true
}
},
"additionalProperties": false,
"description": "Response returned when a case is successfully activated."
},
"Debitura.Web.ExternalApi.Contracts.V1.Cases.TimelineActorDto": {
"required": [
"type"
],
"type": "object",
"properties": {
"type": {
"type": "string",
"description": "The type of actor. One of: \"System\", \"Creditor user\", \"Partner user\".",
"nullable": true
},
"name": {
"type": "string",
"description": "Display name of the actor, if available.",
"nullable": true
}
},
"additionalProperties": false,
"description": "Represents the actor (person or system) that performed a timeline action."
},
"Debitura.Web.ExternalApi.Contracts.V1.Cases.TimelineItemDto": {
"required": [
"description",
"title",
"type"
],
"type": "object",
"properties": {
"date": {
"type": "string",
"format": "date-time"
},
"type": {
"type": "string",
"nullable": true
},
"title": {
"type": "string",
"nullable": true
},
"description": {
"type": "string",
"nullable": true
},
"actor": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.TimelineActorDto"
}
},
"additionalProperties": false
},
"Debitura.Web.ExternalApi.Contracts.V1.Cases.UpdateCaseFeesResponse": {
"type": "object",
"properties": {
"caseId": {
"type": "string",
"description": "The case ID.",
"format": "uuid"
},
"grossAmount": {
"type": "number",
"description": "Updated principal claim amount (gross amount), in the case currency.",
"format": "double"
},
"interestFees": {
"type": "number",
"description": "Updated interest fees, in the case currency.",
"format": "double"
},
"reminderFees": {
"type": "number",
"description": "Updated reminder fees, in the case currency.",
"format": "double"
},
"collectionFees": {
"type": "number",
"description": "Updated collection fees, in the case currency.",
"format": "double"
},
"totalAddedFees": {
"type": "number",
"description": "Sum of all fee types.",
"format": "double"
},
"recalculatedSuccessFee": {
"type": "number",
"description": "Recalculated success fee after the principal update. Null if no collection partner is\nassigned or if the principal was not changed.",
"format": "double",
"nullable": true
},
"remainder": {
"type": "number",
"description": "Outstanding remainder after the update (principal + fees ā payments).",
"format": "double"
}
},
"additionalProperties": false,
"description": "Response returned when case fees (and optionally the principal) are successfully updated."
},
"Debitura.Web.ExternalApi.Contracts.V1.Chats.ChatDto": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"dateCreated": {
"type": "string",
"format": "date-time"
},
"dateUpdated": {
"type": "string",
"format": "date-time",
"nullable": true
},
"role": {
"$ref": "#/components/schemas/Debitura.Domain.Model.CommunicationCenter.Chats.ChatRole"
},
"roleLabel": {
"type": "string",
"description": "Human-readable label for the role (e.g., \"Partner\", \"Creditor\", \"Managed by partner\").\nCompanion to Debitura.Web.ExternalApi.Contracts.V1.Chats.ChatDto.Role ā always present when Role is set.",
"nullable": true
},
"message": {
"type": "string",
"nullable": true
},
"isSeen": {
"type": "boolean"
},
"user": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Users.UserRelationDto"
}
},
"additionalProperties": false
},
"Debitura.Web.ExternalApi.Contracts.V1.Chats.SendChatRequest": {
"required": [
"message"
],
"type": "object",
"properties": {
"message": {
"maxLength": 10000,
"minLength": 0,
"type": "string",
"description": "The chat message content to send.",
"example": "Please provide the signed contract for this case."
},
"userId": {
"type": "string",
"description": "ID of the team member sending this message.\nMust be a valid user ID from GET /users belonging to your team.\nDeprecated: use UserEmail instead. At least one of UserId or UserEmail must be provided.",
"format": "uuid",
"nullable": true,
"example": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"deprecated": true
},
"userEmail": {
"type": "string",
"description": "Email address of the team member sending this message.\nMust correspond to an active member of your team (same account as the API key).\nPreferred over UserId. At least one of UserEmail or UserId must be provided.",
"format": "email",
"nullable": true,
"example": "john.doe@example.com"
}
},
"additionalProperties": false,
"description": "Request to send a chat message on a case."
},
"Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto": {
"type": "object",
"properties": {
"error": {
"type": "string",
"description": "Short human-readable error label (legacy field ā preserved for backward compatibility).",
"nullable": true
},
"message": {
"type": "string",
"description": "Human-readable error description (legacy field ā preserved for backward compatibility).",
"nullable": true
},
"businessErrors": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Cases.BusinessErrorApiDTO"
},
"description": "Canonical structured error array. Consumers should migrate to reading this field.",
"nullable": true
}
},
"additionalProperties": false,
"description": "Generic structured error response for API endpoints.\n \nDual-write design: existing fields (Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto.Error / Debitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto.Message etc.)\nare preserved for backward compatibility alongside the canonical\nDebitura.Web.ExternalApi.Contracts.V1.Errors.ApiErrorResponseDto.BusinessErrors array, allowing consumers to migrate at their own pace."
},
"Debitura.Web.ExternalApi.Contracts.V1.Files.CaseFileDto": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"dateCreated": {
"type": "string",
"format": "date-time"
},
"dateUpdated": {
"type": "string",
"format": "date-time"
},
"caseId": {
"type": "string",
"format": "uuid"
},
"entityType": {
"type": "string",
"nullable": true
},
"entityId": {
"type": "string",
"format": "uuid"
},
"fileName": {
"type": "string",
"nullable": true
},
"url": {
"type": "string",
"nullable": true
},
"description": {
"type": "string",
"nullable": true
},
"documentType": {
"type": "string",
"nullable": true
}
},
"additionalProperties": false
},
"Debitura.Web.ExternalApi.Contracts.V1.Notes.CreateNoteRequest": {
"required": [
"description"
],
"type": "object",
"properties": {
"description": {
"maxLength": 10000,
"minLength": 0,
"type": "string",
"description": "Note content",
"example": "Called debtor on 2025-11-19. They acknowledged the debt and promised to pay within 7 days. Will follow up on 2025-11-26."
},
"eventDate": {
"type": "string",
"description": "The date when the event actually occurred. Must not be in the future.\nWhen provided, the note will appear at this date in the timeline instead of the upload time.\nThis is useful for importing historical events (e.g. a phone call that happened last week).\nOmit or set to null to use the current time (default behaviour).",
"format": "date-time",
"nullable": true,
"example": "2025-11-14T09:30:00Z"
}
},
"additionalProperties": false,
"description": "Request to create a new note on a case"
},
"Debitura.Web.ExternalApi.Contracts.V1.Notes.NoteCreatedByDto": {
"required": [
"userName"
],
"type": "object",
"properties": {
"userId": {
"type": "integer",
"format": "int32"
},
"userName": {
"type": "string",
"nullable": true
}
},
"additionalProperties": false
},
"Debitura.Web.ExternalApi.Contracts.V1.Notes.NoteDto": {
"required": [
"caseReference",
"title",
"visibility"
],
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"caseReference": {
"type": "string",
"nullable": true
},
"title": {
"type": "string",
"nullable": true
},
"description": {
"type": "string",
"nullable": true
},
"visibility": {
"type": "string",
"nullable": true
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"eventDate": {
"type": "string",
"description": "The event date provided at creation time. Null if no EventDate was supplied,\nmeaning the note was recorded in real-time (CreatedAt reflects the actual event time).",
"format": "date-time",
"nullable": true
},
"createdBy": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Notes.NoteCreatedByDto"
}
},
"additionalProperties": false,
"description": "Note details response"
},
"Debitura.Web.ExternalApi.Contracts.V1.Payments.CreateManagedCasePaymentRequest": {
"required": [
"date",
"paymentAmount"
],
"type": "object",
"properties": {
"date": {
"type": "string",
"description": "Payment date (when payment was received).",
"format": "date-time",
"example": "2025-11-19"
},
"paymentAmount": {
"maximum": 1.7976931348623157E+308,
"minimum": 0.01,
"type": "number",
"description": "Total payment amount received.",
"format": "double",
"example": 5000.00
},
"closeCase": {
"type": "boolean",
"description": "Whether to close the case after recording this payment (default: false).\nIf true and payment < invoice remainder, returns validation error.",
"example": false
}
},
"additionalProperties": false,
"description": "Request to record a payment on a test case as managing partner.\nOnly available for cases created with isTestCase: true."
},
"Debitura.Web.ExternalApi.Contracts.V1.Payments.CreateManagedCasePaymentResponse": {
"required": [
"caseReference"
],
"type": "object",
"properties": {
"paymentId": {
"type": "string",
"format": "uuid"
},
"caseReference": {
"type": "string",
"nullable": true
},
"date": {
"type": "string",
"format": "date-time"
},
"paymentAmount": {
"type": "number",
"format": "double"
},
"caseClosed": {
"type": "boolean"
},
"remainingAmount": {
"type": "number",
"format": "double"
}
},
"additionalProperties": false,
"description": "Response after recording a payment as managing partner on a test case."
},
"Debitura.Web.ExternalApi.Contracts.V1.Payments.CreatePaymentRequest": {
"required": [
"date",
"paymentAmount",
"paymentRecipient"
],
"type": "object",
"properties": {
"date": {
"type": "string",
"description": "Payment date (when payment was received). Provide date only without time component.",
"format": "date-time",
"example": "2025-11-19"
},
"paymentAmount": {
"maximum": 1.7976931348623157E+308,
"minimum": 0.01,
"type": "number",
"description": "Total payment amount received.\n \nWhen both PayoutCreditor and PayoutCollectionPartner are supplied they must sum to this amount.\nWhen both are omitted, the split is computed server-side from the case's pricing terms.",
"format": "double",
"example": 5000.00
},
"payoutCreditor": {
"maximum": 1.7976931348623157E+308,
"minimum": 0,
"type": "number",
"description": "Amount to be paid out to creditor. **Optional ā omit by default.**\n \nNormal usage is to leave this (and PayoutCollectionPartner) unset: the split is then computed\nserver-side from the case's pricing terms (success fee), which is correct for almost every\nintegration. Setting this is an **advanced, opt-in override** for legitimate edge cases (e.g. a\nnegotiated split where the collection partner already holds funds) ā most callers should never\nneed it. When supplied, PayoutCollectionPartner must also be supplied and the two must sum to\nPaymentAmount. A zero value here (entire payment routed to the partner), or an explicit split\nsupplied on a case that already has no outstanding balance, is accepted but surfaced as a\nwarning in the response (`CreatePaymentResponse.Warnings`) rather than rejected ā review\nthese warnings, as they are signs of a misconfigured or duplicate payment.",
"format": "double",
"nullable": true,
"example": 4000.00
},
"payoutCollectionPartner": {
"maximum": 1.7976931348623157E+308,
"minimum": 0,
"type": "number",
"description": "Amount to be kept by collection partner (commission). **Optional ā omit by default.**\n \nNormal usage is to leave this (and PayoutCreditor) unset: the split is then computed\nserver-side from the case's pricing terms (success fee), which is correct for almost every\nintegration. Setting this is an **advanced, opt-in override** for legitimate edge cases (e.g. a\nnegotiated split where the collection partner already holds funds) ā most callers should never\nneed it. When supplied, PayoutCreditor must also be supplied and the two must sum to\nPaymentAmount. See PayoutCreditor (above) for the soft-guard warnings this can trigger.",
"format": "double",
"nullable": true,
"example": 1000.00
},
"paymentRecipient": {
"minLength": 1,
"type": "string",
"description": "Who received the payment.\n \n**Valid values:**\n- **Creditor**: Payment was received by the creditor (client). When used, you must also specify CommissionPaymentStatus.\n- **Platform**: Payment was received by Debitura platform. Commission is automatically marked as paid.\n- **CollectionPartner**: Payment was received by the collection partner. Commission is automatically marked as paid.",
"example": "Creditor"
},
"commissionPaymentStatus": {
"type": "string",
"description": "Commission payment status. **Required only if PaymentRecipient is Creditor.**\n \nWhen PaymentRecipient is CollectionPartner or Platform, this field is ignored and commission is automatically marked as Paid.\n \n**Valid values:**\n- **Paid**: Commission has been paid to collection partner\n- **Unpaid**: Commission has not yet been paid to collection partner",
"nullable": true,
"example": "Paid"
},
"closeCase": {
"type": "boolean"
},
"createUnpaidCommissionFollowUp": {
"type": "boolean",
"description": "Whether to run the unpaid-commission follow-up chain when this payment leaves the\ncollection partner's commission Unpaid (PaymentRecipient = Creditor, CommissionPaymentStatus = Unpaid).\nThe chain is: stamp the payout reminder date, email the partner, and create the\nUnpaidCommissionInvoiceClient follow-up task ā which the reminder robot then drives.\n \nDefaults to `true`, preserving the standard API / UI behaviour. Set to `false`\nto opt this source out of the entire chain (no stamp, email, task, reminders or escalation);\nthe Payment and Payout are still created normally. Used by ingestion partners (e.g. ASTOP)\nthat already report commission settlement out of band and must not trigger the chase.",
"example": true
}
},
"additionalProperties": false,
"description": "Request to create a payment on a case.\n \n**Currency:** Payment must be in the same currency as the invoice. Currency is automatically determined from the case and cannot be specified in the request.",
"example": {
"date": "2026-07-21",
"paymentAmount": 5000,
"payoutCreditor": 4000,
"payoutCollectionPartner": 1000,
"paymentRecipient": "Creditor",
"commissionPaymentStatus": "Paid",
"closeCase": false
}
},
"Debitura.Web.ExternalApi.Contracts.V1.Payments.CreatePaymentResponse": {
"required": [
"caseReference",
"commissionPaymentStatus",
"paymentRecipient"
],
"type": "object",
"properties": {
"paymentId": {
"type": "string",
"format": "uuid"
},
"caseReference": {
"type": "string",
"nullable": true
},
"date": {
"type": "string",
"format": "date-time"
},
"paymentAmount": {
"type": "number",
"format": "double"
},
"payoutCreditor": {
"type": "number",
"format": "double"
},
"payoutCollectionPartner": {
"type": "number",
"format": "double"
},
"paymentRecipient": {
"type": "string",
"nullable": true
},
"commissionPaymentStatus": {
"type": "string",
"nullable": true
},
"closeCase": {
"type": "boolean"
},
"caseClosed": {
"type": "boolean"
},
"closeCode": {
"type": "string",
"nullable": true
},
"remainingAmount": {
"type": "number",
"format": "double"
},
"warnings": {
"type": "array",
"items": {
"type": "string"
},
"description": "Non-blocking warnings about this payment. Always present (empty when there is nothing to flag).\nCurrently populated only when an explicit PayoutCreditor/PayoutCollectionPartner override was\nsupplied and (a) it allocates zero to the creditor, or (b) the case already had no outstanding\nbalance before this payment ā both are signs of a misconfigured or duplicate payment. The\npayment is still recorded; these are advisory only, not errors. Review and resolve out of band\nif unexpected (e.g. via the case's Payments view in the Partner Portal, or by contacting\nDebitura support).",
"nullable": true
}
},
"additionalProperties": false,
"description": "Response after creating a payment"
},
"Debitura.Web.ExternalApi.Contracts.V1.Payments.PaymentDto": {
"required": [
"currency",
"invoice",
"method",
"recipient"
],
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"dateCreated": {
"type": "string",
"format": "date-time"
},
"dateUpdated": {
"type": "string",
"format": "date-time",
"nullable": true
},
"date": {
"type": "string",
"format": "date-time"
},
"grossAmount": {
"type": "number",
"format": "double"
},
"recipient": {
"type": "string",
"nullable": true
},
"method": {
"type": "string",
"nullable": true
},
"currency": {
"type": "string",
"nullable": true
},
"invoice": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Payments.PaymentRelatedInvoiceDto"
}
},
"additionalProperties": false
},
"Debitura.Web.ExternalApi.Contracts.V1.Payments.PaymentRelatedInvoiceDto": {
"required": [
"reference",
"status"
],
"type": "object",
"properties": {
"status": {
"type": "string",
"nullable": true
},
"reference": {
"type": "string",
"nullable": true
},
"invoiceId": {
"type": "string",
"format": "uuid"
}
},
"additionalProperties": false
},
"Debitura.Web.ExternalApi.Contracts.V1.Payments.UpdatePaymentRequest": {
"required": [
"date",
"paymentAmount",
"paymentRecipient"
],
"type": "object",
"properties": {
"date": {
"type": "string",
"description": "Payment date (when payment was received). Provide date only without time component.",
"format": "date-time",
"example": "2025-11-19"
},
"paymentAmount": {
"maximum": 1.7976931348623157E+308,
"minimum": 0.01,
"type": "number",
"description": "Total payment amount received.\n \nWhen both PayoutCreditor and PayoutCollectionPartner are supplied they must sum to this amount.\nWhen both are omitted, the split is computed server-side from the case's pricing terms.",
"format": "double",
"example": 5000.00
},
"payoutCreditor": {
"maximum": 1.7976931348623157E+308,
"minimum": 0,
"type": "number",
"description": "Amount to be paid out to creditor. **Optional.**\n \nWhen omitted (along with PayoutCollectionPartner), the split is computed server-side from the\ncase's pricing terms (success fee). When supplied, PayoutCollectionPartner must also be supplied\nand the two must sum to PaymentAmount.",
"format": "double",
"nullable": true,
"example": 4000.00
},
"payoutCollectionPartner": {
"maximum": 1.7976931348623157E+308,
"minimum": 0,
"type": "number",
"description": "Amount to be kept by collection partner (commission). **Optional.**\n \nWhen omitted (along with PayoutCreditor), the split is computed server-side from the\ncase's pricing terms (success fee). When supplied, PayoutCreditor must also be supplied\nand the two must sum to PaymentAmount.",
"format": "double",
"nullable": true,
"example": 1000.00
},
"paymentRecipient": {
"minLength": 1,
"type": "string",
"description": "Who received the payment.\n \n**Valid values:**\n- **Creditor**: Payment was received by the creditor (client). When used, you must also specify CommissionPaymentStatus.\n- **CollectionPartner**: Payment was received by the collection partner. Commission is automatically marked as paid.",
"example": "Creditor"
},
"commissionPaymentStatus": {
"type": "string",
"description": "Commission payment status. **Required only if PaymentRecipient is Creditor.**\n \nWhen PaymentRecipient is CollectionPartner, this field is ignored and commission is automatically marked as Paid.\n \n**Valid values:** Paid, Unpaid.",
"nullable": true,
"example": "Paid"
},
"reopenCaseIfNeeded": {
"type": "boolean",
"description": "Consent to reopen the case if this edit lowers the payment so a previously closed (Paid)\ncase is left with a positive outstanding balance.\n \nWhen the edit would reopen the case and this flag is `false` (default), the request is\nrejected with HTTP 409 Conflict. Resend with `true` to confirm the reopen ā the case is\nreopened to Active and a `case.updated` webhook fires.",
"example": false
}
},
"additionalProperties": false,
"description": "Request to edit an existing payment on a case. Mirrors the payout-split semantics of\nDebitura.Web.ExternalApi.Contracts.V1.Payments.CreatePaymentRequest.\n \n**Currency:** A payment's currency cannot be changed ā it is fixed to the case currency.\n \n**Invoiced payments are frozen:** a payment whose payout has already been invoiced\n(Stripe/QBO) cannot be edited and returns HTTP 422."
},
"Debitura.Web.ExternalApi.Contracts.V1.Users.CollectionPartnerUserDto": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "The user's unique ID. Use this as `assignedUserId` in POST /cases/{id}/start.",
"format": "uuid"
},
"name": {
"type": "string",
"description": "The user's full name.",
"nullable": true
},
"email": {
"type": "string",
"description": "The user's email address.",
"nullable": true
}
},
"additionalProperties": false,
"description": "A user belonging to the authenticated collection partner's team.\nUse the Debitura.Web.ExternalApi.Contracts.V1.Users.CollectionPartnerUserDto.Id as the `assignedUserId` when starting a case via POST /cases/{id}/start."
},
"Debitura.Web.ExternalApi.Contracts.V1.Users.UserListDto": {
"required": [
"page"
],
"type": "object",
"properties": {
"page": {
"$ref": "#/components/schemas/Debitura.Domain.Model.Base.PageData"
},
"users": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Debitura.Web.ExternalApi.Contracts.V1.Users.CollectionPartnerUserDto"
},
"nullable": true
}
},
"additionalProperties": false
},
"Debitura.Web.ExternalApi.Contracts.V1.Users.UserRelationDto": {
"required": [
"email"
],
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int32"
},
"dateCreated": {
"type": "string",
"format": "date-time",
"nullable": true
},
"dateUpdated": {
"type": "string",
"format": "date-time",
"nullable": true
},
"firstName": {
"type": "string",
"nullable": true
},
"lastName": {
"type": "string",
"nullable": true
},
"email": {
"type": "string",
"nullable": true
}
},
"additionalProperties": false
},
"Microsoft.AspNetCore.Mvc.ProblemDetails": {
"type": "object",
"properties": {
"type": {
"type": "string",
"nullable": true
},
"title": {
"type": "string",
"nullable": true
},
"status": {
"type": "integer",
"format": "int32",
"nullable": true
},
"detail": {
"type": "string",
"nullable": true
},
"instance": {
"type": "string",
"nullable": true
}
},
"additionalProperties": { }
}
},
"securitySchemes": {
"ApiKey": {
"type": "apiKey",
"description": "Collection Partner API Key (use XApiKey header)",
"name": "XApiKey",
"in": "header"
}
}
},
"security": [
{
"ApiKey": [ ]
}
],
"tags": [
{
"name": "Cases",
"description": "Cases"
},
{
"name": "IngestionJobs",
"description": "IngestionJobs"
},
{
"name": "ManagedCases",
"description": "Managed Cases"
},
{
"name": "Me",
"description": "Collection Partner Profile"
},
{
"name": "TestCases",
"description": "Test Cases"
},
{
"name": "TestWebhooks",
"description": "Test Webhooks"
},
{
"name": "Users",
"description": "Users"
},
{
"name": "WebhookEvents",
"description": "Webhooks"
},
{
"name": "Webhooks",
"description": "Manage webhook subscriptions and inspect the delivery event log. Create subscriptions to receive real-time notifications for case lifecycle events, payments, and chats. Use GET /webhooks/events to verify deliveries and POST /webhooks/events/{id}/replay to re-deliver a specific event."
},
{
"name": "Test Cases",
"description": "Drive test cases through lifecycle states without manual intervention. POST /test/cases/{id}/advance activates or closes a test case in a single call, triggering the real webhook pipeline so your handlers can be verified end-to-end. Hard-delete by ID or tag to keep CI environments clean between runs."
},
{
"name": "Test Webhooks",
"description": "Fire synthetic webhook events against test cases without driving the case to the state that would naturally produce them. POST /test/webhooks/fire emits any event type (case.assigned, case.updated, case.closed, payment.created, payment.deleted, chat.created) against a test case ā useful for testing rare or hard-to-reach event handlers in isolation."
}
],
"externalDocs": {
"description": "Debitura developer documentation",
"url": "https://docs.debitura.com"
}
}