Chrome le dice a cada servidor que tu teléfono usa Android 10
Desde 2023, Chrome en Android envía el mismo user agent desde cualquier teléfono: Android 10, modelo K. Qué supuso eso para el matching de deferred deep links, por qué no lo resolvimos con Critical-CH y cómo los dominios de enlaces de Appy recuperan ahora la versión y el modelo reales. Y, de paso, la versión de iOS 26 del mismo problema.
Ahora todos los Android son «K»
Toma un Pixel con la última versión de Android y un Galaxy de hace cuatro años. Abre la misma página en Chrome en los dos. Salvo por la versión de Chrome, la cabecera User-Agent que envían es idéntica: Android 10, modelo de dispositivo K.
No es un error. Es la reducción del user agent (user-agent reduction), un cambio de privacidad de Chrome que congeló las partes de la cadena que servían para hacer fingerprinting de un dispositivo. En Android llegó con Chrome 110. Según el calendario del proyecto Chromium, el despliegue empezó el 7 de febrero de 2023 y llegó a todos los clientes Android el 11 de mayo de 2023.
La mayoría de las webs ni se enteraron. Todo lo que asociaba instalaciones de apps con clics, sí.
La misma cabecera, antes y después
Antes de Chrome 110
Mozilla/5.0 (Linux; Android 9; SM-A205U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.0.0 Mobile Safari/537.36Chrome 110 y posteriores
Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.0.0 Mobile Safari/537.36Lo que rompió en los deferred deep links
Un deferred deep link tiene que sobrevivir a la instalación. Cuando la tienda puede llevar un token, lo lleva: Google Play y Huawei AppGallery entregan a la app recién instalada un install referrer, y eso resuelve la coincidencia con exactitud. Cuando no puede, porque la instalación empezó con una búsqueda en la tienda, con un sideload o en una tienda sin referrer, queda la estimación: buscar un clic reciente desde la misma red y ver si parece del mismo teléfono.
Ese «parece» se apoyaba antes en el user agent. Un clic desde Android 14 era mal candidato para un teléfono que declara Android 15 en su primera apertura, y un clic desde un Galaxy era mal candidato para un Pixel. Tras la reducción, todos los clics de Chrome decían Android 10 y K. La versión dejó de acotar nada, y en una red concurrida, como una oficina o un campus, todos los Android del edificio se parecían entre sí.
Appy lee Android 10; K como lo que es: ni versión ni modelo. Sin nada más en el clic, todos los clics de Android desde la misma red parecían iguales, y Appy no podía distinguir el teléfono de tu nuevo usuario del resto.
La solución de manual cuenta cada clic dos veces
Chrome no borró la información: la trasladó a User-Agent Client Hints. Algunos hints de baja entropía acompañan a cada solicitud: la marca y la versión mayor del navegador, si el dispositivo es móvil y el nombre de la plataforma. Los dos que importan aquí, Sec-CH-UA-Platform-Version y Sec-CH-UA-Model, son de alta entropía. Chrome solo los envía después de que el sitio los pida con una cabecera de respuesta Accept-CH, así que la primera solicitud a un sitio nunca los lleva.
Para los datos que una página necesita desde la primera carga, la guía de Privacy Sandbox de Google sobre la reducción en Android (27 de febrero de 2023) remite a Critical-CH. El servidor indica los hints sin los que no puede trabajar; Chrome ve que faltaban, descarta la respuesta y repite la solicitud, esta vez con los hints.
El problema está en ese «repite». Para un servicio de redirección, ese reintento es una segunda navegación al mismo enlace: cada toque en Android se contaría dos veces y dejaría dos registros de clic. Preferimos trabajar un poco más antes que poner cifras erróneas en el panel de cada cliente, así que Appy no usa Critical-CH.
Lo que hacen en su lugar los dominios de enlaces de Appy
Dos mecanismos: uno para el primer toque desde un navegador y otro para todos los siguientes.
Chrome en el teléfono
acme.appy.to
- 01Primer toque en un enlace
GET /spring HTTP/2 Host: acme.appy.to User-Agent: Mozilla/5.0 (Linux; Android 10; K) … Chrome/154.0.0.0 Mobile Safari/537.36 Sec-CH-UA-Mobile: ?1 Sec-CH-UA-Platform: "Android"Solo hints de baja entropía. El user agent dice Android 10, modelo K.
- 02Página intermedia
HTTP/2 200 Accept-CH: Sec-CH-UA-Platform-Version, Sec-CH-UA-Model Content-Type: text/html; charset=utf-8La página que abre la app o la tienda. Accept-CH pide los dos hints en todas las solicitudes posteriores.
- 03Antes de redirigir
const hints = await navigator.userAgentData .getHighEntropyValues(["platformVersion", "model"]) → {platformVersion: "16.0.0", model: "Pixel 9", …} navigator.sendBeacon(…)La página lee los valores reales, los añade al registro de este clic y después redirige.
- 04Los toques siguientes
GET /summer HTTP/2 Host: acme.appy.to Sec-CH-UA-Platform-Version: "16.0.0" Sec-CH-UA-Model: "Pixel 9"Chrome recuerda lo que pidió este origen hasta que el usuario borra los datos del sitio, así que ahora los hints viajan como cabeceras. Sin script y sin reintento.
Qué cambian la versión y el modelo reales
Con la versión y el modelo reales en el clic, el clic y el teléfono tienen que coincidir en ambos. El SDK informa del modelo del teléfono a partir de Build.MODEL cuando la app se abre por primera vez, así que se pueden comparar. Un clic desde un Pixel 9 ya no puede confundirse con una instalación en un Galaxy, y un clic desde Android 15 ya no encaja con un teléfono con Android 16.
Donde más se nota es en las redes concurridas. En la red de una oficina con cuarenta teléfonos, los clics de otros modelos quedan fuera, y muchas veces el único que queda es el del propio Pixel.
Todo esto se refiere a las instalaciones que llegan sin token. En Android, los install referrers de Google Play y AppGallery siguen resolviendo primero la mayoría de las instalaciones, y Client Hints está para el resto. Sin referrer ni click ID, Appy no puede verificar la instalación, así que con la atribución estricta activada cuenta como orgánica, aunque el clic encaje a la perfección.
Una red de oficina, antes y después
Un Pixel 9 conectado a una red de oficina concurrida abre la app por primera vez, cuatro minutos después de que su dueño tocara un enlace. Cerró la página de la tienda que abrió el enlace e instaló la app buscándola en Play Store, así que no llega ningún referrer.
iOS también congeló su número
Safari llegó al mismo sitio por otro camino. Según las notas de la versión de Safari 26.0 publicadas por Apple, Safari indica ahora en su user agent una versión de sistema congelada en iOS 26 y iPadOS 26: la última publicada antes de iOS 26. En la práctica, un iPhone con iOS 26 se presenta como «iPhone OS 18_6». El token Version/26.0, más adelante en la cadena, sigue reflejando la versión del propio Safari.
Safari no admite User-Agent Client Hints, así que no hay nada que pedir. Appy lo resuelve en el matching: si el teléfono tiene iOS 26 o posterior, un clic que dice iOS 18.6 se interpreta como «26 o posterior», no como una versión exacta, porque Safari ya no dice cuál es.
Si atribuyes instalaciones por tu cuenta
Nada de esto es exclusivo de Appy.
Trata «Android 10; K» como desconocido
Reconócelo y descártalo. Un valor congelado que parece un dato hace más daño que un campo vacío.
Pide los hints desde el dominio que sirve el clic
Envía Accept-CH: Sec-CH-UA-Platform-Version, Sec-CH-UA-Model desde tu dominio de enlaces y lee navigator.userAgentData en la primera visita, cuando las cabeceras todavía no pueden llegar.
Mide el efecto del reintento antes de añadir Critical-CH
Una navegación reintentada es una segunda solicitud. Si cuentas solicitudes, deduplícalas o prescinde del reintento.
Interpreta iOS 18.6 como «26 o posterior»
No rechaces una instalación de iOS 26 porque su clic decía 18.6. Trátala como iOS 26 o posterior, no como una versión exacta.
Mejor tokens que estimaciones
Los install referrers y los click IDs valen más que cualquier user agent. Recurre a una estimación solo cuando no haya llegado nada determinista, y di que es una estimación.
Sigue leyendo
Preguntas frecuentes
¿Por qué Chrome dice Android 10 en todos los teléfonos?
Por la reducción del user agent. Desde Chrome 110, desplegado entre febrero y mayo de 2023, Chrome en Android congela la versión del sistema en 10 y el modelo del dispositivo en K dentro de la cadena User-Agent. Los valores reales se pueden obtener con User-Agent Client Hints.
¿Cómo obtengo la versión real de Android en Chrome?
Pide el hint Sec-CH-UA-Platform-Version con una cabecera de respuesta Accept-CH, o llama a navigator.userAgentData.getHighEntropyValues(["platformVersion"]) desde la página. La cabecera solo llega en las solicitudes posteriores a que Chrome haya visto tu Accept-CH.
¿Critical-CH resuelve la primera solicitud?
Te da los hints a costa de que Chrome repita la solicitud. Para páginas normales, funciona. Para todo lo que cuente solicitudes, como las redirecciones o el seguimiento de clics, la repetición parece una segunda visita salvo que la deduplices.
¿Qué indica Safari en iOS 26?
Una versión de sistema congelada. En iOS 26 y iPadOS 26, Safari indica la última versión publicada antes de iOS 26, en la práctica 18_6, mientras que el token Version/26 sigue reflejando la versión de Safari. Safari no admite User-Agent Client Hints.
¿También se reduce el user agent en los WebView de Android y en los navegadores in-app?
Por defecto, todavía no. Google ha dicho que el user agent predeterminado de WebView recibirá el mismo tratamiento a partir de Android 17, y las apps que definen su propio user agent lo conservan.
Seguir explorando
Deferred deep linking sin SDK: cómo funciona realmente por dentro
Puedes llevar el contexto de un enlace a través de una instalación sin incrustar un SDK de atribución. Esto es lo que sobrevive a la frontera de la tienda en Android e iOS, lo que se rompe y el coste en privacidad de cada alternativa.
Descubre qué enlace trajo cada instalación: el SDK de Appy para iOS y Android
Appy ahora sigue tus enlaces más allá de la tienda de apps. El nuevo SDK te muestra instalaciones, eventos in-app e ingresos de cada enlace, código QR y campaña, y abre la pantalla correcta a los nuevos usuarios.
Deferred deep linking: cómo funciona y cuándo usarlo
Conserva la intención original del enlace tras la instalación para que los nuevos usuarios aterricen en la pantalla correcta y no en la home por defecto.
¿Buscas otra cosa? Explora todos los temas en el blog.
Atribuye instalaciones con pruebas, no con «Android 10»
Los dominios de enlaces de Appy ya piden Client Hints. El deferred deep linking y la atribución de instalaciones vienen con el SDK en el plan Enterprise, y con los smart links puedes empezar gratis.