> ## Documentation Index
> Fetch the complete documentation index at: https://docs.paywise.de/llms.txt
> Use this file to discover all available pages before exploring further.

# Submit a titled order

> Create titled claims and enforcement costs inline or in stages, confirm the success fee, and finalize safely.

## Outcome

You have a finalized titled order with at least one complete titled
claim, its primary title document, and an explicit success-fee confirmation.
Optional enforcement costs remain separate `ReceivableClaim` entries.

> [!NOTE]
>
> Enforcement is automatic for `type: "titled"`. Omit `starting_approach`
> and `creditor_obligation_fulfilled` on create and update; sending either
> field, even as `null`, returns `400`. Do not send
> `starting_approach: "enforcement"`: enforcement is derived by paywise,
> and the titled-order response does not expose a starting-approach field.

## Prerequisites

* A production or sandbox base URL and Bearer key.
* An entitled company UUID on every call when using a Partner key.
* A debtor UUID with sufficient address and notification data.
* Per titled claim: the enforceable title's kind, issuing authority, file
  number, issue date, gross amount, and the title document as PDF, JPEG, or
  PNG (10 MiB at most).
* One stable `Idempotency-Key` per logical `POST` command.

## Lifecycle context

A titled order follows the same draft → `submitted` → `accepted` lifecycle
as an invoice order. Enforcement is implicit: there are no starting-approach
decisions, and finalization additionally requires `success_fee_confirmed:
true`. Each `TitledClaim` owns one enforceable title singleton whose amount
is authoritative; enforcement costs are ordinary `ReceivableClaim` entries.
Documents scan asynchronously and never block finalization.

## 0. Create or reuse the debtor

Create the reusable debtor first. Each example parses the exact returned UUID;
persist it as `DEBTOR_ID` and use that value in the order request. Reconcile
an ambiguous retry by the exact `your_reference`; never guess an ID.

```python Python theme={null}
import uuid
import requests

PAYWISE_API_URL = "https://api-sandbox.paywise.de"
PAYWISE_API_KEY = "pw_sbx_your_api_key"
DEBTOR_COMMAND_ID = "your-debtor-command-id"
DEBTOR_REFERENCE = "quickstart-debtor-80000000-0000-4000-8000-000000000001"
payload = {
    "your_reference": DEBTOR_REFERENCE,
    "acting_as": "consumer",
    "person": {"salutation": "mx", "first_name": "Alex", "last_name": "Example"},
    "addresses": [{"street": "Example Street 12", "postal_code": "10115", "city": "Berlin", "country": "DE", "primary": True}],
}
response = requests.post(
    f"{PAYWISE_API_URL}/v2/debtors/",
    headers={"Authorization": f"Bearer {PAYWISE_API_KEY}", "Content-Type": "application/json", "Idempotency-Key": DEBTOR_COMMAND_ID},
    json=payload,
    timeout=(5, 30),
)
if response.status_code != 201:
    response.raise_for_status()
    raise RuntimeError(f"Expected 201, received {response.status_code}")
debtor_id = str(uuid.UUID(response.json()["id"]))
```

```javascript JavaScript theme={null}
const payload = {
  your_reference: process.env.DEBTOR_REFERENCE,
  acting_as: "consumer",
  person: { salutation: "mx", first_name: "Alex", last_name: "Example" },
  addresses: [{ street: "Example Street 12", postal_code: "10115", city: "Berlin", country: "DE", primary: true }],
};
const response = await fetch(`${process.env.PAYWISE_API_URL.replace(/\/$/, "")}/v2/debtors/`, {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.PAYWISE_API_KEY}`, "Content-Type": "application/json", "Idempotency-Key": process.env.DEBTOR_COMMAND_ID },
  body: JSON.stringify(payload),
  signal: AbortSignal.timeout(30000),
});
if (response.status !== 201) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
const debtorId = (await response.json()).id;
if (!/^[0-9a-f-]{36}$/i.test(debtorId)) throw new Error("Invalid debtor UUID");
```

```java Java theme={null}
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;

class CreateDebtorRequest {
  public static void main(String[] args) throws IOException, InterruptedException {
    String json = "{\"your_reference\":\"quickstart-debtor-80000000-0000-4000-8000-000000000001\",\"acting_as\":\"consumer\",\"person\":{\"salutation\":\"mx\",\"first_name\":\"Alex\",\"last_name\":\"Example\"},\"addresses\":[{\"street\":\"Example Street 12\",\"postal_code\":\"10115\",\"city\":\"Berlin\",\"country\":\"DE\",\"primary\":true}]}";
    HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(5)).build();
    HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create(System.getenv("PAYWISE_API_URL") + "/v2/debtors/"))
        .timeout(Duration.ofSeconds(30))
        .header("Authorization", "Bearer " + System.getenv("PAYWISE_API_KEY"))
        .header("Content-Type", "application/json")
        .header("Idempotency-Key", System.getenv("DEBTOR_COMMAND_ID"))
        .POST(HttpRequest.BodyPublishers.ofString(json)).build();
    HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
    if (response.statusCode() != 201) throw new IOException(response.body());
    String debtorId = response.body().replaceFirst("(?s).*\\\"id\\\"\\s*:\\s*\\\"([0-9a-fA-F-]{36})\\\".*", "$1");
    if (debtorId.equals(response.body())) throw new IOException("Missing debtor UUID");
  }
}
```

```csharp C# theme={null}
using System;
using System.Net.Http;
using System.Net.Http.Json;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;

class CreateDebtorRequest {
    static async Task Main() {
        using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
        var payload = new {
            your_reference = "quickstart-debtor-80000000-0000-4000-8000-000000000001",
            acting_as = "consumer",
            person = new { salutation = "mx", first_name = "Alex", last_name = "Example" },
            addresses = new[] { new { street = "Example Street 12", postal_code = "10115", city = "Berlin", country = "DE", primary = true } }
        };
        using var request = new HttpRequestMessage(HttpMethod.Post, $"{Environment.GetEnvironmentVariable("PAYWISE_API_URL")}/v2/debtors/");
        request.Headers.Authorization = new("Bearer", Environment.GetEnvironmentVariable("PAYWISE_API_KEY"));
        request.Headers.Add("Idempotency-Key", Environment.GetEnvironmentVariable("DEBTOR_COMMAND_ID"));
        request.Content = JsonContent.Create(payload);
        using var cancellation = new CancellationTokenSource(TimeSpan.FromSeconds(30));
        using var response = await client.SendAsync(request, cancellation.Token);
        if ((int)response.StatusCode != 201) throw new HttpRequestException(await response.Content.ReadAsStringAsync());
        using var debtor = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
        var debtorId = debtor.RootElement.GetProperty("id").GetGuid();
    }
}
```

```bash cURL theme={null}
status="$(curl --fail-with-body --silent --show-error --connect-timeout 5 --max-time 30 \
  --request POST "$PAYWISE_API_URL/v2/debtors/" \
  --header "Authorization: Bearer $PAYWISE_API_KEY" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: $DEBTOR_COMMAND_ID" \
  --output debtor-created.json --write-out '%{http_code}' \
  --data '{"your_reference":"quickstart-debtor-80000000-0000-4000-8000-000000000001","acting_as":"consumer","person":{"salutation":"mx","first_name":"Alex","last_name":"Example"},"addresses":[{"street":"Example Street 12","postal_code":"10115","city":"Berlin","country":"DE","primary":true}]}')"
[ "$status" -eq 201 ] || exit 1
DEBTOR_ID="$(jq -er '.id' debtor-created.json)" || exit 1
```

## 1. Create inline

Use one [POST `/v2/orders/`](https://docs.paywise.de/api-docs/case-management-api/reference/orders/create-order)
when the title and its evidence are ready. The order, claim, title, payment,
and document writes commit atomically.

```python Python theme={null}
import requests

PAYWISE_API_URL = "https://api-sandbox.paywise.de"
PAYWISE_API_KEY = "pw_sbx_your_api_key"
ORDER_COMMAND_ID = "your-order-command-id"
DEBTOR_ID = debtor_id  # Parsed from the immediately preceding create response.

payload = {
    "type": "titled",
    "debtor_id": DEBTOR_ID,
    "additional_debtor_ids": [],
    "success_fee_confirmed": True,
    "claims": [
        {
            "type": "titled",
            "your_reference": "TITLE-2026-0042",
            "subject_matter": "Enforcement title",
            "is_disputed": False,
            "enforceable_title": {
                "title_type": "enforcement_order",
                "issuing_authority": "Amtsgericht Berlin",
                "file_number": "12-3456789-0-1",
                "issued_on": "2026-01-15",
                "legally_binding_since": "2026-02-01",
                "served_on": "2026-01-20",
                "amount": {
                    "value": "2500.00",
                    "currency": "EUR"
                },
                "documents": [
                    {
                        "type": "enforceable_title",
                        "filename": "enforcement-order.pdf",
                        "base64": "JVBERi0xLjQKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFszIDAgUl0gL0NvdW50IDEgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCAyMDAgMTAwXSA+PgplbmRvYmoKeHJlZgowIDQKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDA5IDAwMDAwIG4gCjAwMDAwMDAwNTggMDAwMDAgbiAKMDAwMDAwMDExNSAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDQgL1Jvb3QgMSAwIFIgPj4Kc3RhcnR4cmVmCjE4NgolJUVPRgo="
                    }
                ]
            }
        }
    ]
}
response = requests.post(
    f"{PAYWISE_API_URL}/v2/orders/",
    headers={
        "Authorization": f"Bearer {PAYWISE_API_KEY}",
        "Content-Type": "application/json",
        "Idempotency-Key": ORDER_COMMAND_ID,
    },
    json=payload,
    timeout=(5, 30),
)
if response.status_code != 201:
    response.raise_for_status()
    raise RuntimeError(f"Expected 201, received {response.status_code}")
order = response.json()
order_id = order["id"]
matching_claims = [claim for claim in order.get("claims", []) if claim.get("your_reference") == "TITLE-2026-0042"]
if len(matching_claims) != 1:
    raise RuntimeError("Expected exactly one matching claim")
claim_id = matching_claims[0]["id"]
```

```javascript JavaScript theme={null}
const payload = {
  "type": "titled",
  "debtor_id": process.env.DEBTOR_ID,
    "additional_debtor_ids": [],
  "success_fee_confirmed": true,
  "claims": [
    {
      "type": "titled",
      "your_reference": "TITLE-2026-0042",
      "subject_matter": "Enforcement title",
      "is_disputed": false,
      "enforceable_title": {
        "title_type": "enforcement_order",
        "issuing_authority": "Amtsgericht Berlin",
        "file_number": "12-3456789-0-1",
        "issued_on": "2026-01-15",
        "legally_binding_since": "2026-02-01",
        "served_on": "2026-01-20",
        "amount": {
          "value": "2500.00",
          "currency": "EUR"
        },
        "documents": [
          {
            "type": "enforceable_title",
            "filename": "enforcement-order.pdf",
            "base64": "JVBERi0xLjQKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFszIDAgUl0gL0NvdW50IDEgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCAyMDAgMTAwXSA+PgplbmRvYmoKeHJlZgowIDQKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDA5IDAwMDAwIG4gCjAwMDAwMDAwNTggMDAwMDAgbiAKMDAwMDAwMDExNSAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDQgL1Jvb3QgMSAwIFIgPj4Kc3RhcnR4cmVmCjE4NgolJUVPRgo="
          }
        ]
      }
    }
  ]
};
const response = await fetch(`${process.env.PAYWISE_API_URL.replace(/\/$/, "")}/v2/orders/`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.PAYWISE_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": process.env.ORDER_COMMAND_ID,
  },
  body: JSON.stringify(payload),
  signal: AbortSignal.timeout(30000),
});
if (response.status !== 201) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
const order = await response.json();
const orderId = order.id;
const matchingClaims = order.claims.filter((claim) => claim.your_reference === payload.claims[0].your_reference);
if (matchingClaims.length !== 1) throw new Error("Expected exactly one matching claim");
const claimId = matchingClaims[0].id;
```

```java Java theme={null}
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;

class TitledOrderRequest {
  static int closingDelimiter(String json, int opening, char open, char close) {
    int depth = 0;
    boolean inString = false;
    boolean escaped = false;
    for (int index = opening; index < json.length(); index++) {
      char character = json.charAt(index);
      if (inString) {
        if (escaped) escaped = false;
        else if (character == '\\') escaped = true;
        else if (character == '\"') inString = false;
      } else if (character == '\"') inString = true;
      else if (character == open) depth++;
      else if (character == close && --depth == 0) return index;
    }
    throw new IllegalArgumentException("Malformed JSON response");
  }
  static int closingQuote(String json, int opening) {
    boolean escaped = false;
    for (int index = opening + 1; index < json.length(); index++) {
      char character = json.charAt(index);
      if (escaped) escaped = false;
      else if (character == '\\') escaped = true;
      else if (character == '\"') return index;
    }
    throw new IllegalArgumentException("Malformed JSON string");
  }
  static int hexDigit(char character) {
    if (character >= '0' && character <= '9') return character - '0';
    if (character >= 'a' && character <= 'f') return character - 'a' + 10;
    if (character >= 'A' && character <= 'F') return character - 'A' + 10;
    throw new IllegalArgumentException("Malformed Unicode escape");
  }
  static int unicodeEscape(String json, int firstDigit, int closing) {
    if (firstDigit + 4 > closing) throw new IllegalArgumentException("Malformed Unicode escape");
    int value = 0;
    for (int index = firstDigit; index < firstDigit + 4; index++)
      value = value * 16 + hexDigit(json.charAt(index));
    return value;
  }
  static String decodeJsonString(String json, int opening, int closing) {
    StringBuilder decoded = new StringBuilder();
    for (int index = opening + 1; index < closing; index++) {
      char character = json.charAt(index);
      if (character == '\\') {
        if (++index >= closing) throw new IllegalArgumentException("Malformed JSON escape");
        char escape = json.charAt(index);
        switch (escape) {
          case '\"': decoded.append('\"'); break;
          case '\\': decoded.append('\\'); break;
          case '/': decoded.append('/'); break;
          case 'b': decoded.append('\b'); break;
          case 'f': decoded.append('\f'); break;
          case 'n': decoded.append('\n'); break;
          case 'r': decoded.append('\r'); break;
          case 't': decoded.append('\t'); break;
          case 'u':
            char unit = (char) unicodeEscape(json, index + 1, closing);
            index += 4;
            if (Character.isHighSurrogate(unit)) {
              if (index + 6 >= closing || json.charAt(index + 1) != '\\' || json.charAt(index + 2) != 'u')
                throw new IllegalArgumentException("Missing low surrogate");
              char low = (char) unicodeEscape(json, index + 3, closing);
              if (!Character.isLowSurrogate(low)) throw new IllegalArgumentException("Invalid low surrogate");
              decoded.appendCodePoint(Character.toCodePoint(unit, low));
              index += 6;
            } else if (Character.isLowSurrogate(unit)) throw new IllegalArgumentException("Unexpected low surrogate");
            else decoded.append(unit);
            break;
          default: throw new IllegalArgumentException("Unsupported JSON escape");
        }
      } else {
        if (character < 0x20) throw new IllegalArgumentException("Unescaped control character");
        if (Character.isHighSurrogate(character)) {
          if (index + 1 >= closing || !Character.isLowSurrogate(json.charAt(index + 1)))
            throw new IllegalArgumentException("Missing raw low surrogate");
          decoded.append(character).append(json.charAt(++index));
        } else if (Character.isLowSurrogate(character)) throw new IllegalArgumentException("Unexpected raw low surrogate");
        else decoded.append(character);
      }
    }
    return decoded.toString();
  }
  static String directStringField(String object, String wanted) {
    int opening = 0;
    while (opening < object.length() && Character.isWhitespace(object.charAt(opening))) opening++;
    if (opening >= object.length() || object.charAt(opening) != '{')
      throw new IllegalArgumentException("Expected JSON object");
    int closing = closingDelimiter(object, opening, '{', '}');
    for (int cursor = opening + 1; cursor < closing;) {
      while (cursor < closing && (Character.isWhitespace(object.charAt(cursor)) || object.charAt(cursor) == ',')) cursor++;
      if (cursor >= closing) break;
      if (object.charAt(cursor) != '\"') throw new IllegalArgumentException("Malformed JSON field");
      int keyClosing = closingQuote(object, cursor);
      String key = decodeJsonString(object, cursor, keyClosing);
      cursor = keyClosing + 1;
      while (cursor < closing && Character.isWhitespace(object.charAt(cursor))) cursor++;
      if (cursor >= closing || object.charAt(cursor++) != ':') throw new IllegalArgumentException("Malformed JSON field");
      while (cursor < closing && Character.isWhitespace(object.charAt(cursor))) cursor++;
      if (cursor >= closing) throw new IllegalArgumentException("Missing JSON value");
      char valueStart = object.charAt(cursor);
      if (valueStart == '\"') {
        int valueClosing = closingQuote(object, cursor);
        if (key.equals(wanted)) return decodeJsonString(object, cursor, valueClosing);
        cursor = valueClosing + 1;
      } else if (valueStart == '{' || valueStart == '[') {
        char valueClose = valueStart == '{' ? '}' : ']';
        if (key.equals(wanted)) throw new IllegalArgumentException("Expected string field " + wanted);
        cursor = closingDelimiter(object, cursor, valueStart, valueClose) + 1;
      } else {
        if (key.equals(wanted)) throw new IllegalArgumentException("Expected string field " + wanted);
        while (cursor < closing && object.charAt(cursor) != ',') cursor++;
      }
    }
    return null;
  }
  static String topLevelId(String object) {
    String id = object.replaceFirst(
        "(?s)^\\s*\\{(?:(?!\\{).)*?\\\"id\\\"\\s*:\\s*\\\"([^\\\"]+)\\\".*$", "$1");
    if (id.equals(object)) throw new IllegalArgumentException("Missing top-level id");
    return id;
  }
  static String[] responseIds(String body, String reference) {
    if (reference == null) throw new IllegalArgumentException("Missing business reference");
    String orderId = topLevelId(body);
    java.util.regex.Matcher claims = java.util.regex.Pattern
        .compile("\\\"claims\\\"\\s*:\\s*\\[").matcher(body);
    if (!claims.find()) throw new IllegalArgumentException("Missing claims collection");
    int opening = body.indexOf('[', claims.start());
    int closing = closingDelimiter(body, opening, '[', ']');
    int matches = 0;
    String claimId = null;
    for (int cursor = opening + 1; cursor < closing;) {
      while (cursor < closing && (Character.isWhitespace(body.charAt(cursor)) || body.charAt(cursor) == ',')) cursor++;
      if (cursor >= closing) break;
      if (body.charAt(cursor) != '{') throw new IllegalArgumentException("Malformed claim object");
      int claimClosing = closingDelimiter(body, cursor, '{', '}');
      String claim = body.substring(cursor, claimClosing + 1);
      if (reference.equals(directStringField(claim, "your_reference"))) {
        matches++;
        claimId = directStringField(claim, "id");
        if (claimId == null) throw new IllegalArgumentException("Missing direct claim id");
      }
      cursor = claimClosing + 1;
    }
    if (matches != 1) throw new IllegalArgumentException("Expected exactly one matching claim");
    return new String[] {orderId, claimId};
  }
  public static void main(String[] args) throws IOException, InterruptedException {
    String json = "{\"type\":\"titled\",\"debtor_id\":\"" + System.getenv("DEBTOR_ID") + "\",\"additional_debtor_ids\":[],\"succes"
        + "s_fee_confirmed\":true,\"claims\":[{\"type\":\"titled\",\"your_reference\":\"TITLE"
        + "-2026-0042\",\"subject_matter\":\"Enforcement title\",\"is_disputed\":false,\"en"
        + "forceable_title\":{\"title_type\":\"enforcement_order\",\"issuing_authority\":\""
        + "Amtsgericht Berlin\",\"file_number\":\"12-3456789-0-1\",\"issued_on\":\"2026-01-"
        + "15\",\"legally_binding_since\":\"2026-02-01\",\"served_on\":\"2026-01-20\",\"amoun"
        + "t\":{\"value\":\"2500.00\",\"currency\":\"EUR\"},\"documents\":[{\"type\":\"enforceabl"
        + "e_title\",\"filename\":\"enforcement-order.pdf\",\"base64\":\"JVBERi0xLjQKMSAwIG"
        + "9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPD"
        + "wgL1R5cGUgL1BhZ2VzIC9LaWRzIFszIDAgUl0gL0NvdW50IDEgPj4KZW5kb2JqCjMgMCBvYm"
        + "oKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCAyMDAgMTAwXS"
        + "A+PgplbmRvYmoKeHJlZgowIDQKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDA5IDAwMD"
        + "AwIG4gCjAwMDAwMDAwNTggMDAwMDAgbiAKMDAwMDAwMDExNSAwMDAwMCBuIAp0cmFpbGVyCj"
        + "w8IC9TaXplIDQgL1Jvb3QgMSAwIFIgPj4Kc3RhcnR4cmVmCjE4NgolJUVPRgo=\"}]}}]}";
    HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(5)).build();
    HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create(System.getenv("PAYWISE_API_URL") + "/v2/orders/"))
        .timeout(Duration.ofSeconds(30))
        .header("Authorization", "Bearer " + System.getenv("PAYWISE_API_KEY"))
        .header("Content-Type", "application/json")
        .header("Idempotency-Key", System.getenv("ORDER_COMMAND_ID"))
        .POST(HttpRequest.BodyPublishers.ofString(json)).build();
    HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
    if (response.statusCode() != 201) throw new IOException(response.body());
    String[] ids = responseIds(response.body(), "TITLE-2026-0042");
    String orderId = ids[0];
    String claimId = ids[1];
  }
}
```

```csharp C# theme={null}
using System;
using System.Net.Http;
using System.Net.Http.Json;
using System.Linq;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;

class TitledOrderRequest
{
    static async Task Main()
    {
        using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
        var payload = new {
            type = "titled",
            debtor_id = Environment.GetEnvironmentVariable("DEBTOR_ID"), additional_debtor_ids = Array.Empty<string>(),
            success_fee_confirmed = true,
            claims = new[] {
                new {
                    type = "titled",
                    your_reference = "TITLE-2026-0042",
                    subject_matter = "Enforcement title",
                    is_disputed = false,
                    enforceable_title = new {
                        title_type = "enforcement_order",
                        issuing_authority = "Amtsgericht Berlin",
                        file_number = "12-3456789-0-1",
                        issued_on = "2026-01-15",
                        legally_binding_since = "2026-02-01",
                        served_on = "2026-01-20",
                        amount = new {
                            value = "2500.00",
                            currency = "EUR"
                        },
                        documents = new[] {
                            new {
                                type = "enforceable_title",
                                filename = "enforcement-order.pdf",
                                base64 = "JVBERi0xLjQKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFszIDAgUl0gL0NvdW50IDEgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCAyMDAgMTAwXSA+PgplbmRvYmoKeHJlZgowIDQKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDA5IDAwMDAwIG4gCjAwMDAwMDAwNTggMDAwMDAgbiAKMDAwMDAwMDExNSAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDQgL1Jvb3QgMSAwIFIgPj4Kc3RhcnR4cmVmCjE4NgolJUVPRgo="
                            }
                        }
                    }
                }
            }
        };
        using var request = new HttpRequestMessage(HttpMethod.Post,
            $"{Environment.GetEnvironmentVariable("PAYWISE_API_URL")}/v2/orders/");
        request.Headers.Authorization = new("Bearer", Environment.GetEnvironmentVariable("PAYWISE_API_KEY"));
        request.Headers.Add("Idempotency-Key", Environment.GetEnvironmentVariable("ORDER_COMMAND_ID"));
        request.Content = JsonContent.Create(payload);
        using var cancellation = new CancellationTokenSource(TimeSpan.FromSeconds(30));
        using var response = await client.SendAsync(request, cancellation.Token);
        if ((int)response.StatusCode != 201) throw new HttpRequestException(await response.Content.ReadAsStringAsync());
        using var order = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
        var orderId = order.RootElement.GetProperty("id").GetGuid();
        var matches = order.RootElement.GetProperty("claims").EnumerateArray()
            .Where(claim => claim.GetProperty("your_reference").GetString() == payload.claims[0].your_reference).ToArray();
        if (matches.Length != 1) throw new InvalidOperationException("Expected exactly one matching claim");
        var claimId = matches[0].GetProperty("id").GetGuid();
    }
}
```

```bash cURL theme={null}
http_status="$(curl --fail-with-body --output order-response.json --write-out '%{http_code}' --silent --show-error --connect-timeout 5 --max-time 30 \
  --request POST "$PAYWISE_API_URL/v2/orders/" \
  --header "Authorization: Bearer $PAYWISE_API_KEY" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: $ORDER_COMMAND_ID" \
  --data @- <<JSON
{
  "type": "titled",
  "debtor_id": "$DEBTOR_ID",
    "additional_debtor_ids": [],
  "success_fee_confirmed": true,
  "claims": [
    {
      "type": "titled",
      "your_reference": "TITLE-2026-0042",
      "subject_matter": "Enforcement title",
      "is_disputed": false,
      "enforceable_title": {
        "title_type": "enforcement_order",
        "issuing_authority": "Amtsgericht Berlin",
        "file_number": "12-3456789-0-1",
        "issued_on": "2026-01-15",
        "legally_binding_since": "2026-02-01",
        "served_on": "2026-01-20",
        "amount": {
          "value": "2500.00",
          "currency": "EUR"
        },
        "documents": [
          {
            "type": "enforceable_title",
            "filename": "enforcement-order.pdf",
            "base64": "JVBERi0xLjQKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFszIDAgUl0gL0NvdW50IDEgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCAyMDAgMTAwXSA+PgplbmRvYmoKeHJlZgowIDQKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDA5IDAwMDAwIG4gCjAwMDAwMDAwNTggMDAwMDAgbiAKMDAwMDAwMDExNSAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDQgL1Jvb3QgMSAwIFIgPj4Kc3RhcnR4cmVmCjE4NgolJUVPRgo="
          }
        ]
      }
    }
  ]
}
JSON
)"
[ "$http_status" -eq 201 ] || exit 1
ORDER_ID="$(jq -er '.id' order-response.json)" || exit 1
CLAIM_ID="$(jq -er --arg ref "TITLE-2026-0042" '[.claims[] | select(.your_reference == $ref)] | if length == 1 then .[0].id else error("expected exactly one matching claim") end' order-response.json)" || exit 1
```

The claim's `type` must be `titled`. The title's `amount`, metadata, and
documents are authoritative. Do not send `principal_amount`, items, charges,
dates, reminders, legal basis, or generic claim documents on a titled claim. Its response has
`principal_amount: null`, and `total_amount` mirrors the title amount.

`served_on` and `legally_binding_since` are optional finalization fields, but
normally supply service date and proof of service when available so paywise
can assess enforcement without a later clarification. Neither date may be
earlier than `issued_on`.

## 2. Choose the exact title kind

`title_type` accepts only the generated enum:

| Value | German legal term |
| - | - |
| `enforcement_order` | Vollstreckungsbescheid |
| `default_judgment` | Versäumnisurteil |
| `final_judgment` | Endurteil |
| `acknowledgment_judgment` | Anerkenntnisurteil |
| `reservation_judgment` | Vorbehaltsurteil |
| `court_settlement` | Gerichtlicher Vergleich |
| `enforceable_notarial_deed` | Vollstreckbare notarielle Urkunde |
| `cost_assessment_order` | Kostenfestsetzungsbeschluss |
| `other` | Sonstiger Titel |

## 3. Build the draft in stages

Create the empty titled draft first, then use a distinct stable idempotency key
for the claim command. Preserve the exact key and body for replay, and store the
returned claim UUID only after verifying the exact `your_reference`.

```python Python theme={null}
import requests

PAYWISE_API_URL = "https://api-sandbox.paywise.de"
PAYWISE_API_KEY = "pw_sbx_your_api_key"
CREATE_CLAIM_KEY = "your-distinct-create-claim-key"
claim_payload = {
    "order_id": "20000000-0000-4000-8000-000000000001",
    "type": "titled", "your_reference": "TITLE-2026-0042",
    "subject_matter": "Enforcement title", "is_disputed": False,
    "enforceable_title": {
        "title_type": "enforcement_order", "issuing_authority": "Amtsgericht Berlin",
        "file_number": "12-3456789-0-1", "issued_on": "2026-01-15",
        "legally_binding_since": "2026-02-01", "served_on": "2026-01-20",
        "amount": {"value": "2500.00", "currency": "EUR"},
        "documents": [{"type": "enforceable_title", "filename": "enforcement-order.pdf", "base64": "JVBERi0xLjQKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFszIDAgUl0gL0NvdW50IDEgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCAyMDAgMTAwXSA+PgplbmRvYmoKeHJlZgowIDQKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDA5IDAwMDAwIG4gCjAwMDAwMDAwNTggMDAwMDAgbiAKMDAwMDAwMDExNSAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDQgL1Jvb3QgMSAwIFIgPj4Kc3RhcnR4cmVmCjE4NgolJUVPRgo="}],
    },
}
response = requests.post(
    f"{PAYWISE_API_URL}/v2/claims/",
    headers={"Authorization": f"Bearer {PAYWISE_API_KEY}", "Content-Type": "application/json", "Idempotency-Key": CREATE_CLAIM_KEY},
    json=claim_payload, timeout=(5, 30),
)
if response.status_code != 201:
    response.raise_for_status()
    raise RuntimeError(f"Expected 201, received {response.status_code}")
claim = response.json()
if claim.get("your_reference") != claim_payload["your_reference"]:
    raise RuntimeError("Claim business reference mismatch")
claim_id = claim["id"]
```

```javascript JavaScript theme={null}
const claimPayload = {
  order_id: "20000000-0000-4000-8000-000000000001",
  type: "titled", your_reference: "TITLE-2026-0042", subject_matter: "Enforcement title", is_disputed: false,
  enforceable_title: {
    title_type: "enforcement_order", issuing_authority: "Amtsgericht Berlin",
    file_number: "12-3456789-0-1", issued_on: "2026-01-15",
    legally_binding_since: "2026-02-01", served_on: "2026-01-20",
    amount: { value: "2500.00", currency: "EUR" },
    documents: [{ type: "enforceable_title", filename: "enforcement-order.pdf", base64: "JVBERi0xLjQKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFszIDAgUl0gL0NvdW50IDEgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCAyMDAgMTAwXSA+PgplbmRvYmoKeHJlZgowIDQKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDA5IDAwMDAwIG4gCjAwMDAwMDAwNTggMDAwMDAgbiAKMDAwMDAwMDExNSAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDQgL1Jvb3QgMSAwIFIgPj4Kc3RhcnR4cmVmCjE4NgolJUVPRgo=" }],
  },
};
const response = await fetch(`${process.env.PAYWISE_API_URL.replace(/\/$/, "")}/v2/claims/`, {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.PAYWISE_API_KEY}`, "Content-Type": "application/json", "Idempotency-Key": process.env.CREATE_CLAIM_KEY },
  body: JSON.stringify(claimPayload), signal: AbortSignal.timeout(30000),
});
if (response.status !== 201) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
const claim = await response.json();
if (claim.your_reference !== claimPayload.your_reference) throw new Error("Claim business reference mismatch");
const claimId = claim.id;
```

```java Java theme={null}
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
class CreateTitledClaimRequest {
  static String quoteJsonString(String value) {
    if (value == null) throw new IllegalArgumentException("Missing business reference");
    return "\"" + value.replace("\\", "\\\\").replace("\"", "\\\"") + "\"";
  }
  static String topLevelId(String object) {
    String id = object.replaceFirst(
        "(?s)^\\s*\\{(?:(?!\\{).)*?\\\"id\\\"\\s*:\\s*\\\"([^\\\"]+)\\\".*$", "$1");
    if (id.equals(object)) throw new IllegalArgumentException("Missing top-level claim id");
    return id;
  }
  static String createdClaimId(String body, String reference) {
    String referencePattern = "(?s)^\\s*\\{(?:(?!\\{).)*?\\\"your_reference\\\"\\s*:\\s*"
        + java.util.regex.Pattern.quote(quoteJsonString(reference));
    if (!java.util.regex.Pattern.compile(referencePattern).matcher(body).find())
      throw new IllegalArgumentException("Claim business reference mismatch");
    return topLevelId(body);
  }
  public static void main(String[] args) throws IOException, InterruptedException {
    String json = "{\"order_id\":\"20000000-0000-4000-8000-000000000001\",\"type\":\"titled\",\"your_reference\":\"TITLE-2026-0042\",\"subject_matter\":\"Enforcement title\",\"is_disputed\":false,\"enforceable_title\":{\"title_type\":\"enforcement_order\",\"issuing_authority\":\"Amtsgericht Berlin\",\"file_number\":\"12-3456789-0-1\",\"issued_on\":\"2026-01-15\",\"legally_binding_since\":\"2026-02-01\",\"served_on\":\"2026-01-20\",\"amount\":{\"value\":\"2500.00\",\"currency\":\"EUR\"},\"documents\":[{\"type\":\"enforceable_title\",\"filename\":\"enforcement-order.pdf\",\"base64\":\"JVBERi0xLjQKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFszIDAgUl0gL0NvdW50IDEgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCAyMDAgMTAwXSA+PgplbmRvYmoKeHJlZgowIDQKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDA5IDAwMDAwIG4gCjAwMDAwMDAwNTggMDAwMDAgbiAKMDAwMDAwMDExNSAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDQgL1Jvb3QgMSAwIFIgPj4Kc3RhcnR4cmVmCjE4NgolJUVPRgo=\"}]}}";
    HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(5)).build();
    HttpRequest request = HttpRequest.newBuilder().uri(URI.create(System.getenv("PAYWISE_API_URL") + "/v2/claims/"))
        .timeout(Duration.ofSeconds(30)).header("Authorization", "Bearer " + System.getenv("PAYWISE_API_KEY"))
        .header("Content-Type", "application/json").header("Idempotency-Key", System.getenv("CREATE_CLAIM_KEY"))
        .POST(HttpRequest.BodyPublishers.ofString(json)).build();
    HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
    if (response.statusCode() != 201) throw new IOException(response.body());
    String claimId = createdClaimId(response.body(), "TITLE-2026-0042");
  }
}
```

```csharp C# theme={null}
using System;
using System.Net.Http;
using System.Net.Http.Json;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
class CreateTitledClaimRequest {
    static async Task Main() {
        using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
        var payload = new {
            order_id = "20000000-0000-4000-8000-000000000001", type = "titled",
            your_reference = "TITLE-2026-0042", subject_matter = "Enforcement title", is_disputed = false,
            enforceable_title = new {
                title_type = "enforcement_order", issuing_authority = "Amtsgericht Berlin",
                file_number = "12-3456789-0-1", issued_on = "2026-01-15",
                legally_binding_since = "2026-02-01", served_on = "2026-01-20",
                amount = new { value = "2500.00", currency = "EUR" },
                documents = new[] { new { type = "enforceable_title", filename = "enforcement-order.pdf", base64 = "JVBERi0xLjQKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFszIDAgUl0gL0NvdW50IDEgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCAyMDAgMTAwXSA+PgplbmRvYmoKeHJlZgowIDQKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDA5IDAwMDAwIG4gCjAwMDAwMDAwNTggMDAwMDAgbiAKMDAwMDAwMDExNSAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDQgL1Jvb3QgMSAwIFIgPj4Kc3RhcnR4cmVmCjE4NgolJUVPRgo=" } }
            }
        };
        using var request = new HttpRequestMessage(HttpMethod.Post, $"{Environment.GetEnvironmentVariable("PAYWISE_API_URL")}/v2/claims/");
        request.Headers.Authorization = new("Bearer", Environment.GetEnvironmentVariable("PAYWISE_API_KEY"));
        request.Headers.Add("Idempotency-Key", Environment.GetEnvironmentVariable("CREATE_CLAIM_KEY"));
        request.Content = JsonContent.Create(payload);
        using var cancellation = new CancellationTokenSource(TimeSpan.FromSeconds(30));
        using var response = await client.SendAsync(request, cancellation.Token);
        if ((int)response.StatusCode != 201) throw new HttpRequestException(await response.Content.ReadAsStringAsync());
        using var claim = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
        if (claim.RootElement.GetProperty("your_reference").GetString() != payload.your_reference) throw new InvalidOperationException("Claim business reference mismatch");
        var claimId = claim.RootElement.GetProperty("id").GetGuid();
    }
}
```

```bash cURL theme={null}
status="$(curl --fail-with-body --silent --show-error --connect-timeout 5 --max-time 30 \
  --request POST "$PAYWISE_API_URL/v2/claims/" \
  --header "Authorization: Bearer $PAYWISE_API_KEY" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: $CREATE_CLAIM_KEY" \
  --output claim-created.json --write-out '%{http_code}' \
  --data '{"order_id":"20000000-0000-4000-8000-000000000001","type":"titled","your_reference":"TITLE-2026-0042","subject_matter":"Enforcement title","is_disputed":false,"enforceable_title":{"title_type":"enforcement_order","issuing_authority":"Amtsgericht Berlin","file_number":"12-3456789-0-1","issued_on":"2026-01-15","legally_binding_since":"2026-02-01","served_on":"2026-01-20","amount":{"value":"2500.00","currency":"EUR"},"documents":[{"type":"enforceable_title","filename":"enforcement-order.pdf","base64":"JVBERi0xLjQKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFszIDAgUl0gL0NvdW50IDEgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCAyMDAgMTAwXSA+PgplbmRvYmoKeHJlZgowIDQKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDA5IDAwMDAwIG4gCjAwMDAwMDAwNTggMDAwMDAgbiAKMDAwMDAwMDExNSAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDQgL1Jvb3QgMSAwIFIgPj4Kc3RhcnR4cmVmCjE4NgolJUVPRgo="}]}}')"
[ "$status" -eq 201 ] || exit 1
CLAIM_ID="$(jq -er --arg ref "TITLE-2026-0042" 'if .your_reference == $ref then .id else error("claim business reference mismatch") end' claim-created.json)" || exit 1
```

## Staged-title repair details

Create a `type: "titled"` draft with `success_fee_confirmed: false` and an
empty claim list. Add a titled claim with
[POST `/v2/claims/`](https://docs.paywise.de/api-docs/case-management-api/reference/claims/create-claim):

```json theme={null}
{
  "type": "titled",
  "your_reference": "TITLE-STAGED-2026-0042",
  "subject_matter": "Enforcement title",
  "is_disputed": false,
  "enforceable_title": {
    "title_type": "court_settlement",
    "issuing_authority": "Landgericht Berlin",
    "file_number": "42 O 100/26",
    "issued_on": "2026-02-10",
    "amount": {"value": "5000.00", "currency": "EUR"}
  }
}
```

Manage the claim-owned singleton later with
[PUT `/v2/claims/{claim_id}/enforceable-title/`](https://docs.paywise.de/api-docs/case-management-api/reference/claims/replace-enforceable-title)
or
[PATCH `/v2/claims/{claim_id}/enforceable-title/`](https://docs.paywise.de/api-docs/case-management-api/reference/claims/update-enforceable-title).
`PUT` creates it if absent (`201`) or replaces all writable metadata and
amount (`200`); omitted writable fields are cleared, but documents remain, and
an empty body is `400`. The title exists only on a `titled` claim: on a
receivable claim of the order, such as K014 enforcement costs, `PUT`, `PATCH`,
and `DELETE …/enforceable-title/` answer `404`
(`No enforceable title found for the given reference.`). `PATCH` changes only
supplied fields. Draft-only
DELETE removes the title metadata; it conflicts with `409` (listing
`document_ids[]`) while title documents exist, so delete those documents
first. The claim stays `type: titled` with `enforceable_title: null` until you
`PUT` a new title or delete the claim.

### Repair an incompatible titled draft

An existing or staff-converted draft can return `422` readiness errors for
incompatible `ReceivableClaim` fields on a titled claim, such as
`claims.{claim_id}.items` or `claims.{claim_id}.additional_charges`. The
supported public repair is to replace that Claim while the order is a draft:

1. Because deletion is permanent, preserve any needed data client-side before
   deleting the claim.
2. Send DELETE `/v2/claims/{claim_id}/`.
3. Send POST `/v2/claims/` with `"type": "titled"`, only
   neutral claim fields, and an inline `enforceable_title`.

These claim mutations are draft-only, so complete the repair before
finalizing.

Upload exactly one primary `enforceable_title` document below the singleton.
Additional `other` documents are allowed. Creating a second primary returns
`409` until the old draft document is deleted.

## 4. Add enforcement costs separately

A titled order may contain ordinary enforcement costs as `ReceivableClaim`
entries (`"type": "receivable"`). Omit `legal_basis.claim_type_code`; paywise
derives K014. For example:

```json theme={null}
{
  "type": "receivable",
  "your_reference": "ENFORCEMENT-COST-1",
  "subject_matter": "Enforcement costs",
  "document_date": "2026-02-12",
  "is_disputed": false,
  "principal_amount": {"value": "75.00", "currency": "EUR"}
}
```

In titled totals, `main_claims` combines authoritative title amounts and
`ReceivableClaim` principals. `charges` contains only receivable-claim additional
charges, and `order_value` is their gross sum. Payments are reported
separately and do not reduce those gross totals.

## 5. Confirm and finalize

Before finalizing, patch the draft with `{"success_fee_confirmed": true}`.
This explicitly acknowledges the success-fee condition and is required even
when every title is otherwise complete. See the
[paywise General Terms and Conditions (AGB)](https://paywise.de/agb/) for the
exact conditions for titled orders.

Finalize with an empty-body
[POST `/v2/orders/{id}/finalize/`](https://docs.paywise.de/api-docs/case-management-api/reference/orders/finalize-order)
and a fresh `Idempotency-Key`. Each titled claim must have a positive
amount, title type, issuing authority, file number, issue date, and primary
title document. An incomplete aggregate returns `422`; invalid values return
`400`; immutable, duplicate-document, and lifecycle conflicts return `409`.

Read the order after an ambiguous outcome, withdraw it only while submitted
and eligible, or delete the whole order while it is still a draft.

## Runnable Python workflow

This orchestration proves the sandbox before any write, creates the titled
draft with the success fee unconfirmed, confirms it with a `PATCH`, uses one
generated key per logical POST, and never automatically repeats an ambiguous
finalize call.

```python Python workflow theme={null}
import uuid
import requests

PAYWISE_API_URL = "https://api-sandbox.paywise.de"
PAYWISE_API_KEY = "pw_sbx_your_api_key"
DEBTOR_ID = "40000000-0000-4000-8000-000000000001"

base_url = PAYWISE_API_URL
if not base_url.startswith("https://"):
    raise ValueError("PAYWISE_API_URL must be an HTTPS sandbox URL")
headers = {"Authorization": f"Bearer {PAYWISE_API_KEY}"}

probe = requests.get(
    f"{base_url}/v2/orders/",
    headers=headers,
    params={"limit": 1},
    timeout=(5, 30),
)
if probe.status_code != 200:
    probe.raise_for_status()
    raise RuntimeError(f"Expected 200, received {probe.status_code}")
if probe.headers.get("X-Paywise-Environment", "").lower() != "sandbox":
    raise RuntimeError("Refusing writes without authenticated sandbox proof")

# Stage 1: a titled draft with the success fee still unconfirmed and one
# complete titled claim. The title document is a placeholder PDF here.
create_key = str(uuid.uuid4())
created = requests.post(
    f"{base_url}/v2/orders/",
    headers={**headers, "Idempotency-Key": create_key},
    json={
        "type": "titled",
        "debtor_id": DEBTOR_ID,
        "success_fee_confirmed": False,
        "claims": [{
            "type": "titled",
            "your_reference": "TITLE-2026-0042",
            "subject_matter": "Enforcement title",
            "is_disputed": False,
            "enforceable_title": {
                "title_type": "enforcement_order",
                "issuing_authority": "Amtsgericht Berlin",
                "file_number": "12-3456789-0-1",
                "issued_on": "2026-01-15",
                "legally_binding_since": "2026-02-01",
                "served_on": "2026-01-20",
                "amount": {"value": "2500.00", "currency": "EUR"},
                "documents": [{
                    "type": "enforceable_title",
                    "filename": "enforcement-order.pdf",
                    "base64": "JVBERi0xLjQKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFszIDAgUl0gL0NvdW50IDEgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCAyMDAgMTAwXSA+PgplbmRvYmoKeHJlZgowIDQKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDA5IDAwMDAwIG4gCjAwMDAwMDAwNTggMDAwMDAgbiAKMDAwMDAwMDExNSAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDQgL1Jvb3QgMSAwIFIgPj4Kc3RhcnR4cmVmCjE4NgolJUVPRgo=",
                }],
            },
        }],
    },
    timeout=(5, 30),
)
if created.status_code != 201:
    created.raise_for_status()
    raise RuntimeError(f"Expected 201, received {created.status_code}")
order = created.json()
if order.get("type") != "titled" or order.get("status") != "draft":
    raise RuntimeError("Created order is not an editable titled draft")
order_id = order["id"]
matching_claims = [
    claim for claim in order.get("claims", [])
    if claim.get("your_reference") == "TITLE-2026-0042"
]
if len(matching_claims) != 1:
    raise RuntimeError("Expected exactly one claim with the submitted business reference")
claim_id = matching_claims[0]["id"]

# Stage 2: acknowledge the success-fee condition explicitly; finalize
# refuses a titled draft without it.
confirmed = requests.patch(
    f"{base_url}/v2/orders/{order_id}/",
    headers=headers,
    json={"success_fee_confirmed": True},
    timeout=(5, 30),
)
if confirmed.status_code != 200:
    confirmed.raise_for_status()
    raise RuntimeError(f"Expected 200, received {confirmed.status_code}")
if confirmed.json().get("success_fee_confirmed") is not True:
    raise RuntimeError("Success fee confirmation was not persisted")

finalize_key = str(uuid.uuid4())
try:
    finalized = requests.post(
        f"{base_url}/v2/orders/{order_id}/finalize/",
        headers={**headers, "Idempotency-Key": finalize_key},
        timeout=(5, 30),
    )
except requests.Timeout:
    recovered = requests.get(
        f"{base_url}/v2/orders/{order_id}/",
        headers=headers,
        timeout=(5, 30),
    )
    if recovered.status_code != 200:
        recovered.raise_for_status()
        raise RuntimeError(f"Expected 200, received {recovered.status_code}")
    order = recovered.json()
    if order.get("status") not in {
        "submitted",
        "awaiting_client_response",
        "accepted",
        "rejected",
        "withdrawn",
        "expired",
    }:
        raise RuntimeError(
            "Finalize outcome remains ambiguous; inspect the draft before deciding whether to retry with the same key"
        )
else:
    if finalized.status_code != 200:
        finalized.raise_for_status()
        raise RuntimeError(f"Expected 200, received {finalized.status_code}")
    order = finalized.json()

WORKFLOW_RESULT = {"order_id": order_id, "claim_id": claim_id, "status": order["status"]}
```

## Failure and recovery

* `400 validation_error`: `success_fee_confirmed` as anything but JSON `true`
  or `false`, `starting_approach` or
  `creditor_obligation_fulfilled` sent on a titled order (even as `null`),
  `principal_amount`, dates, items, charges, reminders, or a legal basis on a
  titled claim, a `served_on` or `legally_binding_since` earlier than
  `issued_on`, or an unknown `title_type`. Correct the field paths named in
  `errors[]` and issue a new logical command.
* `409`: a second primary `enforceable_title` document (delete the old draft
  document first), an immutable-field change such as the order or claim
  `type`, a `DELETE …/enforceable-title/` while title documents still exist
  (the envelope lists them in `document_ids[]`), or a lifecycle conflict —
  including an order merged into another order, which answers
  `Order was merged into another order.` on every write; an expired draft
  answers `409 order_expired` on every write. Refetch the order before
  deciding. A `PUT` or `PATCH` on the title that repeats the stored
  values is a `200` no-op and leaves `updated_at` and the `ETag` unchanged.
* `422` on finalize: an incomplete titled claim (missing amount, title
  metadata, or primary title document — a title-less claim reports
  `claims.{claim_id}.enforceable_title` / `required`), `success_fee_confirmed`
  still `false`, or incompatible receivable fields on a titled claim — see
  [Repair an incompatible titled draft](#repair-an-incompatible-titled-draft).
  The draft stays editable; complete it and finalize with a fresh key.
* Finalize timeout, `500`, or `503`: read the order by ID before deciding
  on a retry. Only an observed `draft` justifies repeating finalize with the
  **same** key.
* `429`: wait at least the integer seconds in `Retry-After`, then retry the
  same command and key.

## Verify

```python Python theme={null}
import requests

PAYWISE_API_URL = "https://api-sandbox.paywise.de"
PAYWISE_API_KEY = "pw_sbx_your_api_key"
ORDER_ID = "20000000-0000-4000-8000-000000000001"

response = requests.get(
    f"{PAYWISE_API_URL}/v2/orders/{ORDER_ID}/",
    headers={"Authorization": f"Bearer {PAYWISE_API_KEY}"},
    timeout=(5, 30),
)
if response.status_code != 200:
    response.raise_for_status()
    raise RuntimeError(f"Expected 200, received {response.status_code}")
```

```javascript JavaScript theme={null}
const response = await fetch(`${process.env.PAYWISE_API_URL.replace(/\/$/, "")}/v2/orders/${process.env.ORDER_ID}/`, {
  method: "GET", headers: { Authorization: `Bearer ${process.env.PAYWISE_API_KEY}` }, signal: AbortSignal.timeout(30000),
});
if (response.status !== 200) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
```

```java Java theme={null}
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;

class ReadTitledOrderRequest {
  public static void main(String[] args) throws IOException, InterruptedException {
    HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(5)).build();
    HttpRequest request = HttpRequest.newBuilder().uri(URI.create(System.getenv("PAYWISE_API_URL") + "/v2/orders/" + System.getenv("ORDER_ID") + "/"))
        .timeout(Duration.ofSeconds(30)).header("Authorization", "Bearer " + System.getenv("PAYWISE_API_KEY")).GET().build();
    HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
    if (response.statusCode() != 200) throw new IOException(response.body());
  }
}
```

```csharp C# theme={null}
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

class ReadTitledOrderRequest
{
    static async Task Main()
    {
        using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
        using var request = new HttpRequestMessage(HttpMethod.Get, $"{Environment.GetEnvironmentVariable("PAYWISE_API_URL")}/v2/orders/{Environment.GetEnvironmentVariable("ORDER_ID")}/");
        request.Headers.Authorization = new("Bearer", Environment.GetEnvironmentVariable("PAYWISE_API_KEY"));
        using var cancellation = new CancellationTokenSource(TimeSpan.FromSeconds(30));
        using var response = await client.SendAsync(request, cancellation.Token);
        if ((int)response.StatusCode != 200) throw new HttpRequestException(await response.Content.ReadAsStringAsync());
    }
}
```

```bash cURL theme={null}
http_status="$(curl --fail-with-body --silent --show-error --connect-timeout 5 --max-time 30 \
  --request GET "$PAYWISE_API_URL/v2/orders/$ORDER_ID/" \
  --header "Authorization: Bearer $PAYWISE_API_KEY" \
  --output titled-order.json --write-out '%{http_code}')"
[ "$http_status" -eq 200 ] || exit 1
```

Require `.type` to be `titled`, `.status` to be `submitted` or `accepted`,
`.success_fee_confirmed` to be `true`, and every claim with `type` `titled`
to carry `enforceable_title.amount` and a primary title document before
recording the workflow as successful.

## Reconcile acceptance by claim UUID

Webhook deliveries are at least once. On `order.accepted`, intersect the event's
`claim_ids` with the claim UUIDs stored by exact business reference. For every
match, refetch `/v2/claims/{claim_id}/` and trust the claim's current
`order_id` and `mandate_id`, even when the event order differs from the
originally submitted order. The claim UUID remains stable; do not scan orders
or reconstruct merge chains.

## Related reference

* [GET `/v2/claims/{claim_id}/enforceable-title/`](https://docs.paywise.de/api-docs/case-management-api/reference/claims/get-enforceable-title)
* [DELETE `/v2/claims/{claim_id}/enforceable-title/`](https://docs.paywise.de/api-docs/case-management-api/reference/claims/delete-enforceable-title)
* [POST `/v2/claims/{claim_id}/enforceable-title/documents/`](https://docs.paywise.de/api-docs/case-management-api/reference/claims/create-enforceable-title-document)
* [GET `/v2/orders/{id}/`](https://docs.paywise.de/api-docs/case-management-api/reference/orders/get-order)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.