Shipping Zones
This guide covers how to create, manage, and configure shipping zones via the Back-office and DJUST API.
Introduction
Shipping zones are geographical areas (e.g. "France Metropolitan", "EU", "North America") used to scope shipping rules and pricing. They define where delivery is offered and at which conditions, before being referenced in the shipping price matrix.
Managing Shipping Zones from the Back-Office
Most operators manage shipping zones directly from the DJUST Back-Office. The API described below performs the same actions and is intended for integrators.
Where to find it
Settings → Shipping fee management → Shipping zones
List view
The list view displays all existing shipping zones with:
- Search — free-text on
nameandid(case- and accent-insensitive) - Sorting — by name, creation date, or last update
- Row actions — Edit, Delete
- Each row shows the number of locations attached to the zone
Creating a shipping zone
Click "Create zone" and fill in the form:
| Field | Required | Notes |
|---|---|---|
Name | Yes | Display name (up to 255 characters). |
Description | No | Additional context (up to 10,000 characters). |
ID | No | Custom identifier. Auto-generated if left blank. Immutable after creation. Must be unique. |
Managing locations
Locations define the geographical scope of the zone. Add them from the Locations section of the zone editor.
Each location can be one of four types:
| Location type | Description |
|---|---|
| Other countries | One or more foreign countries (excluding France). |
| Whole France | All of France, no exception. |
| France with exclusions | All of France minus some specific departments. |
| Specific French departments | Selected French departments only. |
The last three modes are Back-Office shortcuts for France — they all resolve into an explicit list of French department codes at the API level. See Adding Locations to a Shipping Zone for the underlying schema.
A country or department can belong to only one zone at a time. Selected locations will be removed from other zones if needed — the Back-Office displays the impacted zones before you save.
Editing a shipping zone
Only Name and Description can be modified. The ID is locked. Locations are managed separately (see above).
Deleting a shipping zone
Deletion is blocked if the shipping zone is still referenced in the shipping price matrix. The Back-Office displays an error and lists the associated price rows. Remove them first, then retry the deletion.
Warning:
You must remove every shipping price matrix line referencing this zone before it can be deleted.
Key Endpoints
| Action | Method | Path | OperationId | Response |
|---|---|---|---|---|
| Create a shipping zone | POST | /v1/shipping-zones | ADM-SHIPPING-ZONE-100 | 201 Created |
| Update a shipping zone | PUT | /v1/shipping-zones/{id} | ADM-SHIPPING-ZONE-200 | 204 No Content |
| Delete a shipping zone | DELETE | /v1/shipping-zones/{id} | ADM-SHIPPING-ZONE-300 | 204 No Content |
| List shipping zones | GET | /v1/shipping-zones | ADM-SHIPPING-ZONE-550 | 200 OK |
| Get a shipping zone by ID | GET | /v1/shipping-zones/{id} | ADM-SHIPPING-ZONE-500 | 200 OK |
| Add locations to a zone | PATCH | /v1/shipping-zones/{shippingZoneId}/locations | ADM-SHIPPING-ZONE-210 | 200 OK |
| Remove locations from a zone | DELETE | /v1/shipping-zones/{shippingZoneId}/locations | ADM-SHIPPING-ZONE-350 | 204 No Content |
| List the locations of a zone | GET | /v1/shipping-zones/{shippingZoneId}/locations | ADM-SHIPPING-ZONE-551 | 200 OK |
All endpoints require dj-client: OPERATOR and dj-api-key headers.
Creating a Shipping Zone
POST /v1/shipping-zones
dj-client: OPERATOR
dj-api-key: {{apiKey}}
Content-Type: application/jsonRequest Body
| Field | Type | Required | Description |
|---|---|---|---|
id | string | No | Custom identifier. Auto-generated if omitted. Immutable after creation. Must be unique. |
name | string | Yes | Display name of the zone (max 255 characters) |
description | string | No | Description of the zone (max 10,000 characters) |
Example
{
"id": "eu-west",
"name": "EU West",
"description": "Western European countries including France, Spain, Portugal, and Benelux"
}Response — 201 Created
{
"id": "eu-west"
}Errors
| HTTP | Code | Description |
|---|---|---|
| 400 | F-E-010 | Name or description exceeds maximum length |
| 400 | F-E-012 | Invalid ID format |
| 401 | F-E-032 | Missing or invalid authentication token |
| 403 | F-E-030 | Caller is not OPERATOR |
| 409 | F-E-003 | A shipping zone with this ID already exists |
| 422 | F-E-001 | Name is absent, null, empty, or whitespace-only |
For the complete list of error codes, refer to Error / Warning codes.
Updating a Shipping Zone
Applies a full replacement of the modifiable fields (name and description). The id is immutable, and the zone's locations are not affected by this call — manage them with the dedicated locations endpoints.
PUT /v1/shipping-zones/{id}
dj-client: OPERATOR
dj-api-key: {{apiKey}}
Content-Type: application/jsonPath Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Identifier of the shipping zone |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Updated display name (1–255 characters) |
description | string | No | Updated description (max 10,000 characters). Pass null or "" to clear. |
Example
{
"name": "EU West - Updated",
"description": "Western European countries including France, Spain, Portugal, Benelux, and Ireland"
}Response — 204 No Content
No response body.
Errors
| HTTP | Code | Description |
|---|---|---|
| 400 | F-E-010 | Name or description exceeds maximum length |
| 401 | F-E-032 | Missing or invalid authentication token |
| 403 | F-E-030 | Caller is not OPERATOR |
| 404 | F-E-002 | Shipping zone not found |
| 422 | F-E-001 | Name is absent, null, empty, or whitespace-only |
Deleting a Shipping Zone
Permanently deletes a shipping zone. Deletion is blocked if any line of the shipping price matrix still references the zone — remove those price lines first.
DELETE /v1/shipping-zones/{id}
dj-client: OPERATOR
dj-api-key: {{apiKey}}Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Identifier of the shipping zone to delete |
Response — 204 No Content
No response body.
Errors
| HTTP | Code | Description |
|---|---|---|
| 401 | F-E-032 | Missing or invalid authentication token |
| 403 | F-E-030 | Caller is not OPERATOR |
| 404 | F-E-002 | Shipping zone not found |
| 409 | F-E-042 | Shipping zone is still referenced in the shipping price matrix. Remove the associated price lines first. |
Warning: You must remove every shipping price matrix line referencing this zone before it can be deleted.
For the complete list of error codes, refer to Error / Warning codes.
Adding Locations to a Shipping Zone
After creating a shipping zone, you can define its geographical scope by adding locations. The rules are simple:
- Foreign countries are added as a whole (one entry per country).
- France (
FR) must be added as individual departments — France cannot be added as a whole country.
PATCH /v1/shipping-zones/{shippingZoneId}/locations
dj-client: OPERATOR
dj-api-key: {{apiKey}}
Content-Type: application/jsonPath Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| shippingZoneId | string | yes | Identifier of the shipping zone |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
locations | array | Yes | List of locations to add. |
locations[].countryCode | string | Yes | ISO 3166-1 alpha-2 country code (e.g. FR, DE, US). |
locations[].departmentCodes | string[] | For FR | French department codes to add (INSEE format: 01–95, 2A/2B for Corsica, 971–976 for overseas). Required and non-empty when countryCode is FR. Ignored otherwise. |
Business Rules
- France must be added as individual departments — you cannot add FR as a whole country.
- If a country or department is already assigned to another shipping zone, it is automatically moved to the current one — the previous zone loses it silently (a warning is returned).
- Re-adding a location already present in this zone is idempotent (no error).
Whole France and France with exclusions are Back-Office UX shortcuts. At the API level,
FRalways requires an explicit list ofdepartmentCodes— the Back-Office simply resolves the shortcut into the full department list (minus any excluded ones) before calling the API.
Example — Foreign countries
{
"locations": [
{ "countryCode": "BE" },
{ "countryCode": "DE" },
{ "countryCode": "ES" }
]
}Example — French departments
{
"locations": [
{ "countryCode": "FR", "departmentCodes": ["75", "92", "93"] }
]
}Example — Mixed
{
"locations": [
{ "countryCode": "BE" },
{ "countryCode": "FR", "departmentCodes": ["59", "62"] }
]
}Response — 200 OK
The response contains a warnings array reporting every location moved from another zone. Empty if no reassignment occurred.
{
"warnings": [
{
"countryCode": "FR",
"departmentCode": "75",
"code": "F_W_039",
"message": "Location 75 has been moved from shipping zone zone-corse to shipping zone zone-idf.",
"previousShippingZoneId": "zone-corse"
}
]
}Errors
| HTTP | Code | Description |
|---|---|---|
| 400 | F-E-012 | Invalid country code |
| 401 | F-E-032 | Missing or invalid authentication token |
| 403 | F-E-030 | Caller is not OPERATOR |
| 404 | F-E-002 | Shipping zone not found |
| 422 | F-E-001 | locations array absent/empty or mandatory field missing |
Removing Locations from a Shipping Zone
Remove one or more locations from an existing shipping zone. The request follows the same structure as adding locations.
DELETE /v1/shipping-zones/{shippingZoneId}/locations
dj-client: OPERATOR
dj-api-key: {{apiKey}}
Content-Type: application/jsonPath Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
shippingZoneId | string | Yes | Identifier of the shipping zone |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| locations | array | yes | List of locations to remove. |
| locations[].countryCode | string | yes | ISO 3166-1 alpha-2 country code (e.g. FR, DE, US). |
| locations[].departmentCodes | string[] | For FR | French department codes to remove. Taken into account only when countryCode is FR; ignored otherwise. |
Business Rules
- An empty
locationsarray is accepted and performs no modification. - Removing a location not currently in the zone is silently idempotent (no error).
- A location currently attached to another shipping zone is left untouched.
- After removal, if the customer destination is no longer covered by any zone, the checkout process will be blocked for that destination.
Example — Remove a foreign country
{
"locations": [
{ "countryCode": "BE" }
]
}Example — Remove French departments
{
"locations": [
{ "countryCode": "FR", "departmentCodes": ["75", "92"] }
]
}Response — 204 No Content
No response body.
Errors
| HTTP | Code | Description |
|---|---|---|
| 400 | F-E-012 | Invalid country code |
| 401 | F-E-032 | Missing or invalid authentication token |
| 403 | F-E-030 | Caller is not OPERATOR |
| 404 | F-E-002 | Shipping zone not found |
For the complete list of error codes, refer to Error / Warning codes.
Listing the Locations of a Shipping Zone
Retrieve all locations attached to a shipping zone. The response is not paginated.
Locations are grouped by country:
- An entire foreign country is represented by
countryCodealone (nodepartmentCodes). - France is represented by
countryCode: "FR"together with the list of assigneddepartmentCodes.
GET /v1/shipping-zones/{shippingZoneId}/locations
dj-client: OPERATOR
dj-api-key: {{apiKey}}Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
shippingZoneId | string | Yes | Identifier of the shipping zone |
Response — 200 OK
{
"locations": [
{ "countryCode": "FR", "departmentCodes": ["75", "92"] },
{ "countryCode": "BE" },
{ "countryCode": "DE" }
]
}Zone with no locations:
{ "locations": [] }Errors
| HTTP | Code | Description |
|---|---|---|
| 401 | F-E-032 | Missing or invalid authentication token |
| 403 | F-E-030 | Caller is not OPERATOR |
| 404 | F-E-002 | Shipping zone not found |
For the complete list of error codes, refer to Error / Warning codes.
Listing Shipping Zones
Retrieve a paginated list of shipping zones with optional filters and sorting.
GET /v1/shipping-zones
dj-client: OPERATOR
dj-api-key: {{apiKey}}Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
page | integer | No | Page number (0-based). Default: 0 |
size | integer | No | Number of items per page. Default: 20. Min: 1. Max: 100. |
sort | string | No | Format: property:direction. Sortable fields: name, createdAt, updatedAt. Default: createdAt:desc. Invalid entries are silently ignored. |
search | string | No | Free-text search matched against both name and id (external ID) — partial match, OR logic, case- and accent-insensitive. |
createdAtFrom | datetime | No | Filter by creation date (inclusive, from) |
createdAtTo | datetime | No | Filter by creation date (inclusive, to) |
updatedAtFrom | datetime | No | Filter by update date (inclusive, from) |
updatedAtTo | datetime | No | Filter by update date (inclusive, to) |
Response — 200 OK
{
"content": [
{
"id": "eu-west",
"name": "EU West",
"description": "Western European countries including France, Spain, Portugal, and Benelux",
"locationsCount": 5,
"createdAt": "2026-06-01T10:00:00Z",
"updatedAt": "2026-06-10T14:30:00Z"
},
{
"id": "north-america",
"name": "North America",
"description": "US and Canada",
"locationsCount": 2,
"createdAt": "2026-05-15T08:30:00Z",
"updatedAt": "2026-05-15T08:30:00Z"
}
],
"numberOfElements": 2,
"number": 0,
"size": 20,
"first": true,
"last": true,
"empty": false
}Errors
| HTTP | Code | Description |
|---|---|---|
| 400 | F-E-010 | size exceeds the maximum (100) |
| 400 | F-E-008 | size is less than 1 or page is negative |
| 401 | F-E-032 | Missing or invalid authentication token |
| 403 | F-E-030 | Caller is not OPERATOR |
For the complete list of error codes, refer to Error / Warning codes.
Retrieving a Shipping Zone
GET /v1/shipping-zones/{id}
dj-client: OPERATOR
dj-api-key: {{apiKey}}Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Functional identifier of the shipping zone |
Response — 200 OK
{
"id": "eu-west",
"name": "EU West",
"description": "Western European countries including France, Spain, Portugal, and Benelux",
"locationsCount": 5,
"createdAt": "2026-06-01T10:00:00Z",
"updatedAt": "2026-06-10T14:30:00Z"
}Errors
| HTTP | Code | Description |
|---|---|---|
| 401 | F-E-032 | Missing or invalid authentication token |
| 403 | F-E-030 | Caller is not OPERATOR |
| 404 | F-E-002 | Shipping zone not found |
For the complete list of error codes, refer to Error / Warning codes.
Best Practices
- Use meaningful custom IDs — if you provide a custom
id, make it descriptive and consistent (e.g.eu-west,metropolitan-france,dom-tom). Once created, the ID cannot be changed. - Design your zone map with the price matrix in mind — a shipping zone is a pricing bucket in the shipping price matrix. Design zones so each represents a distinct pricing area.
- Plan French department coverage carefully — even when using the Back-Office shortcut "Whole France", the zone stores the explicit list of French departments. Since a department can only belong to one zone, plan the coverage before splitting France across multiple zones.
- Watch for silent reassignments — when adding a location already assigned to another zone, it is transferred silently (a
F_W_039warning is returned). Always check thewarningsarray in the API response, or the reassignment banner in the Back-Office. - Keep zone names business-friendly — they are shown to operators in the shipping price matrix and other Back-Office screens. Use clear, unambiguous labels.
Common Mistakes
| Mistake | Consequence | How to avoid |
|---|---|---|
Providing a duplicate id when creating a zone | 409 Conflict (F-E-003) | Ensure IDs are unique across all shipping zones |
Omitting name in create/update | 422 validation error | name is always required |
Exceeding max length on name or description | 400 error | Keep name under 255 characters and description under 10,000 |
Trying to update the id after creation | id is immutable | Plan your identifiers before creating the zone |
| Sending {"countryCode": "FR"} via the API without departmentCodes | 422 (F-E-001) | The API always requires an explicit list of French departments. The Back-Office "Whole France" shortcut is resolved to the full list before the call. |
| Not realizing a location was reassigned from another zone | Previous zone silently loses the location | Check the warnings array in the response (code F_W_039) |
| Deleting a shipping zone still referenced in the price matrix | 409 Conflict (F-E-042) | Remove all associated price matrix lines before deleting the zone |
Trying to modify locations via PUT /shipping-zones/{id} | Locations are unchanged | Locations must be managed via the dedicated PATCH / DELETE /locations routes |
Updated 26 days ago

