AdSense Management API v2: OAuth, informes y cuotas

Guía de implementación de la API oficial de AdSense v2: OAuth 2.0, informes automatizados, inventario, alertas, límites y diagnóstico.

La AdSense Management API v2 es una API REST autenticada para consultar inventario y rendimiento de una cuenta de AdSense desde una herramienta propia. Sirve para automatizar informes, conciliarlos con analítica o vigilar cambios; no sustituye el panel, no aprueba sitios y no ofrece una vía para alterar clics ni pujas. Esta guía sigue el contrato de la API v2 y presenta identificadores ficticios: sustituye cada valor de ejemplo por el de tu cuenta antes de ejecutar nada.

El flujo tiene cuatro piezas: autorización OAuth 2.0 de una persona con acceso a AdSense, token renovable guardado en privado, llamadas de solo lectura y validación antes de exportar. El ejemplo usa adsense.readonly; nunca guardes el token en public_html, JavaScript público ni un repositorio abierto.

Arquitectura de lectura con AdSense Management API La persona autoriza una herramienta por OAuth; la herramienta consulta la API v2 y valida el informe antes de guardarlo. Editor con accesoconsentimiento OAuth Script privadotoken + cliente API API AdSense v2informes e inventario ValidaciónCSV o BI El permiso de lectura limita lo que puede hacer el programa
La API no necesita ejecutarse en el navegador: la credencial y los informes se procesan en un entorno privado.

Recursos principales y forma de una petición

La API agrupa las operaciones bajo un recurso de cuenta, escrito como accounts/{account}. El valor debe ser el nombre de recurso real que devuelve accounts.list; accounts/pub-0000000000000000 es solo un ejemplo inventado y no identifica una cuenta válida. Las operaciones que se usan con más frecuencia son de lectura. Las colecciones grandes pueden devolver un nextPageToken; no asumas que una primera respuesta contiene todo.

RecursoOperación v2Uso prácticoDato necesario
Informesaccounts.reports.generateSolicitar filas agregadas por fecha, país, unidad o página.Cuenta, rango, métricas y dimensiones compatibles.
Clientes de anunciosaccounts.adclients.listDescubrir los productos/clientes de anuncios de la cuenta.Cuenta; paginar si la respuesta incluye token.
Unidadesaccounts.adclients.adunits.listInventariar unidades bajo un cliente de anuncios.Cuenta y recurso del cliente; no es una lista global sin padre.
Alertasaccounts.alerts.listConsultar alertas disponibles para la cuenta.Cuenta y, cuando proceda, paginación.

reports.generate es una petición GET al recurso de cuenta en la API v2. La biblioteca oficial construye la llamada; evita rutas de la antigua v1.4 y valida los parámetros en la referencia vigente.

OAuth 2.0 desde Google Cloud Console

  1. Crea o selecciona un proyecto. En Google Cloud Console, habilita AdSense Management API v2. La consola del proyecto controla las credenciales y cuotas del cliente API; no cambia la configuración de monetización de AdSense.
  2. Configura el consentimiento. Indica el nombre de la herramienta y los datos solicitados. Autoriza solo cuentas que deban leer esos informes. Para una aplicación en modo de prueba, el usuario de AdSense debe estar incluido en la lista de usuarios de prueba.
  3. Crea un cliente OAuth adecuado. El ejemplo de abajo usa una aplicación de escritorio con un flujo local interactivo. Una aplicación web desplegada debe registrar sus URI de redirección exactos; no reutilices el cliente de escritorio en el navegador público.
  4. Solicita el alcance mínimo. https://www.googleapis.com/auth/adsense.readonly basta para estas consultas. Un alcance más amplio aumenta el impacto potencial de una filtración sin aportar nada a un informe de solo lectura.
  5. Protege la sesión renovable. El token de acceso expira; un token de actualización permite renovarlo. Guarda client_secret.json y token.json con permisos privados, exclúyelos del control de versiones y permite revocar el acceso desde la cuenta de Google.

Dimensiones y métricas: diseña informes pequeños

Una dimensión crea grupos; una métrica mide cada grupo. DATE devuelve días en formato ISO, COUNTRY_CODE devuelve el código de región, AD_UNIT_ID identifica la unidad de anuncios y PAGE_URL es la URL de página asociada a la impresión. La URL de la dimensión puede venir canonicalizada e incluir parámetros; no siempre coincide byte a byte con la URL que una persona vio. Por privacidad y cardinalidad, conviene agrupar por país o unidad antes de pedir un desglose por URL.

CampoQué representaConsejo de análisis
DATEFecha del informe.Comprueba zona horaria y rango antes de comparar con analítica.
COUNTRY_CODERegión del usuario según el código CLDR.Úsalo para localizar diferencias agregadas, no para perfilar personas.
AD_UNIT_IDIdentificador de la unidad en el informe.Combínalo con el inventario y conserva la etiqueta de la unidad.
PAGE_URLURL de la página donde se sirvió el anuncio.Úsalo en una extracción aparte si genera demasiadas filas.
ESTIMATED_EARNINGSIngresos estimados en la moneda de la cuenta o la solicitada.Es estimación y puede ajustarse; no la presentes como pago liquidado.
PAGE_VIEWS_RPMIngresos estimados por mil páginas vistas.Compara periodos equivalentes y el mismo denominador.
IMPRESSIONSImpresiones de unidades que empezaron a cargarse.No equivale necesariamente a anuncios individuales dentro de una unidad.

Las dimensiones y métricas tienen reglas de compatibilidad. Prueba una dimensión cada vez; PAGE_URL puede producir muchas filas y devolver URLs canonicalizadas con parámetros. Guarda zona horaria y moneda para comparar periodos homogéneos.

La referencia v2 enumera IMPRESSIONS y TOTAL_IMPRESSIONS; INDIVIDUAL_AD_IMPRESSIONS cuenta anuncios individuales y no debe confundirse con impresiones de unidad. Al mapear respuestas, conserva los nombres de cabecera de la API.

En informes de alta cardinalidad define un limit razonable y compara las filas devueltas con totalMatchedRows para detectar truncamiento. La referencia fija máximos distintos para informes normales y CSV; consulta el método concreto antes de planificar una extracción masiva.

Ejemplo completo en Python: informe diario

Instala google-api-python-client, google-auth-oauthlib y google-auth-httplib2. Coloca el cliente OAuth de escritorio como client_secret.json fuera de la raíz pública. El ID del ejemplo es ficticio.

from pathlib import Path
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build

SCOPES = ["https://www.googleapis.com/auth/adsense.readonly"]
ACCOUNT = "accounts/pub-0000000000000000"  # ID ficticio: sustituir por accounts.list
TOKEN = Path("token.json")
CLIENT = Path("client_secret.json")

def credentials():
    creds = Credentials.from_authorized_user_file(str(TOKEN), SCOPES) if TOKEN.exists() else None
    if creds and creds.expired and creds.refresh_token:
        creds.refresh(Request())
    if not creds or not creds.valid:
        flow = InstalledAppFlow.from_client_secrets_file(str(CLIENT), SCOPES)
        creds = flow.run_local_server(host="localhost", port=0)
    TOKEN.write_text(creds.to_json(), encoding="utf-8")
    return creds

def main():
    api = build("adsense", "v2", credentials=credentials(), cache_discovery=False)
    report = api.accounts().reports().generate(
        account=ACCOUNT,
        dateRange="LAST_30_DAYS",
        dimensions=["DATE"],
        metrics=["ESTIMATED_EARNINGS", "PAGE_VIEWS_RPM", "IMPRESSIONS"],
        orderBy=["+DATE"],
        languageCode="es",
    ).execute()

    headers = [cell.get("name") for cell in report.get("headers", [])]
    print("Columnas:", headers)
    for row in report.get("rows", []):
        print([cell.get("value") for cell in row.get("cells", [])])

if __name__ == "__main__":
    main()

La primera autorización abre un navegador, por lo que el ejemplo no es un cron autónomo desde cero. Si se revoca el permiso o no hay refresh token, detén la tarea y solicita consentimiento de nuevo; no compartas credenciales en el navegador.

Antes de exportar, conserva las cabeceras y sus tipos, el rango devuelto, la moneda y totalMatchedRows. Esa metadata permite detectar cambios de esquema y truncamiento; guarda los valores originales y aplica formato regional solo en el panel que los presenta.

Automatización, cuotas y límites operativos

Reduce solicitudes: pide el rango necesario, sigue todos los nextPageToken y programa la extracción con la frecuencia que requiera el análisis. La API sirve para informes e inventario, no para decidir anuncios en tiempo real.

No codifiques un límite de cuota supuesto: consulta el proyecto en Google Cloud Console. Registra estado y método; para 429 aplica backoff con variación aleatoria y respeta Retry-After. Ante 401 revisa OAuth; ante 403, API habilitada, alcance y acceso del usuario.

Los ingresos recientes son estimaciones que pueden ajustarse. Guarda fecha de extracción y contrasta cambios con consentimiento, disponibilidad y etiquetas antes de inferir causas. Para inventario, consulta ads.txt y SupplyChain; para recursos que afectan a la carga, revisa Core Web Vitals.

Errores frecuentes en producción y diagnóstico

  • invalid_grant: comprueba fecha del sistema, cliente OAuth y revocación; renueva o repite el consentimiento.
  • 403 PERMISSION_DENIED: verifica API habilitada, usuario autorizado y alcance de lectura.
  • Inventario incompleto: sigue nextPageToken y usa el ad client correcto como padre de adunits.list.
  • Informe vacío o dimensión incompatible: prueba rango y métrica simples; añade dimensiones gradualmente y consulta compatibilidad.
  • 429 o cifras cambiantes: reduce sondeos, aplica backoff y recuerda que ganancias recientes son estimadas.

Preguntas frecuentes

¿La API puede pedir una revisión o forzar la aprobación?

No. Consulta y gestiona información de cuenta; la aprobación depende de la revisión del sitio.

¿Puedo combinar las cuatro dimensiones?

La combinación depende de compatibilidad y puede multiplicar filas. Empieza con DATE y añade una dimensión por informe.

¿IMPRESSIONS cuenta anuncios individuales?

Cuenta unidades o consultas que mostraron anuncios y empezaron a cargarse; una unidad puede contener varios anuncios.

¿Dónde se ejecuta el ejemplo?

En un equipo para el consentimiento inicial y después en un servidor privado, nunca en el sitio estático público.

Referencias técnicas