> ## 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.
</Note>

## 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.

<CodeGroup>
  ```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
  ```
</CodeGroup>

## 1. Create inline

Use one [POST `/v2/orders/`](/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.

<CodeGroup>
  ```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
  ```
</CodeGroup>

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`.

<CodeGroup>
  ```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
  ```
</CodeGroup>

## 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/`](/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/`](/api-docs/case-management-api/reference/claims/replace-enforceable-title)
or
[PATCH `/v2/claims/{claim_id}/enforceable-title/`](/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/`](/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

<CodeGroup>
  ```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
  ```
</CodeGroup>

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/`](/api-docs/case-management-api/reference/claims/get-enforceable-title)
* [DELETE `/v2/claims/{claim_id}/enforceable-title/`](/api-docs/case-management-api/reference/claims/delete-enforceable-title)
* [POST `/v2/claims/{claim_id}/enforceable-title/documents/`](/api-docs/case-management-api/reference/claims/create-enforceable-title-document)
* [GET `/v2/orders/{id}/`](/api-docs/case-management-api/reference/orders/get-order)


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