tva
← Insights

Google Ads API: Configuración, Autenticación, Operaciones de Lectura y Escritura

Una guía técnica para configurar el acceso programático a Google Ads — desde la arquitectura hasta la primera llamada a la API. Cubre la configuración del MCC, OAuth 2.0, niveles del Developer Token, la librería Python google-ads, consultas GAQL de lectura y el patrón de escritura validate_only.

Arquitectura

Se requieren tres entidades separadas antes de que una sola llamada a la API funcione:

EntidadPropósitoEjemplo
**Cuenta de Gestor (MCC)**Emite el Developer Token`login_customer_id`
**Proyecto de Google Cloud**Cliente OAuth 2.0 para autenticaciónClient ID + Secret
**Cuenta de Google Ads**Destino de todas las operaciones de la API`customer_id`

No son la misma cuenta. Un MCC puede poseer un Developer Token sin ser propietario de la cuenta destino — solo necesita estar vinculado como gestor. El proyecto de Google Cloud puede estar bajo una identidad de Google diferente a la del MCC. La cuenta destino es la cuenta de anunciante donde residen las campañas.

Esta separación es importante porque API Center (donde se aprovisionan los Developer Tokens) solo está disponible dentro de Cuentas de Gestor. Una cuenta de Google Ads independiente no puede acceder a API Center, incluso si tiene usuarios administrativos.

La cabecera de la llamada a la API ensambla estas tres identidades más un token Bearer de 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>

Requisitos Previos

  • Una Cuenta de Gestor de Google Ads con configuración completada
  • La cuenta de anuncios destino vinculada a la Cuenta de Gestor y el vínculo aceptado
  • Un proyecto de Google Cloud con la API de Google Ads habilitada
  • Python 3.9+ con la librería google-ads (pip install google-ads)
  • Un navegador para el flujo único de consentimiento OAuth

Paso 1: Cuenta de Gestor y Developer Token

API Center se encuentra en Herramientas y Configuración → Configuración → API Center dentro de una Cuenta de Gestor. Si API Center no aparece, la cuenta o bien no es una Cuenta de Gestor o su configuración está incompleta.

Desde API Center, solicita un Developer Token. Establece el tipo de cuenta como Anunciante (no Agencia ni Terceros) cuando el token es para tus propias cuentas. El token se emite inmediatamente con nivel de Acceso de Prueba.

El Acceso de Prueba permite:

  • Operaciones de lectura contra cualquier cuenta vinculada
  • Operaciones de escritura solo contra cuentas de prueba
  • Sin operaciones de escritura contra cuentas de producción
  • El error para escrituras contra cuentas de producción con Acceso de Prueba es RESOURCE_NOT_FOUND — no PERMISSION_DENIED. Esto es confuso porque el recurso sí existe y es legible. El error significa que la API se niega a enrutar la mutación bajo el nivel de acceso actual.

    Solicitud de Acceso Básico

    Para escribir contra cuentas de producción, solicita Acceso Básico desde la misma página de API Center. El formulario de solicitud contiene 12 preguntas. Para uso interno en tus propias cuentas, las respuestas relevantes son:

    PreguntaRespuesta
    Q4: Relación con un Representante de GoogleNo
    Q6: Modelo de NegocioDescribe tu caso de uso (e-commerce, generación de leads, reporting interno)
    Q8: Quién tendrá accesoUsuarios internos — solo empleados
    Q9: Herramienta desarrollada por tercerosNo (scripts/agentes propios)
    Q10: API de Seguimiento de Conversiones y RemarketingNo (a menos que realmente la uses)
    Q11: Tipos de CampañaSearch, Performance Max, Shopping (según corresponda)
    Q12: CapacidadesCreación de Campañas, Gestión de Campañas, Reporting

    Se requiere un documento de diseño (PDF) para Q7. Debe describir la arquitectura de la API, el flujo de autenticación, la estrategia de rate-limiting, el manejo de errores y el caso de uso exclusivamente interno. Mantenlo factual — el equipo de cumplimiento revisa la consistencia con el caso de uso declarado.

    Tiempo de procesamiento a junio de 2026: aproximadamente 3 días hábiles, con una nota sobre un volumen de solicitudes superior al habitual.

    Paso 2: OAuth 2.0

    Configuración del Proyecto en Google Cloud

    En la Consola de Google Cloud, dentro del proyecto correspondiente:

    1. Habilita la API de Google Ads (APIs y Servicios → Biblioteca)
    2. Configura la pantalla de consentimiento OAuth:
  • Tipo de Usuario: Interno (solo usuarios de tu Google Workspace pueden autorizar — omite la verificación externa de la app)
  • Nombre de la app, email de soporte, email de contacto del desarrollador
  • Añade el scope en Acceso a Datos: https://www.googleapis.com/auth/adwords
  • Crea un OAuth Client ID:
  • Tipo de aplicación: Desktop app
  • Descarga el JSON del secreto de cliente
  • El tipo Desktop app usa http://localhost como URI de redirección. Esto es correcto — el flujo OAuth abre un navegador, Google redirige a localhost con el código de autorización, y un servidor HTTP local lo captura.

    Generación del Refresh Token

    Un script Python que ejecuta un servidor HTTP local en 127.0.0.1:0 (puerto aleatorio), imprime la URL de autorización, espera una solicitud, extrae el parámetro code y lo intercambia por 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())

    Dos parámetros son importantes:

  • access_type='offline' — devuelve un refresh token, no solo un access token
  • prompt='consent' — fuerza una nueva pantalla de consentimiento incluso si el usuario autorizó previamente; necesario para obtener un nuevo refresh token si los scopes cambiaron
  • El refresh token es permanente a menos que se revoque, el usuario cambie su contraseña o el token no se use durante 6 meses.

    Problema de Scope con Clientes Existentes

    Si el cliente OAuth fue autorizado previamente para otros scopes (Gmail, Drive, Calendar), Google devuelve la unión de los scopes antiguos y nuevos. La librería google-auth-oauthlib rechaza esta discrepancia de scopes por defecto. Establece la variable de entorno antes de cargar el flujo:

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

    Alternativamente, omite include_granted_scopes=true de la URL de autorización, lo que le indica a Google que solicite solo el scope explícitamente pasado.

    Paso 3: `google-ads.yaml`

    La librería lee la configuración de un archivo YAML:

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

    Reglas de seguridad:

  • Permisos del archivo: 0600 (solo lectura/escritura del propietario)
  • Nunca incluir en control de versiones
  • Almacenar fuera de cualquier repositorio Git
  • Para configuraciones de equipo, distribuir mediante un gestor de secretos, no un archivo compartido
  • login_customer_id es el ID numérico del MCC sin guiones. Le indica a la API qué Developer Token de cuenta de gestor usar. El customer_id destino se pasa en el momento de la llamada, no en la configuración.

    use_proto_plus: true habilita la interfaz protobuf-plus, que es necesaria para las versiones actuales de la API.

    Paso 4: Inicialización del Cliente 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')

    El parámetro version selecciona explícitamente la versión de la API. La librería google-ads incluye múltiples versiones instaladas en paralelo (v19 a v22 a junio de 2026). Especifica siempre la versión — la predeterminada puede estar desactualizada o no soportar campos más recientes.

    Verificar conectividad:

    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']

    Paso 5: Operaciones de Lectura (GAQL)

    Google Ads usa GAQL (Google Ads Query Language), una sintaxis similar a SQL. Todas las operaciones de lectura pasan por GoogleAdsService.search_stream(), que evita la paginación y es preferible a search() para la mayoría de las consultas.

    Campañas con Métricas de Rendimiento

    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

    Presupuestos de Campaña

    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

    Grupos de Anuncios

    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

    Palabras Clave (por Impresiones)

    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

    Anuncios con Estado de Política

    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

    Acciones de Conversión

    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

    Patrón de Ejecución en 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

    Paso 6: Operaciones de Escritura con `validate_only`

    La API v22 requiere objetos de solicitud, no argumentos keyword. Cada servicio de mutación (CampaignService, AdGroupService, AdGroupCriterionService, CampaignBudgetService) sigue el mismo patrón:

    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)

    Diferencias clave respecto a versiones anteriores de la API:

  • validate_only es un campo en el objeto de solicitud, no un argumento keyword del método mutate
  • Las operaciones se añaden mediante req.operations.append(op), no req.operations.add(op)
  • Las rutas de recursos son strings explícitas ('customers/1305475941/campaigns/22479990461'), no valores de retorno de métodos auxiliares
  • Puerta de Mutación en Tres Fases

    Por seguridad en producción, las mutaciones pasan por tres puertas:

    Puerta 1 — validate_only=True: La API valida la estructura de la solicitud, los campos obligatorios y las referencias a recursos. No se crea ningún objeto. Ejecuta esto primero para cada mutación.

    Puerta 2 — Creación en Pausa: Establece validate_only=False y crea el objeto con status=PAUSED. Verifica el resultado con una consulta de lectura antes de continuar.

    Puerta 3 — Activación en Vivo: Una llamada API separada que actualiza solo el campo status a ENABLED. Esto debe requerir aprobación explícita, no integrarse en la creación.

    # 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)

    Actualización de Presupuesto

    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)

    Actualización de Puja de Grupo de Anuncios

    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)

    Creación de Palabra Clave

    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)

    Manejo de Errores

    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}')

    Códigos de error comunes y su significado:

    Código de ErrorCausa
    `RESOURCE_NOT_FOUND`Token de Acceso de Prueba contra una cuenta de producción (esperado) o recurso genuinamente inexistente
    `REQUIRED`Falta un campo obligatorio (ej. estrategia de puja en la creación de campaña)
    `UNRECOGNIZED_FIELD`Campo de una versión de API diferente o nombre de campo incorrecto
    `INVALID_ARGUMENT`El valor del campo no supera la validación (ej. presupuesto negativo)
    `PERMISSION_DENIED`El usuario OAuth no tiene acceso a la cuenta destino

    Niveles de Acceso a la API

    El acceso a la API de Google Ads es escalonado, no binario:

    NivelAprovisionamientoLectura (Producción)Escritura (Producción)Escritura (Cuentas de Prueba)Límite Diario de Operaciones
    **Acceso de Prueba**Inmediato desde API Center del MCC15.000
    **Acceso Básico**Solicitud + revisión de cumplimiento15.000
    **Acceso Estándar**Umbral de gasto + revisiónIlimitado

    El Acceso de Prueba es suficiente para desarrollo: autenticación, consultas GAQL, pruebas validate_only y lectura/escritura completa contra cuentas de prueba de Google Ads. El salto al Acceso Básico depende de la revisión de cumplimiento, no del gasto.

    El Acceso Estándar elimina el límite diario de operaciones. Requiere o bien un historial de gasto gestionado a través del token o una solicitud por separado.

    Cuentas de Prueba

    Las cuentas de prueba son cuentas gratuitas de Google Ads sin facturación. Aceptan cualquier mutación. Para crear una: en el MCC, ve a Cuentas → + → Crear nueva cuenta → Cuenta de prueba. Vincúlala al MCC y úsala como customer_id destino durante el desarrollo con Acceso de Prueba.

    `validate_only` en los Distintos Niveles de Acceso

    validate_only=True funciona en todos los niveles de acceso, pero el Acceso de Prueba sigue rechazando mutaciones validate_only contra cuentas de producción con RESOURCE_NOT_FOUND. Esto no es una limitación de validate_only — es el mismo control de acceso aplicado a todas las operaciones de escritura independientemente del flag validate_only.

    Seguimiento de Conversiones: Lectura de API vs. Estado Funcional

    La interfaz de Google Ads puede mostrar "Configurar seguimiento de conversiones" como recomendación incluso cuando existe una acción de conversión habilitada. La API puede confirmar la existencia de una acción de conversión (tipo WEBPAGE, categoría PURCHASE, estado ENABLED, include_in_conversions_metric: true), pero esto solo demuestra que el objeto de acción existe. No demuestra que el sitio web emita el evento AW-.../label correspondiente, que la etiqueta de Google esté cargada o que se haya recibido una señal de conversión.

    Al auditar el seguimiento de conversiones, separa la verificación por API (metadatos de la acción de conversión) de la verificación por navegador (pestaña de red, carga de etiquetas, emisión de eventos). La API es la fuente de verdad para la configuración; el navegador es la fuente de verdad para la ejecución.

    El patrón para atribución de ingresos en backend aplica aquí: si los eventos de conversión del lado del cliente no son fiables, planifica la subida de conversiones server-side u offline mediante el ConversionUploadService de la API de Google Ads como alternativa.

    Versionado de la API

    La librería Python google-ads incluye múltiples versiones de la API. A junio de 2026, v19 a v22 están disponibles. Cada versión añade, deprecia o elimina campos GAQL y métodos de servicio.

    Reglas para la selección de versión:

  • Especifica la versión explícitamente en load_from_storage(version='v22'). La predeterminada puede estar obsoleta.
  • Consulta las notas de versión de la API de Google Ads para conocer las deprecaciones de campos antes de actualizar.
  • El método search_stream está disponible desde v6+ y es la ruta de lectura recomendada.
  • Protobuf-plus (use_proto_plus: true) es obligatorio para v12+.
  • El patrón de objeto de solicitud para mutaciones (mutate_campaigns(request=req)) reemplazó el estilo de argumentos keyword en v17+.
  • Seguridad Local

    Todos los archivos de credenciales deben permanecer fuera del control de versiones:

    ~/.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

    Para el repositorio de trabajo, añade un .gitignore:

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

    Un archivo de plantilla con valores placeholder puede incluirse en el repositorio para documentar la estructura esperada:

    # 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

    Campos Obligatorios para Operaciones Comunes

    OperaciónCampos Obligatorios
    Crear Campaña (Search)`name`, `status`, `advertising_channel_type`, `campaign_budget`, `manual_cpc` o estrategia de puja
    Crear Grupo de Anuncios (Search)`name`, `status`, `type_`, `cpc_bid_micros`, `campaign`
    Crear Palabra Clave`ad_group`, `status`, `keyword.text`, `keyword.match_type`
    Actualizar Estado de Campaña`resource_name`, `status`, `update_mask` (paths: `['status']`)
    Actualizar Presupuesto`resource_name`, `amount_micros`, `update_mask` (paths: `['amount_micros']`)

    La ausencia de un campo obligatorio devuelve REQUIRED con el nombre del campo. La ausencia de update_mask en una operación de actualización se ignora silenciosamente — el campo no se actualiza y no se devuelve ningún error.

    Script de Prueba Completo

    Un único script que lee todos los tipos de entidad y ejecuta pruebas de escritura 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.')

    Versión ejecutable completa en el skill de operaciones de Google Ads API en el repositorio de operaciones publicitarias.

    Referencias

  • Documentación de Google Ads API
  • Librería Python google-ads
  • Referencia GAQL
  • OAuth 2.0 para Aplicaciones de Escritorio
  • Construyendo un Asistente de IA Específico de Proyecto vía Telegram — mismo patrón OAuth aplicado a un scope diferente de Google
  • Arquitectura de Referencia para una Capa de Operaciones de IA Basada en Hilos — el modelo operativo al que se conecta la automatización de API
  • Operaciones en Solitario a Escala: Gestionando Docenas de Proyectos con un Equipo Pequeño — por qué la automatización de API reemplaza el trabajo manual en la UI a escala
  • Artículos relacionados