Install Referrer en iOS: alternativas sin fingerprinting
En Android, atribuir un referido después de la instalación está resuelto: pones el código en el enlace de Play Store y tu app lo lee en el primer arranque. Luego construyes la versión de iOS, buscas la misma API… y no existe.
Esta guía explica qué te da Android, por qué iOS no tiene equivalente y qué opciones existen de verdad en iOS, contrastadas con la documentación de Apple. Al final tienes un diseño determinista y una tabla de decisión.
Fuentes: documentación de Apple Developer, Ayuda de App Store Connect y documentación de Android Developers, a octubre de 2026. Las APIs y políticas cambian: revisa las páginas enlazadas antes de construir. Las citas están en su versión original en inglés.
La respuesta corta
| Opción | ¿Funciona antes de instalar la app? | ¿Por usuario? | ¿Determinista? |
|---|---|---|---|
| Play Install Referrer (solo Android) | Sí | Sí | Sí |
| Universal links | No: el enlace abre tu web | Sí | Sí |
| Fingerprinting / coincidencia probabilística | A veces | Adivinado | No, y Apple no lo permite |
| Portapapeles | Sí, si el portapapeles sobrevive | Sí | Sí, cuando funciona |
| App Clip | Sí, si el usuario abre antes el clip | Sí | Sí |
| AdAttributionKit / SKAdNetwork | Sí, para redes publicitarias registradas | No: agregado | No para personas |
| Códigos de oferta de Apple (códigos personalizados) | Sí | Por oferta, no por código | En parte |
| Introducir el código a mano en el onboarding | Sí | Sí | Sí |
| Registro web primero, luego login en la app | Sí | Sí | Sí |
Ninguna API de iOS te entrega un código de referido en el primer arranque. Un sistema fiable combina varias opciones deterministas.
Lo que te da Android: el Play Install Referrer
La Play Install Referrer API de Google permite a una app "securely retrieve referral content from Google Play", es decir, obtener de forma segura los datos de referencia desde Google Play. Añades un parámetro referrer al enlace de la tienda —el ejemplo de Google es https://play.google.com/store/apps/details?id=com.example.package&referrer=example_referrer_source (documentado aquí)— y, tras la instalación, la biblioteca cliente devuelve un objeto ReferrerDetails:
getInstallReferrer(): la cadena del referrer del enlacegetReferrerClickTimestampSeconds(): cuándo se hizo clic en el enlacegetInstallBeginTimestampSeconds(): cuándo empezó la instalacióngetGooglePlayInstantParam(): si el usuario usó tu versión instantánea en los últimos 7 días
La documentación del servicio añade marcas de tiempo del servidor y la versión de la app en la primera instalación. Según Google, los datos están disponibles durante 90 días. Para un programa de referidos es todo lo que necesitas: el código viaja con la instalación.
Por qué iOS no tiene equivalente
La App Store sí acepta parámetros en un enlace, pero no para tu app. Los enlaces de campaña de la App Store llevan un token de proveedor (pt=) y un token de campaña (ct=), y los resultados aparecen en App Store Connect Analytics: agregados, y cada métrica solo se muestra cuando alcanza un umbral de 5 en el periodo elegido. Apple no documenta ninguna forma de que la app instalada lea el valor ct.
Las herramientas de atribución de Apple miden campañas, no quién invitó a quién. El código tiene que llegar a la app por un camino que recorre el propio usuario.
Las opciones, una a una
1. Universal links: solo si la app ya está instalada
Los universal links son enlaces HTTPS normales que iOS abre en tu app en lugar del navegador. Un enlace como https://example.com/r/ABC123 lleva el código directamente al onboarding.
La pega está en la propia descripción de Apple: "If the person hasn't installed your app, the system opens the URL in their default web browser". Sin la app, se abre el navegador, y la persona a la que quieres atraer normalmente aún no tiene la app. Los universal links solo ayudan si primero instala y después toca el enlace.
Antes de confiar en ellos:
- Necesitas el entitlement de Associated Domains y un archivo
apple-app-site-association. Según la documentación de Associated Domains, la CDN de Apple solicita el archivo en un plazo de 24 horas y los dispositivos buscan actualizaciones aproximadamente una vez por semana tras la instalación. - Si el usuario navega por tu web en Safari y toca un universal link del mismo dominio, iOS se queda en Safari. Prueba los enlaces de referido desde Mensajes y otras apps, no solo desde tu web.
Un aliado relacionado es el Smart App Banner: con un app-argument, abre la app instalada con esa URL. Según Apple, tras una descarga desde el banner, el botón pasa a "Abrir" cuando el usuario vuelve a la página; si vuelve, el código también llega.
2. Deferred deep linking con fingerprinting: lo que dice Apple
Para cubrir el hueco "clic en el enlace, app sin instalar", algunas soluciones de deep linking usan coincidencia probabilística: en el clic, un servidor guarda señales como la dirección IP, el user agent, la versión del sistema y la hora; en el primer arranque, la app envía las mismas señales y el servidor adivina qué clic corresponde a qué instalación.
Apple lo responde en su FAQ de User Privacy and Data Use. A la pregunta de si puedes hacer fingerprinting o usar señales del dispositivo para identificar un dispositivo o un usuario, la respuesta es no —"you may not derive data from a device for the purpose of uniquely identifying it"—, y las apps que lo hagan, o que usen SDKs que lo hagan, pueden ser rechazadas. La documentación de las required reason APIs añade que el fingerprinting no está permitido, haya dado o no el usuario permiso de rastreo. El consentimiento de App Tracking Transparency no lo arregla.
Además, es una base débil para un programa que paga dinero. Las coincidencias son conjeturas: una oficina o una operadora móvil pueden poner a mucha gente detrás de una misma IP, y la comisión se la lleva otra persona. Las señales son cada vez peores: con Relay privado de iCloud, las webs visitadas en Safari ven una dirección IP temporal (Soporte de Apple). Y "la puntuación de coincidencia era baja" no es una respuesta que acepte quien recomienda.
3. El portapapeles y el aviso de pegado desde iOS 16
La landing copia el código (o el enlace de referido completo) y la app lo lee en el primer arranque. O el código está en el portapapeles o no: determinista.
iOS lo ha ido restringiendo. Desde iOS 14, el sistema avisa al usuario cuando una app lee contenido del portapapeles procedente de otra app sin intención del usuario. Y según la documentación de UIPasteControl, "In iOS 16 and later, programmatic pasting raises a user alert that prompts the user for approval". Un aviso de permiso en el primer arranque, antes de que el usuario sepa para qué, es un mal comienzo.
La solución: deja que pegue el usuario.
UIPasteControl/PasteButtonde SwiftUI (iOS 16+): un botón del sistema que el usuario toca; según Apple, sirve para pegar "without a user prompt", sin aviso.- Detección de patrones:
detectPatterns(for:completionHandler:)(iOS 14+, variantes async desde iOS 15) te dice si el portapapeles contiene probablemente una URL, un número o un término de búsqueda. Como no revela el contenido, el sistema no avisa al usuario. Los métodosdetectValuessí devuelven el contenido, y sí avisan.
Así que copia el enlace de referido completo (una URL), compruébalo en silencio y solo entonces muestra un botón de pegar:
let found = try? await UIPasteboard.general.detectedPatterns(for: [\.probableWebURL])
showPasteInvite = found?.contains(\.probableWebURL) == true
// En el onboarding: PasteButton(payloadType: String.self) { items in parseCode(items.first) }
El usuario puede copiar otra cosa antes del primer arranque, así que trata el pegado como un atajo junto a un campo de código.
4. App Clips: lo más parecido a un install referrer
Un App Clip es una pequeña parte de tu app que se abre sin instalación completa: desde un enlace, un código QR, una etiqueta NFC o un App Clip Code. Al arrancar recibe su URL de invocación (responding to invocations), así que https://example.com/r/ABC123 le entrega el código al clip.
El clip puede escribir en un contenedor compartido de App Group o en UserDefaults compartidos. Cuando el usuario instala la app completa, esta sustituye al clip y puede leer esos datos (compartir datos entre App Clip y app). Guarda ahí el código y la app lo encontrará en el primer arranque.
Contras: es trabajo nativo de verdad (un target más en Xcode, experiencias de App Clip en App Store Connect, los límites de tamaño de Apple), y solo cubre a quien abre el clip antes de instalar. Además, los clips no pueden pedir permiso de rastreo; aquí da igual, porque el usuario trae el código consigo.
5. AdAttributionKit y SKAdNetwork: agregado, no por usuario
La atribución de instalaciones de Apple es AdAttributionKit (iOS 17.4+) y, antes, SKAdNetwork, cuya página ya remite a AdAttributionKit para las campañas publicitarias en la App Store. Ambos están pensados para redes publicitarias que se registran en Apple y firman sus anuncios. Los postbacks llegan con un retraso mínimo documentado de 24 a 48 horas, su nivel de detalle depende de niveles de anonimato de grupo (crowd anonymity) y el postback firmado "doesn't include user- or device-specific data": no incluye datos del usuario ni del dispositivo.
Herramienta correcta para campañas de anuncios, equivocada para referidos: quienes recomiendan no son redes publicitarias.
6. Códigos de oferta de Apple con códigos personalizados
Los códigos de oferta para suscripciones dan un periodo con descuento o gratis. Los códigos personalizados son códigos con nombre, como SPRINGPROMO, de hasta 64 caracteres, canjeables mediante una URL de canje o dentro de tu app (iOS 14+). A octubre de 2026, la Ayuda de App Store Connect indica hasta 1 millón de canjes por app y trimestre y hasta 10 ofertas activas por SKU de suscripción.
Buenos para premiar al invitado, limitados para atribuir:
- En StoreKit, el ID de oferta de la transacción contiene el nombre de referencia de la oferta; la documentación no describe un campo para el código personalizado concreto. Para distinguir a quienes recomiendan, cada uno necesitaría su propia oferta, y 10 por SKU no dan para mucho.
- El canje en la app se hace en la hoja del sistema de Apple, y Apple indica que no uses una interfaz propia, así que tu app no ve lo que se escribió.
Úsalos para unos pocos socios grandes, o como descuento además de tu propio código, no como el código en sí.
7. Introducir el código a mano en el onboarding
La opción menos ingeniosa es la más fiable: un campo "¿Tienes un código de invitación?" en el onboarding o en el paywall. Funciona para cualquier camino: búsqueda en la App Store, un código dicho en voz alta, una captura de pantalla. Ponlo fácil: códigos cortos sin caracteres que se confundan (0/O, 1/I), sin distinguir mayúsculas, validación inmediata, y rellénalo automáticamente cuando el código llegue por otra vía.
8. Registro web primero, luego vinculación de la cuenta
Si tu producto tiene cuentas, te saltas el problema de la instalación: el usuario se registra en tu web, el código se guarda con la cuenta y, cuando inicia sesión en la app, tu backend ya sabe quién lo invitó.
Para las compras dentro de la app, vincula la transacción a esa cuenta: appAccountToken de StoreKit (iOS 15+) admite un UUID para tu usuario, y la App Store lo devuelve en la transacción resultante.
Un diseño determinista que funciona
Todos los caminos acaban en el mismo sitio: un código asociado a un usuario.
- Cada persona que recomienda recibe un código y un enlace en un dominio que gestiona tu app, por ejemplo
https://example.com/r/ABC123. - App instalada: el universal link abre la app, el onboarding muestra el código ya rellenado y el usuario confirma.
- App sin instalar: el enlace abre una landing con el código en grande, un botón "Copiar código" (copia el enlace completo para que la detección de patrones lo encuentre), un botón de la App Store y, si tienes cuentas, "Regístrate en la web".
- Primer arranque: el onboarding muestra el campo de código y, si probablemente hay una URL en el portapapeles, un botón de pegar. Nunca leas el portapapeles en silencio.
- Registro web: el código ya está en la cuenta; el login en la app lo vincula y
appAccountTokenle asocia la compra. - En el servidor: valida el código, bloquea los autorreferidos y asocia el código a la suscripción.
Quien se salte todo esto no queda atribuido. Es el precio honesto de no adivinar.
Tabla de decisión
| Tu situación | Usa |
|---|---|
| App de suscripción, las instalaciones llegan desde la App Store | Campo de código + relleno por universal link + botón de pegar |
| Los usuarios suelen registrarse primero en la web | Vinculación por registro web + appAccountToken; campo de código como respaldo |
| Códigos QR, carteles, eventos | App Clip que pasa el código por un App Group, si puedes invertir en trabajo nativo |
| Quieres dar un descuento al invitado | Código de oferta de Apple para el descuento, tu propio código para la atribución |
| Mides campañas de anuncios de pago | AdAttributionKit / SKAdNetwork a través de tu red publicitaria |
| Te tienta el matching "mágico" de instalaciones | No lo hagas: Apple no permite el fingerprinting, con o sin consentimiento |
Checklist antes de publicar
- Campo de código en el onboarding y en el paywall, con validación inmediata
- Universal links configurados y probados desde Mensajes, no solo desde tu web
- Portapapeles solo mediante
PasteButton/UIPasteControl; comprobaciones silenciosas solo con detección de patrones - Los registros web guardan el código en el servidor; las compras en la app llevan
appAccountToken - Ningún SDK en la app que haga fingerprinting o coincidencia probabilística
- Condiciones del programa visibles en la app (consulta las reglas de la App Store para programas de referidos)
Dónde encaja AppThunder
AppThunder Referrals se basa justo en este modelo determinista: un referido solo cuenta cuando llega un código de verdad, sin fingerprinting del dispositivo ni coincidencias probabilísticas. Los códigos llegan por tres vías: el webhook de suscripciones (tu app guarda el código como atributo de suscriptor at_ref y los eventos de suscripción dentro de la app lo llevan consigo), el webhook de Stripe para pagos web y una API REST para tu backend (POST /codes, /referrals, /events con la clave secreta; GET /codes/:code con la clave pública para validar un código escrito en tu campo de onboarding). Hay plantillas para copiar y pegar en Swift, Kotlin, React Native, Flutter y web; el snippet web conserva un código como primer contacto durante 90 días en el mismo dispositivo, lo que cubre el caso "visita ahora, regístrate en la web más tarde".
Las comisiones quedan pendientes durante una retención de 30 días por defecto, los reembolsos las anulan, los autorreferidos están bloqueados y pagas tú a partir de exportaciones (PayPal Mass Pay, lote de Wise, CSV): AppThunder nunca guarda ni mueve dinero. A octubre de 2026 cuesta una tarifa plana de 19 € al mes, sin IVA y sin porcentaje sobre ingresos.
Lo que no hace: atribuir a un usuario que nunca introduce, pega ni trae un código; es el precio de no adivinar. No configura tus universal links, tu Smart App Banner ni tu App Clip, y no puede darte un install referrer en iOS, porque no existe.
Preguntas frecuentes
¿Hay en iOS un equivalente al Play Install Referrer? No. La atribución de instalaciones de Apple (AdAttributionKit, SKAdNetwork, enlaces de campaña) es agregada. Un código por usuario tiene que llegar por un camino que recorre el usuario: un enlace, un pegado, un App Clip, un código escrito o una cuenta.
¿Puedo hacer fingerprinting si el usuario permite el rastreo? No. Según la documentación de Apple, el fingerprinting no está permitido, con o sin permiso de rastreo.
¿Puedo leer el portapapeles en el primer arranque?
Desde iOS 16, una lectura programática muestra un aviso de permiso. Usa PasteButton o UIPasteControl para que el usuario pegue de forma deliberada, sin aviso.
¿Pueden los códigos de oferta de Apple sustituir a mis códigos de referido? No del todo. StoreKit identifica la oferta por su nombre de referencia, no por el código personalizado concreto, y hay un máximo de 10 ofertas activas por SKU de suscripción.