Skip to content

Financing & Solvency

When an end customer wants to finance a quote rather than pay outright, the quote enters a financing & solvency review. This guide walks through the flow an integration drives over the API: request financing for a quote, answer the lender's information and document requests, and receive the solvency decision. Every request is authenticated with your X-Api-Key header.

The financing lifecycle

A financing case moves through the states below — a filtered view of the quote state machine, showing only its finance_* stages. The diagram is generated directly from the code, so it always matches the API. Most transitions are driven internally by the lender's review (via Kairos and the Lynck solvency check); the calls in this guide are the ones you make. The full state machine is also on the Lifecycle page.

Financing Flow

The financing states of a quote (a filtered view of the quote lifecycle), from finance review to acceptance.

Transitions (text alternative)
Transitions of Financing Flow
Transition From To
request_finance_review accepted_by_customer finance_review
request_finance_review_direct in_progress finance_review
finance_accept finance_review finance_accepted
finance_accept manual_finance_review finance_accepted
finance_accept finance_questions finance_accepted
finance_accept finance_rejected finance_accepted
complete finance_accepted completed
finance_needs_help finance_review finance_questions
finance_needs_help manual_finance_review finance_questions
start_manual_finance_review accepted_by_customer manual_finance_review
start_manual_finance_review in_progress manual_finance_review
finance_reject finance_review finance_rejected
finance_reject manual_finance_review finance_rejected
finance_reject finance_questions finance_rejected
finance_resume finance_rejected finance_accepted

Build it step by step

POST /api/carts/{id}/checkout

Financing starts by checking out a cart with a financingType (leasing, rent_to_own, rent or a Print-Plan variant). Print-Plan variants require every cart item to reference a Print-Plan-capable category (hasPrintPlanCapability in GET /api/product-categories); otherwise the checkout is rejected with 422 and nothing is created. Checkout creates the quote and its financing case and submits it for finance review. The response returns the financeCaseId — keep it; every step below addresses this case. Build the cart first with POST /api/carts (see the Cart reference); for the non-financing path see the Create a Quote guide.

curl -X POST 'https://sandbox.partner.miete24.com/api/carts/42/checkout' \
  -H 'X-Api-Key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "duration": 36,
    "financingType": "leasing",
    "paymentInterval": "monthly",
    "customer": {
      "firstName": "Anna",
      "lastName": "Schmidt",
      "email": "anna.schmidt@example.com",
      "street": "Hauptstrasse",
      "houseNumber": "12a",
      "zipCode": "10115",
      "city": "Berlin",
      "country": "Deutschland",
      "company": "Schmidt GmbH",
      "vatId": "DE123456789"
    },
    "deliveryAddress": {
      "recipientName": "David Bühler",
      "street": "Weingartenstraße",
      "houseNumber": "5",
      "zipCode": "79211",
      "city": "Denzlingen",
      "country": "Deutschland"
    }
  }'
Response 201 (truncated)
{
  "financeCaseId": "019e964c-fb93-73a6-a672-254c170c72d9",
  "financeCaseLink": "https://app.example.com/partner/financing-cases/019e964c-fb93-73a6-a672-254c170c72d9",
  "message": "Quote successfully created"
}

Delivery address: the customer block is the lessee — its company is mandatory and its address is the contact and billing address. To ship somewhere else, add the optional deliveryAddress block with its own recipientName (mandatory) and, only for a business delivery target, a company. The quote, the contract and the offer PDF then show exactly that recipient; the lessee company is not prepended, and the customer's master data is never changed. Without the block the customer address is the delivery address, headed by the customer's company and contact person. In API responses the resolved delivery address appears as the quote's shippingAddress — the two terms name the same thing.

Quote only, without starting financing: send "submitFinancing": false in the same checkout body (optional boolean, default true). The checkout then only creates the quote, like create quote in the PartnerHub: the financing case stays in status in_progress with financingRequest: false, nothing is submitted to the lender and no e-mail goes to the customer. The partner completes the quote, sends it or starts the financing request in the PartnerHub; follow the status via GET /api/financing_cases/{id} or the financing_case.status_changed webhook. This works for every financing type, including Print-Plan. A value other than true or false is rejected with 400.

Request body (quote only)
{
  "duration": 36,
  "financingType": "leasing",
  "paymentInterval": "monthly",
  "submitFinancing": false,
  "customer": { "...": "as above" }
}
Response 201 (truncated)
{
  "financeCaseId": "019e964c-fb93-73a6-a672-254c170c72d9",
  "financeCaseLink": "https://app.example.com/partner/financing-cases/019e964c-fb93-73a6-a672-254c170c72d9",
  "message": "Quote created without financing request"
}

Errors: the checkout rejects a request before anything is created when it can tell up front that the order cannot go ahead:

Checkout rejections by HTTP status
Status When
400 The product sector is not enabled for your account, a category id or slug is unknown or belongs to another sector, the financing type is not offered for this duration, the duration is outside the depreciation (AfA) range of the products, or a rent quote has no valid custom SLA.
401 The API key is missing or invalid.
403 The cart belongs to another partner.
404 The cart does not exist.
409 The cart has already been checked out, a checkout for it is still running, or the quoteNumber is already used for one of your quotes.
422 A field is missing, invalid or unknown, the payment interval or commission tier is not available to you, a Print-Plan rule is not met, or an Idempotency-Key is reused with a different body. It is also returned when the cart items have different article types: the response then holds one violation per item with the code MIXED_ARTICLE_TYPES (this also applies to carts created before the rule); create one cart per article type. A detail starting with partner_financing_not_ready: means your partner account is still being set up by Miete24 (no financing partner assigned yet) — the cart stays active and the same request succeeds once the setup is complete.

PartnerHub does not check product availability at checkout: products are created from the item data you send. Whether the order goes ahead is decided in the review after the checkout. To learn right away when a case is canceled or rejected, subscribe to webhooks.

Full parameters, all operations & code samples → Cart reference

GET /api/financing-cases/{financingCaseId}/document-requests

During the review the lender may ask for additional information or documents. Poll this endpoint to see everything that is outstanding for the case: each item has a type (information, document or fill_and_return), a category, a status, and when present a callbackRequestId linking to the partner callback inbox. You then answer each one with the matching call below.

curl -X GET 'https://sandbox.partner.miete24.com/api/financing-cases/019e964c-fb93-73a6-a672-254c170c72d9/document-requests' \
  -H 'X-Api-Key: YOUR_API_KEY'
Response 200 (truncated)
[
  {
    "id": 12,
    "type": "information",
    "label": "Shareholder structure",
    "status": "pending",
    "category": "shareholder_information",
    "templateDownloadUrl": null,
    "callbackRequestId": 87,
    "callbackStatus": "new",
    "requestedAt": "2025-11-07T12:00:00+00:00"
  },
  {
    "id": 34,
    "type": "document",
    "label": "Business registration",
    "status": "pending",
    "category": "business_registration",
    "templateDownloadUrl": null,
    "callbackRequestId": 87,
    "callbackStatus": "new",
    "requestedAt": "2025-11-07T12:00:00+00:00"
  }
]

POST /api/financing-cases/{financingCaseId}/document-requests/information/{informationId}/respond

Answer an information request by posting the text response, using the request's id from the list above as informationId.

curl -X POST 'https://sandbox.partner.miete24.com/api/financing-cases/019e964c-fb93-73a6-a672-254c170c72d9/document-requests/information/12/respond' \
  -H 'X-Api-Key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "response": "Managing director Anna Schmidt holds 100% of the shares."
  }'

POST /api/financing-cases/{financingCaseId}/document-requests/{type}/{itemId}/not-available

Mark an optional request as not available (liegt mir nicht vor). Use the item type and id from the list. Only optional, pending, partner-visible items are accepted; wrong partner scope returns 403.

curl -X POST 'https://sandbox.partner.miete24.com/api/financing-cases/019e964c-fb93-73a6-a672-254c170c72d9/document-requests/document/34/not-available' \
  -H 'X-Api-Key: YOUR_API_KEY' \
  -H 'Content-Type: application/json'

POST /api/financing-cases/{financingCaseId}/documents

Answer a document request by uploading the file as multipart/form-data. file (PDF, PNG or JPG, max 10 MB) and category are required; pass the matching request's id as requestedDocumentId to fulfil a specific request.

curl -X POST 'https://sandbox.partner.miete24.com/api/financing-cases/019e964c-fb93-73a6-a672-254c170c72d9/documents' \
  -H 'X-Api-Key: YOUR_API_KEY' \
  -F 'file=@business_registration.pdf' \
  -F 'category=business_registration' \
  -F 'description=Handelsregisterauszug 2024' \
  -F 'requestedDocumentId=34'
Response 201 (truncated)
{
  "id": 42,
  "financingCaseId": "019e964c-fb93-73a6-a672-254c170c72d9",
  "originalName": "business_registration.pdf",
  "mimeType": "application/pdf",
  "fileSize": 1048576,
  "category": "business_registration",
  "description": "Handelsregisterauszug 2024",
  "uploadedAt": "2025-11-07T12:30:00+00:00",
  "downloadUrl": "/api/documents/42/download"
}

Errors: 422 when the file is missing, too large, not a PDF/PNG/JPG, or the category is not a document category; 404 for an unknown financing case or request id; 401 for a missing or invalid API key.

All request operations → Document Request reference · Upload & document metadata → Financing Document reference

WEBHOOK finance status update → your endpoint

When the solvency review concludes, the case moves to finance_accepted or finance_rejected (or to finance_questions / manual_finance_review if the lender needs more). You do not call an endpoint for the decision — instead, PartnerHub POSTs a financing_case.status_changed event to a webhook endpoint you register, with the new status in data.toStatus. The same event tells you when a case is canceled. Registration, signature check and retries are explained in the Webhooks guide. Every event has this shape:

Request body: financing_case.status_changed
{
  "id": "01K70Q8V6M3J5Z2R9T4X7B1C8D",
  "event": "financing_case.status_changed",
  "occurredAt": "2026-10-07T09:15:00+02:00",
  "version": 1,
  "data": {
    "financingCaseId": "019e964c-fb93-73a6-a672-254c170c72d9",
    "fromStatus": "finance_review",
    "toStatus": "canceled",
    "status": "canceled",
    "transition": "cancel",
    "quoteId": "019e964c-fb94-7c1e-9f0a-3b5d8e2a6c41"
  }
}

If you prefer to pull instead of receiving webhooks, read the case at any time and inspect its status:

curl -X GET 'https://sandbox.partner.miete24.com/api/financing_cases/019e964c-fb93-73a6-a672-254c170c72d9' \
  -H 'X-Api-Key: YOUR_API_KEY'
Response 200 (truncated)
{
  "@id": "/api/financing_cases/019e964c-fb93-73a6-a672-254c170c72d9",
  "id": "019e964c-fb93-73a6-a672-254c170c72d9",
  "caseNumber": "FC-2025-000123",
  "type": "quote",
  "status": "finance_accepted"
}

Errors: 404 for an unknown financing case id; 401 for a missing or invalid API key.

Full fields, all operations & code samples → Financing Case reference

Sandbox: simulate a solvency decision

In the sandbox there is no real lender, so the case never leaves finance_review on its own. To test both branches of your integration — an approved and a declined solvency check — drive the decision yourself with the sandbox-only endpoint below. It moves the case to finance_accepted or finance_rejected end-to-end, firing the same downstream subscribers (partner mails, webhooks) as a real Kairos decision — without an HMAC signature, response hash or Kairos/Lynck call. It requires a sandbox API key and only operates on your own financing cases.

POST /api/sandbox/financing_cases/{id}/finance-decision

curl -X POST 'https://sandbox.partner.miete24.com/api/sandbox/financing_cases/019e964c-fb93-73a6-a672-254c170c72d9/finance-decision' \
  -H 'X-Api-Key: YOUR_SANDBOX_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{ "decision": "accepted" }'

Responses: 204 on success; 422 when the case is in a non-decidable state; 404 outside the sandbox environment, where the endpoint is inactive; 401 for a missing or invalid API key.

For every simulate scenario (document requests, contract places, e-signature states, reset), see the Sandbox Simulate guide. · All sandbox endpoints → Sandbox reference

What's next

  • Browse every endpoint and schema in the API Reference.
  • See the complete state machine on the Lifecycle page.
  • Get notified of every status change instead of polling — see the Webhooks guide.
  • New to the API? Start with the Create a Quote guide.