Intra-Community Movements

If you use ZFS International Warehousing, the Intra-Community Movements API provides you with information about movement of your stock between the warehouses that you have chosen to enable in different EU countries.

If you require more details about cross-border movement of stock between all Zalando facilities (not only between the warehouses that you have chosen to enable, but also between return centers, consolidation locations, etc.), the Cross-Border Movements API may be a better option for you.

Authentication

The zDirect API requires OAuth 2.0 authentication for all API calls. Use the Authentication API to generate access tokens as described in the Authentication section.

Intra-Community Movements Report

If you have enabled International Warehousing, ZFS may move inventory between Zalando warehouses located in different EU countries. Such movements of inventory between EU countries may create fiscal or compliance obligations, and we provide the Intra-Community Movements (ICM) report to give you data that you may need to meet those obligations.

It’s important to understand that Zalando does not provide tax advice, so you should consult your own tax advisor to determine whether these intra-EU inventory movements generate reporting obligations for your business.

Each time an item arrives in a Zalando facility in a new country, that arrival will be included in an ICM report. Note that the ICM report does not provide any information about movement of your stock among warehouses in different countries, nor does it include separate "dispatch" and "arrival" transactions.

Requesting movement data

When you call the Intra-Community Movements (ICM) API, you are fetching one or several days of reports. ICM reports are generated once per day. If you want to fetch a report for D-1 (yesterday), we recommend that you fetch it at 12pm CET or later on business days to ensure that the report has already been generated when you try to fetch it.

When calling the API to fetch the report, from and to query parameters refer to the reported date. This is the date when the movement was included in a report. This date is different from the transaction date in the response (see information about the response below the response example).

Requesting all movement data with a single request (deprecated)

/zfs/stock-movements/intra-community-movements/{merchant-id}?from=$FROM_DATE&to=$TO_DATE

For example, to get all relevant cross border movements that were reported in April 2020:

/zfs/stock-movements/intra-community-movements/{merchant-id}?from=2020-04-01&to=2020-04-30

The same call from httpie:

http GET \
https://api-sandbox.merchants.zalando.com/zfs\
/stock-movements/intra-community-movements/{merchant-id}\
?from=2020-04-01&to=2020-04-30 \
"Authorization:Bearer $YOUR_ACCESS_TOKEN"

You will receive an HTTP 200 reply to a successful request. The following JSON reply example shows an ICM report with only one item:

{
  "merchant_id": "246aabbc -beeb-45a7-99a3-6a8270887a74",
  "reports": [
    {
      "transaction_date": "2020-04-01",
      "movements": [
        {
          "product_sku": "AAA22O08A-A1100AS000",
          "ean": "2001231121234",
          "merchant_sku": "12345678",
          "quantity": 1,
          "destination_stock_location": {
              "location_id": "b1aa94aa-104a-457a-a17a-a52aaa88aa3a",
              "name": "Gardno",
              "country_code": "PL"
          },
          "source_stock_location": {
              "location_id": "32aaa430-a835-44aa-947a-4a1aaaa1a615",
              "name": "Erfurt",
              "country_code": "DE"
          },
          "order_number": "20200401-erfurt-gardno",
          "movement_type": "customer_order_relocation"
        }
      ]
    }
  ]
}

Requesting all movement data using endpoint where movements are paginated

/intra-community-movements/{merchant-id}?from=$FROM_DATE&to=$TO_DATE

For example, to get the first page of the relevant movements that were reported in April 2020:

/intra-community-movements/{merchant-id}?from=2020-04-01&to=2020-04-30

The same call from httpie:

http GET https://api-sandbox.merchants.zalando.com/intra-community-movements/{merchant-id}\
?from=2020-04-01&to=2020-04-30 "Authorization:Bearer $YOUR_ACCESS_TOKEN"

You will receive an HTTP 200 reply to a successful request. The following JSON reply example shows an ICM report with only one item for the whole requested period of time:

{
  "merchant_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "items": [
    {
      "transaction_date": "2020-04-01",
      "movements": [
        {
          "product_sku": "AAA22O08A-A1100AS000",
          "ean": "2001231121234",
          "merchant_sku": "12345678",
          "quantity": 1,
          "destination_stock_location": {
              "location_id": "b1aa94aa-104a-457a-a17a-a52aaa88aa3a",
              "name": "Gardno",
              "country_code": "PL"
          },
          "source_stock_location": {
              "location_id": "32aaa430-a835-44aa-947a-4a1aaaa1a615",
              "name": "Erfurt",
              "country_code": "DE"
          },
          "order_number": "20200401-erfurt-gardno",
          "movement_type": "customer_order_relocation"
        }
      ]
    }
  ],
  "next": "",
  "query": {
    "from": "2020-04-01",
    "to": "2020-04-30"
  }
}
How-To Guide for Pagination
  1. Fetch the 1st page of the movements list for needed dates.
  2. Store or process movements from the response.
  3. Check if there is a pointer for the next page (non-empty string from the “next” attribute of the received response).
  4. If there is no pointer - there are no more movements for the requested period. If there is a pointer - fetch the next bunch of movements using the same uri as for the 1st page but with query parameter “cursor” with the value from response next attribute.
  5. Repeat the 4th step until there is an empty next attribute of a response.

The following pseudocode illustrates how to fetch all movements for the desired period of time:

METHOD fetchPage(string from, string to, string cursorValue)
    queryParameters = "?from=" + from + "&to=" + to

    IF cursorValue IS NOT EMPTY THEN
        queryParameters = queryParameters + "&cursor=" + cursorValue
    END IF

    RETURN request(
        url: "https://<host>/zfs/cross-border-movements/<merchantId>" + queryParameters,
        headers: {
            "Authorization": "Bearer <token>"
        }
    )
END METHOD

METHOD fetchMovements(string from, string to)
    cursorValue = ""
    data = []

    REPEAT
        response = fetchPage(from, to, cursorValue)

        APPEND response.items TO data
        cursorValue = response.next
    UNTIL cursorValue IS EMPTY

    RETURN data
END METHOD

// Usage
movements = fetchMovements("2025-04-14", "2025-04-14")

Useful information about the response

Information in the response

  • Transaction date: The date on which the item(s) arrived at their destination. Items are grouped by this date.
  • Product SKU: The article identifier that Zalando assigned to your article.
  • Merchant SKU: The article identifier you provided when onboarding the article to Zalando systems.
  • Destination stock location: The Zalando warehouse, active for storing/selling stock (per your network configuration), where the item was scanned as received on the transaction_date.
  • Source stock location: The most recent Zalando warehouse, active for storing/selling stock (per your network configuration), where the item was scanned before it was scanned in the destination_stock_location.
  • Order number: An internal ZFS identifier for the movement. This number is not unique.
  • Movement type: See below.

Movement Types

  • Return Center Inbound
    Customer returns via return centers which are added to offerable stock in a country different from their last stock location. The source_stock_location on these movements will match the Zalando location from where the item was picked in order to fulfill the customer order. The destination_stock_location is the first Zalando warehouse that you have enabled for storing and selling stock where the item arrives after it is returned.

  • Customer Return Inbound
    Customer returns which arrive directly in a warehouse and are added to offerable stock in a country different from their last offerable stock location. The source_stock_location on these movements will match the Zalando location from where the item was picked in order to fulfill the customer order. The destination_stock_location is the first Zalando warehouse that you have enabled for storing and selling stock where the item arrives after it is returned.

  • Automatic Relocation
    Movements from one country to another triggered by algorithms to optimize availability in all markets.

  • Customer Order Relocation
    An item was in offerable stock in one country, was ordered by a customer, and during order fulfillment, the item was moved to another country for order consolidation. The item was ultimately not used to fulfill the order, so the item was instead added to the offerable stock of the destination country. This can happen if an order is canceled after the item is already in transit to the consolidation location, or if another unit of the same item became available closer to the customer and was used to fulfill the order.

Reports may contain transactions from previous days

A single day's report may contain transactions from previous days, because in the case of cancellations or cutoffs (see Customer Order Relocation movement type below), our systems cannot always determine whether a movement should be included in this report on the day it occurs.

Possible issues

Requesting too much data: If the number of movements you request exceeds our capacity to return them, you will see a 500 error "There are too many movements in the database for the requested period of time. Try requesting a shorter period."

For other non-200 error responses, try re-fetching after two minutes or more.

Additional Resources

Contact Support