Conventions
Conventions qui s'appliquent à chaque endpoint de l'API publique. Lisez cette page une fois ; les pages par ressource partent du principe que vous avez intégré tout ce qui est ici.
Format des requêtes
- Protocole : HTTPS uniquement. Le HTTP simple est refusé.
- Body : JSON, UTF-8. Le header
Content-Type: application/jsonest requis surPOST,PUTetPATCH. Sans ce header, l'API renvoie415 unsupported_media_type. - Limite de taille du body : 5 MB. Les payloads plus gros reçoivent
413 Payload Too Large. Pour les imports bulk de gros catalogues, utilisez les endpoints batch (max 500 items par appel) ou l'API Imports en streaming. - Toutes les réponses sont en JSON, UTF-8.
curl -X POST https://api.thehumind.com/public/v1/products \
-H "Authorization: Bearer hmd_live_..." \
-H "Content-Type: application/json" \
-d '{ "external_id": "SKU-123", "title": "..." }'Identifiants
Chaque ressource exposée par l'API publique a deux identifiants : un que vous contrôlez (external_id) et un que Humind contrôle (humind_id). Choisissez celui qui est le plus pratique pour l'appel que vous faites.
| Identifiant | Qui le pose | Format | Notes |
|---|---|---|---|
external_id | Vous | String free-form, unique par company | Votre SKU, votre slug, n'importe quoi que vous pouvez déduire de vos propres données. Utilisé pour les upserts : reposter un produit avec le même external_id qu'un existant met à jour celui-là. |
humind_id | Humind | 24 caractères hex minuscules | Renvoyé dans chaque réponse. Stable pendant toute la vie de la ressource. |
Pour les path parameters qui prennent un {id} (GET /products/{id}, PATCH /products/{id}, …), passez l'une ou l'autre forme :
| Forme | Exemple | Quand l'utiliser |
|---|---|---|
api:<external_id> | api:SKU-123 | Quand vous voulez agir sur une ressource par votre propre identifiant. Le préfixe api: désambiguïse de humind_id. |
<humind_id> | 65f1ab9c8e7d4a2b1c3d4e5f | Quand vous avez stocké le humind_id d'une réponse précédente et voulez l'utiliser directement. |
Choisissez external_id pour vos scripts
Si vous écrivez un script de sync, external_id est presque toujours le bon choix, votre script connaît déjà votre SKU et vous n'avez pas à round-tripper Humind pour récupérer le humind_id d'abord.
Dates
Tous les timestamps en réponse sont en ISO 8601 UTC avec le Z final :
2026-04-25T14:30:00ZEn requête, n'importe quel timestamp ISO 8601 est accepté ; les valeurs non-UTC (par exemple 2026-04-25T16:30:00+02:00) sont normalisées en UTC à l'écriture et stockées avec le suffixe Z. On recommande quand même d'envoyer en UTC côté client pour que ce que vous lisez corresponde exactement à ce que vous avez envoyé.
Pagination
Les endpoints de liste (GET /products, GET /collections, GET /knowledge) utilisent une pagination par cursor opaque. Chaque réponse inclut une chaîne next_cursor ; passez-la en retour comme ?cursor=… pour récupérer la page suivante. Les pages sont plafonnées à 100 items (par défaut 50). Quand next_cursor est null, vous êtes à la fin. Le cursor est opaque — ne le parsez pas, le format peut changer dans une version future.
Idempotency
Pour chaque appel modifiant l'état (POST, PUT, PATCH, DELETE), incluez un header Idempotency-Key à un UUID v4 (ou n'importe quelle valeur unique, max 255 caractères) :
curl -X POST https://api.thehumind.com/public/v1/products \
-H "Authorization: Bearer hmd_live_..." \
-H "Idempotency-Key: 3f1a8d92-7c4b-4e6f-b2a1-d5e9c8f7a3b4" \
-H "Content-Type: application/json" \
-d '{ ... }'Ce que ça fait :
- Si votre client retente la même requête (même méthode + path + body) dans les 24h, l'API rejoue la réponse originale au lieu d'exécuter la mutation une seconde fois. Safe à retry sur les interruptions réseau, timeouts, gateway errors.
- Si vous réutilisez la même clé avec un body différent, l'API rejette la requête en
409 Conflictavec le codeidempotency_conflict. Générez un UUID frais pour chaque nouvelle opération.
Requis sur chaque write
Idempotency-Key est requis sur chaque appel modifiant l'état (POST, PUT, PATCH, DELETE). Deux exceptions state-machine-idempotent sont documentées inline : POST /imports/{sync_id}/start et POST /imports/{sync_id}/cancel acceptent le header mais ne le requièrent pas. Tout le reste renvoie 400 idempotency_key_required si le header est manquant.
Pour les endpoints batch, la clé d'idempotency s'applique au batch entier, un retry rejoue toute la réponse 207 Multi-Status.
Versioning
L'API est versionnée par URL. La version actuelle est /public/v1.
- Changements additifs (nouveaux endpoints, nouveaux champs optionnels, nouveaux headers optionnels) sortent sous la version existante. Votre code continue de marcher.
- Breaking changes (champs renommés, endpoints supprimés, règles de validation changées) sortent sous une nouvelle version (
/public/v2). La précédente reste vivante en parallèle. - Fenêtre de dépréciation : 6 mois minimum entre l'annonce d'une dépréciation et la suppression. On envoie un mail à l'adresse enregistrée pour la company et on affiche une bannière dans le dashboard.
Une version future pourra introduire une pagination cursor-based sur les endpoints list (?cursor=...&limit=... avec { "data": [...], "next_cursor": "..." }). Quand ça sortira, les clients qui ne passent pas de cursor continueront de fonctionner : l'API retombera sur la plus grande taille de page raisonnable.
La fenêtre de migration exacte vers v2 sera annoncée dans le changelog quand v2 sera sur la roadmap.
Localisation
La façon standard de pousser du contenu multilingue est de l'embarquer directement dans le payload de la ressource. Chaque ressource a un champ default_language plus une map optionnelle translations clée par codes ISO 639-1 :
{
"default_language": "fr",
"title": "Crème hydratante",
"description": "...",
"handle": "creme-hydratante",
"translations": {
"en": {
"title": "Hydrating cream",
"description": "...",
"handle": "hydrating-cream"
}
}
}default_language est la langue des champs top-level. translations[<lang>] est l'override par locale.
Les codes de langue suivent ISO 639-1 (minuscule, deux lettres) : en, fr, de, es, it, nl, pt, ru, ar, he, zh.
Translations comme sub-resource
Pour les workflows de traduction où chaque langue sort à sa propre cadence, une sub-resource translations dédiée vous laisse patcher une locale à la fois sans renvoyer le payload complet : voir Products / Translations, Collections / Translations et Knowledge / Translations.
Rate limits
Les limites par clé API sont enforced aujourd'hui (buckets séparés pour les reads, writes et triggers d'imports), plus un throttle de 5/minute/IP sur les tentatives d'auth échouées. Voir Rate limits pour les valeurs actives, la forme de la réponse 429 et les snippets de backoff.
Isolation cross-tenant
Les clés API sont strictement liées à une seule company. Tenter de lire ou écrire une ressource qui appartient à une autre company renvoie toujours 404 Not Found (jamais 403) : Humind ne révèle pas l'existence des ressources d'autres tenants. Ça s'applique même quand vous connaissez par hasard un humind_id valide d'une autre company.