# Clés (vos propres clés)

Gérez les clés API de **votre** boutique. Toutes les opérations sur les clés nécessitent une **clé plateforme** que vous avez créée. Une clé publique reçoit `403 forbidden` (« Key management requires a platform key »), une clé utilisée par Copilot ou par un assistant IA connecté (Claude ou ChatGPT) reçoit `403` (« This connection cannot manage API keys »), et le jeton d'une application installée reçoit `403` (« Apps cannot use this endpoint »).

> **Attention :** une clé créée via l'API est **active immédiatement**. Pas de confirmation par email, pas d'approbation admin. Si vous créez une clé avec des scopes larges et la fuiez, le destinataire peut agir avec ses pleins droits jusqu'à ce que vous fassiez `DELETE`. Gardez les secrets hors des repos et des écrans partagés.

## Obtenir votre première clé[​](#obtenir-votre-première-clé "Lien direct vers Obtenir votre première clé")

L'API est **réservée au plan Enterprise** : les clés ne peuvent être émises que pour des boutiques disposant d'un plan Enterprise actif, et la création échoue pour tout autre plan. Générez votre première clé depuis le tableau de bord marchand : **Paramètres → API** (`/dashboard/api`), accessible au propriétaire de la boutique ; le secret n'est affiché qu'une seule fois, à la création. Vous pouvez aussi créer et faire tourner vos clés avec les endpoints ci-dessous. Une boutique peut détenir au plus **3 clés actives** créées par vous, depuis le tableau de bord ou via `POST /v1/keys` ; révoquez-en une pour libérer une place. Les clés utilisées par Copilot, par un assistant IA connecté (Claude ou ChatGPT) ou par une application installée n'occupent pas ces places. Une création au-delà de la limite via `POST /v1/keys` renvoie `400 bad_request` (« Key limit reached for this store »).

L'API est aussi actuellement **restreinte à un pilote**. Les clés que vous créez héritent de l'enrôlement pilote de votre clé, elles fonctionnent donc — mais toute clé créée hors pilote renvoie `403 forbidden` (« API is in pilot mode; key not enrolled ») à chaque appel.

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

Liste les clés de votre boutique (exclut les clés révoquées ; elles sont conservées dans l'historique d'audit mais cachées de cette liste). Les clés utilisées par Copilot, par un assistant IA connecté (Claude ou ChatGPT) ou par une application installée ne sont pas listées.

**Auth :** clé plateforme.

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

```
{

  "data": {

    "items": [

      {

        "key_id":          "dzpk_live_xxxxxxxxxxxxxx",

        "type":            "platform",

        "name":            "production-server-1",

        "scopes":          ["store:read", "products:read", "orders:read", "orders:write"],

        "rate_limit_tier": "enterprise",

        "pilot":           true,

        "status":          "active",

        "last_used_at":    "2026-04-30 19:35:49",

        "last_used_ip":    "203.0.113.42",

        "created_at":      "2026-04-30 19:27:55",

        "expires_at":      null

      }

    ]

  }

}
```

Notes :

* `last_used_at` est rafraîchi au plus une fois par minute et par clé, il peut donc être en retard sur votre dernier appel.
* `last_used_ip` est l'IP source de l'appelant telle que vue par l'API — l'IP client originale, pas celle d'un proxy intermédiaire.
* Les secrets ne sont **JAMAIS** retournés par `GET`.
* `expires_at` vaut toujours `null` — rien ne le définit et les clés n'expirent pas d'elles-mêmes. Révoquez-les explicitement.
* Les clés en `status: "suspended"` apparaissent toujours dans cette liste ; seules les clés révoquées sont masquées.
* `key_id` fait toujours exactement 24 caractères, préfixe `dzpk_live_` / `dzpub_live_` compris.

## `POST /v1/keys` — créer[​](#post-v1keys--créer "Lien direct vers post-v1keys--créer")

Crée une nouvelle clé. **Le secret est retourné une seule fois** — sauvegardez-le immédiatement.

**Auth :** clé plateforme. **Nécessite `Idempotency-Key`**, mais une création n'est jamais conservée pour rejeu car la réponse contient des secrets : réessayer avec la même `Idempotency-Key` crée une deuxième clé, vérifiez donc `GET /v1/keys` avant de réessayer.

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

| Champ  | Type                   | Requis | Notes                                                                                                                                                                                                              |
| ------ | ---------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `type` | `platform` \| `public` |        | Défaut `platform`, envoyez-le donc toujours explicitement. Une nouvelle clé plateforme n'obtient jamais plus de scopes que la clé appelante n'en détient (voir ci-dessous). Une valeur hors ensemble renvoie `400` |
| `name` | string ≤ 100           |        | Libellé libre. Défaut `default`. Un nom plus long est coupé à 100 octets, pas à 100 caractères (une lettre arabe occupe 2 octets), gardez-le donc court                                                            |

> **Le tier et l'enrôlement pilote sont hérités de la clé appelante, et une nouvelle clé plateforme n'obtient jamais plus de scopes que la clé appelante n'en détient.** Une clé plateforme créée via `POST /v1/keys` reçoit les scopes plateforme par défaut que la clé appelante possède déjà ; si la clé appelante n'en possède aucun, l'appel renvoie `403 forbidden` (« This key holds none of the scopes a new platform key can carry »). L'ensemble plateforme par défaut, que les clés générées dans le tableau de bord reçoivent en entier, est `store:read`/`store:write`, `products:read`/`products:write`, `orders:read`/`orders:write`, `customers:read`, `landing_pages:read`/`landing_pages:write`, `promos:read`/`promos:write`, `pixels:read`/`pixels:write`, `shipping:read`/`shipping:write`, `webhooks:read`/`webhooks:write`, `usage:read`, `analytics:read`, `whatsapp:read` et `whatsapp:send`. Les clés publiques reçoivent toujours `signups:write` et `events:write`. Contactez le support si vous avez besoin d'une clé émise avec un jeu de scopes réduit.

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

```
curl -X POST 'https://api.dzbuild.app/v1/keys' \

  -H "Authorization: Bearer $DZ_KEY" \

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

  -H "Idempotency-Key: $(uuidgen)" \

  -d '{ "type": "platform", "name": "ci-deploy-key" }'
```

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

La création d'une clé renvoie HTTP **200**, pas 201 — vérifiez `data.key_id` plutôt que le code de statut.

```
{

  "data": {

    "key_id":         "dzpk_live_a3f9...",

    "bearer_token":   "dzpk_live_a3f9..........73ad…",

    "signing_secret": "<64-character hex signing secret>",

    "note":           "Save these now — secrets are not retrievable."

  }

}
```

Pour une clé **plateforme**, `bearer_token` est ce que vous mettez dans `Authorization: Bearer ...` — son format est `{key_id}.{secret hex de 48 caractères}`. Pour une clé **publique**, `bearer_token` vaut `null` et vous utilisez `signing_secret` pour calculer les signatures HMAC (voir [Authentification](https://dzbuild.com/fr/fr/api-docs/authentication.md)).

## `DELETE /v1/keys/{key_id}` — révoquer[​](#delete-v1keyskey_id--révoquer "Lien direct vers delete-v1keyskey_id--révoquer")

**Auth :** clé plateforme. **Nécessite `Idempotency-Key`.** Une clé qui n'appartient pas à votre boutique, ou une clé utilisée par Copilot, par un assistant IA connecté (Claude ou ChatGPT) ou par une application installée, renvoie `404 not_found`. Révoquer une clé déjà révoquée renvoie quand même `revoked: true`.

```
curl -X DELETE 'https://api.dzbuild.app/v1/keys/dzpk_live_a3f9...' \

  -H "Authorization: Bearer $DZ_KEY" \

  -H "Idempotency-Key: revoke-a3f9"
```

Réponse :

```
{ "data": { "revoked": true, "key_id": "dzpk_live_a3f9..." } }
```

Ce qui se passe :

* Le statut de la clé passe immédiatement à `revoked` et elle disparaît de `GET /v1/keys`.
* La révocation est enregistrée dans l'historique d'audit de vos clés.
* La révocation peut mettre jusqu'à \~60 s à se propager partout ; jusque-là, la clé peut encore réussir sur certains appels. S'il vous faut une coupure immédiate, contactez le support.

## Bonnes pratiques[​](#bonnes-pratiques "Lien direct vers Bonnes pratiques")

* **Une clé par environnement** — une clé `staging` et une clé `production`. Ne pas partager.
* **Une clé par intégration** — une pour Zapier, une pour la sync CRM, une pour l'analytics. Plus facile de révoquer une intégration sans casser les autres.
* **Faites tourner périodiquement** — tous les 90 jours pour les clés de production est une cadence raisonnable.
* **Auditez `last_used_at`** — les clés non utilisées depuis 30+ jours sont candidates à la révocation.
* **N'envoyez jamais un secret par email** — collez-le une fois dans votre gestionnaire de secrets et plus jamais.
