Skip to main content

Home page sections

Read and change the sections of a store's home page from your own code, with ten section types, then add, update, hide, reorder, delete, replace or undo.

Written by Support

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

  • GET needs store:read and the writes need store:write. Merchant keys carry both.

  • POST, PATCH and DELETE need an Idempotency-Key. On PUT it is optional. See Idempotency.

  • A category id comes from GET /v1/categories, which needs products:read.

The section object

Field

Type

Notes

id

int

Stable while the section exists. A section that comes back through an undo gets a new id.

type

string

One of the type values listed in types by GET /v1/store/home-layout.

settings

object

Every setting of the type, with the defaults filled in.

is_active

bool

false hides the section from buyers and keeps it in the list.

available

bool

false when the store's theme no longer has this type. The section is kept as stored and a write may keep it.

Settings of category-products

Setting

Type

Default

Rules

category

category id

0

A category of this store. 0 means none, and the section then shows nothing to buyers. An id of another store answers 422 invalid_settings.

title

text

""

Up to 80 characters, HTML removed. Empty shows the category name.

count

range

8

4 to 12. A number outside that range is moved to the nearest end.

layout

select

grid

grid or slider.

show_view_all

checkbox

true

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

category

An id from GET /v1/categories, or 0 for none.

link

#anchor, a /path on the store, an http:// or https:// address, or a tel: or mailto: link, up to 500 characters, or "". An address sent without its scheme, such as wa.me/213..., is stored with https:// in front.

youtube

A YouTube video link or its 11-character id. The id is stored.

image

The path of an image uploaded in the dashboard for this store, /uploads/banners/{store_id}/..., or "". The API cannot upload images today: the merchant uploads the picture in the section's settings in the dashboard first, and GET then returns its path.

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

category-products

category is a category of the store that has products.

featured

the chosen source has products.

categories

the store has a category with products, or any category when show_empty is true.

banner

image is set.

image-with-text

image is set, with a title or a text.

rich-text

title or text is set.

trust-badges

always. Empty badges 1 and 2 show the default delivery and cash on delivery lines.

testimonials

at least one tN_text is set.

faq

at least one qN is set with its aN.

video

video holds a YouTube id.

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

theme

The store's theme key.

rendered

false when the store's current theme does not show home page sections. The sections are kept and show again on a theme that does. On a section theme it is true only while a visible product-grid section is saved.

max_sections

25, the most sections one home page holds.

cap

The sections the store's plan allows: 3 on Free or an expired plan, 25 from Pro.

version

A fingerprint of the stored layout. Send it back as version on PUT to refuse a layout that changed since this read.

sections

The sections in render order, hidden ones included.

types

The types that can be added on this theme, with name, description, icon, limit (the most sections of that type one page holds) and settings_schema. The sample above shows one of them.

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

type

string

yes

A type from types.

settings

object

no

Settings you do not send take the type's defaults.

position

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

settings

object

no

Merged over the stored settings.

is_active

bool

no

false hides the section, true shows it.

replace

bool

no

With settings, true resets every setting you do not send to its default.

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

sections

array

yes

At most 25 items, each {id?, type, settings?, is_active?}. An empty list removes every section.

version

string

no

The version from your last read. When the layout changed since, the call answers 409 write_conflict with the current sections and version, and writes nothing.

How each item is read:

  • An item with an id keeps that section. Its type must be the section's current type.

  • An item without an id creates a section.

  • A section of the page that is not in the list is deleted.

  • settings is the whole object: a setting you leave out goes back to its default. Send the full settings of every section you keep.

  • is_active defaults to true.

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_changed and 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 answers 409 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_layout lists the home layout changes, newest first, with store:read.

  • An installed app's token cannot read or undo changes: GET /v1/changes and the undo answer 403 forbidden (Apps cannot use this endpoint). Write answers still carry the change_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

bad_request

The body is not a JSON object, a field has the wrong type (type missing, settings not an object, is_active or replace not a boolean, position outside 0 to 24, ids not an array of section ids, version not a string), the section id in the path is not a positive number, or Idempotency-Key is missing or malformed on POST, PATCH or DELETE.

401

unauthorized

Bad or missing key.

402

quota_exceeded

The store's monthly request quota is used up. See Rate limits.

403

forbidden

Missing scope: store:read or Missing scope: store:write, or API access requires an active Enterprise plan for a merchant key whose store is not on an active Enterprise plan.

403

plan_required

The write would leave more sections than the plan allows. The error carries plan and cap.

404

section_not_found

No section with this id on the page.

409

write_conflict

Another write landed first, or the version sent on PUT is not the current one. When the error carries sections and version, they are the current layout: retry from them. Otherwise read the layout and retry.

409

layout_changed

Undo only: the home page changed after this change.

409

already_undone

Undo only: the change was already undone.

413

payload_too_large

The body is over 1 MB.

422

invalid_settings

A value was refused. fields lists every refused setting of the section, such as settings.category. On PUT it lists those of the first refused section only, such as sections.2.settings.layout, and it also covers an id that is not on the page (sections.N.id) and a kept section sent with another type (sections.N.type). message names the paths too.

422

invalid_section_type

The type does not exist or cannot be added on this theme. fields gives the path.

422

limit_reached

More than 25 sections, or more of one type than its limit. The error carries limit, except when a PUT sends more than 25 items.

422

invalid_order

Reorder ids miss a section or repeat one.

422

no_changes

A PATCH without settings or is_active.

422

idempotency_key_reuse

The same Idempotency-Key was used with another body.

429

rate_limited

Too many requests, including more than 30 home layout writes a minute for the store. Wait for Retry-After.

429

too_many_concurrent

More than 5 home layout writes running at once for the store. Retry in a few seconds.

500

server_error

The request failed. Retry with the same Idempotency-Key.

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 answers 403 plan_required.

  • Per type: each type has a limit in types, 12 for category-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

show_hero_slider, hero_slides, show_sidebar_widget, sidebar_widget_title, sidebar_widget_category_id, show_category_cards, show_top_sellers, top_sellers_title, show_popular_by_category, popular_by_category_title, show_promo_banners, banner_1_* and banner_2_* (title, subtitle, button_text, button_link, image), show_multi_column_lists, column_1_title to column_4_title, column_1_category_id to column_4_category_id, section_order

Prestige

show_testimonials, testimonials_title, testimonials

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

bad_request

The body is not JSON, or Idempotency-Key is missing or malformed.

403

forbidden

Missing scope: store:read or Missing scope: store:write, or API access requires an active Enterprise plan for a merchant key whose store is not on an active Enterprise plan.

422

no_writable_fields

The body holds none of the keys this endpoint accepts.

422

invalid_category

A *_category_id is not a category of this store.

422

invalid_url

A button link uses another scheme, such as javascript:.

422

idempotency_key_reuse

The same Idempotency-Key was used with another body.

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.

Did this answer your question?