Aprobación del developer-token de Google Ads: las 6 semanas de espera y cómo saltártelas
Las subidas de conversión server-side por la API de Google Ads requieren un developer-token. La aprobación tarda 4-6 semanas de ida y vuelta con Google. Un broker central abstrae el token sin ver tus datos de conversión, aquí va cómo está cableada la arquitectura y por qué no compromete la privacidad.
Dos credenciales, no una
Autenticarse contra la API de Google Ads necesita dos credenciales distintas, y ahí está la fuente de toda la fricción:
- Un developer-token. Pertenece a quien escribió la aplicación que usa la API. Identifica la integración ante Google, regula la cuota de API, es lo que Google revisa durante la aprobación. Uno por integración, sin importar cuántos clientes la usen.
- Una credencial OAuth. Pertenece a cada titular de cuenta de Ads. Identifica qué cliente sube y a qué Customer ID. Se emite al instante mediante el handshake OAuth estándar, sin revisión.
El lado OAuth es rápido y bien rodado. El lado del developer-token es donde vive la ventana de 4-6 semanas.
Cómo funciona realmente la aprobación del developer-token
Cada nuevo proyecto de Google Cloud que quiere hablar con la API de Google Ads arranca en basic access: 15.000 operaciones API por día, solo sandbox contra cuentas de prueba. Útil para desarrollo, inútil para subidas de conversión en producción.
Para conseguir standard access, lo que necesitas para subir conversiones reales, envías una solicitud por escrito a Google. El formulario pide descripción del caso de uso, volumen diario esperado, arquitectura de la integración, prácticas de manejo de datos y capturas de la integración. Google revisa. Las revisiones implican ida y vuelta: preguntas de aclaración, peticiones de más capturas, a menudo correos de seguimiento sobre casos límite.
El plazo objetivo publicado es "unas pocas semanas". El promedio realista en los clientes que hemos observado es de 4 a 6 semanas, ocasionalmente más cuando la cola de revisión de Google va saturada. No hay vía de escalado para clientes pequeños individuales.
Resultado: una pequeña tienda WordPress que quiere trackear conversiones de Google Ads server-side tiene que esperar más de un mes antes incluso de empezar.
Por qué "self-host del token" no funciona
Dos razones por las que el workaround obvio, conseguir un developer-token aprobado y compartirlo con todos los clientes, no funciona en la práctica.
Primero, la política de developer-token de Google prohíbe expresamente compartir tokens entre clientes que no operes tú mismo. El token te representa a ti como autor de la integración, garantizando cómo manejas los datos. Prestarlo a terceros viola los términos de servicio.
Segundo, aunque ignoraras la política, el rastro de auditoría aflora de inmediato. Google asocia las operaciones de API al developer-token en sus logs internos. Si 500 Customer IDs de clientes no relacionados aparecen bajo un mismo developer-token, hay algo estructuralmente mal y Google lo nota.
La forma legítima de usar un developer-token con muchos clientes es que el titular del token siga en el camino del dispatch, sea efectivamente la integración que gestiona la subida, no un mero prestamista de credencial.
La arquitectura del broker Phase-2
Beaconry corre un Cloudflare Worker central que guarda el developer-token aprobado de Beaconry. La instalación de WordPress del cliente no ve este token. La instalación de WordPress del cliente guarda un refresh-token OAuth emitido para la cuenta de Google del cliente, scoped a la cuenta de Ads del cliente.
El flujo en cada subida de conversión:
- WordPress monta el payload de subida (Customer ID, conversion-action ID, gclid, valor, divisa).
- WordPress acuña un access-token fresco a partir de su refresh-token guardado (refresh OAuth estándar, habla directamente con el endpoint de tokens de Google, no pasa por el broker).
- WordPress envía payload + access-token al broker de Beaconry.
- El broker hace rate-limit (máx N subidas/seg por cliente, evita bucles accidentales), añade el developer-token de Beaconry en la cabecera del request, reenvía a
googleads.googleapis.com. - Google valida el token OAuth (debe corresponder al Customer ID), valida el developer-token (el de Beaconry), acepta o rechaza.
- El broker hace stream de la respuesta de vuelta a WordPress.
El broker es una capa de tránsito para el body de subida. Hace rate-limit, añade la cabecera del developer-token, reenvía. El body va cifrado por HTTPS en tránsito y no se loguea ni se almacena.
Lo que el broker NO ve
Arquitectónicamente el broker es un forwarder privilegiado. Hay una pregunta de confianza no trivial: ¿cómo saben los clientes que no leemos los bodies? Tres compromisos concretos:
- Sin persistencia del body. El código del Worker se despliega desde un repositorio público. Sin escrituras KV, sin escrituras Durable Object, sin líneas de log que incluyan el body del request. Cloudflare Workers sí registra metadatos del request (ruta, status, timing), pero el body no está en esos logs.
- Cifrado de extremo a extremo de WP a Google. El handshake TLS se cierra entre WordPress y
googleads.googleapis.coma través del forward transparente del broker. El broker termina TLS para añadir la cabecera del developer-token; no tiene acceso al refresh-token OAuth (ese se queda en WP y nunca toca al broker). - Customer IDs visibles, contenido de conversión no. El broker registra para qué Customer ID es una subida (necesario para rate-limit y asignación de cuota). No registra gclids, valores de conversión ni datos a nivel de visitante.
El trade-off es real y no fingimos lo contrario: los clientes cambian la complejidad de "operar tu propio contenedor Cloud Run" por "confiar en el código del broker de Beaconry". Los clientes que no pueden hacer este cambio tienen una salida explícita, pueden auto-desplegar el broker (es open-source), traer su propio developer-token (la espera de 4-6 semanas reaparece) y operarlo ellos mismos.
Garantías de privacidad: lo que el cliente conserva
La asimetría que hace funcionar el patrón broker: los refresh-tokens nunca salen del WordPress del cliente.
- Refresh-token OAuth: cifrado en reposo en WP, usado solo para acuñar access-tokens de corta duración directamente del endpoint de Google.
- Access-tokens: acuñados en WP, usados una vez por subida, expiran en ~1 hora.
- Developer-token: vive solo en el broker, nunca se envía a WP.
Si el broker se viera comprometido alguna vez, el atacante obtiene el developer-token de Beaconry (lo revocaríamos y volveríamos a solicitar, doloroso pero acotado), pero no puede suplantar la cuenta de Ads de ningún cliente individual porque no tiene el refresh-token de ningún cliente. Si el WP de un cliente se ve comprometido, el atacante obtiene el refresh-token de ese único cliente (revocable en el panel de seguridad de cuenta de Google), pero no puede subir a las cuentas de Ads de otros clientes.
Comparado con patrones "el broker guarda los refresh-tokens de todos": un único compromiso del broker quemaría a todos los clientes simultáneamente. La división de Beaconry lo evita.
Latencia y rate-limits
Un salto de Worker añade aproximadamente 5-15 ms sobre WP-a-Google directo. La latencia real de subida de conversión la domina la propia API de Google Ads (típicamente 200-500 ms server-side), así que el salto del broker queda en el ruido.
Los rate-limits en el broker se configuran por Customer ID, por defecto 50 subidas por segundo. Está muy por encima de cualquier volumen legítimo plausible para un sitio e-commerce pequeño-mediano. El tope existe para pillar bucles e integraciones desbocadas pronto, antes de que consuman la cuota de Google para todos los que comparten el developer-token.
Modos de fallo
Los modos de fallo honestos que han surgido o podrían surgir:
- La cuenta Google del cliente revoca el grant OAuth. El token expira, el broker reenvía un 401 de Google a WP, el dashboard muestra "Reconectar con Google". El cliente hace clic en Conectar, el handshake OAuth se repite, la configuración se restaura. Los Conversion-Rule-IDs y el Customer ID se mantienen en WP.
- Caída del broker. Cloudflare Worker se cae (raro pero posible). WP reintenta con backoff exponencial durante ~24 horas. Más allá, las conversiones encoladas en ese período se pierden. La integración con la status-page alerta al operador antes de esa ventana.
- El rate-limit de Google se activa. El broker propaga el 429 de vuelta a WP. WP reintenta con backoff. Si el cliente está realmente por encima de su cuota por Customer ID, verá los reintentos estabilizarse en plateau y tendrá que hablar con Google sobre cuota.
- El developer-token de Beaconry es revocado. El servicio se degrada para todos a la vez (el caso de fallo que defiende el self-deployment si no puedes tolerarlo). Tenemos procesos para monitorizar la salud del token, pero ese es el riesgo residual que asumen los clientes.
Para llevar
Si quieres subidas de conversión server-side de Google Ads en un sitio WP pequeño, la elección es: esperar 4-6 semanas por tu propio developer-token, o usar un patrón broker que abstrae el token sin comprometer tu propiedad de los datos. El broker Phase-2 es lo segundo, con la propiedad arquitectónica de que los refresh-tokens del cliente se quedan en el WP del cliente, solo el developer-token de Beaconry vive centralmente. Mismo resultado en el endpoint de la API de Google Ads, tiempo hasta primera conversión muy distinto.