Klarna Docs - API Integration
API Integration

A guide to implement the Shipping API

  • Checkout API: API implemented by Klarna. The Merchant calls this API to start an order session or manage it.
  • Shipping API: API specified by Klarna; must be implemented by the Integrator (TMS) (see below). The Klarna Shipping Assistant queries this API to retrieve shipping options dynamically.
  • Integrator: Implementer of the Shipping API. Usually, this is a logistics partner, like Unifaun or Consignor. In a direct integration, the Merchant can take this role.

An ideal integration with the Shipping API enables the following:

  • Shipping options are shown within the Klarna Checkout, based on real-time user data.
  • The user’s selected option is saved, and a preliminary shipment is created based on it. The preliminary shipment can be later used by the merchant to print the actual shipping label.
  • Tracking is shared with Klarna after the purchase is completed.

Please note that to use the Klarna Shipping Assistant, you may have to adjust your Checkout integration. More info about that is in this section.

This section describes how to authorize requests from the Klarna Shipping Assistant.

The user has entered the checkout, and Klarna tries to obtain authentication from the Integrator.

The merchant has provided Klarna with authentication credentials. More information can be found in the Getting Started section.

Communications between the Klarna Shipping Assistant and the Integrator must be authenticated using a bearer token scheme. Consequently, each request has a header like this:

HTTP
  Authorization: Bearer <token>

Where <token> is a secret string provided by the Integrator. To obtain it, Klarna Shipping Assistant calls POST /auth with credentials provided by the Merchant. This is a payload example:

JSON
{
  "identifier": <username>
  "secret": {
    "nonce": <random string>
    "digest": <encoded nonce + key>
  }
}

The digest is calculated by concatenating the (random) nonce and the (Merchant-provided) key and then feeding the result into the SHA-256 algorithm. To check that the secret is correct, the Integrator must compare our value by doing the same process on their end:

JAVASCRIPT
digest = sha256(nonce + key)

We recommend the Integrator give a unique token per merchant and let the token expire after a reasonable time (1h is a good duration). If the Klarna Shipping Assistant provides an old or wrong token to a call other than POST /auth, the Integrator must answer with HTTP 401 (Unauthorized). If the Klarna Shipping Assistant provides the wrong credentials to POST /auth, the Integrator must also answer with HTTP 401 (Unauthorized).

The Klarna Shipping Assistant will cache the bearer token until an HTTP 401 response is received and then fetch a new one.

This section describes what preview options are and how to set them.

The user has entered the checkout.

No address data is available for the user.

When a new user enters the checkout, Klarna has no data to pre-fill the address. To ensure a user-friendly experience, we show placeholder options based only on the country of purchase. These temporary options are called preview options.

This is what it looks like:

To make this work, the Integrator needs to be able to return shipping options for partial address data on a POST /shippingoptions call (described in the next section). A partial address could be only the country in cases like the above. The Integrator must mark these options with a preview flag.

Once Klarna has a full address, the Klarna Shipping Assistant will call the endpoint again with the complete information. Then the Integrator must answer with fully valid (non-preview) shipping options.

This section describes how to provide shipping options to the Klarna Shipping Assistant.

The user is in the checkout and has provided address data, or their address data is prefilled.

Complete address data is available for the user, and the authentication call to the Shipping API was successful.

The Klarna Shipping Assistant obtains shipping options from the Integrator by calling POST /shippingoptions every time the user updates their cart or address information. This call must be authenticated using the bearer token obtained previously, as described in the Authorization section.

You can test a Shipping API implementation and see how the shipping selector looks in our test tool, Shipwreck. This is an example request from Shipwreck:

JSON
path: /shippingoptions
method: POST
Headers:
Content-Type: application/vdn.klarna.shipping.get_options-v1+json
body:
  {
      "session_id": "f7b7dda8-c9a6-405d-8cca-1c3cbdfda1c0",
      "locale": "sv-SE",
      "currency": "SEK",
      "geoblocking": false,

Klarna passes the order information to the Shipping API. The order information is set by the Merchant while creating a Checkout session.

To enhance the shipping experience, we added shipping attributes to the order and order line level. Like the rest of the order information, these attributes will be passed on to the shipping API. The attributes can be used to set the rules about which shipping options should be shown.

  • Weight and dimensions.
  • Tags.

The following is a response example from an Integrator (adapted from our test integration tool, Ghostship):

JSON
{
    "shipping_options": [

        {
            "id": "id-1070",
            "type": "postal",
            "carrier": "postnord",
            "name": "Postal delivery",
            "price": 0,
            "tax_rate": 0,

You can find the complete list of supported shipping typesservices and carriers in our API documentation. Below you can find a non-exhaustive summary of the key information.

Each shipping option must have a shipping type indicating whether, for example, it is a home delivery option. These are some of the supported types:

  • delivery-address - Delivery to door / address. The final selected option will contain an address and can contain a timeslot.
  • pickup-box - Delivery to a pickup locker/box. The final selected option will contain a location.
  • pickup-point - Delivery to a pickup point. The final selected option will contain a location.
  • pickup-merchant-store - Delivery to a merchant store for pickup. The final selected option will contain a location.
  • postal - Delivery of a package/letter using the postal network.
  • generic-pickup - Delivery to a pickup point when location is unknown.
  • generic-shipping - Shipping option when the carrier decides on the shipping method.
  • office-delivery - Delivery to an office address. For example, to an office reception.
  • boat-delivery - Delivery by boat.
  • digital - Delivery via email or SMS.
  • click-collect - Order goods online for reservation and pick them up at a merchant store.
  • pickup-warehouse - Delivery to a merchant warehouse for pick up.

The type attribute controls which name KSA will show in the shipping option. For example, delivery-address is shown in English as “To door delivery”.

The banner about digital delivery will be shown if there is a digital item in the order. When the order has a digital item but no physical items, Klarna Shipping Assistant will not request any shipping options from TMS, the shipping selector will not be shown, and the shipping type will be set to digital.

Add-ons are additional services or information that can be added to an option. They can be marked as mandatory. Here are some examples:

  • addon_notification - Booking email or SMS notification. The final selected option will contain an email address and/or a phone number.
  • addon_delivery - Adding entry code (door code) and delivery instructions. The final selected option will contain the door code and instruction text.

A shipping option’s delivery time is crucial information for the users. It can be provided in two different formats:

  • You can use an offset in days from the current date to show intervals. For example,
JSON
"delivery_time": {
    "interval": {
        "earliest": 1,
        "latest": 3
    }
}

This will be shown as 1-3 working days.

  • To show an exact time, you can use an ISO 8601 date-time (you can try it out in this tool). For example,
JSON
"delivery_time": {
    "latest":"2019-08-28T12Z"
}

Assuming today is 2019-08-27 in Sweden (UTC+2 in the summer), this will be shown as “Tomorrow at 14h”(Z is the same as +00:00. It indicates UTC+0, Greenwich time).

This section describes the pickup point map and the associated location search.

The user opens the pickup point map and searches for locations.

The user inserted a new postal code into the location search field.

Pickup locations are presented on a map view. The user can search for new locations by postal code.

Whenever the user inserts a new postal code, Klarna will call POST /shippingoptions with country and postal_code. The following swimlane explains the flow:

Be careful when implementing your /shippingoptions endpoint. From the Integrator’s perspective, a location search looks like a preview options call, since it uses this endpoint with an incomplete address. However, Klarna Shipping Service discards any changes other than the locations.

This section describes how Klarna finalizes the selected shipping option.

The user is completing the purchase (pushing the buy button).

A valid (non-preview) shipping option is selected. The user has not tried to finalize before.

Receiving this call does not guarantee the purchase is final. If something fails, this can lead to a PUT operation (see Update Shipping Option section).

The first time the user tries to finalize their purchase by pressing the buy button, the Klarna Shipping Assistant validates the selected shipping option with POST /shipment. Finalizing can fail for several reasons (for example, the payment method is rejected), so this is not a guarantee that the shipment is final. Depending on the details mentioned in the next section, subsequent attempts to finalize might be realized as PUT /shipment/<shipment ID>.

If the Integrator receives valid data, they must respond with HTTP 201 (Created) and a valid payload:

JSON
{
    "selected_shipping_option": {...},
    "shipment_id": <shipment ID>,
    "shipments": [...]
}

Where <shipment ID> is a unique identifier for the (pre-reserved) shipment. The response must also set the Location header:

HTTP
Location: <Integrator's base URL>/shipment/<shipment ID>

The shipment ID must be unique per session_id (this is sent in the request payload). Its presence, and the presence of the location header, will be taken as confirmation that an entry has been correctly created in the Integrator’s service. This information will be forwarded to the merchant once the purchase is confirmed, and they can print the shipping label.

The following image shows the ideal workflow:

Klarna uses different identifiers during the API flow. To avoid confusion, please check this swimlane.

The following is an example request from our test tool Shipwreck:

JSON
{
    "session_id": "9e8de95f-f8b7-4711-85d9-53ac848ee0d8",
    "locale": "sv-SE",
    "currency": "SEK",
    "recipient": {
        "given_name": "Klara",
        "family_name": "Joyce",
        "street_address": "Sveavägen 42",
        "postal_code": "111 34",
        "city": "Stockholm",

Example request from our test tool Shipwreck

HTTP
{
  "header": "Location: https://foo.bar/c2059e35-58b1-4482-ad55-5e7ef541eae4",
  "body": {
    "shipment_id": "100",
    "selected_shipping_option": {
      "carrier": "budbee",
      "carrier_product": {
        "name": "MyPack",
        "identifier": "10",
        "addon_identifiers": [

Example response from our test integration tool, Ghostship

This section describes how and when the Klarna Shipping Assistant updates the finalized shipping option.

The user tries to finalize after a previous finalize attempt.

A previous POST /shipment call was successful (see Save shipping option section).

Klarna validates several items when the user completes their purchase (for example, shipping options and payment method). If any of those fail, the purchase will not proceed.

For example, the POST /shipment call may be successful, but the payment method may fail. The user then gets an error message and can change their details before trying again. This allows them to change anything, like adding items to the cart or changing the shipping address. When the user completes the checkout for the second time, the Klarna Shipping Assistant will validate the selected shipping option again to ensure the user’s choice is still valid.

If the Klarna Shipping Assistant has an available shipment ID from a previous POST /shipment call, the subsequent attempts to finalize will be realized as PUT /shipment/<shipment ID> instead.

The Shipping API will not communicate whether the order is completed successfully. This means that the Klarna Shipping Service can update the shipping option several times, sometimes with long waits until the order is placed. The merchant will know when the order is completed through the Order Management API.

This section describes how to provide Klarna with tracking information.

The user has completed the purchase.

The order is successfully completed.

Suppose the Integrator does not provide complete tracking information on the POST /shipment/<shipment ID> or PUT /shipment/<shipment ID> responses. In that case, the Klarna Shipping Assistant will call GET /shipment/<shipment ID> periodically after completing the purchase. The expected response format is the same as in the POST and PUT operations.

The response to this call should list all shipments connected to this purchase and contain tracking numbers (tracking_id) for each shipment. Klarna uses the tracking information to allow users to track their parcels and get notified upon any updates.

Alternatively, you can provide us with the tracking number and carrier information via the order management API. Just follow these instructions.