# Boutique

La « boutique » est le conteneur de plus haut niveau des produits, commandes, clients, etc. Chaque clé est liée à **exactement une** boutique. Il n'existe aucun moyen de requêter les boutiques d'autres marchands.

## `GET /v1/store`[​](#get-v1store "Lien direct vers get-v1store")

Retourne le profil de la boutique à laquelle appartient la clé appelante.

**Auth :** clé plateforme avec `store:read`. Les clés du marchand l'ont par défaut ; une clé sans ce scope reçoit `403 forbidden` (`Missing scope: store:read`).

Servi à neuf à chaque appel : une modification faite dans le tableau de bord apparaît au `GET` suivant via `api.dzbuild.app` comme via l'alias `dzbuild.com/api/v1/store`.

### Requête[​](#requête "Lien direct vers Requête")

```
curl https://api.dzbuild.app/v1/store \

  -H "Authorization: Bearer $DZ_KEY"
```

### Réponse 200[​](#réponse-200 "Lien direct vers Réponse 200")

```
{

  "data": {

    "id":         12345,

    "name":       "My Store",

    "slug":       "my-store",

    "language":   "ar",

    "description": "Short tagline",

    "logo":       "/uploads/logos/12345/logo.webp",

    "favicon":    null,

    "banner":     null,

    "theme": {

      "primary_color":    "#f59e0b",

      "secondary_color":  "#fbbf24",

      "background_color": "#ffffff",

      "font_family":      "Cairo"

    },

    "store_theme":          "starter",

    "fast_checkout_theme":  "classic",

    "variant_card_style":   "default",

    "subdomain":            "my-store.dzbuild.app",

    "custom_domain":        null,

    "custom_domain_verified": false,

    "public_url":            "https://my-store.dzbuild.app",

    "hide_branding":         false,

    "created_at":            "2026-01-01 12:00:00"

  },

  "meta": { "request_id": "...", "api_version": "v1" }

}
```

### Référence des champs[​](#référence-des-champs "Lien direct vers Référence des champs")

| Champ                    | Type         | Notes                                                                                                                                                                                                                                    |
| ------------------------ | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                     | int          | Identifiant interne stable. Identique à `store_id` partout ailleurs.                                                                                                                                                                     |
| `name`                   | string       | Nom d'affichage. Apparaît dans la navbar et les emails.                                                                                                                                                                                  |
| `slug`                   | string       | Identifiant compatible URL. Utilisé dans `<slug>.dzbuild.app`, etc.                                                                                                                                                                      |
| `language`               | enum         | `ar` ou `fr`. Détermine le sens RTL/LTR de la vitrine.                                                                                                                                                                                   |
| `description`            | string\|null | Tagline courte.                                                                                                                                                                                                                          |
| `logo`                   | string\|null | Chemin sur `cdn.dzbuild.app` s'il est défini. Préfixez l'URL CDN pour l'afficher.                                                                                                                                                        |
| `favicon`                | string\|null | Même logique.                                                                                                                                                                                                                            |
| `banner`                 | string\|null | Même logique.                                                                                                                                                                                                                            |
| `theme.primary_color`    | hex string   | Couleur dominante des boutons et accents.                                                                                                                                                                                                |
| `theme.secondary_color`  | hex string   | Hover / accents secondaires.                                                                                                                                                                                                             |
| `theme.background_color` | hex string   | Fond de page.                                                                                                                                                                                                                            |
| `theme.font_family`      | string       | Typographie (par défaut `Cairo`).                                                                                                                                                                                                        |
| `store_theme`            | string       | Clé du thème de boutique utilisé, la même que `current` dans `GET /v1/themes`. En lecture seule ici : changez-la avec `POST /v1/store/theme`.                                                                                            |
| `fast_checkout_theme`    | string       | Clé du thème du formulaire Fast Checkout, `classic` tant que le marchand n'en choisit pas un autre. Changez-la avec `POST /v1/store/fast-checkout-theme`.                                                                                |
| `variant_card_style`     | string       | Clé du style du sélecteur de variantes, `default` quand aucun style n'est choisi. Changez-la avec `POST /v1/store/variant-style`.                                                                                                        |
| `subdomain`              | string\|null | Sous-domaine émis par DZBuild. Normalement présent ; `null` si aucun sous-domaine n'est encore configuré pour la boutique.                                                                                                               |
| `custom_domain`          | string\|null | Domaine personnel du marchand. Défini uniquement s'il a été ajouté depuis le tableau de bord.                                                                                                                                            |
| `custom_domain_verified` | bool         | `true` dès que les réglages DNS du domaine sont confirmés. Le certificat de sécurité et la dernière vérification peuvent encore être en cours à ce moment ; `public_url` ne passe sur le domaine que lorsqu'il est entièrement en ligne. |
| `public_url`             | string\|null | URL où arrivent réellement les clients : le domaine du marchand lorsqu'il est entièrement en ligne et défini comme adresse principale de la boutique, sinon le sous-domaine ; `null` si aucun des deux n'existe.                         |
| `hide_branding`          | bool         | « Powered by DZBuild » caché dans le footer. Plan Illimité.                                                                                                                                                                              |
| `created_at`             | timestamp    | Heure de création de la boutique, heure d'Alger (UTC+01:00).                                                                                                                                                                             |

### Erreurs[​](#erreurs "Lien direct vers Erreurs")

| HTTP | Code             | Cause                                                                                                                                                                                                                               |
| ---- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 401  | `unauthorized`   | Clé invalide ou manquante                                                                                                                                                                                                           |
| 402  | `quota_exceeded` | Quota mensuel de requêtes de la boutique épuisé — voir [Limites de débit](https://dzbuild.com/fr/fr/api-docs/rate-limits.md)                                                                                                        |
| 403  | `forbidden`      | `Missing scope: store:read` ; clé du marchand dont la boutique n'a pas de plan Enterprise actif (« API access requires an active Enterprise plan ») ; ou mode pilote : clé non enrôlée (« API is in pilot mode; key not enrolled ») |
| 404  | `not_found`      | La boutique a été supprimée pendant que vous utilisiez la clé (très rare)                                                                                                                                                           |
| 429  | `rate_limited`   | Plafond par minute atteint pour cette boutique, partagé par toutes ses clés ; respectez `Retry-After`. Voir [Limites de débit](https://dzbuild.com/fr/fr/api-docs/rate-limits.md)                                                   |

## `PATCH /v1/store`[​](#patch-v1store "Lien direct vers patch-v1store")

Met à jour le profil de la boutique, avec les mêmes champs que la page des paramètres de la boutique dans le tableau de bord, sauf le numéro WhatsApp. Seuls les champs envoyés changent.

**Auth :** clé plateforme avec `store:write`. **Nécessite `Idempotency-Key`.**

### Corps[​](#corps "Lien direct vers Corps")

| Champ                      | Type         | Notes                                                                                          |
| -------------------------- | ------------ | ---------------------------------------------------------------------------------------------- |
| `store_name`               | string       | Jusqu'à 100 caractères. Ne peut pas être vide.                                                 |
| `description`              | string       | Jusqu'à 5000 caractères.                                                                       |
| `wilaya_id`                | int\|null    | Un id de wilaya issu de `GET /v1/wilayas` (nécessite `shipping:read`). `0` ou `null` l'efface. |
| `commune`                  | string       | Jusqu'à 100 caractères.                                                                        |
| `address`                  | string       | Jusqu'à 500 caractères.                                                                        |
| `store_phone`              | string       | Jusqu'à 20 caractères.                                                                         |
| `store_email`              | string\|null | Une adresse email valide. `""` ou `null` l'efface.                                             |
| `google_site_verification` | string\|null | Code de vérification Google Search Console, jusqu'à 100 caractères. `""` ou `null` l'efface.   |
| `bing_site_verification`   | string\|null | Code de vérification Bing Webmaster, jusqu'à 100 caractères. `""` ou `null` l'efface.          |

Les balises HTML sont retirées des valeurs texte et un texte plus long est coupé à la limite. Le slug, le domaine personnalisé et les couleurs ne font pas partie de cet endpoint ; les couleurs et les autres réglages de design se modifient avec `PATCH /v1/store/design`.

### Requête[​](#requête-1 "Lien direct vers Requête")

```
curl -X PATCH https://api.dzbuild.app/v1/store \

  -H "Authorization: Bearer $DZ_KEY" \

  -H "Content-Type: application/json" \

  -H "Idempotency-Key: store-profile-1" \

  -d '{"store_phone": "0550000000", "description": "Short tagline"}'
```

### Réponse 200[​](#réponse-200-1 "Lien direct vers Réponse 200")

```
{

  "data": {

    "updated": ["description", "store_phone"],

    "values":  {"description": "Short tagline", "store_phone": "0550000000"}

  },

  "meta": { "request_id": "...", "api_version": "v1" }

}
```

Le changement est enregistré et peut être annulé avec `POST /v1/changes/{change_id}/undo` ; retrouvez son id avec `GET /v1/changes?entity=store.settings`. Un `GET /v1/store` envoyé juste après l'écriture renvoie les nouvelles valeurs.

### Erreurs[​](#erreurs-1 "Lien direct vers Erreurs")

| HTTP | Code                    | Cause                                                                                               |
| ---- | ----------------------- | --------------------------------------------------------------------------------------------------- |
| 400  | `bad_request`           | Le corps n'est pas un JSON valide, ou `Idempotency-Key` manque ou est mal formée.                   |
| 403  | `forbidden`             | `Missing scope: store:write`, ou clé du marchand dont la boutique n'a pas de plan Enterprise actif. |
| 404  | `store_not_found`       | La boutique a été supprimée.                                                                        |
| 422  | `no_writable_fields`    | Le corps ne contient aucun des champs ci-dessus.                                                    |
| 422  | `invalid_value`         | Un champ est un objet ou une liste, ou `store_name` est vide.                                       |
| 422  | `invalid_wilaya`        | `wilaya_id` n'est pas une wilaya connue.                                                            |
| 422  | `invalid_email`         | `store_email` n'est pas une adresse email valide.                                                   |
| 422  | `idempotency_key_reuse` | La même `Idempotency-Key` a été utilisée avec un autre corps.                                       |

## `GET /v1/store/design`[​](#get-v1storedesign "Lien direct vers get-v1storedesign")

Renvoie le design de la boutique : les champs de la page de personnalisation du tableau de bord (`/dashboard/customize`) pour le thème actuel de la boutique, regroupés dans les mêmes sections, chacun avec sa valeur actuelle. Quelques thèmes masquent certains de ces champs sur cette page ; l'API les liste tous.

**Auth :** clé plateforme avec `store:read`.

Servi à neuf via `api.dzbuild.app`, comme `GET /v1/store`. La réponse de `PATCH /v1/store/design` porte aussi les valeurs écrites dans `values`.

### Requête[​](#requête-2 "Lien direct vers Requête")

```
curl https://api.dzbuild.app/v1/store/design \

  -H "Authorization: Bearer $DZ_KEY"
```

### Réponse 200[​](#réponse-200-2 "Lien direct vers Réponse 200")

Deux sections sont montrées, avec une partie de leurs champs.

```
{

  "data": {

    "theme": "starter",

    "plan":  "enterprise",

    "sections": [

      {

        "key":  "theme",

        "name": {"ar": "الألوان والخط", "fr": "Couleurs et Police"},

        "plan_required": "free",

        "page": "home",

        "fields": [

          {"key": "primary_color", "type": "color", "plan_required": "free", "writable": true, "locked": false, "value": "#f59e0b"},

          {"key": "background_color", "type": "color", "plan_required": "pro", "writable": true, "locked": false, "value": "#ffffff"},

          {"key": "font_family", "type": "select", "plan_required": "free", "writable": true, "locked": false, "value": "Cairo"}

        ]

      },

      {

        "key":  "productCard",

        "name": {"ar": "بطاقة المنتج", "fr": "Carte produit"},

        "plan_required": "free",

        "page": "home",

        "fields": [

          {"key": "card_hide_price", "type": "switch", "plan_required": "free", "writable": true, "locked": false, "value": false},

          {"key": "card_border_radius", "type": "select", "plan_required": "free", "writable": true, "locked": false, "allowed_values": ["0px", "8px", "16px", "24px"], "value": "16px"}

        ]

      }

    ]

  },

  "meta": { "request_id": "...", "api_version": "v1" }

}
```

### Référence des champs[​](#référence-des-champs-1 "Lien direct vers Référence des champs")

| Champ                      | Type   | Notes                                                                                                                                                                                         |
| -------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `theme`                    | string | Clé du thème utilisé par la boutique. Voir [Thèmes](https://dzbuild.com/fr/fr/api-docs/resources/themes.md).                                                                                  |
| `plan`                     | string | Le plan sur lequel les verrous sont calculés : `free`, `pro`, `unlimited` ou `enterprise`. Un plan payant expiré compte comme `free`.                                                         |
| `sections[].key`           | string | Identifiant de la section, par exemple `header`, `theme`, `productCard` ou `checkoutPage`.                                                                                                    |
| `sections[].name`          | object | Le titre de la section affiché par le tableau de bord, en `ar` et en `fr`.                                                                                                                    |
| `sections[].plan_required` | string | Le plan que le tableau de bord affiche sur la section.                                                                                                                                        |
| `sections[].page`          | string | `home` quand la page de personnalisation liste la section sous l'aperçu de l'accueil, `all` quand elle la liste sur chaque aperçu.                                                            |
| `sections[].fields`        | array  | Les champs de la section. Peut être vide : quelques sections, comme `helpWidget` et les blocs d'accueil du thème Digital, ne s'enregistrent pas par des champs de design.                     |
| `fields[].key`             | string | Le nom à envoyer dans `PATCH /v1/store/design`.                                                                                                                                               |
| `fields[].type`            | string | Le contrôle du tableau de bord : `text`, `textarea`, `color`, `select` ou `switch`.                                                                                                           |
| `fields[].plan_required`   | string | Le plan que le tableau de bord affiche sur le champ.                                                                                                                                          |
| `fields[].writable`        | bool   | `false` quand l'API n'accepte pas le champ. `custom_js` en fait partie : il se règle dans le tableau de bord seulement.                                                                       |
| `fields[].locked`          | bool   | `true` quand le plan de la boutique ne permet pas d'écrire le champ par l'API. Fiez-vous à ce drapeau, pas à `plan_required`, pour savoir si une écriture sera appliquée.                     |
| `fields[].allowed_values`  | array  | Seulement sur les champs à choix fixe : les valeurs que le champ accepte.                                                                                                                     |
| `fields[].value`           | any    | La valeur actuelle. Les champs `switch` reviennent en `true` ou `false`, `products_per_page` en nombre, le reste tel qu'enregistré. `null` quand la boutique n'a pas de valeur pour ce champ. |

## `GET /v1/store/design/fields`[​](#get-v1storedesignfields "Lien direct vers get-v1storedesignfields")

La même liste sans la clé `value`. Appelez-la avant une écriture pour voir les champs que le thème de la boutique affiche, le nom à envoyer pour chacun et ceux que le plan verrouille.

**Auth :** clé plateforme avec `store:read`. Servi à neuf via `api.dzbuild.app`, comme `GET /v1/store`.

### Requête[​](#requête-3 "Lien direct vers Requête")

```
curl https://api.dzbuild.app/v1/store/design/fields \

  -H "Authorization: Bearer $DZ_KEY"
```

### Réponse 200[​](#réponse-200-3 "Lien direct vers Réponse 200")

Les deux dernières sections sont montrées.

```
{

  "data": {

    "theme": "starter",

    "plan":  "enterprise",

    "sections": [

      {

        "key":  "customCss",

        "name": {"ar": "CSS مخصّص", "fr": "CSS personnalisé"},

        "plan_required": "enterprise",

        "page": "all",

        "fields": [

          {"key": "custom_css", "type": "textarea", "plan_required": "enterprise", "writable": true, "locked": false}

        ]

      },

      {

        "key":  "customJs",

        "name": {"ar": "JavaScript مخصّص", "fr": "JavaScript personnalisé"},

        "plan_required": "enterprise",

        "page": "all",

        "fields": [

          {"key": "custom_js", "type": "textarea", "plan_required": "enterprise", "writable": false, "locked": false}

        ]

      }

    ]

  },

  "meta": { "request_id": "...", "api_version": "v1" }

}
```

### Erreurs[​](#erreurs-2 "Lien direct vers Erreurs")

`GET /v1/store/design` et `GET /v1/store/design/fields` répondent les mêmes erreurs que `GET /v1/store` : `401 unauthorized`, `402 quota_exceeded`, `403 forbidden` (`Missing scope: store:read`, plan ou pilote), `404 not_found` et `429 rate_limited`.

## `PATCH /v1/store/design`[​](#patch-v1storedesign "Lien direct vers patch-v1storedesign")

Modifie les champs de design : couleurs, en-tête, hero, cartes produit, page produit, textes de la page de commande, pied de page, liens sociaux, SEO et plus encore. Seuls les champs envoyés changent. Les couleurs et `hide_branding` se règlent ici, pas avec `PATCH /v1/store`.

**Auth :** clé plateforme avec `store:write`. **Nécessite `Idempotency-Key`.**

### Corps[​](#corps-1 "Lien direct vers Corps")

Envoyez n'importe quel champ que `GET /v1/store/design/fields` liste avec `writable: true`. Les champs de design que le thème actuel ne liste pas sont aussi acceptés : ils sont enregistrés, et un thème qui les affiche les utilise. Les clés que l'API ne connaît pas sont ignorées. Chaque valeur est nettoyée selon son type :

| Type                    | Exemples                                                            | Ce qui est enregistré                                                                                                                                                                          |
| ----------------------- | ------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Interrupteur            | `show_hero`, `navbar_sticky`, `card_hide_price`                     | Envoyez `true` ou `false`. La réponse affiche `1` ou `0`.                                                                                                                                      |
| Couleur                 | `primary_color`, `navbar_color`, `footer_color`                     | Une valeur `#RRGGBB`. `null` l'efface. Toute autre valeur est remplacée par la couleur par défaut du champ, par exemple `#f59e0b` pour `primary_color`.                                        |
| Couleur de remplacement | `announcement_bg_color`, `product_buy_now_color`, `fc_button_color` | Une valeur `#RRGGBB`. Tout le reste efface la couleur de remplacement.                                                                                                                         |
| Texte                   | `hero_title`, `footer_about`, `seo_description`                     | Les balises HTML sont retirées et le texte est coupé à la longueur du champ, par exemple 255 caractères pour `hero_title` et 2000 pour `footer_about`.                                         |
| Lien                    | `hero_button_link`, `facebook`, `custom_link_url`                   | Un lien `https://`, `http://`, `mailto:` ou `tel:`, un `/path`, une `#anchor` ou un identifiant seul, coupé à 255 caractères (20 pour `whatsapp`). Tout autre schéma répond `422 invalid_url`. |
| Choix fixe              | `card_border_radius`, `checkout_layout`, `store_language`           | L'une des `allowed_values` du champ. Toute autre valeur est enregistrée comme la valeur par défaut du champ.                                                                                   |
| Nombre                  | `products_per_page`                                                 | Gardé entre 4 et 48.                                                                                                                                                                           |

Certains champs ont leurs propres règles :

* `font_family` : lettres latines, chiffres, espaces et tirets. Tout le reste est enregistré comme `Cairo`. Le tableau de bord propose `Cairo`, `Tajawal` et `Almarai`.
* `button_style` : le tableau de bord propose `rounded`, `square` et `pill`.
* `navbar_style` accepte `default`, `centered`, `minimal` ou `transparent` ; `navbar_menu_style` accepte `default`, `pills`, `underline` ou `buttons` ; `navbar_logo_size` accepte `small`, `medium` ou `large` ; `cart_icon_style` accepte `default`, `filled`, `outline` ou `minimal`. Ces quatre champs n'ont pas d'`allowed_values`, et toute autre valeur refuse l'écriture entière avec `422 invalid_value`.
* `facebook_pixel_id` : 15 à 17 chiffres, ou vide pour l'effacer.
* `custom_css` : plan Enterprise seulement. Il est nettoyé avant d'être enregistré.

La barre d'achat et le formulaire de commande des pages produit ont quatre champs à eux. Tous les plans peuvent les écrire, et leurs valeurs par défaut gardent l'apparence qu'avait la boutique avant leur arrivée.

| Champ                 | Valeurs                          | Ce qu'il change                                                                                                                                                                                                 |
| --------------------- | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `buybar_show_mobile`  | `true` (par défaut) ou `false`   | `false` masque la barre d'achat fixée en bas des pages produit sur téléphone. La barre reste quand le formulaire Fast Checkout est désactivé : un téléphone affiche donc toujours un bouton d'achat.            |
| `buybar_show_qty`     | `true` (par défaut) ou `false`   | `false` retire les boutons de quantité de la barre d'achat, sur téléphone comme sur ordinateur.                                                                                                                 |
| `fc_show_qty`         | `true` (par défaut) ou `false`   | `false` retire la quantité du formulaire Fast Checkout. Le client commande alors un seul article, sauf s'il a choisi une offre ou une quantité dans la barre d'achat, ou si le produit a une quantité minimale. |
| `product_button_size` | `normal` (par défaut) ou `large` | `large` donne aux boutons de la barre d'achat et au bouton de commande du formulaire Fast Checkout une hauteur de 56 pixels, avec un texte de 17 pixels. Toute autre valeur est enregistrée comme `normal`.     |

Le thème Digital n'a pas de formulaire Fast Checkout : `fc_show_qty` n'y change rien, et `buybar_show_mobile: false` masque la barre du téléphone tandis que les boutons d'achat restent dans la page.

### Verrous de plan[​](#verrous-de-plan "Lien direct vers Verrous de plan")

Un champ que le plan de la boutique verrouille n'est pas écrit. Il est listé dans `skipped` avec la raison, et l'appel répond quand même `200` si un autre champ a été écrit. Quand tous les champs envoyés sont ignorés, l'appel répond `422 no_writable_fields`.

| Raison dans `skipped`          | Quand                                                                                                                                                                                 |
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `requires a paid plan`         | Un champ réservé au plan `pro` et au-dessus, par exemple `background_color`, `navbar_color`, `hide_branding` ou les champs de la barre d'annonce, envoyé pour une boutique en `free`. |
| `requires the enterprise plan` | `custom_css` sur tout plan autre que `enterprise`.                                                                                                                                    |
| `requires the unlimited plan`  | `hide_branding: true` pour une boutique en `pro`. Une boutique `pro` peut quand même envoyer `hide_branding: false`, ce qui réaffiche « Powered by DZBuild » dans le footer.          |

Une clé marchand appartient à une boutique sur un plan Enterprise actif : rien n'est verrouillé pour elle. Les verrous s'appliquent aux jetons d'application installée, qui fonctionnent avec tous les plans.

### Requête[​](#requête-4 "Lien direct vers Requête")

```
curl -X PATCH https://api.dzbuild.app/v1/store/design \

  -H "Authorization: Bearer $DZ_KEY" \

  -H "Content-Type: application/json" \

  -H "Idempotency-Key: store-design-1" \

  -d '{"primary_color": "#0f766e", "show_hero": true, "hero_title": "New collection"}'
```

### Réponse 200[​](#réponse-200-4 "Lien direct vers Réponse 200")

```
{

  "data": {

    "updated": ["primary_color", "show_hero", "hero_title"],

    "skipped": [],

    "values":  {"primary_color": "#0f766e", "show_hero": 1, "hero_title": "New collection"},

    "change_id": 812

  },

  "meta": { "request_id": "...", "api_version": "v1" }

}
```

`updated` liste les champs écrits et `values` la valeur enregistrée pour chacun, après nettoyage. `skipped` est une liste vide quand rien n'a été ignoré, sinon un objet comme `{"hide_branding": "requires the unlimited plan"}`.

Le changement est enregistré et peut être annulé avec `POST /v1/changes/{change_id}/undo`, avec le `change_id` de la réponse ; il vaut `null` dans le cas rare où l'écriture est enregistrée sans trace d'annulation, et `GET /v1/changes?entity=store.design` liste les précédents. Le jeton d'une application installée ne peut ni lire ni annuler les changements (`403 forbidden`, `Apps cannot use this endpoint`). Un `GET /v1/store/design` envoyé juste après l'écriture renvoie les nouvelles valeurs.

### Erreurs[​](#erreurs-3 "Lien direct vers Erreurs")

| HTTP | Code                    | Cause                                                                                                      |
| ---- | ----------------------- | ---------------------------------------------------------------------------------------------------------- |
| 400  | `bad_request`           | Le corps n'est pas un JSON valide, ou `Idempotency-Key` manque ou est mal formée.                          |
| 403  | `forbidden`             | `Missing scope: store:write`, ou clé du marchand dont la boutique n'a pas de plan Enterprise actif.        |
| 404  | `store_not_found`       | La boutique a été supprimée.                                                                               |
| 413  | `payload_too_large`     | Le corps dépasse 1 Mo.                                                                                     |
| 422  | `no_writable_fields`    | Le corps ne contient aucun champ de design, ou tous ses champs ont été ignorés à cause du plan.            |
| 422  | `invalid_value`         | Un champ est un objet ou une liste, ou une valeur a été refusée, comme un `navbar_style` hors de sa liste. |
| 422  | `invalid_url`           | Un champ lien utilise un schéma autre que `https`, `http`, `mailto` ou `tel`.                              |
| 422  | `invalid_pixel_id`      | `facebook_pixel_id` ne fait pas 15 à 17 chiffres.                                                          |
| 422  | `idempotency_key_reuse` | La même `Idempotency-Key` a été utilisée avec un autre corps.                                              |

Une réponse `422` n'écrit rien.
