Shipping Rates configuration

Introduction

Shipping rates define the shipping tariffs applied by DJUST at checkout. Each rate associates a price (and optionally a free-shipping threshold) with a unique combination of logistic family, shipping zone, shipping type, and — in marketplace contexts — supplier.

In marketplace contexts, a rate can also be flagged as a default shipping fee: instead of targeting one supplier, it applies to every supplier that has no rate of its own for the same logistic family, zone and shipping type. See Default shipping fee.

Operators configure these rates via the DJUST Back-Office and the API described on this page. Once configured, they become the tariff source DJUST evaluates on every cart read to compute the shipping fees applied to each logistic order at checkout.

For the complete checkout flow (cart split, zone resolution, free-shipping mechanics, order validation snapshot), see the Shipping module overview.


Managing Shipping Rates from the Back-Office

Most operators manage shipping rates directly from the DJUST Back-Office. The API described below performs the same actions and is intended for integrators.

⚠️

Operator-only configuration for now. Only operators can configure shipping rates — both in the Back-Office and via the API. Direct configuration by suppliers is planned for a future iteration.

🚧

Default shipping fee: API only for now. Rates flagged as default shipping fee (isDefault: true) can currently be created and managed through the API only. The corresponding Back-Office controls will arrive in a future version.

🚧

Currency: API only for now. The currency of a rate can currently be set and filtered on through the API only. The corresponding Back-Office controls will arrive in a future version.

Where to find it

Settings → Shipping fee management → Shipping rates

List view

The list view displays all existing shipping rates with:

  • Sorting — by creation date or last update
  • Columns — Logistic family, Shipping zone, Shipping type, Supplier (marketplace only), Price, Free shipping threshold (displayed as "From X€"), Created at, Last updated
  • Row actions — Edit, Delete

Filters

Refine the list with the filter panel:

FilterTypeDescription
Logistic familyDropdownShow only rates for the selected logistic family
Shipping zoneDropdownShow only rates for the selected shipping zone
Shipping typeDropdownShow only rates for the selected shipping type
SupplierDropdownShow only rates for the selected supplier (marketplace contexts only)
Created afterDateShow only rates created on or after the selected date
Updated afterDateShow only rates updated on or after the selected date

Creating a rate

Click + Add a rate and fill in the form:

FieldRequiredNotes
Logistic familyYesSelect from the existing logistic families.
Shipping zoneYesSelect from the existing shipping zones.
Shipping typeYesSelect from the existing shipping types.
SupplierYes (marketplace)Select from the existing suppliers. Required in marketplace contexts, not shown in e-commerce contexts.
Shipping priceYesThe shipping cost, in the tenant's currency.
Free shipping thresholdNoOrder amount above which shipping becomes free. Leave empty for no threshold.
ℹ️

The combination of logistic family × shipping zone × shipping type × supplier must be unique across all shipping rates. Attempting to create a duplicate will be rejected.

Editing a rate

Open the row action menu (⋯) and click Edit. All fields can be modified, provided the resulting combination remains unique.

Deleting a rate

Open the row action menu (⋯) and click Delete. Deletion is allowed even if past orders reference the rate — only future checkout calculations are affected.

⚠️

Checkout impact: If the deleted rate was the only one covering a specific combination of logistic family, zone, type (and supplier), the checkout will be blocked for that combination until a new rate is added.


Key Concepts

Price Line Dimensions

Each shipping price line is scoped by a combination of four dimensions:

DimensionDescription
logisticFamilyIdThe logistic family (e.g. "fragile-items", "standard").
shippingZoneIdThe geographical zone (e.g. "eu-west", "north-america").
shippingTypeIdThe delivery mode (e.g. "express-24h", "standard").
supplierIdThe supplier (marketplace context only). Omit for single-vendor setups, and omit on a default shipping fee line.
isDefaultBoolean (marketplace context only). true flags the line as the default shipping fee for the combination: it covers every supplier without a line of its own. Mutually exclusive with supplierId.
currencyThe currency of the amounts carried by the line — see Currency. Part of the uniqueness key. EUR when omitted.
⚠️

Warning:

The combination logistic family × zone × type × supplier × currency must be unique across all price lines. Attempting to create a duplicate returns error F-E-003. Likewise, at most one default shipping fee line may exist per logistic family × zone × type × currency combination.

Currency

Each price line carries a currency, which applies to its shipping price, to its francoAmount and to the amount thresholds of its tranches when the line is priced by tranches.

  • Format — an ISO 4217 code among the currencies of the platform, case-insensitive. EUR when omitted or null.
  • Part of the uniqueness key — the same logistic family × zone × type × supplier combination may exist once per currency, with different amounts. Two identical lines in the same currency are still rejected as a duplicate.
  • Pricing mode per currency — whether a line is priced at a fixed price or by tranches is chosen independently for each currency.

At checkout, the line applied is the one whose currency is the currency of the order, with no conversion, and the free-shipping threshold is compared to the order amount in that same currency. If no line exists in the currency of the order, the default shipping fee line of that currency applies when there is one; otherwise the checkout is blocked, as before.

flowchart LR
  %% Styles (Readme)
  classDef create   fill:#e8f1ff,stroke:#2f6feb,stroke-width:2px,color:#0b3d91;
  classDef read     fill:#ede9fe,stroke:#7c3aed,stroke-width:2px,color:#1e1b4b;
  classDef update   fill:#e0f7fa,stroke:#06b6d4,stroke-width:2px,color:#0c4a6e;
  classDef add      fill:#ecfdf5,stroke:#10b981,stroke-width:2px,color:#064e3b;
  classDef remove   fill:#fee2e2,stroke:#ef4444,stroke-width:2px,color:#7f1d1d;
  classDef decision fill:#fff4e5,stroke:#f59e0b,stroke-width:2px,color:#7a3e00;
  classDef place    fill:#dcfce7,stroke:#16a34a,stroke-width:2px,color:#14532d;
  classDef sys      fill:#f2f4f7,stroke:#475569,stroke-width:2px,color:#111827;
  classDef stop     fill:#fee2e2,stroke:#ef4444,stroke-width:2px,color:#7f1d1d;

  A["🧾 Order in currency C"]:::sys
  B{"Supplier line<br>in currency C"}:::decision
  C{"Default line<br>in currency C"}:::decision
  D["✅ Supplier price applied<br>no conversion"]:::place
  E["✅ Default price applied<br>no conversion"]:::place
  F["⛔ No price in currency C<br>checkout blocked"]:::stop

  A --> B
  B -->|"yes"| D
  B -->|"no"| C
  C -->|"yes"| E
  C -->|"no"| F

  style A rx:8,ry:8
  style B rx:8,ry:8
  style C rx:8,ry:8
  style D rx:8,ry:8
  style E rx:8,ry:8
  style F rx:8,ry:8
⚠️

Warning:

There is never a fallback onto a line in another currency. A combination priced only in EUR blocks the checkout of an order placed in GBP, exactly as an uncovered combination does.

ℹ️

Backward compatible. A line saved without a currency is in euros, and a single-currency tenant selling in euros sees no difference — same lines, same fees, same free-shipping threshold.

Default Shipping Fee

In a marketplace, every supplier normally needs its own price line for each logistic family × shipping zone × shipping type combination it ships on. A supplier with no line for the combination requested at checkout has no price, and the customer's checkout is blocked. Maintaining one line per supplier, and adding new lines every time a supplier joins the marketplace, quickly becomes a burden.

A price line flagged isDefault: true acts as a safety net for a combination:

  • It carries no supplierId and applies to any supplier that has no line of its own for the same logistic family × zone × type — including suppliers already present elsewhere in the matrix and suppliers created after the default line, with no change to the matrix.
  • A supplier's own line always takes precedence. The default line only steps in where no supplier-specific price exists.
  • A line targets either one supplier or all uncovered suppliers: a line carrying both supplierId and isDefault: true is rejected, and so is a marketplace line carrying neither.
  • One default line per combination, enforced at creation and update, including in bulk payloads.
  • price, francoAmount, cart split and fee calculation behave exactly as for a supplier-specific line. A default line at price: 0 is a valid way to offer free shipping to every unconfigured supplier.

The safety net is per combination: a combination with neither a supplier line nor a default line still blocks the checkout, as before. Existing supplier lines keep their behaviour.

flowchart LR
  %% Styles (Readme)
  classDef create   fill:#e8f1ff,stroke:#2f6feb,stroke-width:2px,color:#0b3d91;
  classDef read     fill:#ede9fe,stroke:#7c3aed,stroke-width:2px,color:#1e1b4b;
  classDef update   fill:#e0f7fa,stroke:#06b6d4,stroke-width:2px,color:#0c4a6e;
  classDef add      fill:#ecfdf5,stroke:#10b981,stroke-width:2px,color:#064e3b;
  classDef remove   fill:#fee2e2,stroke:#ef4444,stroke-width:2px,color:#7f1d1d;
  classDef decision fill:#fff4e5,stroke:#f59e0b,stroke-width:2px,color:#7a3e00;
  classDef place    fill:#dcfce7,stroke:#16a34a,stroke-width:2px,color:#14532d;
  classDef sys      fill:#f2f4f7,stroke:#475569,stroke-width:2px,color:#111827;
  classDef ok       fill:#ecfdf5,stroke:#10b981,stroke-width:2px,color:#064e3b;
  classDef stop     fill:#fee2e2,stroke:#ef4444,stroke-width:2px,color:#7f1d1d;

  A["📦 Logistic order<br>supplier S<br>family x zone x type"]:::sys
  B{"Line for<br>supplier S"}:::decision
  C{"Default line<br>isDefault true"}:::decision
  D["✅ Supplier price applied"]:::place
  E["✅ Default price applied"]:::place
  F["⛔ No price<br>checkout blocked"]:::stop

  A --> B
  B -->|"yes"| D
  B -->|"no"| C
  C -->|"yes"| E
  C -->|"no"| F

  style A rx:8,ry:8
  style B rx:8,ry:8
  style C rx:8,ry:8
  style D rx:8,ry:8
  style E rx:8,ry:8
  style F rx:8,ry:8
ℹ️

In non-marketplace (single-vendor) contexts, isDefault is not relevant: it is always returned as false and is ignored on input, together with supplierId.

Price and Franco Amount

FieldTypeRules
pricenumberThe shipping cost. Must be >= 0.
francoAmountnumber or nullThe logistic order amount threshold above which shipping is free. Must be > 0 if provided. Set to null for no free-shipping threshold.
ℹ️

Whether francoAmount is compared to the tax-inclusive or tax-exclusive total of the logistic order is driven by the tenant setting francoTaxBasis (default TTC). See Free-shipping tax basis.


How Shipping Fees Are Calculated at Checkout

When the Shipping module is enabled (shippingEnabled: true), DJUST resolves shipping fees dynamically from the configured price lines throughout the checkout. No API contract change is required on your side: the cart v2 and order DTOs expose the same fields and structure — only the values are now driven by the configured shipping price lines.

Logistic Orders

At checkout, the cart is split into logistic orders, and each logistic order carries its own shipping fees:

  • E-commerce — one logistic order per logistic family.
  • Marketplace — one logistic order per supplier × logistic family combination.

Price lines are evaluated per logistic order along the dimensions logistic family × shipping zone × shipping type (plus supplier in marketplace), within the currency of the order. In marketplace, the supplier's own line is used first; when the supplier has none, the default shipping fee line of the combination is used, if any — in that same currency, with no conversion. See Currency.

Shipping Zone Resolution

The shipping zone is derived from the customer's shipping address:

  • Priority is given to the address department.
  • If no department is available, the zone is resolved from the postal code.

Free Shipping (Franco)

The francoAmount threshold is applied per logistic order, never on the global cart. When a logistic order reaches its threshold, its shipping fees drop to 0 — independently of the other logistic orders in the same cart.

The amount compared to the threshold depends on the tenant setting francoTaxBasis:

francoTaxBasisThreshold compared to
TTC (default)The tax-inclusive total of the logistic order
HTThe tax-exclusive total of the logistic order

Configuring this setting is described in Free-shipping tax basis. Note that the setting only changes the comparison basis — the price configured on the price line stays tax-inclusive (TTC).

Where Shipping Fees Are Read

Shipping fees resolved from the matrix live on the logistic order (totalShippingFeesWithTax, totalShippingFeesWithoutTax, totalShippingTaxAmount), not on the order lines. For orders coming from direct checkout, the per-line shipping fields are not populated — see Where shipping fees are exposed.

Dynamic Recalculation

Shipping fees are recomputed on every cart read — GET /v2/shop/carts/{cartId} and GET /v2/shop/carts/{cartId}/lines — so the amounts always reflect the current price lines and the current shipping address in real time.

Selection and Snapshot

  • Selecting a shipping type and committing the address — PUT /v2/shop/commercial-orders/{id}/shipping-information (ORDER-215) applies the corresponding shipping price line to the logistic order.
  • Validating the order — the validation step (ORDER-212) freezes (snapshots) the shipping fees on each logistic order in the fields totalShippingFeesWithTax, totalShippingFeesWithoutTax, and totalShippingTaxAmount. If the shipping price lines changed between selection and validation, the price is recomputed at validation time and it is this new value that is frozen.
flowchart LR
  %% Styles (Readme)
  classDef create   fill:#e8f1ff,stroke:#2f6feb,stroke-width:2px,color:#0b3d91;
  classDef read     fill:#ede9fe,stroke:#7c3aed,stroke-width:2px,color:#1e1b4b;
  classDef update   fill:#e0f7fa,stroke:#06b6d4,stroke-width:2px,color:#0c4a6e;
  classDef add      fill:#ecfdf5,stroke:#10b981,stroke-width:2px,color:#064e3b;
  classDef remove   fill:#fee2e2,stroke:#ef4444,stroke-width:2px,color:#7f1d1d;
  classDef decision fill:#fff4e5,stroke:#f59e0b,stroke-width:2px,color:#7a3e00;
  classDef place    fill:#dcfce7,stroke:#16a34a,stroke-width:2px,color:#14532d;
  classDef sys      fill:#f2f4f7,stroke:#475569,stroke-width:2px,color:#111827;
  classDef ok       fill:#ecfdf5,stroke:#10b981,stroke-width:2px,color:#064e3b;
  classDef stop     fill:#fee2e2,stroke:#ef4444,stroke-width:2px,color:#7f1d1d;

  A["🧾 Read cart<br>GET /v2/shop/carts/{cartId}<br>fees recomputed"]:::read
  B["📦 Split into<br>logistic orders"]:::sys
  C{"Price line for<br>zone x type x family"}:::decision
  D["🔄 Select shipping type<br>PUT .../shipping-information"]:::update
  E["✅ Validate order<br>fees snapshot frozen"]:::place
  F["⛔ Checkout blocked<br>no shipping type offered"]:::stop

  A --> B --> C
  C -->|"supplier line or default line found"| D --> E
  C -->|"out of zone / no line"| F

  style A rx:8,ry:8
  style B rx:8,ry:8
  style C rx:8,ry:8
  style D rx:8,ry:8
  style E rx:8,ry:8
  style F rx:8,ry:8

Blocking Cases at Checkout

SituationResult
Shipping address is outside every configured zone, or the combination has neither a line for the supplier nor a default shipping fee line in the currency of the orderNo shipping type is returned — checkout is blocked
The selected shipping type no longer matches a shipping price line (deleted during checkout)404
No shipping price line is available for the combination, at selection or at validation409

Warnings During Checkout

Non-fatal and fatal conditions are surfaced through blockedLineInformation:

  • Blocking — a reference cannot be found, or a shipping type has been made inactive.
  • Informational — the price changed following a price line recalculation.
⚠️

Warning:

Because fees are recomputed on every cart read and re-evaluated at validation, a price line change made mid-checkout can alter the amount the customer finally pays. The value frozen at validation is the source of truth for the order.


Key Endpoints

ActionMethodPathOperationIdResponse
Create shipping price lines (bulk)POST/v1/shipping-pricesADM-SHIPPING-PRICE-150201 Created
Get a shipping price line by IDGET/v1/shipping-prices/{id}ADM-SHIPPING-PRICE-500200 OK
List shipping price linesGET/v1/shipping-pricesADM-SHIPPING-PRICE-550200 OK
Update shipping price lines (bulk)PUT/v1/shipping-pricesADM-SHIPPING-PRICE-250200 OK
Delete shipping price lines (bulk)DELETE/v1/shipping-pricesADM-SHIPPING-PRICE-350200 OK

All endpoints require dj-client: OPERATOR and dj-api-key headers.


Typical Workflow

flowchart LR
  %% Styles (Readme)
  classDef create   fill:#e8f1ff,stroke:#2f6feb,stroke-width:2px,color:#0b3d91;
  classDef read     fill:#ede9fe,stroke:#7c3aed,stroke-width:2px,color:#1e1b4b;
  classDef update   fill:#e0f7fa,stroke:#06b6d4,stroke-width:2px,color:#0c4a6e;
  classDef add      fill:#ecfdf5,stroke:#10b981,stroke-width:2px,color:#064e3b;
  classDef remove   fill:#fee2e2,stroke:#ef4444,stroke-width:2px,color:#7f1d1d;
  classDef decision fill:#fff4e5,stroke:#f59e0b,stroke-width:2px,color:#7a3e00;
  classDef place    fill:#dcfce7,stroke:#16a34a,stroke-width:2px,color:#14532d;
  classDef sys      fill:#f2f4f7,stroke:#475569,stroke-width:2px,color:#111827;
  classDef ok       fill:#ecfdf5,stroke:#10b981,stroke-width:2px,color:#064e3b;
  classDef stop     fill:#fee2e2,stroke:#ef4444,stroke-width:2px,color:#7f1d1d;

  A["➕ Create price lines<br>POST /v1/shipping-prices"]:::create
  B["📘 List / Get prices<br>GET /v1/shipping-prices"]:::read
  C["🔄 Update prices<br>PUT /v1/shipping-prices"]:::update
  D["➖ Delete obsolete lines<br>DELETE /v1/shipping-prices"]:::remove
  E["✅ Price lines ready<br>for checkout"]:::place

  A --> E
  E --> B
  E --> C --> E
  E --> D --> E

  style A rx:8,ry:8
  style B rx:8,ry:8
  style C rx:8,ry:8
  style D rx:8,ry:8
  style E rx:8,ry:8

Creating Shipping Price Lines (Bulk)

Create one or more shipping price lines in a single request. Each line is validated independently — valid lines are created and invalid lines are rejected with detailed error messages.

POST /v1/shipping-prices
dj-client: OPERATOR
dj-api-key: {{apiKey}}
Content-Type: application/json

Request Body

An array of shipping price line objects:

FieldTypeRequiredDescription
logisticFamilyIdstringYesLogistic family identifier
shippingZoneIdstringYesShipping zone identifier
shippingTypeIdstringYesShipping type identifier
supplierIdstringNoSupplier identifier (marketplace context). Omit on a default shipping fee line
isDefaultbooleanNotrue = default shipping fee line for the combination (marketplace context). Default: false. Mutually exclusive with supplierId
currencystringNoISO 4217 code among the platform currencies, case-insensitive. Defaults to EUR when omitted or null
pricenumberYesShipping cost (>= 0)
francoAmountnumberNoFree-shipping threshold (> 0 if provided, null = no threshold)

Example

The same supplier combination priced in two currencies, plus a default shipping fee line covering every other supplier on the express combination in euros:

[
  {
    "logisticFamilyId": "standard",
    "shippingZoneId": "eu-west",
    "shippingTypeId": "express-24h",
    "supplierId": "supplier-001",
    "currency": "EUR",
    "price": 12.50,
    "francoAmount": 150.00
  },
  {
    "logisticFamilyId": "standard",
    "shippingZoneId": "eu-west",
    "shippingTypeId": "express-24h",
    "supplierId": "supplier-001",
    "currency": "GBP",
    "price": 10.90,
    "francoAmount": 130.00
  },
  {
    "logisticFamilyId": "standard",
    "shippingZoneId": "eu-west",
    "shippingTypeId": "express-24h",
    "isDefault": true,
    "currency": "EUR",
    "price": 15.00,
    "francoAmount": null
  }
]

Business Rules

  • In marketplace contexts, a line targets either one supplier (supplierId) or every uncovered supplier (isDefault: true): exactly one of the two is required, and sending both is rejected (F-E-040).
  • In non-marketplace (single-vendor) contexts, supplierId is forbidden and isDefault is ignored.
  • The combination of (logisticFamilyId, shippingZoneId, shippingTypeId, supplierId, currency) must be unique across all shipping price lines.
  • At most one default shipping fee line per (logisticFamilyId, shippingZoneId, shippingTypeId, currency) combination, including within the same bulk payload.
  • An unknown currency is rejected with a 400 (F-E-012).

Response — 201 Created

The response contains a singleWarningReportDtos array with one entry per input item. Successful items have detail: null; rejected items have detail containing the error message. The overall request always returns 201 — item-level failures do not fail the whole request.

{
  "singleWarningReportDtos": [
    { "id": "row-001", "detail": null },
    { "id": "row-002", "detail": "F_E_002 - At least one resource does not exist in Djust system. shippingZoneId=zone-idf" }
  ]
}

Errors

HTTPCodeDescription
400F-E-010Invalid value (e.g. negative price, francoAmount <= 0)
400F-E-012Invalid ID format, or unknown currency
401F-E-032Missing or invalid authentication token
403F-E-030Caller is not OPERATOR
404F-E-002Referenced entity not found (logistic family, zone, type, or supplier)
409F-E-003Duplicate id, duplicate dimension combination (currency included), or second default shipping fee line on a combination
422F-E-001Required field missing
422F-E-040supplierId and isDefault: true sent on the same line

Getting a Shipping Price Line

GET /v1/shipping-prices/{id}
dj-client: OPERATOR
dj-api-key: {{apiKey}}

Path Parameters

ParameterTypeRequiredDescription
idstringYesFunctional identifier of the shipping price line

Response — 200 OK

{
  "id": "sp-001",
  "logisticFamilyId": "standard",
  "logisticFamilyName": "Standard",
  "shippingZoneId": "eu-west",
  "shippingZoneName": "EU West",
  "shippingTypeId": "express-24h",
  "shippingTypeName": "Express 24h",
  "supplierId": "supplier-001",
  "supplierName": "Acme Supplies",
  "isDefault": false,
  "currency": "EUR",
  "price": 12.50,
  "francoAmount": 150.00,
  "createdAt": "2026-06-01T10:00:00Z",
  "updatedAt": "2026-06-01T10:00:00Z"
}

A default shipping fee line is returned with isDefault: true and supplierId / supplierName at null, so it can be told apart from a supplier line without ambiguity:

{
  "id": "sp-default-express",
  "logisticFamilyId": "standard",
  "logisticFamilyName": "Standard",
  "shippingZoneId": "eu-west",
  "shippingZoneName": "EU West",
  "shippingTypeId": "express-24h",
  "shippingTypeName": "Express 24h",
  "supplierId": null,
  "supplierName": null,
  "isDefault": true,
  "currency": "EUR",
  "price": 15.00,
  "francoAmount": null,
  "createdAt": "2026-09-01T09:00:00Z",
  "updatedAt": "2026-09-01T09:00:00Z"
}
✅

Tip:

The response includes the name of each dimension (logistic family, zone, type, supplier) alongside its ID, making it easy to display in a UI without additional lookups.

Errors

HTTPCodeDescription
401F-E-032Missing or invalid authentication token
403F-E-030Caller is not OPERATOR
404F-E-002Shipping price line not found

For the complete list of error codes, refer to Error / Warning codes.


Listing Shipping Price Lines

Retrieve a paginated, filterable list of shipping price lines.

GET /v1/shipping-prices
dj-client: OPERATOR
dj-api-key: {{apiKey}}

Query Parameters

ParameterTypeRequiredDescription
pageintegerNoPage number (0-based). Default: 0
sizeintegerNoItems per page. Default: 20. Min: 1. Max: 100.
sortstringNoFormat: property:direction. Sortable fields: createdAt, updatedAt. Default: createdAt:desc
logisticFamilyIdsstringNoComma-separated logistic family IDs
shippingZoneIdsstringNoComma-separated shipping zone IDs
shippingTypeIdsstringNoComma-separated shipping type IDs
supplierIdsstringNoComma-separated supplier IDs (marketplace only). Default shipping fee lines are returned alongside the matching suppliers, since they apply wherever those suppliers have no line of their own
currenciesstringNoComma-separated ISO 4217 currency codes among the platform currencies, case-insensitive. OR within the filter. An unknown value returns a 400 (F-E-012)
isDefaultbooleanNotrue keeps only the default shipping fee lines, false only the lines targeting a supplier. Omitted: both are returned
createdAtFromdatetimeNoFilter by creation date (inclusive, from)
createdAtTodatetimeNoFilter by creation date (inclusive, to)
updatedAtFromdatetimeNoFilter by update date (inclusive, from)
updatedAtTodatetimeNoFilter by update date (inclusive, to)

All filters are combined with AND logic. Multi-valued filters (e.g. logisticFamilyIds=a,b) match any of the listed values (OR within the filter).

✅

To list only the lines a given supplier owns, combine supplierIds=supplier-001 with isDefault=false. Without isDefault=false, the default shipping fee lines that would apply to that supplier are returned too.

Response — 200 OK

{
  "content": [
    {
      "id": "sp-001",
      "logisticFamilyId": "standard",
      "logisticFamilyName": "Standard",
      "shippingZoneId": "eu-west",
      "shippingZoneName": "EU West",
      "shippingTypeId": "express-24h",
      "shippingTypeName": "Express 24h",
      "supplierId": "supplier-001",
      "supplierName": "Acme Supplies",
      "isDefault": false,
      "currency": "EUR",
      "price": 12.50,
      "francoAmount": 150.00,
      "createdAt": "2026-06-01T10:00:00Z",
      "updatedAt": "2026-06-01T10:00:00Z"
    },
    {
      "id": "sp-default-express",
      "logisticFamilyId": "standard",
      "logisticFamilyName": "Standard",
      "shippingZoneId": "eu-west",
      "shippingZoneName": "EU West",
      "shippingTypeId": "express-24h",
      "shippingTypeName": "Express 24h",
      "supplierId": null,
      "supplierName": null,
      "isDefault": true,
      "currency": "EUR",
      "price": 15.00,
      "francoAmount": null,
      "createdAt": "2026-09-01T09:00:00Z",
      "updatedAt": "2026-09-01T09:00:00Z"
    }
  ],
  "numberOfElements": 2,
  "number": 0,
  "size": 20,
  "sort": ["createdAt:desc"],
  "first": true,
  "last": true,
  "empty": false
}

Errors

HTTPCodeDescription
400F-E-010size exceeds the maximum (100)
400F-E-008size is less than 1 or page is negative
401F-E-032Missing or invalid authentication token
403F-E-030Caller is not OPERATOR

For the complete list of error codes, refer to Error / Warning codes.


Updating Shipping Price Lines (Bulk)

Update one or more existing price lines. This is a full replacement of all modifiable fields. Each line is validated independently.

PUT /v1/shipping-prices
dj-client: OPERATOR
dj-api-key: {{apiKey}}
Content-Type: application/json

Request Body

An array of objects, each including the id of the line to update and the new field values:

FieldTypeRequiredDescription
idstringYesIdentifier of the price line to update
logisticFamilyIdstringYesLogistic family identifier
shippingZoneIdstringYesShipping zone identifier
shippingTypeIdstringYesShipping type identifier
supplierIdstringNoSupplier identifier. Omit on a default shipping fee line
isDefaultbooleanNotrue = default shipping fee line for the combination (marketplace context). Default: false. Mutually exclusive with supplierId
currencystringNoISO 4217 code among the platform currencies, case-insensitive. Left unchanged when omitted or null, unlike the other fields
pricenumberYesUpdated shipping cost (>= 0)
francoAmountnumberNoUpdated free-shipping threshold (> 0 if provided, null to remove)

Business Rules

  • id identifies the shipping price line to update and is immutable.
  • All other fields are fully replaced by the request body (full update, not partial). A supplier line can therefore be turned into a default shipping fee line, and vice versa, by changing supplierId / isDefault.
  • currency is the exception to the full replacement: omitted or null, it keeps the currency already stored. Amounts only make sense in their currency, so they are never silently moved to another one.
  • In marketplace contexts, exactly one of supplierId or isDefault: true is required; both together are rejected (F-E-040). In non-marketplace contexts, supplierId is forbidden and isDefault is ignored.
  • The combination of (logisticFamilyId, shippingZoneId, shippingTypeId, supplierId, currency) must remain unique across all shipping price lines, and at most one default shipping fee line may exist per (logisticFamilyId, shippingZoneId, shippingTypeId, currency) combination.
  • An unknown currency is rejected with a 400 (F-E-012).

Example

[
  {
    "id": "sp-001",
    "logisticFamilyId": "standard",
    "shippingZoneId": "eu-west",
    "shippingTypeId": "express-24h",
    "supplierId": "supplier-001",
    "currency": "EUR",
    "price": 14.00,
    "francoAmount": 200.00
  }
]

Response — 200 OK

The response contains a singleWarningReportDtos array with one entry per input item. Successful items have detail: null; rejected items have detail containing the error message.

{
  "singleWarningReportDtos": [
    { "id": "row-001", "detail": null },
    { "id": "row-002", "detail": "F_E_002 - At least one resource does not exist in Djust system. id=row-002" }
  ]
}

Errors

HTTPCodeDescription
400F-E-010Invalid value (e.g. negative price, francoAmount <= 0)
400F-E-012Invalid ID format, or unknown currency
401F-E-032Missing or invalid authentication token
403F-E-030Caller is not OPERATOR
404F-E-002Shipping price line or a referenced entity does not exist
409F-E-003Duplicate dimension combination (currency included), or second default shipping fee line on a combination
422F-E-001Required field missing
422F-E-040supplierId and isDefault: true sent on the same line

Deleting Shipping Price Lines (Bulk)

Delete one or more price lines by ID. Each deletion is processed independently — a failure on one line does not block the others.

DELETE /v1/shipping-prices
dj-client: OPERATOR
dj-api-key: {{apiKey}}
Content-Type: application/json

Request Body

An array of price line IDs to delete:

["sp-001", "sp-002"]

Response — 200 OK

The response contains a singleWarningReportDtos array with one entry per input item. Successful deletions have detail: null; items that could not be found have detail containing the error message.

{
  "singleWarningReportDtos": [
    { "id": "row-001", "detail": null },
    { "id": "row-999", "detail": "F_E_002 - At least one resource does not exist in Djust system. id=row-999" }
  ]
}
ℹ️

Item-level failures (not found) are reported per-item in detail with code F_E_002 — they don't cause the overall request to fail.

✅

Tip:

Deleting a price line is allowed even if past orders reference it. Only future checkout calculations are affected.

Errors

HTTPCodeDescription
401F-E-032Missing or invalid authentication token
403F-E-030Caller is not OPERATOR

Not-found items are reported per-item in the response detail field (with code F_E_002), not as an HTTP status.

For the complete list of error codes, refer to Error / Warning codes.


Best Practices

  1. Use bulk operations — create, update, and delete operations all support bulk payloads. Batch your changes to minimize API calls.
  2. Set up dimensions first — create your logistic families, shipping zones, and shipping types before populating the price lines. Missing references cause F-E-002 errors.
  3. Use francoAmount for free shipping — instead of setting price: 0 for large orders, use the francoAmount threshold to automatically waive shipping fees above a certain order value.
  4. Filter with dimension IDs — when reviewing the price lines, use the multi-valued filters (e.g. shippingZoneIds=eu-west,eu-east) to narrow results efficiently.
  5. Add a default shipping fee line per combination (marketplace) — one isDefault: true line per logistic family × zone × type guarantees that a supplier without its own line, including one onboarded later, never blocks the checkout. Keep supplier-specific lines for the suppliers that need a different price: they always take precedence.
  6. Audit the safety net with isDefault=true — list the default lines to spot the combinations that are still uncovered.
  7. Cover every selling currency — there is no conversion and no fallback onto another currency. For each currency you sell in, make sure every combination has either a supplier line or a default shipping fee line in that currency. Use currencies to audit one currency at a time.
  8. Omit currency on an update you do not intend to re-denominate — it keeps the stored currency, where sending a wrong code would move the amounts to another currency and create a second line on the combination.

Common Mistakes

MistakeConsequenceHow to avoid
Creating a duplicate dimension combination409 Conflict (F-E-003)Ensure each (logisticFamilyId + shippingZoneId + shippingTypeId + supplierId) is unique
Setting price to a negative value400 error (F-E-010)Price must be >= 0
Setting francoAmount to 0 or negative400 error (F-E-010)Franco amount must be strictly > 0, or null for no threshold
Referencing a non-existent dimension ID404 error (F-E-002)Create logistic families, zones, types, and suppliers before creating price lines
Deleting a shipping type that is still used in a price line409 Conflict (F-E-042) on the type deletionRemove price lines referencing the type before deleting it
Sending supplierId and isDefault: true on the same line422 error (F-E-040)A line targets either one supplier or all uncovered suppliers, never both
Marketplace line with neither supplierId nor isDefault: trueLine rejectedSet supplierId for a supplier line, or isDefault: true for the default shipping fee
Creating a second default shipping fee line on a combination409 Conflict (F-E-003)Update the existing default line instead; only one is allowed per family × zone × type
Expecting the default line to override a supplier's own lineThe supplier price is appliedThe supplier line always wins; delete it if the default price should apply to that supplier
Expecting a EUR line to cover an order placed in another currencyCheckout blocked, no shipping type offeredThere is no conversion and no fallback — create a line in the currency of the order
Sending an unknown or non-platform currency code400 error (F-E-012)Use an ISO 4217 code among the currencies configured on the platform
Re-creating the same combination in a second currency and expecting a duplicate errorBoth lines coexistCurrency is part of the uniqueness key — this is the intended way to price a combination in several currencies

Error Reference

For the complete list of DJUST error and warning codes, refer to the dedicated page:
Error / Warning codes



Did this page help you?