Opérations en masse sur les campagnes, groupes d'annonces et annonces (Bulk API)
Idée centrale
Le Bulk API est un point de terminaison asynchrone qui permet de créer ou mettre à jour, en une seule requête, jusqu'à 1 000 opérations portant sur des campagnes, groupes d'annonces et annonces. Un job soumis se suit et se récupère par identifiant, avec inspection du résultat de chaque opération individuelle. Le Bulk API est en « limited preview » et activé par compte publicitaire ; il n'est pas inclus dans la spécification OpenAPI téléchargeable.
Définition
Le point de terminaison POST /bulk_mutation_jobs de l'API Ads (et ses endpoints de suivi associés), qui permet des mutations en masse sur la hiérarchie campagne → groupe d'annonces → annonce, en s'appuyant sur des références internes au job (via des clés d'idempotence) plutôt que sur des identifiants réels connus à l'avance.
Contexte
Documente un mécanisme opérationnel autonome, compréhensible et utilisable sans avoir lu le détail complet des pages de référence classiques (Campagnes et annonces dans l'API Ads), bien que les types d'opérations reprennent directement les entités et une partie des champs documentés par ces pages. Si un endpoint bulk renvoie 404, il faut contacter l'équipe de compte OpenAI pour confirmer l'accès associé à la clé API utilisée. Capturée le 2026-08-08.
Fonctionnement
Soumission d'un job — POST /bulk_mutation_jobs
Authentification par Authorization: Bearer $OPENAI_ADS_API_KEY (voir Authentification, compte publicitaire et fichiers dans l'API Ads) ; chaque clé est propre à un compte publicitaire, sans en-tête OpenAI-Ad-Account supplémentaire. Un en-tête optionnel Idempotency-Key sécurise les nouvelles tentatives : le réutiliser avec un corps différent renvoie une erreur ; pour rejouer un job failed ou partially_failed, soumettre le même corps avec une nouvelle clé d'idempotence au niveau requête (les créations déjà réussies sont réutilisées).
La réponse à la soumission est 202 Accepted avec un objet job : id (préfixe blkmtnjob_), status (pending au départ), operation_count, created_at, completed_at (null tant que non terminé).
| Champ | Type | Requis | Description |
|---|---|---|---|
operations | object[] | Oui | Entre 1 et 1 000 opérations de création ou mise à jour. |
validate_only | boolean | Non | Valide champs et dépendances sans modifier les ressources si true. Défaut false. |
partial_failure | boolean | Non | Poursuit les opérations indépendantes après une erreur si true. Défaut true. |
Mettre partial_failure à false interrompt les opérations suivantes après un échec (n'annule pas les opérations déjà effectuées). Un job en validate_only ne garantit pas la réussite finale : il ne vérifie ni l'existence des cibles de mise à jour, ni la récupération des images, ni les limites d'entités, ni les autres erreurs qui ne surviennent qu'à l'écriture.
Opérations prises en charge
Chaque entrée de operations inclut un operation_id unique, un type, et un objet input. Les créations exigent une idempotency_key unique ; les mises à jour exigent target_resource_id et au moins un champ d'entrée.
| Type | Entrée requise | Autres entrées prises en charge |
|---|---|---|
campaign.create | name, max_budget_micros | billing_event_type, budget_type, status, target_countries, location_ids |
campaign.update | Au moins un champ pris en charge | name, description, status, max_budget_micros, budget_type, start_time, end_time, location_ids |
ad_group.create | campaign_idempotency_key, name | context_hints, exclusion_hints, max_bid_micros, max_cpm_bid_micros, status |
ad_group.update | Au moins un champ pris en charge | name, description, status, context_hints, exclusion_hints, max_bid_micros, max_cpm_bid_micros |
ad.create | campaign_idempotency_key, ad_group_idempotency_key, title, body, target_url, source_image_url | status |
ad.update | Au moins un champ pris en charge | name, status, creative |
Références internes au job : campaign_idempotency_key pointe vers l'idempotency_key de l'opération de campagne, ad_group_idempotency_key vers celle du groupe d'annonces — cela évite d'avoir à connaître à l'avance les identifiants réels des ressources parentes. La référence de campagne sur ad.create doit correspondre au ad_group.create parent. Une mise à jour ne peut cibler qu'une ressource qui existait déjà au moment de la soumission : impossible de mettre à jour une ressource créée dans le même job. Chaque ressource ne doit être mise à jour qu'une seule fois par job.
Statuts de création : active ou paused ; les mises à jour prennent en charge en plus archived. campaign.create a par défaut une facturation à l'impression, un budget lifetime, un statut paused, budget minimum 1000000 micro-unités. Les enchères de groupe d'annonces doivent correspondre à l'événement de facturation de la campagne parente : fournir soit max_bid_micros (clics) soit max_cpm_bid_micros (impressions, nécessite un accès de compte spécifique), pas les deux.
Contraintes de longueur : noms de campagne/groupe entre 3 et 1 000 caractères ; titres d'annonce entre 3 et 50 caractères ; corps d'annonce jusqu'à 100 caractères ; URLs jusqu'à 2 048 caractères. Une campagne accepte jusqu'à 2 500 identifiants de localisation (voir Ciblage géographique des campagnes dans l'API Ads (Campaign Targeting) pour location_ids) ; un groupe d'annonces jusqu'à 2 000 « context hints ». Pour mettre à jour une création publicitaire (creative), inclure title, body, target_url et file_id.
Récupération d'un job — GET /bulk_mutation_jobs/{job_id}
| Statut | Signification |
|---|---|
pending | Le job attend d'être exécuté. |
in_progress | Le job traite les opérations. |
completed | Toutes les opérations ont réussi. |
partially_failed | Au moins une opération réussie, une autre failed ou skipped. |
failed | Aucune opération n'a réussi. |
completed, partially_failed et failed sont des statuts terminaux.
Liste des résultats d'opérations — GET /bulk_mutation_jobs/{job_id}/operations
Paramètre limit entre 1 et 100 (défaut 100). Réponse object: "list", data[] (chaque élément portant operation_id, type, status, resource_id, submitted_version_id, error_code, error, retryable, retry_after_seconds), has_more, complete, error (au niveau job). Utiliser has_more et le dernier operation_id pour paginer avec after. Les curseurs de pagination ne sont disponibles qu'une fois complete: true ; tant que le job tourne, l'endpoint peut renvoyer un instantané incomplet des résultats déjà collectés. submitted_version_id est null pour les créations de campagne et de groupe d'annonces.
| Statut d'opération | Signification |
|---|---|
created | Création réussie. |
updated | Mise à jour réussie. |
validated | Validation passée, en mode validation seule. |
failed | Erreur ; utiliser les champs de nouvelle tentative. |
skipped | Non exécutée car une dépendance ou opération antérieure a échoué. |
Limites par défaut
| Limite | Valeur |
|---|---|
| Opérations par job | 1 000 |
| Taille du corps de requête | 16 MiB |
| Taille sérialisée d'une opération | 512 KiB |
| Requêtes de création par compte publicitaire | 10 requêtes par 10 secondes |
| Résultats d'opération par page | 100 |
| Campagnes self-serve par compte publicitaire | 5 000 campagnes non archivées |
| Groupes d'annonces self-serve par compte publicitaire | 5 000 groupes non archivés |
| Annonces self-serve par compte publicitaire | 5 000 annonces actives ou en pause |
operation_id et idempotency_key (au niveau opération de création) doivent être uniques au sein d'un job, jusqu'à 255 caractères chacune. Si retryable: true, attendre retry_after_seconds (si fourni) avant de resoumettre le même corps dans un nouveau job, en réutilisant les idempotency_key de création d'origine.
Éléments essentiels
- Un job ne peut jamais mettre à jour une ressource qu'il vient lui-même de créer : toute modification d'une ressource fraîchement créée attend un job ultérieur.
- Statut d'accès « limited preview, enabled per ad account » et absence de la spec OpenAPI : à vérifier au cas par cas plutôt que supposer disponible pour tout compte.
Distinctions importantes
Ne pas confondre operation_id (identifiant unique de l'opération dans le job, fourni par l'appelant) et idempotency_key (identifiant de création, réutilisé pour les références internes au job et les nouvelles tentatives).
Ne pas confondre max_bid_micros (enchère au clic) et max_cpm_bid_micros (enchère à l'impression, accès de compte spécifique requis) : un groupe d'annonces fournit l'un ou l'autre, jamais les deux, selon l'événement de facturation de la campagne parente.
Cas pratiques
Aucun cas pratique disponible : les identifiants et limites (5 000 campagnes, 1 000 opérations) sont des valeurs documentées par la source, pas des retours d'usage réel.
Erreurs fréquentes
Ne pas tenter de mettre à jour, dans le même job, une ressource créée par une opération précédente du même job : ce n'est pas pris en charge, il faut un job ultérieur.
Ne pas fournir à la fois max_bid_micros et max_cpm_bid_micros sur un même groupe d'annonces.
Ne pas ignorer has_more/complete lors de la lecture des résultats d'opérations : tant que complete n'est pas true, la pagination par curseur n'est pas fiable.
Limites et nuances
- Source unique, page de documentation développeur officielle récupérée par le web (dérogation ponctuelle autorisée), sans SHA-256 de fichier local.
- Note de fidélité de récupération : une première tentative de récupération avait produit un résumé condensé ; seule une seconde tentative, plus complète, a été retenue comme base de cette page.
- Format et valeurs possibles de
error_codedans les résultats d'opération en échec non détaillés par cette source. - La page de référence « Ad Groups » est absente du lot de sources traité : le détail complet des champs
context_hints,location_ids, et de la structure decreativepourad.updaten'est illustré que par cette page, pas par une spécification exhaustive de la ressource groupe d'annonces.
Relations
- Campagnes et annonces dans l'API Ads — les types d'opérations reprennent les entités et champs de cette référence.
- Ciblage géographique des campagnes dans l'API Ads (Campaign Targeting) — format des identifiants utilisés dans
location_ids. - Authentification, compte publicitaire et fichiers dans l'API Ads — authentification commune.
- Lancement d'une campagne dans Ads Manager — mécanisme d'import en masse équivalent côté interface Ads Manager (schéma CSV), à distinguer de ce mécanisme API par job asynchrone.
Points à vérifier
- Format et valeurs possibles de
error_codepour les opérations en échec. - Contenu de la page de référence « Ad Groups », absente de ce lot de sources.
- Cohérence des noms d'entités et de champs avec les pages
api-reference/*correspondantes une fois toutes cartographiées.
Sources
SRC-2026-036— « Bulk API »,developers.openai.com/ads/bulk-api, capturée le 2026-08-08.