Passer au contenu principal

Catégories

Listez, lisez, créez, renommez, déplacez, supprimez et réordonnez les catégories de produits d'une boutique depuis votre code, puis annulez un changement.

Écrit par Support

Les catégories regroupent les produits d'une boutique. Elles ont deux niveaux : une catégorie principale peut contenir des sous-catégories, et une sous-catégorie n'en contient aucune. Ces six endpoints listent, lisent, créent, modifient, suppriment et réordonnent les catégories.

Un produit rejoint une catégorie par son champ category_id, voir Produits. Une section category-products de la page d'accueil prend aussi un id de catégorie, voir Sections de la page d'accueil.

Avant de commencer

  • Les lectures demandent products:read et les écritures products:write, les mêmes scopes que pour les produits. Les clés marchand ont les deux.

  • POST, PATCH et DELETE demandent une Idempotency-Key. Voir Idempotence.

  • L'image de la catégorie s'ajoute dans le dashboard. L'API renvoie son URL mais ne peut ni la téléverser ni la changer.

L'objet catégorie

Champ

Type

Notes

id

int

L'id de la catégorie.

name

string

1 à 100 caractères.

slug

string

Tiré du nom et unique dans la boutique. La page de la catégorie dans la boutique l'utilise dans son adresse.

description

string ou null

Texte libre.

image

string ou null

URL complète de l'image, ou null.

parent_id

int ou null

La catégorie parente, ou null pour une catégorie principale.

show_subcategories

bool

Affiche les sous-catégories en vignettes sur la page de la catégorie dans la boutique (Afficher la section des sous-catégories dans le formulaire de la catégorie). Enregistré à true pour une sous-catégorie. Tant que Sous-catégories uniquement dans la catégorie parente est activé (/dashboard/categories), la boutique affiche les vignettes sur la page de chaque catégorie, quelle que soit la valeur de ce champ.

sort_order

int

Position dans les listes de catégories de la boutique, la plus petite d'abord.

status

string

active ou inactive.

created_at

string

YYYY-MM-DD HH:MM:SS, heure du serveur.

La liste et la lecture unitaire ajoutent product_count, le nombre de produits dans la catégorie. La lecture unitaire ajoute aussi children, ses sous-catégories.

GET /v1/categories

Les catégories de la boutique, de la plus récente à la plus ancienne, en liste à curseur. Triez-les par sort_order pour obtenir l'ordre de la boutique.

Auth : clé plateforme avec products:read.

Paramètres de requête

Param

Type

Défaut

Notes

parent_id

id, 0 ou null

aucun

Un id de catégorie renvoie ses sous-catégories. 0, null ou une valeur vide renvoie les catégories principales. Toute autre valeur renvoie 400 bad_request.

status

active ou inactive

aucun

Seulement les catégories qui ont ce statut. Toute autre valeur est ignorée.

limit

int

50

1 à 200.

cursor

string

aucun

Le next_cursor de la page précédente. Voir Pagination.

Requête

curl 'https://api.dzbuild.app/v1/categories?parent_id=0' \
  -H "Authorization: Bearer $DZ_KEY"

Réponse 200

{
  "data": {
    "items": [
      {
        "id": 14,
        "name": "Montres",
        "slug": "montres",
        "description": null,
        "image": null,
        "parent_id": null,
        "show_subcategories": true,
        "sort_order": 4,
        "status": "active",
        "created_at": "2026-09-30 11:20:05",
        "product_count": 0
      },
      {
        "id": 10,
        "name": "Parfums",
        "slug": "parfums",
        "description": "Eaux de parfum et coffrets",
        "image": null,
        "parent_id": null,
        "show_subcategories": true,
        "sort_order": 1,
        "status": "active",
        "created_at": "2026-09-12 09:41:37",
        "product_count": 18
      }
    ],
    "next_cursor": null,
    "has_more": false
  }
}

GET /v1/categories/{id}

Une catégorie avec product_count et children, ses sous-catégories triées par sort_order.

Auth : clé plateforme avec products:read.

Un id qui n'est pas fait que de chiffres répond 400 bad_request. Une catégorie d'une autre boutique répond 404 not_found, comme une catégorie qui n'existe pas.

Requête

curl 'https://api.dzbuild.app/v1/categories/10' \
  -H "Authorization: Bearer $DZ_KEY"

Réponse 200

{
  "data": {
    "id": 10,
    "name": "Parfums",
    "slug": "parfums",
    "description": "Eaux de parfum et coffrets",
    "image": null,
    "parent_id": null,
    "show_subcategories": true,
    "sort_order": 1,
    "status": "active",
    "created_at": "2026-09-12 09:41:37",
    "children": [
      {"id": 11, "name": "Parfums femme", "slug": "parfums-femme", "sort_order": 2, "status": "active"},
      {"id": 12, "name": "Parfums homme", "slug": "parfums-homme", "sort_order": 3, "status": "active"}
    ],
    "product_count": 18
  }
}

POST /v1/categories

Crée une catégorie et la place en dernier : son sort_order vaut un de plus que le plus grand de la boutique.

Auth : clé plateforme avec products:write. Nécessite Idempotency-Key.

Corps

Champ

Type

Requis

Notes

name

string

oui

Espaces de début et de fin retirés, 1 à 100 caractères.

description

string ou null

non

Espaces de début et de fin retirés. Une chaîne vide est enregistrée comme null.

parent_id

int ou null

non

Une catégorie principale de cette boutique : la nouvelle catégorie devient sa sous-catégorie. null ou 0 crée une catégorie principale.

status

active ou inactive

non

active par défaut.

show_subcategories

bool

non

true par défaut. Ignoré, et enregistré à true, pour une sous-catégorie ou tant que Sous-catégories uniquement dans la catégorie parente est activé.

Le slug est tiré du nom : en minuscules, lettres et chiffres gardés, et chaque suite d'autres caractères remplacée par un seul -. Un nom en arabe garde ses lettres arabes. Quand une autre catégorie de la boutique a déjà ce slug, -2, -3 et ainsi de suite est ajouté.

Requête

curl -X POST 'https://api.dzbuild.app/v1/categories' \
  -H "Authorization: Bearer $DZ_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: cat-create-coffrets-1" \
  -d '{"name": "Coffrets cadeaux", "parent_id": 10}'

Réponse 201

La réponse est l'objet catégorie, sans product_count ni children.

{
  "data": {
    "id": 15,
    "name": "Coffrets cadeaux",
    "slug": "coffrets-cadeaux",
    "description": null,
    "image": null,
    "parent_id": 10,
    "show_subcategories": true,
    "sort_order": 5,
    "status": "active",
    "created_at": "2026-10-06 14:02:11"
  }
}

PATCH /v1/categories/{id}

Ne change que les champs envoyés. Le corps accepte les champs de POST, tous facultatifs.

Auth : clé plateforme avec products:write. Nécessite Idempotency-Key.

  • Un nouveau name donne un nouveau slug : l'adresse de la page de la catégorie dans la boutique change et les liens vers l'ancienne adresse ne marchent plus. Renvoyer le même nom garde le slug.

  • parent_id déplace la catégorie. Un id de catégorie principale en fait une sous-catégorie, et null ou 0 en fait une catégorie principale. Une catégorie qui a des sous-catégories ne peut pas devenir une sous-catégorie, et une catégorie ne peut pas être sa propre parente.

  • Un corps vide ne change rien et renvoie la catégorie telle quelle.

Requête

curl -X PATCH 'https://api.dzbuild.app/v1/categories/15' \
  -H "Authorization: Bearer $DZ_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: cat-15-move-1" \
  -d '{"parent_id": null, "status": "inactive"}'

Réponse 200

{
  "data": {
    "id": 15,
    "name": "Coffrets cadeaux",
    "slug": "coffrets-cadeaux",
    "description": null,
    "image": null,
    "parent_id": null,
    "show_subcategories": true,
    "sort_order": 5,
    "status": "inactive",
    "created_at": "2026-10-06 14:02:11"
  }
}

DELETE /v1/categories/{id}

Supprime une catégorie vide et son image.

Auth : clé plateforme avec products:write. Nécessite Idempotency-Key.

Une catégorie qui contient encore des produits ou des sous-catégories répond 409 category_not_empty, et rien n'est supprimé. Le message d'erreur donne les nombres. Pour vider la catégorie :

  • Sous-catégories : passez chacune en catégorie principale avec PATCH et "parent_id": null, ou supprimez-la d'abord.

  • Produits : l'API ne peut pas retirer un produit d'une catégorie. Donner un category_id à un produit ajoute une catégorie et garde celles qu'il a déjà, voir Produits. Changez les catégories de ces produits dans le dashboard.

Requête

curl -X DELETE 'https://api.dzbuild.app/v1/categories/14' \
  -H "Authorization: Bearer $DZ_KEY" \
  -H "Idempotency-Key: cat-14-delete-1"

Réponse 200

{
  "data": {
    "deleted": true,
    "id": 14
  }
}

POST /v1/categories/reorder

Fixe le sort_order des catégories listées, en une seule fois : soit elles changent toutes, soit aucune ne change.

Auth : clé plateforme avec products:write. Nécessite Idempotency-Key.

Corps

Champ

Type

Requis

Notes

categories

array

oui

Les catégories dans leur nouvel ordre. Chaque élément est {"id": 10}, {"id": 10, "sort_order": 7} ou un id seul comme 10.

  • Un élément sans sort_order prend sa position dans le tableau : 1, 2, 3 et ainsi de suite. Un élément avec sort_order prend ce nombre.

  • Chaque id doit appartenir à la boutique et n'apparaître qu'une fois.

  • Les catégories que vous ne listez pas gardent leur sort_order.

  • Un réordonnancement n'est pas enregistré dans l'historique des changements, il ne peut donc pas être annulé. Lisez d'abord la liste si vous risquez de vouloir revenir à l'ancien ordre.

Requête

curl -X POST 'https://api.dzbuild.app/v1/categories/reorder' \
  -H "Authorization: Bearer $DZ_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: cat-reorder-1" \
  -d '{"categories": [{"id": 14}, {"id": 10}]}'

Réponse 200

{
  "data": {
    "reordered": 2,
    "categories": [
      {"id": 14, "sort_order": 1},
      {"id": 10, "sort_order": 2}
    ]
  }
}

Annulation

POST, PATCH et DELETE sont enregistrés dans l'historique des changements de la boutique. Leur réponse ne contient pas l'id du changement : GET /v1/changes?entity=category liste les changements des catégories, du plus récent au plus ancien, avec store:read. entity_id est l'id de la catégorie.

Requête

curl 'https://api.dzbuild.app/v1/changes?entity=category&limit=1' \
  -H "Authorization: Bearer $DZ_KEY"

Réponse 200

{
  "data": {
    "items": [
      {
        "id": 120,
        "entity": "category",
        "entity_id": "15",
        "action": "update",
        "summary": "Updated category #15 (parent_id, status, show_subcategories)",
        "undone_at": null,
        "created_at": "2026-10-06 14:05:48",
        "undone": false
      }
    ],
    "next_cursor": "MTIw",
    "has_more": true
  }
}

POST /v1/changes/{id}/undo annule un changement. Il demande products:write et une Idempotency-Key.

  • Annuler un PATCH remet les valeurs d'avant des champs que cet appel a changés, avec les mêmes contrôles que PATCH.

  • Annuler un DELETE recrée la catégorie sous son ancien id, sans son image. Si son ancienne catégorie parente n'existe plus ou est devenue une sous-catégorie, l'annulation répond 422 invalid_parent.

  • Une création ne s'annule pas : l'annulation répond 422 nothing_to_restore. Supprimez plutôt la catégorie.

  • Quand la catégorie n'existe plus, ou que son ancien id est pris, l'annulation répond 422 restore_target_missing.

  • Un changement annulé une deuxième fois répond 409 already_undone.

  • Les changements faits dans le dashboard ne sont pas enregistrés, on ne peut donc pas les annuler par l'API.

  • Le jeton d'une application installée ne peut ni lire ni annuler les changements : les deux répondent 403 forbidden (Apps cannot use this endpoint).

curl -X POST 'https://api.dzbuild.app/v1/changes/120/undo' \
  -H "Authorization: Bearer $DZ_KEY" \
  -H "Idempotency-Key: undo-120"

{
  "data": {
    "undone": true,
    "change_id": 120,
    "entity": "category",
    "undo_change_id": 121
  }
}

Erreurs

HTTP

Code

Cause

400

bad_request

L'id dans le chemin n'est pas fait que de chiffres, le corps n'est pas un JSON valide, le filtre parent_id n'est ni un id, ni 0, ni null, ni vide, categories manque ou n'est pas un tableau, ou Idempotency-Key manque ou est mal formée.

401

unauthorized

Clé absente ou invalide.

402

quota_exceeded

Le quota mensuel de requêtes de la boutique est épuisé. Voir Limites de taux.

403

forbidden

Missing scope: products:read, Missing scope: products:write ou Missing scope: store:read, ou API access requires an active Enterprise plan pour une clé du marchand dont la boutique n'a pas de plan Enterprise actif, ou Apps cannot use this endpoint quand le jeton d'une application installée lit ou annule des changements.

404

not_found

Aucune catégorie avec cet id dans la boutique, un réordonnancement liste un id qui n'est pas dans la boutique, ou une annulation vise un changement absent de l'historique de la boutique.

409

category_not_empty

La catégorie contient encore des produits ou des sous-catégories.

409

already_undone

Annulation seulement : le changement a déjà été annulé.

413

payload_too_large

Le corps dépasse 1 Mo.

422

validation_error

name manque, est vide ou dépasse 100 caractères, status n'est ni active ni inactive, parent_id n'est pas un id, ou un réordonnancement est vide, répète un id, contient un id qui n'est pas un entier positif ou un sort_order qui n'est pas un entier.

422

invalid_parent

parent_id n'est pas une catégorie de cette boutique, est lui-même une sous-catégorie, est la catégorie elle-même, ou la catégorie a des sous-catégories et ne peut pas passer sous une autre.

422

nothing_to_restore

Annulation seulement : le changement a créé la catégorie.

422

restore_target_missing

Annulation seulement : la catégorie n'existe plus, ou son ancien id est pris.

422

idempotency_key_reuse

La même Idempotency-Key a servi avec un autre corps.

429

rate_limited

Trop d'appels dans la minute en cours. Attendez les secondes indiquées par Retry-After. Voir Limites de taux.

500

server_error

La requête a échoué. Réessayez avec la même Idempotency-Key.

Avez-vous trouvé la réponse à votre question ?