The home layout is the ordered list of sections a store shows on its home page. Each section has a type and settings. Ten types can be added on every theme: category-products, featured, categories, banner, image-with-text, rich-text, trust-badges, testimonials, faq and video. A section theme such as atlas also offers hero and product-grid. types in the GET answer gives the settings of each. Every write on this page is live on the store as soon as it answers.
This is not GET /v1/store/home-sections, which reads the switches of the Digital, Ariana and Prestige home pages. Those switches are described at the end of this page.
Before you start
GETneedsstore:readand the writes needstore:write. Merchant keys carry both.POST,PATCHandDELETEneed anIdempotency-Key. OnPUTit is optional. See Idempotency.A category id comes from
GET /v1/categories, which needsproducts:read.
The section object
Field | Type | Notes |
| int | Stable while the section exists. A section that comes back through an undo gets a new id. |
| string | One of the |
| object | Every setting of the type, with the defaults filled in. |
| bool |
|
| bool |
|
Settings of category-products
Setting | Type | Default | Rules |
| category id |
| A category of this store. |
| text |
| Up to 80 characters, HTML removed. Empty shows the category name. |
| range |
| 4 to 12. A number outside that range is moved to the nearest end. |
| select |
|
|
| checkbox |
| A link to the category page. |
A category with no products shows nothing to buyers either. Read the rules of any type from its settings_schema rather than hard-coding them: the list of types depends on the store's theme.
Setting formats
Setting type | Accepted value |
| An id from |
|
|
| A YouTube video link or its 11-character id. The id is stored. |
| The path of an image uploaded in the dashboard for this store, |
When buyers see a section
A section whose content is not filled in yet is stored and the write answers 2xx, but buyers do not see it until it is:
Type | Buyers see it once |
|
|
| the chosen |
| the store has a category with products, or any category when |
|
|
|
|
|
|
| always. Empty badges 1 and 2 show the default delivery and cash on delivery lines. |
| at least one |
| at least one |
|
|
rendered does not change for this: it says whether the theme shows stored sections, not whether one section is visible. On a section theme (atlas), saved sections replace the theme's own home only while they include a visible product-grid section, and rendered is false until then; buyers see the theme's home, and GET lists only the saved sections, not the theme's own.
GET /v1/store/home-layout
The sections in render order, the section types that can be added on the store's theme, and the plan cap.
Auth: platform key with store:read.
Request
curl 'https://api.dzbuild.app/v1/store/home-layout' \ -H "Authorization: Bearer $DZ_KEY"
Response 200
{
"data": {
"theme": "starter",
"rendered": true,
"max_sections": 25,
"cap": 25,
"version": "9c1e04b7a2d35f68",
"sections": [
{
"id": 412,
"type": "category-products",
"settings": {
"category": 57,
"title": "",
"count": 8,
"layout": "grid",
"show_view_all": true
},
"is_active": true,
"available": true
},
{
"id": 415,
"type": "category-products",
"settings": {
"category": 61,
"title": "Nos parfums",
"count": 10,
"layout": "slider",
"show_view_all": false
},
"is_active": false,
"available": true
}
],
"types": [
{
"type": "category-products",
"name": {"ar": "منتجات فئة", "fr": "Produits d'une catégorie"},
"description": {"ar": "اعرض منتجات فئة واحدة في شبكة أو شريط تمرير.", "fr": "Affichez les produits d'une catégorie en grille ou en carrousel."},
"icon": "bi-grid-3x3-gap",
"limit": 12,
"settings_schema": [
{"id": "category", "type": "category", "default": 0, "label": {"ar": "الفئة", "fr": "Catégorie"}},
{"id": "title", "type": "text", "max": 80, "default": "", "label": {"ar": "العنوان (إذا تركته فارغاً يظهر اسم الفئة)", "fr": "Titre (si vide, le nom de la catégorie s'affiche)"}},
{"id": "count", "type": "range", "min": 4, "max": 12, "default": 8, "label": {"ar": "عدد المنتجات", "fr": "Nombre de produits"}},
{"id": "layout", "type": "select", "options": ["grid", "slider"], "default": "grid", "label": {"ar": "طريقة العرض", "fr": "Affichage"}, "option_labels": {"ar": ["شبكة", "شريط تمرير"], "fr": ["Grille", "Carrousel"]}},
{"id": "show_view_all", "type": "checkbox", "default": true, "label": {"ar": "زر عرض الكل", "fr": "Lien « Voir tout »"}}
]
}
]
},
"meta": {"request_id": "8f2c1a9d4b7e6035", "api_version": "v1"}
}
Field | Meaning |
| The store's theme key. |
|
|
| 25, the most sections one home page holds. |
| The sections the store's plan allows: 3 on Free or an expired plan, 25 from Pro. |
| A fingerprint of the stored layout. Send it back as |
| The sections in render order, hidden ones included. |
| The types that can be added on this theme, with |
Reading after a write
Through api.dzbuild.app every GET is served fresh: a GET sent right after a write returns the new layout. You rarely need it, because every write returns the whole list in render order with the new version.
POST /v1/store/home-layout/sections
Adds one section.
Auth: platform key with store:write. Requires Idempotency-Key.
Body
Field | Type | Required | Notes |
| string | yes | A |
| object | no | Settings you do not send take the type's defaults. |
| int | no | 0 puts the section at the top, 24 is the last place. Without it the section goes at the end. |
Request
curl -X POST 'https://api.dzbuild.app/v1/store/home-layout/sections' \
-H "Authorization: Bearer $DZ_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: hs-add-sacs-1" \
-d '{"type": "category-products", "settings": {"category": 64, "layout": "slider"}, "position": 0}'
Response 201
{
"data": {
"section": {
"id": 418,
"type": "category-products",
"settings": {"category": 64, "title": "", "count": 8, "layout": "slider", "show_view_all": true},
"is_active": true,
"available": true
},
"sections": [
{"id": 418, "type": "category-products", "settings": {"category": 64, "title": "", "count": 8, "layout": "slider", "show_view_all": true}, "is_active": true, "available": true},
{"id": 412, "type": "category-products", "settings": {"category": 57, "title": "", "count": 8, "layout": "grid", "show_view_all": true}, "is_active": true, "available": true},
{"id": 415, "type": "category-products", "settings": {"category": 61, "title": "Nos parfums", "count": 10, "layout": "slider", "show_view_all": false}, "is_active": false, "available": true}
],
"version": "e27a90c4b1f36d05",
"change_id": 90231,
"rendered": true
},
"meta": {"request_id": "3b7d0e5a9c14f862", "api_version": "v1"}
}
PATCH /v1/store/home-layout/sections/{id}
Changes one section. The settings you send are merged over the stored ones. Send settings, is_active or both.
Auth: platform key with store:write. Requires Idempotency-Key.
Body
Field | Type | Required | Notes |
| object | no | Merged over the stored settings. |
| bool | no |
|
| bool | no | With |
Request
curl -X PATCH 'https://api.dzbuild.app/v1/store/home-layout/sections/415' \
-H "Authorization: Bearer $DZ_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: hs-415-show-1" \
-d '{"settings": {"count": 6}, "is_active": true}'
Response 200
The answer has the same fields as the POST answer: section (the section after the change), sections, version, change_id and rendered.
{
"data": {
"section": {
"id": 415,
"type": "category-products",
"settings": {"category": 61, "title": "Nos parfums", "count": 6, "layout": "slider", "show_view_all": false},
"is_active": true,
"available": true
},
"sections": [
{"id": 418, "type": "category-products", "settings": {"category": 64, "title": "", "count": 8, "layout": "slider", "show_view_all": true}, "is_active": true, "available": true},
{"id": 412, "type": "category-products", "settings": {"category": 57, "title": "", "count": 8, "layout": "grid", "show_view_all": true}, "is_active": true, "available": true},
{"id": 415, "type": "category-products", "settings": {"category": 61, "title": "Nos parfums", "count": 6, "layout": "slider", "show_view_all": false}, "is_active": true, "available": true}
],
"version": "51d8c3e06fa2b974",
"change_id": 90232,
"rendered": true
},
"meta": {"request_id": "c90a6e1f2d7b4538", "api_version": "v1"}
}
DELETE /v1/store/home-layout/sections/{id}
Removes one section.
Auth: platform key with store:write. Requires Idempotency-Key.
Request
curl -X DELETE 'https://api.dzbuild.app/v1/store/home-layout/sections/412' \ -H "Authorization: Bearer $DZ_KEY" \ -H "Idempotency-Key: hs-del-412-1"
Response 200
{
"data": {
"deleted": true,
"id": 412,
"sections": [
{"id": 418, "type": "category-products", "settings": {"category": 64, "title": "", "count": 8, "layout": "slider", "show_view_all": true}, "is_active": true, "available": true},
{"id": 415, "type": "category-products", "settings": {"category": 61, "title": "Nos parfums", "count": 6, "layout": "slider", "show_view_all": false}, "is_active": true, "available": true}
],
"version": "0f6b2d9e84a1c357",
"change_id": 90233,
"rendered": true
},
"meta": {"request_id": "71e4b08c3a5d9f26", "api_version": "v1"}
}
POST /v1/store/home-layout/reorder
Sets the render order. ids lists every section of the page exactly once, hidden ones included.
Auth: platform key with store:write. Requires Idempotency-Key.
Request
curl -X POST 'https://api.dzbuild.app/v1/store/home-layout/reorder' \
-H "Authorization: Bearer $DZ_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: hs-order-2" \
-d '{"ids": [415, 418]}'
Response 200
The answer carries sections in the new order, version, change_id and rendered. An id that is not on the page answers 404 section_not_found. A missing or repeated id answers 422 invalid_order.
PUT /v1/store/home-layout
Replaces the whole layout with the list you send, in that order.
Auth: platform key with store:write. Idempotency-Key is optional.
Body
Field | Type | Required | Notes |
| array | yes | At most 25 items, each |
| string | no | The |
How each item is read:
An item with an
idkeeps that section. Itstypemust be the section's current type.An item without an
idcreates a section.A section of the page that is not in the list is deleted.
settingsis the whole object: a setting you leave out goes back to its default. Send the full settings of every section you keep.is_activedefaults totrue.
Request
curl -X PUT 'https://api.dzbuild.app/v1/store/home-layout' \
-H "Authorization: Bearer $DZ_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: hs-replace-7" \
-d '{
"version": "0f6b2d9e84a1c357",
"sections": [
{"id": 415, "type": "category-products", "settings": {"category": 61, "title": "Nos parfums", "count": 6, "layout": "slider", "show_view_all": false}},
{"type": "category-products", "settings": {"category": 57}}
]
}'
Response 200
The answer carries sections, version, change_id and rendered. Section 418 was left out, so it is deleted. Sending back the layout you read, unchanged, answers change_id: null.
With an Idempotency-Key, a retry with the same key and the same body gets the stored answer back for 24 hours with Idempotency-Replay: 1, and the same key with another body answers 422 idempotency_key_reuse. Without a key the call runs every time, which is safe: sending the same list twice leaves the same layout.
Undo
Every write answers with a change_id, or null when it changed nothing. POST /v1/changes/{change_id}/undo puts the whole home page back as it was before that change.
An added section can be undone too: the undo removes it. For other resources, undo refuses a change that created something.
If the home page changed after that change, through the API or in the dashboard, the undo answers
409 layout_changedand writes nothing. Read the layout and write what you want directly.A section that comes back after a delete gets a new id.
The undo is recorded as a change of its own,
undo_change_id, which you can undo in turn. Undoing the undo of a delete answers409 layout_changed, because the section came back with a new id.Changes the merchant saves in the dashboard are not recorded, so they cannot be undone through the API.
GET /v1/changes?entity=store.home_layoutlists the home layout changes, newest first, withstore:read.An installed app's token cannot read or undo changes:
GET /v1/changesand the undo answer403 forbidden(Apps cannot use this endpoint). Write answers still carry thechange_id.The undo answer does not carry the layout. Read it again with
GET /v1/store/home-layout; the read is served fresh.
The undo needs store:write and an Idempotency-Key.
curl -X POST 'https://api.dzbuild.app/v1/changes/90231/undo' \ -H "Authorization: Bearer $DZ_KEY" \ -H "Idempotency-Key: undo-90231"
{
"data": {
"undone": true,
"change_id": 90231,
"entity": "store.home_layout",
"undo_change_id": 90240
},
"meta": {"request_id": "5ad2f7c01e9b8634", "api_version": "v1"}
}
A change undone a second time answers 409 already_undone.
Errors
HTTP | Code | Cause |
400 |
| The body is not a JSON object, a field has the wrong type ( |
401 |
| Bad or missing key. |
402 |
| The store's monthly request quota is used up. See Rate limits. |
403 |
|
|
403 |
| The write would leave more sections than the plan allows. The error carries |
404 |
| No section with this id on the page. |
409 |
| Another write landed first, or the |
409 |
| Undo only: the home page changed after this change. |
409 |
| Undo only: the change was already undone. |
413 |
| The body is over 1 MB. |
422 |
| A value was refused. |
422 |
| The type does not exist or cannot be added on this theme. |
422 |
| More than 25 sections, or more of one type than its |
422 |
| Reorder |
422 |
| A |
422 |
| The same |
429 |
| Too many requests, including more than 30 home layout writes a minute for the store. Wait for |
429 |
| More than 5 home layout writes running at once for the store. Retry in a few seconds. |
500 |
| The request failed. Retry with the same |
An invalid_settings answer looks like this.
{
"error": {
"code": "invalid_settings",
"message": "Invalid value at settings.category: category not found in this store; accepted values are in settings_schema of GET /v1/store/home-layout",
"fields": [{"path": "settings.category", "code": "invalid"}]
},
"meta": {"request_id": "e4c19a0b7d2f5836", "api_version": "v1"}
}
Limits
25 sections per home page (
max_sections).Plan cap (
cap): 3 sections on Free or an expired plan, 25 from Pro. Hidden sections count. A store above its cap after a downgrade keeps its sections and can still edit, hide, reorder and delete them. A write that leaves more sections than the cap and more than before answers403 plan_required.Per type: each type has a
limitintypes, 12 forcategory-products.Settings: 8 KB per section once encoded. Longer text is cut to the setting's
max.Body: 1 MB.
Writes: 30 a minute and 5 at once per store, on top of the store's per-minute limit. See Rate limits.
Home page switches of Digital, Ariana and Prestige
The Digital, Ariana and Prestige themes build their home page from fixed blocks. An older set of switches shows or hides those blocks and sets their titles, categories and banners. GET and PATCH /v1/store/home-sections read and change these switches. They are stored apart from the home layout above, so a write on one never changes the other.
Theme | Keys it reads |
Digital, Ariana |
|
Prestige |
|
No other theme reads these switches: on another theme a write is saved and answers 200, and buyers see no change. A switch that was never saved is missing from the answer, and Digital and Ariana then show its block while Prestige hides its testimonials. section_order sets the order of the Digital and Ariana blocks with the values hero_slider, category_cards, top_sellers, popular_by_category, promo_banners and multi_column_lists. A block left out of that list is not shown.
GET /v1/store/home-sections
Auth: platform key with store:read. Like GET /v1/store/home-layout, the answer is served fresh on every call.
curl 'https://api.dzbuild.app/v1/store/home-sections' \ -H "Authorization: Bearer $DZ_KEY"
{
"data": {
"theme": "digital",
"settings": {"show_top_sellers": 1, "top_sellers_title": "Meilleures ventes", "column_1_category_id": 57}
},
"meta": {"request_id": "...", "api_version": "v1"}
}
settings holds only the keys that were saved. A store that never saved any answers "settings": [].
PATCH /v1/store/home-sections
Auth: platform key with store:write. Requires Idempotency-Key.
Send only the keys to change: the others keep their value, and unknown keys are ignored. show_* keys are stored as 1 or 0. A *_category_id takes a category of this store, and 0 clears it. Text is trimmed and cut to 500 characters, testimonials_title to 200. banner_1_button_link and banner_2_button_link take an https://, http://, mailto: or tel: link, a /path or an #anchor. testimonials keeps up to 24 entries, each with name, comment and stars from 1 to 5.
curl -X PATCH 'https://api.dzbuild.app/v1/store/home-sections' \
-H "Authorization: Bearer $DZ_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: hs-top-sellers-off-1" \
-d '{"show_top_sellers": false, "column_1_category_id": 61}'
{
"data": {
"updated": ["show_top_sellers", "column_1_category_id"],
"settings": {"show_top_sellers": 0, "top_sellers_title": "Meilleures ventes", "column_1_category_id": 61}
},
"meta": {"request_id": "...", "api_version": "v1"}
}
updated lists the keys written, and settings holds every saved key after the write. The answer has no change_id: GET /v1/changes?entity=store.home_sections lists these changes, and POST /v1/changes/{change_id}/undo undoes one. Undoing the first write of a key does not bring back its default: a show_* switch comes back as 0 and section_order as [], which on Digital and Ariana hides that block, or every block. To go back to the defaults, send 1 or the full section_order list with PATCH.
HTTP | Code | Cause |
400 |
| The body is not JSON, or |
403 |
|
|
422 |
| The body holds none of the keys this endpoint accepts. |
422 |
| A |
422 |
| A button link uses another scheme, such as |
422 |
| The same |
401, 402, 413 and 500 mean the same as for the home layout writes. 429 rate_limited comes only from the general per-minute limits in Rate limits: the home layout write limits do not apply here.