Pricing tag:Pricing tag — Price Plans define the standard pricing baseline that applies to every Partner Account, and Bespoke Pricing Configurations override that baseline for transactions that match a configuration's eligibility criteria. For the wider pricing context on the Klarna network, see Pricing overview.| Aspect | Bespoke Pricing Configuration | Bespoke Pricing Enablement |
|---|---|---|
| Who creates it | Klarna, out of band | The Acquiring Partner, via createBespokeEnablement |
| Who can read it | The Acquiring Partner (read-only) | The Acquiring Partner |
| What it carries | type, missing_fee_strategy, enablement_instructions, optional baseline eligibility_criteria | A reference to the configuration plus the requested_criteria that scope it to a Payment Account |
| Lifecycle | Provisioned and maintained by Klarna | Created by the Acquiring Partner; optionally bounded by effective_from / effective_to (both default to "now" and "indefinite" respectively when omitted) |
type that tells you what kind of pricing logic it encodes — for example, whether it overrides per-transaction fees or follows a different fee model. BespokeConfigurationType is an open enum, so Klarna may add new values without a breaking change; always handle unknown types defensively. The value currently in use is:BESPOKE_TRANSACTION_FEE — defines bespoke per-transaction fees that override the standard Price Plan rates for matching transactions. Configurations of this type expose an underlying rate listing (see Verify and inspect).MissingFeeStrategy is also an open enum. It tells Klarna what to do when a transaction matches the enablement's eligibility criteria but doesn't match any specific bespoke rate inside the configuration — for example, when a configuration only declares rates for a few merchant category codes and a transaction comes in for a different one. Values currently include:FALLBACK_TO_PRICE_PLAN — non-matching transactions are priced at the standard Price Plan rate.REJECT_TRANSACTION — non-matching transactions are rejected by Klarna. This is intentional behavior baked into the configuration — not the result of a misconfiguration on the Acquiring Partner side — and is used when Klarna has agreed with the Partner that any non-bespoke transaction should be turned away rather than priced at the Price Plan rate.| Dimension | Required | Purpose |
|---|---|---|
payment_account_id | Yes | The single Payment Account the enablement applies to. |
merchant_category_codes | No | Restrict to specific merchant category codes. |
payment_program_ids | No | Restrict to specific Payment Programs (see Payment program plans for what Payment Program identifiers refer to). |
partner_countries | No | Restrict to specific Partner countries (ISO 3166-1 alpha-2). |
customer_countries | No | Restrict to specific customer countries (ISO 3166-1 alpha-2). |
pricing_payment_categories | No | Restrict to specific pricing payment categories. |
effective_from / effective_to | No | Bound when the enablement applies. effective_from defaults to "now" if omitted; effective_to defaults to "indefinite" if omitted. |
EligibilityCriteria:requested_criteria — echoes the criteria you sent in the request body.inherited_criteria — baseline criteria attached to the parent Bespoke Pricing Configuration by Klarna when the configuration was provisioned. You cannot set or override these; they're read off the configuration. They are what makes a configuration narrower than "any transaction on the Payment Account" out of the box.applied_criteria — the server-computed merge of requested_criteria and inherited_criteria. This is what Klarna actually enforces at transaction time.applied_criteria as authoritative and reconcile against it after creation.missing_fee_strategy in practicemissing_fee_strategy: FALLBACK_TO_PRICE_PLAN and an inherited_criteria.merchant_category_codes: ["0742", "5734"]. You enable it on a Payment Account with no additional criteria. A transaction comes in:0742, matching a bespoke rate → priced at the bespoke rate.0742, matching the eligibility but with no bespoke rate defined for that MCC + Payment Program combination → falls back to the standard Price Plan rate.5812, not matching the inherited eligibility → bespoke pricing doesn't apply at all; the transaction is priced at the standard Price Plan rate as if no enablement existed.REJECT_TRANSACTION instead, the second case (matched eligibility, no bespoke rate) would be rejected by Klarna rather than priced at the Price Plan rate.missing_fee_strategy and understand what happens to transactions that don't match any specific bespoke rate.bespoke-pricing-enablements:read — to list and read configurations, their underlying rates, and existing enablements.bespoke-pricing-enablements:write — to create the enablement.| Do | Don't |
|---|---|
Always set payment_account_id in requested_criteria — it's required. | Omit payment_account_id — eligibility scope is required and the server rejects the request as a validation error. |
Add secondary criteria ( merchant_category_codes, payment_program_ids, partner_countries, customer_countries, pricing_payment_categories) on top to narrow eligibility further. | Try to model "all my Payment Accounts" with a single enablement — there is no Partner-Account-level activation; create one enablement per Payment Account instead. |
Reconcile your requested_criteria against applied_criteria after creation — inherited_criteria from the configuration may have narrowed the eligibility further. | Reuse a bespoke_enablement_reference to "update" an enablement — there is no update endpoint, and the second create returns 409 (see Idempotency on creation). |
bespoke_configuration_id values with listBespokeConfigurationsbespoke_enablement_reference is a Partner-supplied unique key (scoped per authenticated Partner). Reusing one returns a 409 with the existing bespoke_enablement_id in the response body.Klarna-Idempotency-Key is optional in the spec but strongly recommended on every POST. A unique value per request, ideally a UUID v4 or higher, that makes the request safe to retry on network or timeout errors.curl -X POST 'https://api.klarna.com/distribution/products/payment/pricing/bespoke-pricing-enablements' \
-H 'Authorization: Basic <base64-encoded-credentials>' \
-H 'Content-Type: application/json' \
-H 'Klarna-Idempotency-Key: 5b5f9c12-7e7c-4a23-9b5d-19f1b7c2f5c8' \
-d '{
"bespoke_enablement_reference": "ap-bespoke-payacc-shop42-2026-q2",
"bespoke_configuration_id": "krn:partner:global:payment:pricing:bespoke:d5e49846-07e7-4de8-9fb6-a21646b51d39",
"notes": "Bespoke pricing activation for Shop 42 under ticket OPS-48211.",
"requested_criteria": {
"payment_account_id": "krn:partner:global:payment-account:live:a1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d",201 Created:{
"bespoke_enablement_id": "krn:partner:global:payment:pricing:bespoke-enablement:7c123a8e-321b-4a2b-9fc4-2a7e89b5c0c5",
"bespoke_enablement_reference": "ap-bespoke-payacc-shop42-2026-q2",
"bespoke_configuration_id": "krn:partner:global:payment:pricing:bespoke:d5e49846-07e7-4de8-9fb6-a21646b51d39",
"type": "BESPOKE_TRANSACTION_FEE",
"missing_fee_strategy": "FALLBACK_TO_PRICE_PLAN",
"notes": "Bespoke pricing activation for Shop 42 under ticket OPS-48211.",
"requested_criteria": {
"payment_account_id": "krn:partner:global:payment-account:live:a1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d",
"merchant_category_codes": ["0742", "5734"],bespoke_enablement_id — you'll use it to look the enablement up later. Compare your requested_criteria against applied_criteria: the latter is what Klarna will enforce, and it may differ from what you sent because of inherited_criteria from the parent configuration.BESPOKE_TRANSACTION_FEE, you can inspect the underlying rate structure with listBespokeRatesbespoke_enablement_reference — a Partner-supplied unique key sent in the body of every create request. If you replay a request with the same reference (with or without an idempotency key), Klarna returns 409 RESOURCE_CONFLICT and includes the existing bespoke_enablement_id in the response body.Klarna-Idempotency-Key — a transport-level header sent on the request. Optional in the spec, but strongly recommended on every POST. With the same key and the same body, Klarna replays the original 201 response. With the same key and a different body, Klarna returns 422 IDEMPOTENCY_KEY_MISMATCH, which signals a Partner-side programming bug.| Scenario | Result | How to handle on the Partner side |
|---|---|---|
Same Klarna-Idempotency-Key + same request body (network or timeout retry of the original request) | 201 Created — the same response as the original successful create, replayed by Klarna | Treat as the original successful create. Persist the bespoke_enablement_id from the response if you haven't already. |
Same Klarna-Idempotency-Key + different request body | 422 Unprocessable Entity with error_code: IDEMPOTENCY_KEY_MISMATCH | Programming error in your retry path — you've reused a key with a request that isn't byte-equivalent to the original. Do not treat this as a successful create. Surface it as a bug, fix the retry path, and use a fresh key for any subsequent attempt. |
Different Klarna-Idempotency-Key + duplicate bespoke_enablement_reference | 409 Conflict with error_code: RESOURCE_CONFLICT and bespoke_enablement_id in the response body | The enablement already exists. Treat this as a successful terminal outcome. Use the returned bespoke_enablement_id to fetch the full record with listBespokeEnablementsbespoke_enablement_id). |
| Network or timeout error mid-request | Outcome unknown until you retry | Retry with the same Klarna-Idempotency-Key and the same request body. The response will be 201 (replay) or 409 (already exists) — both are safe terminal outcomes. |
{
"error_id": "7c123a8e-321b-4a2b-9fc4-2a7e89b5c0c5",
"error_type": "RESOURCE_ERROR",
"error_code": "RESOURCE_CONFLICT",
"error_message": "A Bespoke Pricing Enablement with the provided reference already exists.",
"bespoke_enablement_id": "krn:partner:global:payment:pricing:bespoke-enablement:7c123a8e-321b-4a2b-9fc4-2a7e89b5c0c5"
}{
"error_id": "9bcf5d12-8ef7-46a9-b2cb-d24a9b9db3c2",
"error_type": "INPUT_ERROR",
"error_code": "IDEMPOTENCY_KEY_MISMATCH",
"error_message": "The Klarna-Idempotency-Key has already been used with a different request body."
}| Do | Don't |
|---|---|
Send a `Klarna-Idempotency-Key` (UUID v4+) on every call to createBespokeEnablement | Treat 422 IDEMPOTENCY_KEY_MISMATCH as a duplicate or successful outcome — it isn't, and ignoring it can hide real bugs in your retry path. |
Treat 409 RESOURCE_CONFLICT as a successful terminal outcome — fetch the existing enablement using the bespoke_enablement_id returned in the body. | Generate a new idempotency key on each retry of the same logical request — that defeats the safety the header gives you. |
Reuse the same idempotency key across retries of the same logical request. | Treat 409 RESOURCE_CONFLICT as a fatal failure — the resource already exists, and you can fetch it by id. |
Surface 422 IDEMPOTENCY_KEY_MISMATCH as a Partner-side bug, log the correlation id, and stop retrying with that key. | Reuse a bespoke_enablement_reference to "update" an enablement — there is no update endpoint, and the second create returns 409. |
bespoke_enablement_id — fetch a single enablement by id.payment_account_id — list enablements scoped to a single Payment Account.bespoke_configuration_id — list every enablement of a given configuration.created_at and paginated using the standard size / starting_after / ending_before query parameters.requested_criteria, inherited_criteria, and applied_criteria. When verifying activation, look at applied_criteria — that's what Klarna actually enforces, and it may differ from the requested_criteria you sent because of inherited baseline criteria from the parent configuration.effective_from and effective_to timestamps you see in applied_criteria:effective_from defaults to the moment Klarna provisions the enablement on its side if you don't set one in requested_criteria.effective_to bounds the validity window. If you don't set one, the enablement applies indefinitely.