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.
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.
| Recurso | Operación v2 | Uso práctico | Dato necesario |
|---|---|---|---|
| Informes | accounts.reports.generate | Solicitar filas agregadas por fecha, país, unidad o página. | Cuenta, rango, métricas y dimensiones compatibles. |
| Clientes de anuncios | accounts.adclients.list | Descubrir los productos/clientes de anuncios de la cuenta. | Cuenta; paginar si la respuesta incluye token. |
| Unidades | accounts.adclients.adunits.list | Inventariar unidades bajo un cliente de anuncios. | Cuenta y recurso del cliente; no es una lista global sin padre. |
| Alertas | accounts.alerts.list | Consultar 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
- 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.
- 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.
- 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.
- Solicita el alcance mínimo.
https://www.googleapis.com/auth/adsense.readonlybasta 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. - Protege la sesión renovable. El token de acceso expira; un token de actualización permite renovarlo. Guarda
client_secret.jsonytoken.jsoncon 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.
| Campo | Qué representa | Consejo de análisis |
|---|---|---|
DATE | Fecha del informe. | Comprueba zona horaria y rango antes de comparar con analítica. |
COUNTRY_CODE | Región del usuario según el código CLDR. | Úsalo para localizar diferencias agregadas, no para perfilar personas. |
AD_UNIT_ID | Identificador de la unidad en el informe. | Combínalo con el inventario y conserva la etiqueta de la unidad. |
PAGE_URL | URL de la página donde se sirvió el anuncio. | Úsalo en una extracción aparte si genera demasiadas filas. |
ESTIMATED_EARNINGS | Ingresos estimados en la moneda de la cuenta o la solicitada. | Es estimación y puede ajustarse; no la presentes como pago liquidado. |
PAGE_VIEWS_RPM | Ingresos estimados por mil páginas vistas. | Compara periodos equivalentes y el mismo denominador. |
IMPRESSIONS | Impresiones 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
nextPageTokeny usa el ad client correcto como padre deadunits.list. - Informe vacío o dimensión incompatible: prueba rango y métrica simples; añade dimensiones gradualmente y consulta compatibilidad.
429o 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.