tva
← Insights

Google Ads API : Configuration, Authentification, Lecture et Écriture

Un guide technique pour la mise en place d'un accès programmatique à Google Ads — de l'architecture au premier appel API. Couvre la configuration MCC, OAuth 2.0, les niveaux de Developer Token, la bibliothèque Python google-ads, les requêtes de lecture GAQL et le pattern d'écriture validate_only.

Architecture

Trois entités distinctes sont nécessaires avant qu'un seul appel API ne fonctionne :

EntitéRôleExemple
**Compte Manager (MCC)**Émet le Developer Token`login_customer_id`
**Projet Google Cloud**Client OAuth 2.0 pour l'authentificationClient ID + Secret
**Compte Google Ads**Cible de toutes les opérations API`customer_id`

Il ne s'agit pas du même compte. Un MCC peut posséder un Developer Token sans posséder le compte cible — il doit seulement être lié en tant que manager. Le projet Google Cloud peut être sous une identité Google différente de celle du MCC. Le compte cible est le compte annonceur où résident les campagnes.

Cette séparation est importante car l'API Center (où les Developer Tokens sont provisionnés) n'est disponible qu'à l'intérieur des comptes Manager. Un compte Google Ads autonome ne peut pas accéder à l'API Center, même s'il dispose d'utilisateurs administratifs.

L'en-tête d'appel API assemble ces trois identités plus un token Bearer OAuth :

developer-token: <from MCC API Center>
login-customer-id: <MCC numeric ID, no dashes>
customer-id: <target account numeric ID>
Authorization: Bearer <OAuth 2.0 access token>

Prérequis

  • Un compte Google Ads Manager avec une configuration complète
  • Le compte publicitaire cible lié au compte Manager et le lien accepté
  • Un projet Google Cloud avec l'API Google Ads activée
  • Python 3.9+ avec la bibliothèque google-ads (pip install google-ads)
  • Un navigateur pour le flux de consentement OAuth unique

Étape 1 : Compte Manager et Developer Token

L'API Center se trouve sous Outils et paramètres → Configuration → Centre API dans un compte Manager. Si l'API Center est absent, le compte n'est soit pas un compte Manager, soit sa configuration est incomplète.

Depuis l'API Center, demandez un Developer Token. Définissez le type de compte sur Annonceur (et non Agence ou Tierce Partie) lorsque le token est destiné à vos propres comptes. Le token est émis immédiatement au niveau Accès Test.

L'accès Test permet :

  • Les opérations de lecture sur tout compte lié
  • Les opérations d'écriture sur les comptes de test uniquement
  • Aucune opération d'écriture sur les comptes de production
  • L'erreur pour les écritures sur des comptes de production avec l'accès Test est RESOURCE_NOT_FOUND — et non PERMISSION_DENIED. Ceci prête à confusion car la ressource existe bel et bien et est accessible en lecture. L'erreur signifie que l'API refuse d'acheminer la mutation sous le niveau d'accès actuel.

    Demande d'Accès de Base

    Pour écrire sur des comptes de production, faites une demande d'Accès de Base depuis la même page de l'API Center. Le formulaire de demande comporte 12 questions. Pour un usage interne sur vos propres comptes, les réponses pertinentes sont :

    QuestionRéponse
    Q4 : Relation avec un représentant GoogleNon
    Q6 : Modèle économiqueDécrivez votre propre cas d'usage (e-commerce, génération de leads, reporting interne)
    Q8 : Qui aura accèsUtilisateurs internes — employés uniquement
    Q9 : Outil développé par un tiersNon (scripts/agents propres)
    Q10 : API Conversion Tracking et RemarketingNon (sauf si vous l'utilisez réellement)
    Q11 : Types de campagnesSearch, Performance Max, Shopping (selon le cas)
    Q12 : CapacitésCréation de campagnes, Gestion de campagnes, Reporting

    Un document de conception (PDF) est requis pour la Q7. Il doit décrire l'architecture de l'API, le flux d'authentification, la stratégie de limitation de débit, la gestion des erreurs et le cas d'usage exclusivement interne. Restez factuel — l'équipe de conformité vérifie la cohérence avec le cas d'usage déclaré.

    Délai de traitement en juin 2026 : environ 3 jours ouvrés, avec une note concernant un volume de demandes plus élevé que d'habitude.

    Étape 2 : OAuth 2.0

    Configuration du Projet Google Cloud

    Dans la console Google Cloud, sous le projet concerné :

    1. Activez l'API Google Ads (API et services → Bibliothèque)
    2. Configurez l'écran de consentement OAuth :
  • Type d'utilisateur : Interne (seuls les utilisateurs de votre Google Workspace peuvent autoriser — évite la vérification d'application externe)
  • Nom de l'application, email d'assistance, email de contact du développeur
  • Ajoutez le scope sous Accès aux données : https://www.googleapis.com/auth/adwords
  • Créez un ID client OAuth :
  • Type d'application : Application de bureau
  • Téléchargez le fichier JSON du secret client
  • Le type Application de bureau utilise http://localhost comme URI de redirection. C'est correct — le flux OAuth ouvre un navigateur, Google redirige vers localhost avec le code d'autorisation, et un serveur HTTP local le capture.

    Génération du Refresh Token

    Un script Python qui exécute un serveur HTTP local sur 127.0.0.1:0 (port aléatoire), affiche l'URL d'autorisation, attend une requête, extrait le paramètre code et l'échange contre des tokens :

    from pathlib import Path
    from http.server import HTTPServer, BaseHTTPRequestHandler
    from urllib.parse import urlparse, parse_qs
    from google_auth_oauthlib.flow import Flow
    
    class CallbackHandler(BaseHTTPRequestHandler):
        code_value = None
        def do_GET(self):
            qs = parse_qs(urlparse(self.path).query)
            CallbackHandler.code_value = (qs.get('code') or [None])[0]
            self.send_response(200)
            self.end_headers()
            self.wfile.write(b'OAuth complete.')
        def log_message(self, format, *args):
            return
    
    server = HTTPServer(('127.0.0.1', 0), CallbackHandler)
    redirect_uri = f'http://127.0.0.1:{server.server_port}/'
    flow = Flow.from_client_secrets_file(
        'client_secret.json',
        scopes=['https://www.googleapis.com/auth/adwords'],
        redirect_uri=redirect_uri
    )
    auth_url, _ = flow.authorization_url(
        access_type='offline',
        prompt='consent'
    )
    print(auth_url)
    server.handle_request()
    flow.fetch_token(code=CallbackHandler.code_value)
    Path('google_ads_token.json').write_text(flow.credentials.to_json())

    Deux paramètres sont importants :

  • access_type='offline' — renvoie un refresh token, pas seulement un access token
  • prompt='consent' — force un nouvel écran de consentement même si l'utilisateur a déjà autorisé ; nécessaire pour obtenir un nouveau refresh token si les scopes ont changé
  • Le refresh token est permanent sauf s'il est révoqué, si l'utilisateur change son mot de passe, ou si le token reste inutilisé pendant 6 mois.

    Piège des Scopes avec des Clients Existants

    Si le client OAuth a été précédemment autorisé pour d'autres scopes (Gmail, Drive, Calendar), Google renvoie l'union des anciens et des nouveaux scopes. La bibliothèque google-auth-oauthlib rejette cette divergence de scopes par défaut. Définissez la variable d'environnement avant de charger le flux :

    import os
    os.environ['OAUTHLIB_RELAX_TOKEN_SCOPE'] = '1'

    Alternativement, omettez include_granted_scopes=true de l'URL d'autorisation, ce qui indique à Google de ne demander que le scope explicitement passé.

    Étape 3 : `google-ads.yaml`

    La bibliothèque lit la configuration depuis un fichier YAML :

    developer_token: <value>
    client_id: <value>
    client_secret: <value>
    refresh_token: <value>
    login_customer_id: 1911599764
    use_proto_plus: true

    Règles de sécurité :

  • Permissions du fichier : 0600 (lecture/écriture propriétaire uniquement)
  • Ne jamais versionner dans un dépôt Git
  • Stocker en dehors de tout dépôt Git
  • Pour les configurations d'équipe, distribuer via un gestionnaire de secrets, pas un fichier partagé
  • login_customer_id est l'identifiant numérique du MCC sans tirets. Il indique à l'API quel Developer Token du compte manager utiliser. Le customer_id cible est passé au moment de l'appel, pas dans la configuration.

    use_proto_plus: true active l'interface protobuf-plus, qui est requise pour les versions actuelles de l'API.

    Étape 4 : Initialisation du Client Python

    from google.ads.googleads.client import GoogleAdsClient
    
    client = GoogleAdsClient.load_from_storage(
        '/path/to/google-ads.yaml',
        version='v22'
    )
    gs = client.get_service('GoogleAdsService')

    Le paramètre version sélectionne explicitement la version de l'API. La bibliothèque google-ads est livrée avec plusieurs versions installées en parallèle (v19 à v22 en juin 2026). Spécifiez toujours la version — la valeur par défaut peut être en retard ou ne pas prendre en charge les champs plus récents.

    Vérifiez la connectivité :

    cs = client.get_service('CustomerService')
    customers = cs.list_accessible_customers()
    ids = [r.split('/')[-1] for r in customers.resource_names]
    # Example output: ['1305475941', '3977581086', '1911599764']

    Étape 5 : Opérations de Lecture (GAQL)

    Google Ads utilise GAQL (Google Ads Query Language), un langage de type SQL. Toutes les opérations de lecture passent par GoogleAdsService.search_stream(), qui évite la pagination et est préféré à search() pour la plupart des requêtes.

    Campagnes avec Métriques de Performance

    SELECT
      campaign.id,
      campaign.name,
      campaign.status,
      campaign.advertising_channel_type,
      campaign.serving_status,
      campaign.bidding_strategy_type,
      metrics.impressions,
      metrics.clicks,
      metrics.cost_micros,
      metrics.conversions,
      metrics.conversions_value,
      metrics.ctr,
      metrics.average_cpc
    FROM campaign
    ORDER BY campaign.id

    Budgets de Campagne

    SELECT
      campaign_budget.id,
      campaign_budget.name,
      campaign_budget.amount_micros,
      campaign_budget.delivery_method,
      campaign_budget.status,
      campaign.id,
      campaign.name
    FROM campaign_budget

    Groupes d'Annonces

    SELECT
      ad_group.id,
      ad_group.name,
      ad_group.status,
      ad_group.cpc_bid_micros,
      campaign.id,
      campaign.name
    FROM ad_group
    ORDER BY campaign.id, ad_group.id

    Mots-clés (par Impressions)

    SELECT
      ad_group_criterion.keyword.text,
      ad_group_criterion.keyword.match_type,
      ad_group_criterion.status,
      ad_group_criterion.criterion_id,
      ad_group.id,
      ad_group.name,
      campaign.id,
      campaign.name,
      metrics.impressions,
      metrics.clicks,
      metrics.cost_micros,
      metrics.conversions
    FROM keyword_view
    WHERE ad_group_criterion.type = 'KEYWORD'
    ORDER BY metrics.impressions DESC
    LIMIT 100

    Annonces avec Statut des Règles

    SELECT
      ad_group_ad.ad.id,
      ad_group_ad.ad.name,
      ad_group_ad.ad.type,
      ad_group_ad.status,
      ad_group_ad.policy_summary.approval_status,
      ad_group.id,
      ad_group.name,
      campaign.id,
      campaign.name
    FROM ad_group_ad

    Actions de Conversion

    SELECT
      conversion_action.id,
      conversion_action.name,
      conversion_action.status,
      conversion_action.type,
      conversion_action.category,
      conversion_action.include_in_conversions_metric,
      conversion_action.counting_type
    FROM conversion_action

    Pattern d'Exécution Python

    def gaql_query(client, customer_id, query):
        gs = client.get_service('GoogleAdsService')
        results = []
        for batch in gs.search_stream(customer_id=customer_id, query=query):
            for row in batch.results:
                results.append(row)
        return results

    Étape 6 : Opérations d'Écriture avec `validate_only`

    L'API v22 nécessite des objets de requête, pas des arguments nommés. Chaque service de mutation (CampaignService, AdGroupService, AdGroupCriterionService, CampaignBudgetService) suit le même pattern :

    from google.protobuf import field_mask_pb2
    
    req = client.get_type('MutateCampaignsRequest')
    req.customer_id = '1305475941'
    req.validate_only = True
    op = client.get_type('CampaignOperation')
    op.create.name = 'Campaign Name'
    op.create.status = client.enums.CampaignStatusEnum.PAUSED
    op.create.advertising_channel_type = client.enums.AdvertisingChannelTypeEnum.SEARCH
    op.create.campaign_budget = 'customers/1305475941/campaignBudgets/123456789'
    op.create.manual_cpc.enhanced_cpc_enabled = False
    req.operations.append(op)  # .append(), not .add()
    client.get_service('CampaignService').mutate_campaigns(request=req)

    Différences clés par rapport aux versions antérieures de l'API :

  • validate_only est un champ de l'objet requête, pas un argument nommé de la méthode mutate
  • Les opérations sont ajoutées via req.operations.append(op), et non req.operations.add(op)
  • Les chemins de ressources sont des chaînes explicites ('customers/1305475941/campaigns/22479990461'), pas des valeurs de retour de méthodes helper
  • Porte de Mutation en Trois Phases

    Pour la sécurité en production, les mutations passent par trois portes :

    Porte 1 — validate_only=True : L'API valide la structure de la requête, les champs obligatoires et les références de ressources. Aucun objet n'est créé. Exécutez ceci en premier pour chaque mutation.

    Porte 2 — Création en Pause : Passez validate_only=False et créez l'objet avec status=PAUSED. Vérifiez le résultat avec une requête de lecture avant de continuer.

    Porte 3 — Activation en Production : Un appel API séparé qui met à jour uniquement le champ status à ENABLED. Cela doit nécessiter une approbation explicite et ne pas être intégré dans la création.

    # Gate 3: enable a previously created paused campaign
    req = client.get_type('MutateCampaignsRequest')
    req.customer_id = '1305475941'
    req.validate_only = False
    op = client.get_type('CampaignOperation')
    op.update.resource_name = 'customers/1305475941/campaigns/22479990461'
    op.update.status = client.enums.CampaignStatusEnum.ENABLED
    op.update_mask.CopyFrom(field_mask_pb2.FieldMask(paths=['status']))
    req.operations.append(op)
    client.get_service('CampaignService').mutate_campaigns(request=req)

    Mise à Jour de Budget

    req = client.get_type('MutateCampaignBudgetsRequest')
    req.customer_id = '1305475941'
    req.validate_only = True
    op = client.get_type('CampaignBudgetOperation')
    op.update.resource_name = 'customers/1305475941/campaignBudgets/123456789'
    op.update.amount_micros = 1_000_000  # $1.00 per day
    op.update_mask.CopyFrom(field_mask_pb2.FieldMask(paths=['amount_micros']))
    req.operations.append(op)
    client.get_service('CampaignBudgetService').mutate_campaign_budgets(request=req)

    Mise à Jour d'Enchère de Groupe d'Annonces

    req = client.get_type('MutateAdGroupsRequest')
    req.customer_id = '1305475941'
    req.validate_only = True
    op = client.get_type('AdGroupOperation')
    op.update.resource_name = 'customers/1305475941/adGroups/165827073530'
    op.update.cpc_bid_micros = 250_000  # $0.25
    op.update_mask.CopyFrom(field_mask_pb2.FieldMask(paths=['cpc_bid_micros']))
    req.operations.append(op)
    client.get_service('AdGroupService').mutate_ad_groups(request=req)

    Création de Mot-clé

    req = client.get_type('MutateAdGroupCriteriaRequest')
    req.customer_id = '1305475941'
    req.validate_only = True
    op = client.get_type('AdGroupCriterionOperation')
    op.create.ad_group = 'customers/1305475941/adGroups/165827073530'
    op.create.status = client.enums.AdGroupCriterionStatusEnum.PAUSED
    op.create.keyword.text = 'example keyword'
    op.create.keyword.match_type = client.enums.KeywordMatchTypeEnum.EXACT
    req.operations.append(op)
    client.get_service('AdGroupCriterionService').mutate_ad_group_criteria(request=req)

    Gestion des Erreurs

    from google.ads.googleads.errors import GoogleAdsException
    
    try:
        response = service.mutate_campaigns(request=req)
    except GoogleAdsException as ex:
        for error in ex.failure.errors:
            print(f'{error.error_code}: {error.message}')

    Codes d'erreur courants et leur signification :

    Code d'erreurCause
    `RESOURCE_NOT_FOUND`Token d'accès Test sur un compte de production (attendu) ou ressource véritablement manquante
    `REQUIRED`Champ obligatoire manquant (ex. stratégie d'enchère à la création de campagne)
    `UNRECOGNIZED_FIELD`Champ d'une version d'API différente ou nom de champ incorrect
    `INVALID_ARGUMENT`La valeur du champ échoue la validation (ex. budget négatif)
    `PERMISSION_DENIED`L'utilisateur OAuth n'a pas accès au compte cible

    Niveaux d'Accès à l'API

    L'accès à l'API Google Ads est par paliers, pas binaire :

    NiveauProvisionnementLecture (Production)Écriture (Production)Écriture (Comptes Test)Limite d'opérations quotidiennes
    **Accès Test**Immédiat depuis l'API Center du MCC15 000
    **Accès de Base**Demande + examen de conformité15 000
    **Accès Standard**Seuil de dépenses + examenIllimité

    L'accès Test est suffisant pour le développement : authentification, requêtes GAQL, tests validate_only et lecture/écriture complète sur les comptes de test Google Ads. Le passage à l'Accès de Base est conditionné par un examen de conformité, pas par les dépenses.

    L'Accès Standard supprime le plafond d'opérations quotidiennes. Il nécessite soit un historique de dépenses gérées via le token, soit une demande séparée.

    Comptes de Test

    Les comptes de test sont des comptes Google Ads gratuits sans facturation. Ils acceptent toute mutation. Pour en créer un : dans le MCC, allez dans Comptes → + → Créer un compte → Compte de test. Liez-le au MCC et utilisez-le comme customer_id cible pendant le développement avec l'Accès Test.

    `validate_only` selon les Niveaux d'Accès

    validate_only=True fonctionne à tous les niveaux d'accès, mais l'Accès Test rejette tout de même les mutations validate_only sur les comptes de production avec RESOURCE_NOT_FOUND. Ce n'est pas une limitation de validate_only — c'est le même contrôle d'accès appliqué à toutes les opérations d'écriture, indépendamment du drapeau validate_only.

    Suivi des Conversions : Lecture API vs. Statut Fonctionnel

    L'interface Google Ads peut afficher « Configurer le suivi des conversions » comme recommandation même lorsqu'une action de conversion existe et est activée. L'API peut confirmer l'existence d'une action de conversion (type WEBPAGE, catégorie PURCHASE, statut ENABLED, include_in_conversions_metric: true), mais cela prouve seulement que l'objet d'action existe. Cela ne prouve pas que le site web émet l'événement AW-.../label correspondant, que le tag Google est chargé, ou qu'un signal de conversion a été reçu.

    Lors de l'audit du suivi des conversions, séparez la vérification API (métadonnées de l'action de conversion) de la vérification navigateur (onglet réseau, chargement du tag, déclenchement d'événement). L'API est la source de vérité pour la configuration ; le navigateur est la source de vérité pour l'exécution.

    Le pattern d'attribution de revenus côté serveur s'applique ici : si les événements de conversion côté client ne sont pas fiables, prévoyez des téléchargements de conversion côté serveur ou hors ligne via le ConversionUploadService de l'API Google Ads comme solution de secours.

    Gestion des Versions de l'API

    La bibliothèque Python google-ads est livrée avec plusieurs versions de l'API. En juin 2026, les versions v19 à v22 sont disponibles. Chaque version ajoute, déprécie ou supprime des champs GAQL et des méthodes de service.

    Règles pour la sélection de version :

  • Spécifiez la version explicitement dans load_from_storage(version='v22'). La valeur par défaut peut être obsolète.
  • Consultez les notes de version de l'API Google Ads pour les dépréciations de champs avant de mettre à niveau.
  • La méthode search_stream est disponible à partir de la v6+ et constitue le chemin de lecture recommandé.
  • Protobuf-plus (use_proto_plus: true) est requis pour la v12+.
  • Le pattern d'objet requête pour les mutations (mutate_campaigns(request=req)) a remplacé le style d'arguments nommés dans la v17+.
  • Sécurité Locale

    Tous les fichiers de credentials doivent rester en dehors du contrôle de version :

    ~/.hermes/
      google-ads.yaml          # 0600 — dev token, OAuth client, refresh token
      google_ads_token.json    # 0600 — OAuth tokens, adwords scope
      google_client_secret.json # 0600 — OAuth client ID + secret

    Pour le dépôt de travail, ajoutez un .gitignore :

    google-ads.yaml
    *_token*.json
    *_secret*.json

    Un fichier template avec des valeurs placeholder peut être versionné pour documenter la structure attendue :

    # google-ads.yaml.template — commit this, fill locally
    developer_token: INSERT_DEV_TOKEN
    client_id: INSERT_CLIENT_ID
    client_secret: INSERT_CLIENT_SECRET
    refresh_token: INSERT_REFRESH_TOKEN
    login_customer_id: INSERT_MCC_ID
    use_proto_plus: true

    Champs Requis pour les Opérations Courantes

    OpérationChamps Requis
    Créer une Campagne (Search)`name`, `status`, `advertising_channel_type`, `campaign_budget`, `manual_cpc` ou stratégie d'enchère
    Créer un Groupe d'Annonces (Search)`name`, `status`, `type_`, `cpc_bid_micros`, `campaign`
    Créer un Mot-clé`ad_group`, `status`, `keyword.text`, `keyword.match_type`
    Mettre à jour le Statut d'une Campagne`resource_name`, `status`, `update_mask` (paths: `['status']`)
    Mettre à jour un Budget`resource_name`, `amount_micros`, `update_mask` (paths: `['amount_micros']`)

    L'absence d'un champ requis renvoie REQUIRED avec le nom du champ. L'absence de update_mask sur une opération de mise à jour est silencieusement ignorée — le champ n'est pas mis à jour et aucune erreur n'est retournée.

    Script de Test Complet

    Un script unique qui lit tous les types d'entités et exécute des tests d'écriture validate_only :

    # google_ads_api_test.py — read all entities + validate_only write tests
    import warnings
    warnings.filterwarnings('ignore')
    from google.ads.googleads.client import GoogleAdsClient
    from google.ads.googleads.errors import GoogleAdsException
    from google.protobuf import field_mask_pb2
    
    CFG = '/path/to/google-ads.yaml'
    CID = '1305475941'
    c = GoogleAdsClient.load_from_storage(CFG, version='v22')
    gs = c.get_service('GoogleAdsService')
    
    def gaql(query, label):
        print(f'\n=== {label} ===')
        n = 0
        for batch in gs.search_stream(customer_id=CID, query=query):
            for row in batch.results:
                n += 1
        print(f'{n} rows')
    
    # Read all entities
    gaql("SELECT customer.id, customer.descriptive_name FROM customer WHERE customer.id = ...", "CUSTOMER")
    gaql("SELECT campaign.id, campaign.name, campaign.status, ...  FROM campaign", "CAMPAIGNS")
    gaql("SELECT campaign_budget.id, campaign_budget.name, ...  FROM campaign_budget", "BUDGETS")
    gaql("SELECT ad_group.id, ad_group.name, ...  FROM ad_group", "AD GROUPS")
    gaql("SELECT ad_group_criterion.keyword.text, ...  FROM keyword_view WHERE ...", "KEYWORDS")
    gaql("SELECT ad_group_ad.ad.id, ...  FROM ad_group_ad", "ADS")
    gaql("SELECT conversion_action.id, ...  FROM conversion_action", "CONVERSIONS")
    
    # Write tests
    def test_write(name, fn):
        print(f'\n--- {name} ---')
        try:
            fn()
            print('PASS')
        except GoogleAdsException as e:
            for err in e.failure.errors:
                print(f'{err.error_code}: {err.message}')
    
    def test_create_campaign():
        req = c.get_type('MutateCampaignsRequest')
        req.customer_id = CID
        req.validate_only = True
        op = c.get_type('CampaignOperation')
        op.create.name = 'TEST_CAMPAIGN'
        op.create.status = c.enums.CampaignStatusEnum.PAUSED
        op.create.advertising_channel_type = c.enums.AdvertisingChannelTypeEnum.SEARCH
        op.create.campaign_budget = f'customers/{CID}/campaignBudgets/123456789'
        op.create.manual_cpc.enhanced_cpc_enabled = False
        req.operations.append(op)
        c.get_service('CampaignService').mutate_campaigns(request=req)
    
    test_write('Create Campaign (validate_only)', test_create_campaign)
    print('\nDone.')

    Version exécutable complète dans la compétence d'opérations Google Ads API du dépôt d'opérations publicitaires.

    Références

  • Documentation de l'API Google Ads
  • Bibliothèque Python google-ads
  • Référence GAQL
  • OAuth 2.0 pour Applications de Bureau
  • Construire un Assistant IA Spécifique à un Projet via Telegram — même pattern OAuth appliqué à un scope Google différent
  • Architecture de Référence pour une Couche d'Opérations IA Basée sur les Fils — le modèle opérationnel dans lequel l'automatisation API s'intègre
  • Opérations Solo à l'Échelle : Gérer des Douzaines de Projets avec une Petite Équipe — pourquoi l'automatisation API remplace le travail manuel dans l'interface à l'échelle
  • Articles connexes