Aller au contenu principal

Catégories

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​

ChampTypeNotes
idintL'id de la catégorie.
namestring1 à 100 caractères.
slugstringTiré du nom et unique dans la boutique. La page de la catégorie dans la boutique l'utilise dans son adresse.
descriptionstring ou nullTexte libre.
imagestring ou nullURL complète de l'image, ou null.
parent_idint ou nullLa catégorie parente, ou null pour une catégorie principale.
show_subcategoriesboolAffiche 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_orderintPosition dans les listes de catégories de la boutique, la plus petite d'abord.
statusstringactive ou inactive.
created_atstringYYYY-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​

ParamTypeDéfautNotes
parent_idid, 0 ou nullaucunUn 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.
statusactive ou inactiveaucunSeulement les catégories qui ont ce statut. Toute autre valeur est ignorée.
limitint501 à 200.
cursorstringaucunLe 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​

ChampTypeRequisNotes
namestringouiEspaces de début et de fin retirés, 1 à 100 caractères.
descriptionstring ou nullnonEspaces de début et de fin retirés. Une chaîne vide est enregistrée comme null.
parent_idint ou nullnonUne catégorie principale de cette boutique : la nouvelle catégorie devient sa sous-catégorie. null ou 0 crée une catégorie principale.
statusactive ou inactivenonactive par défaut.
show_subcategoriesboolnontrue 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​

ChampTypeRequisNotes
categoriesarrayouiLes 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​

HTTPCodeCause
400bad_requestL'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.
401unauthorizedClé absente ou invalide.
402quota_exceededLe quota mensuel de requêtes de la boutique est épuisé. Voir Limites de taux.
403forbiddenMissing 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.
404not_foundAucune 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.
409category_not_emptyLa catégorie contient encore des produits ou des sous-catégories.
409already_undoneAnnulation seulement : le changement a déjà été annulé.
413payload_too_largeLe corps dépasse 1 Mo.
422validation_errorname 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.
422invalid_parentparent_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.
422nothing_to_restoreAnnulation seulement : le changement a créé la catégorie.
422restore_target_missingAnnulation seulement : la catégorie n'existe plus, ou son ancien id est pris.
422idempotency_key_reuseLa même Idempotency-Key a servi avec un autre corps.
429rate_limitedTrop d'appels dans la minute en cours. Attendez les secondes indiquées par Retry-After. Voir Limites de taux.
500server_errorLa requête a échoué. Réessayez avec la même Idempotency-Key.
Cette page pour les outils IAVoir en MarkdownOuvrir dans ChatGPTOuvrir dans Claude