Skip to content

API Epinium ​

Accès : Configuration → API Keys

Epinium expose vos données via une API REST pour que vous puissiez les lire depuis vos propres outils : un tableau de bord maison, un script d'analyse ou un assistant IA. Ce sont les mêmes informations que celles affichées dans l'application, avec les mêmes chiffres.

L'API lit vos données et écrit sur Amazon et dans vos boutiques : elle consulte catalogue, campagnes et métriques, et ce que contiennent vos boutiques Shopify et WooCommerce ; elle crée et édite des campagnes Sponsored Products et édite celles de Sponsored Brands et Display ; elle crée et édite des portefeuilles ; elle crée, édite, clone et exécute des workflows ; elle crée, résout et applique des tâches ; et elle crée, édite et supprime des produits et du contenu dans vos boutiques Shopify et WooCommerce connectées. Votre catalogue Amazon ne change que lorsqu'une tâche approuvée est appliquée ; celui de vos boutiques change directement, sans tâche. Chaque domaine a sa permission, et celles d'écriture, c'est vous qui les donnez à la création de la clé.

Vous voulez l'utiliser depuis un assistant IA ?

Aucun développement n'est nécessaire. Le MCP Epinium connecte ces mêmes données à Claude et à d'autres assistants compatibles.

Générer un token ​

  1. Allez dans Configuration → API Keys
  2. Cliquez sur Créer une API key et donnez-lui un nom qui rappelle son usage
  3. Cochez les permissions nécessaires
  4. Copiez la clé et conservez-la en lieu sûr
  5. Utilisez-la dans l'en-tête Authorization de chaque requête

La clé ne s'affiche qu'une seule fois

La valeur complète apparaît une seule fois à la création. Si vous la perdez elle est irrécupérable : il faut la révoquer et en créer une autre.

Permissions ​

Chaque token porte les permissions cochées à sa création. N'accordez que celles dont votre intégration a besoin.

PermissionDonne accès à
catalog:readProduits, marques, pays et clusters, avec leurs métriques : ventes, frais Amazon et marge, retours, stock et, pour Vendor, avis
campaigns:readCampagnes, portefeuilles, ad groups, targets, product ads et termes de recherche
workflows:readVos workflows, leur configuration et les campagnes qu'ils atteignent
connections:readLes connexions de votre compte : Amazon, Shopify et WooCommerce
tasks:readTâches Epinium et leurs items
skills:readLe catalogue de playbooks marketing validés d’Epinium
platform:readCe que contiennent vos boutiques Shopify et WooCommerce : produits, stock, prix et le reste de ce qu'expose chaque boutique, lu en direct depuis sa propre API. Cela inclut le registre des modifications qui y sont faites (/v1/platform-changes, 1 crédit par ligne renvoyée)
catalog:writeCréer, modifier et supprimer des clusters de mots-clés : leur nom, leurs mots-clés positifs et négatifs et les produits qu'ils regroupent. Rien n'arrive sur Amazon
campaigns:writeCréer et modifier campagnes, portefeuilles, ad groups, targets et product ads sur Amazon, et configurer ce que l'optimiseur poursuit sur chacune
platform:writeCréer, modifier et supprimer des produits et du contenu dans vos boutiques Shopify et WooCommerce connectées, directement et sans validation préalable, par la même route que celle qui sert à les consulter (POST /v1/platform-request) : une mutation dans Shopify, ou une méthode autre que GET dans WooCommerce, avec l'en-tête Idempotency-Key. Il faut aussi platform:read (le niveau Modifier de l'écran API Keys accorde les deux). Chaque modification est enregistrée pendant 12 mois et coûte autant qu'une consultation : 5 crédits par appel plus 1 par KB renvoyé
tasks:writeCréer des tâches, approuver ou rejeter leurs suggestions, les clôturer et appliquer ce qui a été approuvé
workflows:writeCréer, copier, éditer, activer, mettre en pause, supprimer et restaurer des workflows, et les lancer ou les simuler

L'écriture est réservée aux plans Business et Master. En Free et Guru, les tokens lisent : on ne peut ni créer une clé ni autoriser un assistant avec des permissions d'écriture, et si vous passez à l'un de ces plans, ceux que vous aviez déjà continuent de lire mais leurs écritures sont refusées avec un 403.

Un token atteint toutes les connexions de votre compte. Si vous êtes une agence, il atteint les connexions que chaque client vous a partagées en acceptant votre invitation.

Si vous êtes une agence : choisissez le compte à chaque appel ​

Un token d'agence atteint plusieurs comptes, donc chaque requête doit dire sur lequel elle opère. Avec l'en-tête Epinium-Account : <id du compte>, ou avec le paramètre account_id si vous appelez depuis le MCP.

/v1/me et /v1/accounts font exception : ils répondent sans choisir de compte, et ce sont justement eux qui vous disent quels comptes vous atteignez et comment ils s'appellent.

Le compte choisi, vous le voyez en entier : ses produits et ses campagnes sont limités aux connexions qu'il vous a partagées, et ses ressources de compte — workflows, tâches et clusters, qui ne dépendent d'aucune connexion — sont limitées au compte. Ce qui sort de votre portée n'est pas filtré en silence : un account_id auquel vous n'êtes pas invité renvoie une erreur explicite, pas une liste vide.

Quels endpoints elle couvre ​

Chaque ressource dispose d'un listing, et la plupart permettent aussi de récupérer un élément par son id. Les ressources de métriques n'ont qu'un listing : une ligne agrégée sur une plage de dates n'a pas d'identifiant propre.

Catalogue — catalog:read ​

EndpointCe qu'il renvoie
/v1/productsVos produits unifiés
/v1/amazon-seller-productsLa vue Seller Central de chaque produit, et la catégorie de son classement avec expand=salesRanks
/v1/amazon-vendor-productsLa vue Vendor Central, la catégorie du classement avec expand=salesRanks et les avis avec expand=customerFeedback
/v1/amazon-advertising-productsLa vue Advertising
/v1/seller-product-metricsVentes, sessions, Buy Box, rank, frais Amazon, marge, retours, stock, B2B et jours de couverture par produit
/v1/vendor-product-metricsVentes Vendor par produit, avec manufacturing et sourcing, retours, sell-in avec Amazon, inventaire et jours de couverture
/v1/product-brandsVos marques
/v1/countriesPays et marketplaces
/v1/clustersVos clusters de mots-clés ; avec catalog:write, vous les créez et les modifiez aussi

Publicité — campaigns:read ​

EndpointCe qu'il renvoie
/v1/campaignsVos campagnes Amazon Advertising
/v1/campaign-metricsDépense, ventes, ACOS et ROAS par campagne
/v1/portfoliosVos portefeuilles et le plafond de budget que chacun impose à ses campagnes
/v1/adgroupsLes ad groups de chaque campagne
/v1/adgroup-metricsPerformance par ad group
/v1/targetsMots-clés et targets produit
/v1/target-metricsPerformance par target, avec son mot-clé et son type de correspondance
/v1/product-adsLe lien entre un ad group et le produit qu'il annonce
/v1/product-ad-metricsPerformance par produit annoncé, avec son ASIN
/v1/search-termsLes recherches réelles des acheteurs
/v1/search-term-metricsPerformance par recherche, avec le texte et le target qui l'a associée
/v1/campaigns/{id}/optimization-historyCe que l'automatisation a changé sur une campagne, avec l'effet net
/v1/advertising-changesTout ce qu'Epinium a modifié sur Amazon, quelle qu'en soit l'origine

Automatisation — workflows:read ​

EndpointCe qu'il renvoie
/v1/workflowsVos workflows, avec leur planification et s'ils sont actifs
/v1/workflows/{id}La configuration complète de l'un d'eux : son diagramme et chaque variable avec sa valeur effective
/v1/workflows/{id}/campaignsLes campagnes qu'il atteint réellement, et pourquoi chacune en fait partie
/v1/workflows/{id}/performanceLa performance de ces campagnes, avec leur objectif à côté pour pouvoir la juger

Un workflow peut être planifié chaque nuit et ne toucher aucune campagne : /campaigns est ce qui le révèle, et quand l'ensemble revient vide il en donne la raison.

Connexions, tâches et skills ​

EndpointPermissionCe qu'il renvoie
/v1/connectionsconnections:readVos connexions : Amazon, Shopify et WooCommerce
POST /v1/platform-requestplatform:read, et platform:write pour écrireUne requête vers l'une de vos boutiques ou, avec platform:write, une modification : GraphQL sur Shopify, REST sur WooCommerce
/v1/platform-request/docs/{platform}platform:readLa version de l'API de cette plateforme, sa référence et les champs qu'a votre boutique en ce moment
/v1/taskstasks:readTâches Epinium
/v1/task-itemstasks:readLes items de chaque tâche
/v1/skillsskills:readLe catalogue de playbooks marketing d’Epinium

Le catalogue de skills est du contenu rédigé par Epinium, pas des données de votre compte : il est identique pour tous les clients. Les parties de chaque playbook que vous recevez dépendent de votre plan.

Les requêtes vers vos boutiques ne renvoient aucune donnée personnelle : noms, e-mails, téléphones et adresses sont refusés avant que la requête n'atteigne la boutique. Elles sont facturées selon la taille de la réponse, comme les modifications. Ces deux routes ne figurent pas dans la référence navigable : on les utilise d'habitude depuis le MCP Epinium.

Il existe également /v1/me, qui indique quelles permissions et quels comptes votre token atteint. C'est le premier appel utile pour vérifier que la clé fonctionne.

Trois règles pour lire les données ​

Ces trois points expliquent presque toutes les questions d'interprétation :

  • Les montants sont du texte, pas des nombres. "cost": "8.22" arrive en chaîne à dessein, pour ne pas perdre de précision à la conversion en décimal binaire.
  • Les ratios sont en fraction, pas en pourcentage. Un ACOS de 90,83 % arrive comme 0.908287. Multipliez par 100 pour l'afficher.
  • null n'est pas 0. null signifie qu'Amazon n'a pas remonté la donnée ; 0 signifie un vrai zéro. Un acos à null est une campagne qui a dépensé sans vendre, pas de la publicité gratuite. Et new_to_brand_sales arrive à null en Sponsored Products parce qu'Amazon ne le mesure pas pour ce format.

Rentabilité, stock et avis de vos produits ​

Les métriques produit ne s'arrêtent pas aux ventes : elles disent aussi ce que garde Amazon, combien de stock il reste et ce que pensent les acheteurs. Quatre points avant de tirer des conclusions :

  • Les frais et la marge Seller sont hors TVA, alors que sales l'inclut là où elle s'applique : ne soustrayez pas les uns de l'autre. margin_before_ads est ce qui reste après avoir payé Amazon, avant publicité et coût du produit : pour la marge après publicité, soustrayez-lui la dépense de /v1/product-ad-metrics. Amazon impute le stockage à un seul jour du mois et les retours à la date du remboursement, donc la marge se lit par mois, pas par jour.
  • days_of_coverage est le nombre de jours que dure le stock au rythme de la période : le stock du dernier jour divisé par les unités moyennes par jour de la plage demandée. Il vaut null avec toute granularité autre que total, si le produit n'a rien vendu ou, en regroupant, si group_by n'inclut pas le pays. Avec order_by=days_of_coverage&order=asc, vous obtenez d'abord ceux qui sont sur le point d'être en rupture.
  • Côté Vendor il y a aussi le sell-in : les unités que vous avez confirmées à Amazon, celles des commandes d'achat ouvertes, le taux de remplissage et le délai de livraison, ainsi que les retours séparés entre manufacturing et sourcing et la santé de l'inventaire.
  • La catégorie du classement et les avis se demandent au produit, pas aux métriques. expand=salesRanks indique à quelle catégorie appartient chaque position du Best Seller Rank, et côté Vendor expand=customerFeedback renvoie les thèmes positifs et négatifs des avis et les motifs de retour de la catégorie. C'est l'image de la semaine, avec la tendance sur six mois calculée par Amazon, pas un historique.

Totaux du compte, par période et par cluster ​

Pour savoir combien le compte a vendu en septembre, inutile de paginer le catalogue et de faire la somme : les sept ressources de métriques agrègent d'elles-mêmes.

  • group_by additionne les entités entre elles. account donne le total du compte ; country et connection ventilent par pays ou par connexion, et se combinent en répétant le paramètre (group_by[]=connection&group_by[]=country). account ne se combine avec rien. Les lignes restent séparées par devise (les montants ne sont jamais convertis) et, en publicité, par type d'annonce (SP, SB, SD).
  • granularity découpe la plage en périodes calendaires. En plus de total et daily, elle accepte weekly, monthly, quarterly et yearly, et chaque ligne porte dans date le début de sa période : le lundi de la semaine ou le 1er du mois, du trimestre ou de l'année. Les périodes aux extrémités sont partielles : du 15 janvier au 10 mars avec monthly, vous obtenez janvier du 15 au 31, février entier et mars du 1er au 10.
  • cluster restreint à une famille de produits. Dans les métriques Seller, Vendor et produit annoncé, cluster=<id> ne garde que les produits de ce cluster ; avec plusieurs ids, leur union. Il se combine avec ce qui précède : group_by=account&granularity=monthly&cluster=<id> donne la série mensuelle de cette famille.
  • group_by=cluster donne une ligne par cluster. Sur les trois mêmes métriques, group_by=cluster renvoie en un seul appel les chiffres de chacun de vos clusters, avec son id dans cluster et son nom dans cluster_name. Un produit présent dans plusieurs clusters compte en entier dans chacun d'eux : les lignes ne s'additionnent donc pas en total du compte, et les produits sans cluster n'apparaissent pas. Il se combine avec country et connection, et avec le filtre cluster pour choisir les clusters renvoyés ; si vos clusters dépassent 2 000 appartenances produit-cluster, l'API vous demande de les restreindre avec ce filtre.

Dans les lignes regroupées, les champs qui identifient une entité (product, asin, campaign…) valent null, de même que ce qui ne peut pas s'additionner : le rank, le prix, le canal et les taux Vendor. Le stock Seller ne s'additionne que si vous regroupez par pays : avec l'inventaire paneuropéen FBA, Amazon remonte le même stock sur chaque marketplace, et l'additionner entre pays compterait plusieurs fois les mêmes unités. C'est pourquoi, avec group_by=account ou connection, stock et days_of_coverage valent null.

Un cluster regroupe des produits du catalogue, pas des ASIN isolés : le même ASIN sur une autre connexion reste exclu, sauf si son produit figure aussi dans le cluster. Et les lignes qu'Amazon n'a pas pu associer à un produit du catalogue n'entrent pas dans le filtre : environ 5 % des ventes Vendor et 3 % de la dépense en produits annoncés.

Ce que cela fait économiser en crédits, vous le trouverez dans Crédits.

Ce que l'automatisation a changé sur une campagne ​

/v1/campaigns/{id}/optimization-history répond à ce que le workflow a changé sur une campagne, pas à ce qu'il a décidé. La différence compte : dans un historique de décisions, le même target peut apparaître avec une hausse et une baisse la même nuit, et là on ne voit pas qu'elles s'annulent.

Chaque ligne arrive donc agrégée à l'effet net de l'entité : l'enchère d'avant le premier changement de la période face à celle d'après le dernier, plus le nombre de fois où elle a bougé en chemin. Un target passé de 0,18 € à 0,45 € puis ramené à 0,18 € la même nuit revient avec un net de zéro et deux mouvements — c'est la lecture utile, et précisément celle qu'une liste masque.

Trois choses délimitent ce qu'il renvoie :

  • Uniquement les changements réels. Les simulations ne sont pas exposées ici, avec aucun paramètre : ce sont des enchères qui n'ont jamais atteint Amazon.
  • Uniquement l'appliqué, pas le proposé. L'optimiseur calcule une enchère qu'un plafond peut ensuite rogner ; seul ce qui a été envoyé est rapporté.
  • Fenêtre de 90 jours au maximum. C'est la durée de conservation de ces enregistrements. Sans dates, il renvoie les 90 derniers jours.

Les changements qui ne sont pas des enchères — keywords récoltées, négatifs, ajustements d'emplacement, targets en quarantaine ou bloqués — sont comptés à part dans other_changes, car ils n'ont pas d'enchère antérieure à laquelle se comparer.

Tout ce qu'Epinium a modifié sur Amazon ​

/v1/advertising-changes répond à une question différente de la précédente : non pas pourquoi l'automatisation a décidé, mais ce qui a été touché et si Amazon l'a accepté. Et pas seulement ce que fait l'automatisation : aussi ce qu'une personne a fait depuis l'application, un processus interne ou cette API elle-même.

La règle tient en une ligne : si c'est parti vers Amazon, il y a une ligne. Trois conséquences en découlent, et mieux vaut les avoir claires :

  • Ce qu'Amazon a refusé laisse aussi une ligne, avec result: "failed" et le message d'Amazon dans error. C'est le premier endroit où regarder quand un changement n'a pas pris effet.
  • Ce qui n'a jamais été tenté ne laisse pas de ligne : un budget sous le minimum du pays, ou une enchère qui était déjà celle demandée.
  • Les changements de configuration à l'intérieur d'Epinium restent dehors, car ils ne partent pas vers Amazon.

Chaque ligne dit d'où elle vient. source distingue l'application (front), l'optimiseur (workflow), un processus interne (system) et ce canal (public-api, mcp), et actor identifie la personne ou la clé concernée — quand le changement vient de quelqu'un dans l'application, son email est là. S'il vient d'un workflow, correlation_id est l'identifiant de cette exécution, la clé pour croiser cette réponse avec optimization-history.

Vous pouvez filtrer par campaign, adgroup, entity, entity_type, source, result, field et correlation_id, et borner la fenêtre avec start_date et end_date (YYYY-MM-DD, les deux inclus). Les enregistrements sont conservés douze mois.

Écrire sur Amazon ​

Avec la permission campaigns:write, l'API ne fait plus que lire : elle crée campagnes, ad groups, targets et product ads, et déplace leurs états, budgets et enchères. Ce que vous écrivez part réellement vers Amazon et laisse sa ligne dans /v1/advertising-changes.

Cinq choses à savoir avant le premier appel :

  • Tout naît en pause. Une campagne ou un ad group est créé PAUSED sauf si vous demandez ENABLED explicitement, car ce qui est actif commence à dépenser dès qu'Amazon l'accepte.
  • Archiver a son propre verbe : DELETE /v1/<ressource>/{id}. C'est la seule opération irréversible de cette API : sur Amazon, archiver ne se défait pas. C'est pourquoi ce n'est pas une valeur de state que vous pourriez poser par mégarde à côté d'un changement d'enchère, mais un appel distinct avec un verbe distinct. Pour seulement arrêter la dépense, utilisez state: "PAUSED", qui est réversible.
  • Toute écriture exige un en-tête Idempotency-Key. Réutilisez la même valeur si vous réessayez la même intention : sans cela, un timeout réseau devient deux campagnes.
  • Un lot n'est pas tout-ou-rien. POST /v1/<ressource>/batch accepte jusqu'à 1000 entités et répond une ligne par entité, dans l'ordre d'envoi. applied est ce qui est arrivé chez Amazon, et c'est la seule chose facturée. Un résultat partiel est le cas normal, pas une erreur : lisez-le au lieu de réessayer tout le lot, car un nouvel essai dupliquerait ce qui est déjà passé.
  • Une entité n'est appliquée que si tout ce que vous avez demandé est passé. Si un PATCH change état et budget et qu'Amazon accepte le premier et refuse le second, cette entité revient en failed avec le motif — la déclarer appliquée, c'est croire qu'une enchère a bougé alors que non.
RouteCe qu'elle fait
POST /v1/campaignsCréer une campagne
POST /v1/campaigns/fullCampagne + ad group + targets + product ads en un appel
PATCH /v1/campaigns/{id} · POST /v1/campaigns/batchÉtat, budget quotidien, nom et portefeuille (le portefeuille, en Sponsored Products uniquement)
POST /v1/adgroups · PATCH /v1/adgroups/{id} · POST /v1/adgroups/batchCréer ; état, enchère par défaut et nom
POST /v1/targets · PATCH /v1/targets/{id} · POST /v1/targets/batchCréer des targets (les types dépendent de l'ad product de l'ad group) ; état et enchère
POST /v1/product-ads · PATCH /v1/product-ads/{id} · POST /v1/product-ads/batchAnnoncer des produits ; état
POST /v1/portfolios · PATCH /v1/portfolios/{id}Créer un portefeuille ; nom, état et plafond de budget
DELETE /v1/campaigns/{id} · DELETE /v1/adgroups/{id} · DELETE /v1/targets/{id} · DELETE /v1/product-ads/{id}Archiver - irréversible

Ce qui ne peut pas changer, et pourquoi : ce qui définit un target — son mot-clé, son ASIN, son type de correspondance — n'est pas modifiable sur Amazon ; pour le changer, on en crée un autre et on archive le précédent. Un product ad n'accepte que l'état : c'est le lien entre un produit et un ad group, sans enchère ni nom propres. Et les entités gérées par l'optimiseur sont refusées, car son exécution de 03:00 UTC réécrirait par-dessus.

Le plafond d'un portefeuille limite ce que dépensent ensemble toutes ses campagnes. MONTHLY_RECURRING se réinitialise chaque mois, DATE_RANGE s'applique entre startDate et endDate et NO_CAP le supprime ; la devise est celle du marketplace et ne s'envoie pas. Dans un PATCH, budget est remplacé en entier : envoyez le plafond complet que vous voulez, pas seulement le montant. Pour faire entrer ou sortir une campagne Sponsored Products d'un portefeuille, changez son portfolioId avec PATCH /v1/campaigns/{id}.

Deux codes à distinguer. Une entité qui n'existe pas, ou qui appartient à un autre compte, répond 404 — jamais 403, qui confirmerait son existence. Un refus d'Amazon répond 200 avec result: "failed" et le motif : l'appel est bien arrivé, c'est le changement qui a échoué.

Les trois ad products s'écrivent, mais pas de la même façon :

  • Sponsored Brands et Sponsored Display se modifient et s'archivent avec les mêmes routes que Sponsored Products : état, budget, nom et enchères des campagnes, ad groups, targets et product ads. Ce qui n'est pas encore possible, c'est de les créer : POST /v1/campaigns, /v1/campaigns/full, /v1/adgroups et /v1/product-ads sont réservés à Sponsored Products.
  • Les ad groups Sponsored Brands n'ont pas d'enchère par défaut. Un changement de defaultBid sur l'un d'eux est refusé avec un message qui l'explique. Ceux de Sponsored Display en ont une.
  • Les targets et targets négatifs se créent bien dans les ad groups SB et SD, avec POST /v1/targets. Le targetType accepté dépend de l'ad product de l'ad group (tableau ci-dessous). Au niveau de l'ad group uniquement : SB et SD n'ont pas de targets négatifs de campagne.
  • Epinium ne vérifie les limites d'enchère et de budget du marketplace que pour Sponsored Products, avant l'envoi. Pour Brands et Display, il n'applique pas de limites propres : c'est Amazon qui valide, et son motif revient dans la réponse, par entité avec result: "failed" ou, à la création de targets, dans failure_details, où reference identifie le target (mot-clé, ASIN, SKU ou l'id d'audience, de catégorie ou de localisation).
Ad producttargetType acceptés
Sponsored ProductsKEYWORD, PRODUCT, PRODUCT_CATEGORY
Sponsored BrandsCeux de Sponsored Products plus THEME (themeMatchType KEYWORDS_RELATED_TO_YOUR_BRAND ou KEYWORDS_RELATED_TO_YOUR_LANDING_PAGES)
Sponsored DisplayKEYWORD ; PRODUCT par ASIN ou par sku, avec productMatchType PRODUCT_EXACT ou PRODUCT_SIMILAR ; PRODUCT_CATEGORY avec affinages (marque, prix, note, tranche d'âge, éligibilité Prime) ; THEME (INTERESTED_AUDIENCE) ; PRODUCT_AUDIENCE (ASIN + event PURCHASE ou VIEW + lookback de 7, 14, 30, 60, 90, 180 ou 365 jours) ; AUDIENCE (audienceId), CONTENT_CATEGORY (contentCategoryId) et LOCATION (locationId)

Les ids de AUDIENCE, CONTENT_CATEGORY et LOCATION viennent de la console Amazon Ads : l'API ne les liste pas encore.

Configuration de l'optimisation ​

Avec la même permission campaigns:write, en plus d'écrire sur Amazon vous pouvez lire et changer la configuration qu'utilise l'optimiseur d'Epinium : ce qu'il poursuit sur chaque campagne. C'est une surface différente de la précédente, et il ne faut pas les confondre.

Elle ne part jamais vers Amazon. C'est une configuration propre à Epinium, consommée par l'optimiseur lors de son exécution de chaque nuit, pas une donnée du compte Amazon. C'est pourquoi deux règles d'« Écrire sur Amazon » ne s'appliquent pas ici : pas besoin d'en-tête Idempotency-Key - il n'y a aucun aller-retour vers Amazon qu'un nouvel essai pourrait dupliquer - et le changement ne laisse pas de ligne dans /v1/advertising-changes, qui n'enregistre que ce qui a été envoyé à Amazon.

Elle se lit avec expand, pas par défaut. GET /v1/campaigns et GET /v1/campaigns/{id} ne renvoient optimizationConfig que si vous demandez ?expand[]=optimizationConfig. C'est opt-in car très peu de campagnes ont cette configuration enregistrée : sans expand, la colonne reviendrait presque toujours à null.

Ce qui peut être fixé avec PATCH /v1/campaigns/{id}/optimization-config, en langage métier :

  • L'objectif : un ACOS ou un ROAS cible, ou un objectif de volume - impressions ou commandes - accompagné d'un plafond d'ACOS.
  • Les limites d'enchère : le plancher et le plafond qu'elle ne peut pas franchir, le plafond du multiplicateur de placement, et la dépense minimale avant de passer un target en négatif.
  • Le budget mensuel que poursuit l'optimiseur - pas le budget quotidien de la campagne sur Amazon, qui se change avec PATCH /v1/campaigns/{id} et qui est une donnée différente portant le même nom.
  • Les overrides de harvesting de la campagne : son niveau de découverte et si elle autorise le ciblage d'ASIN concurrents.
  • Quels workflows l'optimisent.

Ce dernier point est celui qui compte vraiment : assigner des workflows est ce qui place la campagne sous optimisation, aucun autre champ de ce bloc. linkedWorkflowDefinitionIds la force à entrer - le workflow la traite chaque nuit même si son propre filtre ne l'aurait pas choisie - et c'est la voie par laquelle un workflow déplace de vraies enchères sur Amazon ; confirmez-le avec la personne avant de l'écrire, exactement comme pour activer une automatisation. Un workflow à sélection automatique peut aussi la récupérer de lui-même, et workflowsOptOut: true décline cette sélection automatique. Seul excludedWorkflowDefinitionIds la retire avec certitude : il gagne toujours, quoi que dise le reste.

aiEnabled n'est pas l'interrupteur de l'optimiseur

C'est le consentement du titulaire du compte, et il part vers Amazon comme le tag epinium:ai_enabled. Le mettre à false ne retire pas la campagne de l'optimisation : c'est le rôle d'excludedWorkflowDefinitionIds, ou de la retirer de linkedWorkflowDefinitionIds.

optimizeDate et optimizingSince sont en lecture seule - c'est l'optimiseur lui-même qui les tamponne - et écrire l'un ou l'autre répond par un 400.

POST /v1/campaigns/optimization-config/batch applique le même patch à jusqu'à 1000 campagnes, et ce n'est pas tout-ou-rien : il répond une ligne par campagne, dans l'ordre d'envoi, et chacune est validée contre son propre état enregistré - un plafond obligatoire pour un objectif peut être facultatif pour un autre - donc une ligne peut échouer sans affecter les autres.

Deux codes à distinguer, comme pour l'écriture sur Amazon : un refus de validation - un objectif hors plage, un workflow qui n'est pas le vôtre - répond 200 avec result: "failed" et le motif dans reason. Une campagne qui n'existe pas ou qui appartient à un autre compte répond 404 sur le PATCH individuel ; dans le lot, en revanche, cette même campagne revient comme une ligne failed avec reason: "not_found", précisément pour qu'une ligne en échec ne fasse pas couler les 999 autres.

RouteCe qu'elle fait
PATCH /v1/campaigns/{id}/optimization-configChanger la configuration d'optimisation d'une campagne
POST /v1/campaigns/optimization-config/batchLa même configuration sur jusqu'à 1000 campagnes, une ligne par résultat

Écrire des tâches ​

Avec la permission tasks:write, l'API crée des tâches et décide de leurs suggestions, comme vous le faites dans Processus → Tâches. C'est la pièce qui permet à un assistant ou à une intégration de proposer des changements et à une personne de les examiner avant qu'ils n'arrivent sur Amazon.

Quatre choses à savoir avant le premier appel :

  • Approuver n'applique pas. Il y a deux étapes : approuver ou rejeter chaque suggestion, puis POST /v1/tasks/{id}/apply. À ce moment-là, les changements de campagne — budget quotidien, état et nom — partent vers Amazon immédiatement, et la réponse indique lesquels sont passés (applied) et lesquels ont été refusés (failed). Ceux de produit sont mis en file d'attente (enqueued) et appliqués en arrière-plan : pour savoir s'ils sont passés, relisez les suggestions et regardez appliedAt et applyError.
  • Une suggestion que rien ne sait appliquer est une note. Aujourd'hui, on applique les suggestions de produit et celles de campagne qui portent un fieldPath ; celles qui n'en ont pas, et celles d'ad groups, targets, product ads et termes de recherche, restent des notes. Les approuver garde une trace de la décision et ne change rien, et la réponse l'indique avec autoApplySkipped: true. Ce n'est pas une erreur. En revanche, à la création, une suggestion de campagne avec un champ autre que dailyBudget, state ou name, ou avec une valeur qui ne peut pas être appliquée, est refusée avec un 400 : l'enregistrer reviendrait à promettre un changement que personne ne fera.
  • Les suggestions viennent avec la tâche. Jusqu'à 50 dans items à la création, chacune pointant vers une entité de votre compte ; on ne peut pas en ajouter ensuite. Une entité qui n'existe pas ou qui appartient à un autre compte fait refuser la tâche entière, sans rien créer.
  • Résoudre une tâche est définitif. Ses suggestions en attente ne sont pas résolues avec elle : elles restent figées et ne peuvent plus être approuvées. Décidez d'abord celles qui vous importent et clôturez la tâche ensuite. La résoudre ne relance pas non plus de workflow.
RouteCe qu'elle fait
POST /v1/tasksCréer une tâche, avec ses suggestions
PATCH /v1/tasks/{id}Titre, description, priorité et date d'expiration
POST /v1/tasks/{id}/resolveLa résoudre ou l'écarter
PATCH /v1/task-items/{id} · POST /v1/task-items/batchApprouver ou rejeter des suggestions, éventuellement avec votre propre valeur dans appliedValue
POST /v1/tasks/{id}/applyAppliquer ce qui a été approuvé

Comme sur Amazon, toute écriture exige Idempotency-Key, et le lot de suggestions n'est pas tout-ou-rien : il répond une ligne par suggestion et applied compte celles qui ont été enregistrées. Créer, modifier ou résoudre une tâche coûte un montant fixe par appel ; approuver ou rejeter est facturé par suggestion enregistrée. Appliquer n'est pas facturé à part : chaque suggestion a déjà été facturée lors de son approbation.

Écrire des clusters de mots-clés ​

Avec la permission catalog:write, l'API crée et modifie vos clusters de mots-clés, les mêmes que vous gérez dans Segmentation → Clusters : un groupe de produits nommé, avec les mots-clés positifs sur lesquels ils devraient se positionner ou être annoncés et les mots-clés négatifs dont il faut s'éloigner. C'est le moyen pour un assistant qui a trouvé un trou de mots-clés de le laisser enregistré là où les prompts SEO d'Epinium, la découverte de mots-clés de l'optimiseur et le filtre par cluster des graphiques produit le reprendront.

Quatre choses à savoir avant votre premier appel :

  • Rien n'arrive sur Amazon. Un cluster vit dans Epinium. C'est pourquoi ces écritures ne laissent aucune ligne dans /v1/advertising-changes, et pourquoi votre client d'IA ne vous demandera pas de les confirmer.
  • On modifie par deltas, pas par remplacement. PATCH /v1/clusters/{id} accepte addPositiveKeywords, removePositiveKeywords, addNegativeKeywords, removeNegativeKeywords, addProducts, removeProducts et name ; n'envoyez que ce qui change. Ajouter un mot-clé déjà présent met à jour sa langue, son score et son usage, apparié par son texte ; retirer un mot-clé absent ne fait rien. Un cluster admet jusqu'à 100 mots-clés positifs et 50 négatifs, comptés après le changement, et un mot-clé ne peut pas être positif et négatif à la fois.
  • Les mots-clés suivent les règles de l'application. En minuscules, jusqu'à 80 caractères, le jeu de caractères d'Amazon, sans - ni . au début ni -, + ou . à la fin ; les doublons sont fusionnés. language est un code comme es-ES ou en-GB, epiniumScore va de 1 à 5 et purpose vaut SEO, PPC ou les deux (les deux par défaut).
  • Un cluster protégé est refusé avec 409. Protéger un cluster depuis l'application est la décision d'une personne, et cette API ne peut pas la défaire : déprotégez-le d'abord dans Segmentation → Clusters. Le champ protected de la réponse vous le dit avant d'essayer.
RouteCe qu'elle fait
POST /v1/clustersCréer un cluster, avec ses mots-clés et ses produits si vous les avez déjà
PATCH /v1/clusters/{id}Ajouter ou retirer des mots-clés et des produits, ou le renommer
DELETE /v1/clusters/{id}Le supprimer, sans retour possible

Chaque produit que vous liez doit appartenir à votre compte — pour une agence, aux connexions que le compte vous a partagées — et être un produit de catalogue (type seller ou vendor dans /v1/products ; les produits publicitaires sont refusés), sinon l'appel entier est refusé avec un 400 qui nomme les ids en trop, sans rien écrire. Le cluster appartient à la personne derrière l'identifiant, et apparaît donc dans le tableau de l'application à son nom. La suppression est définitive - il n'y a pas de corbeille - et elle est refusée avec un 409 tant que le cluster est protégé ou qu'une smart campaign l'utilise comme cluster de base ; l'erreur nomme ces smart campaigns, qu'il faut modifier ou supprimer d'abord. Chaque écriture coûte un montant fixe par appel, et le quota de clusters du plan s'applique ici comme dans l'application.

Limites ​

  • Les métriques exigent une plage de dates. start_date et end_date sont obligatoires sur toutes les ressources de métriques.
  • La plage a un maximum, et il dépend de la granularité. Avec granularity=daily, 93 jours ; avec total ou avec les périodes calendaires (weekly, monthly, quarterly, yearly), 366. Sur les targets et les termes de recherche, les ressources les plus lourdes, cela descend à 31 et 93. Demander davantage renvoie une erreur indiquant la limite exacte. Les deux dates sont incluses dans la plage.
  • Les listings se paginent de deux façons. Les ressources de catalogue et de structure utilisent un curseur (starting_after) ; celles de métriques utilisent limit et offset. Dans les deux cas, has_more indique s'il reste une page.
  • Il existe une limite de requêtes par token. Si vous la dépassez vous recevez un 429 et il suffit de réessayer plus lentement.
  • Il existe aussi une limite de requêtes simultanées. Un 429 peut signifier « trop à la fois », pas seulement « trop par minute » ; un 503 signifie que le serveur est momentanément saturé. Les deux comportent Retry-After et les deux sont transitoires : réessayez avec moins de requêtes en parallèle.
  • Une réponse ne peut pas étendre plus de 5 000 objets. expand sur des listes — les produits d'un cluster, les pays d'une connexion — se multiplie à chaque niveau. Au-delà, vous recevez un 400 indiquant combien d'objets auraient été renvoyés : baissez limit, retirez un expand, ou demandez ces données à leur propre endpoint.

Crédits ​

Les appels à cette API consomment des crédits de votre compte. Le coût de chaque ressource est visible dans l'application, sous Configuration → Crédits.

Chaque réponse vous indique ce que vous avez dépensé :

En-têteCe que c'est
X-Epinium-Credits-CostCe qu'a coûté cet appel
X-Epinium-Credits-RemainingCe qu'il vous reste. C'est approximatif : si d'autres traitements consomment en même temps, l'écart est possible
X-Epinium-Credits-BreakdownLe détail, par ressource et prix unitaire : product=100x1,country=100x0
X-Epinium-Credits-MaxLe maximum que l'appel pouvait coûter, calculé avant de l'exécuter

Trois choses à savoir :

  • Vous ne payez que ce qui est livré. Un appel qui échoue ne consomme rien, et un expand qui ne renvoie aucune donnée — parce que votre token n'a pas ce scope, ou que l'enregistrement appartient à un autre compte — non plus.
  • Dans les métriques, la plage de dates coûte aussi, pas seulement les lignes. Demander une année avec limit=1 n'est pas économique : en plus de chaque ligne renvoyée, vous payez chaque jour de la plage, car c'est ce qu'il faut lire pour répondre, avec un minimum de 3 jours par appel. Pour dépenser moins, raccourcissez la plage.
  • Pour un total, group_by plutôt que paginer. Un total de compte tient en peu de lignes (une par devise), alors que paginer le catalogue pour en faire la somme fait payer chaque produit à chaque page. Sur un compte réel, le total des ventes d'un mois coûte 157 crédits avec group_by=account et environ 17 600 en paginant.

Si vos crédits ne suffisent pas, vous recevez un 402 avant l'exécution de l'appel : vous ne vous retrouverez jamais avec une demi-réponse. Et il ne dit pas seulement non, il dit quoi changer et à quelle valeur :

json
{
  "error": {
    "type": "invalid_request_error",
    "code": "insufficient_credits",
    "message": "insufficient credits: needs up to 366 (campaignMetrics=1x1,campaignMetrics:window=365x1), 120 available. Shorten the date range to 119 days or less.",
    "param": "end_date"
  }
}

param est le même remède en version lisible par machine : limit, end_date ou include_total. S'il est absent, aucun paramètre ne permet de faire passer l'appel et il faut recharger.

Paramètres et réponses de chaque endpoint ​

Le tableau ci-dessus indique quelles ressources existent. Pour voir les paramètres d'entrée et la forme exacte de chaque réponse, il y a deux chemins :

  • Référence navigable — chaque endpoint avec ses paramètres, leurs types et un exemple de réponse. Générée depuis l'API elle-même, elle ne peut donc pas devenir obsolète. En anglais.
  • Schéma OpenAPI — le document OpenAPI 3.0 brut, à importer dans Postman, Insomnia ou un générateur de clients. Aucun token nécessaire.

Epinium Documentation