To ensure a seamless migration from Disputes API V1/V2/V3 to V4 with no service disruptions or loss of capability, follow this migration guide.
Klarna is introducing Disputes API V4, which adds multi-phase review, an appeal workflow, and richer dispute outcomes. To allow a seamless migration with no service disruption, V1, V2, V3 and V4 operate in parallel during the migration window.
Two key dates drive the migration:
FRAMEWORK_2020 (legacy); disputes opened after it are FRAMEWORK_2026. Assignment is automatic and permanent. The framework is always readable from configuration.base_framework.ON_DISPUTE_OPEN hold policy activate.Two access models to remember:
FRAMEWORK_2020 events only; V4 subscriptions deliver FRAMEWORK_2026 events only. Both must run in parallel until all FRAMEWORK_2020 disputes have closed.| Property | FRAMEWORK_2020 | FRAMEWORK_2026 |
|---|---|---|
| Applies to disputes opened | Before V4 onboarding timestamp | After V4 onboarding timestamp |
| Lifecycle states (V4) |
CLOSED |
REPRESENTMENT → PRE_ARBITRATION → ARBITRATION → CLOSED |
| Evidence window | Up to 14 days (after up to 21-day open period) | Up to 21 days (from dispute open) |
| Review period | Up to 60 days | 60 days before Nov 1, 2026 / 30 days from Nov 1, 2026 |
| Total max duration | ~95 days | ~81 days before Nov 1, 2026 / ~51 days from Nov 1, 2026 (longer if arbitration) |
| API access (REST) | All API versions | All API versions |
| Webhook subscription | V1/V2/V3 | V4 |
| Default hold policy |
|
ON_DISPUTE_OPEN activates Nov 1, 2026) |
| Appeal workflow | Not available | Available from Nov 1, 2026 |
| Outcome detail | Not available |
|
| Settlement: reversal | Legacy type |
CHARGEBACK_REVERSAL |
| Settlement: fees | Not applicable |
APPEAL_FEE |
| Rollback | N/A | Full rollback to V1/V2/V3 is possible at any time |
Applies to disputes opened before your V4 onboarding timestamp. Follows the legacy dispute rules and lifecycle. No changes are made to disputes already under this framework.
{
"configuration": {
"base_framework": "FRAMEWORK_2020",
"options": { "hold_policy": "NONE" }
}
}
Applies to disputes opened after your V4 onboarding timestamp. Follows the FRAMEWORK_2026 lifecycle with multi-phase review, new settlement transaction types, and a configurable hold policy.
Default configuration from onboarding:
{
"configuration": {
"base_framework": "FRAMEWORK_2026",
"options": { "hold_policy": "NONE" }
}
}
Phased feature rollout — November 1, 2026. Not all FRAMEWORK_2026 features activate at onboarding. The features below only apply to disputes opened on or after Nov 1, 2026:
| Feature | Before Nov 1, 2026 | From Nov 1, 2026 |
|---|---|---|
| Evidence window | Up to 21 days | Up to 21 days |
| Review window | 60 days (same as FRAMEWORK_2020) | 30 days |
| PRE_ARBITRATION / appeal | Not available | Available |
Hold policy ON_DISPUTE_OPEN | Not active | Active |
Implications:
CHARGEBACK_REVERSAL, APPEAL_FEE) must be integrated before Nov 1, 2026 — see Settlement transaction types.hold_policy reference| Value | Meaning |
|---|---|
| Funds placed on hold when a dispute is opened. Only applies to disputes opened on or after Nov 1, 2026. |
| No fund hold on dispute open (FRAMEWORK_2026 default). |
Total maximum duration: ~95 days.
In V1/V2/V3 this is reflected in investigation_status:
V2 investigation_status | Meaning |
|---|---|
| Dispute opened |
| Investigation has started |
| Dispute is unresolved |
| Merchant has replied to request |
| Response deadline passed without reply |
| Merchant accepted loss |
| Dispute is closed |
FRAMEWORK_2026 has two sub-phases depending on whether the dispute opened before or on/after November 1, 2026.
Disputes opened before Nov 1, 2026 (transitional):
Disputes opened on or after Nov 1, 2026 (full):
Key differences from FRAMEWORK_2020:
INITIATED) — the dispute opens with an immediate evidence request, giving up to 21 days from day one.PRE_ARBITRATION (preliminary decision, partner can appeal) and ARBITRATION (final binding review).In V4 this is reflected in state:
V4 state | Meaning |
|---|---|
| Dispute opened with evidence request. Evidence window is open. |
| Partner submitted evidence; Klarna is reviewing. Deadline to accept or escalate. |
| Preliminary decision made. Partner can accept outcome or appeal. |
| Arbitration in progress. Final binding decision pending. |
| Dispute is closed with a final outcome. |
Within INITIATED and REPRESENTMENT, a nested representment.state tracks the evidence request status:
V4 representment.state | Meaning |
|---|---|
| Partner can submit evidence or accept loss |
| Evidence submitted; under review; no further partner action |
| Deadline passed without partner response |
| Partner accepted loss in INITIATED state |
| Dispute amount below threshold; auto-resolved as LOST |
V2 investigation_status | V4 state | V4 representment.state | Notes |
|---|---|---|---|
started |
|
| Evidence window open |
|
|
| Evidence under review |
|
| — | Awaiting partner action on preliminary outcome |
|
|
| Missed the evidence window |
|
|
| Outcome = LOST |
|
| — | Check dispute_outcome for WON/LOST |
Once onboarded to V4, every REST operation is available on every API version, regardless of dispute framework. You can shift workflows dispute-by-dispute or team-by-team at your own pace — for example, accessing FRAMEWORK_2020 disputes via V4, or FRAMEWORK_2026 disputes via your existing V2 integration.
Webhook event delivery does not cross framework boundaries:
| Webhook subscription | FRAMEWORK_2020 events | FRAMEWORK_2026 events |
|---|---|---|
| V1/V2/V3 subscription | Receives | Does NOT receive |
| V4 subscription | Does NOT receive | Receives |
You must run both webhook subscriptions in parallel throughout the migration. Events are already segregated by framework — there is no overlap and no deduplication needed. Do not cancel the V1/V2/V3 subscription until all FRAMEWORK_2020 disputes are closed.
The migration follows five sequential steps. The diagram below summarises the end-to-end flow:
Complete every item below before calling the V4 onboarding endpoint. Once onboarded, disputes opened after the timestamp immediately use FRAMEWORK_2026.
Dispute routing:
configuration.base_framework and routes to the correct processing logic.INITIATED, REPRESENTMENT, PRE_ARBITRATION, ARBITRATION, CLOSED.dispute_outcome_detailed values gracefully (open enum — new values may be added).Evidence submission:
additional_information (max 5000 chars) instead of structured requested_fields.Authentication:
Webhooks (if applicable):
base_framework.No settlement changes are required before V4 onboarding. With hold_policy: NONE (the FRAMEWORK_2026 default), no funds are held when a dispute opens, so settlement behaviour is unchanged from the legacy behavior:
CREDIT appears in the settlement report.FEE continues to appear as it does today.Two new transaction types activate on November 1, 2026 when hold_policy: ON_DISPUTE_OPEN and the appeal workflow go live. These must be integrated before that date — see Settlement transaction types in the API reference for the full table.
Call the V4 self-onboarding endpoint. This records the timestamp that divides FRAMEWORK_2020 from FRAMEWORK_2026.
POST /v4/payment/disputes/merchants/{merchant_id}/enroll
After this call:
FRAMEWORK_2020.FRAMEWORK_2026 with the default config (hold_policy: NONE).Subscribe to V4 webhooks to receive events for FRAMEWORK_2026 disputes.
Contact your Klarna technical point of contact to enable webhook subscriptions for your integration.
Rules:
base_framework = FRAMEWORK_2020.For the full event catalogue, payload routing logic, and deadline-extension handling, see Webhook events and routing in the API reference.
With both integrations active, incrementally migrate dispute workflows to V4 while FRAMEWORK_2020 disputes continue via your existing integration.
Recommended validation sequence:
dispute_outcome_detailed values are handled correctly — this is an open enum; unknown values must not crash your system.PRE_ARBITRATION events — if your workflow requires challenging preliminary decisions, implement the appeal flow before this occurs in production.Once all FRAMEWORK_2020 disputes have reached CLOSED:
V4 onboarding does not modify or break your existing V1/V2/V3 integration. At any point you can:
The only irreversible effect is framework assignment: disputes opened after your onboarding timestamp cannot be moved back to FRAMEWORK_2020.
| Operation | V2 path | V4 path |
|---|---|---|
| List disputes |
|
|
| Get dispute |
|
|
| Submit response / evidence |
|
|
| Accept loss |
|
|
| Upload attachment |
|
|
| Download attachment |
|
|
| Appeal (new in V4) | — |
|
| Concept | V2 field | V4 field | Notes |
|---|---|---|---|
| Dispute ID |
|
| Format changed; store both during migration. |
| Overall state |
|
| Binary → 5-state model. |
| Investigation detail |
|
representment.state | Two-level hierarchy. |
| Creation date |
|
| Renamed; values may differ for the same dispute due to FRAMEWORK_2026 lifecycle changes. Do not treat as equivalent — use a single API version as the source of truth for time-based logic. |
| Response deadline |
|
| Moved to nested object; can be extended (see deadline extension event). |
| Dispute reason |
|
| See reason mapping. |
| Disputed amount |
|
| Renamed and moved to top level. |
| Currency |
|
| Moved to top level. |
| Chargeback amount |
| — | Removed; use settlement data. |
| Region |
| — | Removed. |
| Request/response history |
|
| Structure flattened. |
| Outcome | (inferred from status) |
| Now explicit, CLOSED state only. |
| Outcome detail | — |
| New — see Open enums. |
| Last updated | — |
| New. |
| State transition history | — |
| New. |
| Exceptions | — |
| New — tracks window extensions, immediate resolution. |
V2 reason | V4 dispute_reason |
|---|---|
|
|
|
|
|
|
incorrect_invoice |
|
|
|
|
|
| (removed in V4) |
| — |
|
| — |
|
| V2 parameter | V4 parameter | Notes |
|---|---|---|
| (removed) | Authentication now scopes to your MID. |
|
| Renamed. |
|
| New enum values (see state table). |
|
| Values renamed to UPPER_SNAKE_CASE. |
|
| Field renamed. |
|
| Renamed. |
|
| Renamed. |
| — |
created_at_end | New date range filter. |
| — |
closed_at_end | New date range filter. |
| — |
| New filter. |
| — |
| New filter. |
The evidence submission model changed significantly between V2 and V4.
V2 required merchants to respond to explicit field requests with structured enum values:
// POST /disputes/v2/disputes/{dispute_krn}/requests/{request_id}/responses
{
"requested_fields": {
"tracking_id": "ABC123",
"shipping_date": "2024-01-15",
"shipping_carrier": "DHL",
"delivered_with_proof": "yes",
"goods_returned": "yes_in_full"
},
"comment": "All requested information provided.",
"attachments": [1, 2, 3]
}V4 replaces structured fields with a flexible free-text model:
// POST /v4/payment/disputes/{payment_dispute_id}/represent
{
"additional_information": "Shipment was delivered on 2024-01-20 with signature confirmation. Tracking: XYZ789.",
"attachments": [
{
"payment_dispute_attachment_id": "krn:payment:eu1:dispute:123:attachment:1",
"description": "Signed delivery confirmation"
},
{
"payment_dispute_attachment_id": "krn:payment:eu1:dispute:123:attachment:2",
"description": "Courier tracking history screenshot"
}Key differences:
additional_information max length: 5000 characters.additional_information; supporting documents as attachments.V4 introduces an appeal flow for the PRE_ARBITRATION state. If Klarna issues a preliminary decision and you wish to challenge it:
POST /v4/payment/disputes/{payment_dispute_id}/appeal
PRE_ARBITRATION and the appeal workflow are only available for FRAMEWORK_2026 disputes opened on or after November 1, 2026. For disputes opened before that date, the dispute goes directly from REPRESENTMENT to CLOSED — no appeal is possible. This endpoint has no V2 equivalent.
| Event type | Trigger |
|---|---|
| Dispute moves to INITIATED |
| Dispute moves to REPRESENTMENT |
| Dispute moves to PRE_ARBITRATION |
| Dispute moves to ARBITRATION |
| Dispute moves to CLOSED |
| Non-state update on dispute |
| Evidence response deadline extended |
Use base_framework in the webhook payload to route processing:
if payload.configuration.base_framework == "FRAMEWORK_2020":
route to V1/V2/V3 processing flow
elif payload.configuration.base_framework == "FRAMEWORK_2026":
route to V4 processing flow
Webhook events are not duplicated across subscriptions — each subscription receives only its framework's events, so no deduplication is needed.
V4 introduces deadline extensions via the payment.dispute.updated.representment-deadline-extended event. When received:
representment.expires_at value in your system.CREDIT and FEE are unchanged — they exist today under FRAMEWORK_2020 and continue to work identically under FRAMEWORK_2026.
Before November 1, 2026 (with hold_policy: NONE):
CREDIT in settlement report, same as the legacy behavior.FEE continues to appear as it does today.REPRESENTMENT to CLOSED.Two new transaction types activate on November 1, 2026, when hold_policy: ON_DISPUTE_OPEN and the appeal workflow go live:
| New transaction type | When it appears | Required by |
|---|---|---|
| Dispute held under ON_DISPUTE_OPEN closes in merchant's favor — held funds returned | Nov 1, 2026 |
| Merchant files an appeal in PRE_ARBITRATION state | Nov 1, 2026 |
V2:
{
"error_code": "INCOMPATIBLE_DISPUTE_STATE",
"error_message": "Cannot perform operation in current dispute state"
}
V4:
{
"error_id": "abc123",
"error_type": "BAD_VALUE",
"error_code": "INVALID_FIELD_VALUE",
"error_message": "Human-readable error message",
"validation_errors": [
{
"field": "representment.additional_information",
"message": "Field must be between 0 and 5000 characters"
}
]
}V4 errors include a unique error_id for tracing, an error_type for programmatic handling, and a validation_errors array for field-level detail.
V4 uses API key credentials with HTTP Basic Authentication — different from V2's OAuth2 client credentials flow. Ensure your V4 requests use the correct authentication scheme.
V4 introduces dispute_outcome_detailed in the CLOSED state with 40+ possible values (e.g. partner_provided_valid_shipping_details, no_proof_of_delivery, customer_cancelled_dispute). New values may be added in the future. Your code must not crash or reject unknown values — handle them gracefully and log them for review.