Vue d'ensemble de la plateforme

Page Vue d'ensemble du dashboard DeepLink
Page Vue d'ensemble — KPIs globaux, trafic, conversions, santé technique. Premier écran après login.

DeepLink est une plateforme open-source d'attribution et de deep linking mobile, alternative à Branch.io, Adjust et AppsFlyer. Elle couvre l'intégralité du cycle de vie d'un utilisateur mobile :

  1. Acquisition — Créez des liens universels et des bannières intelligentes pour attirer les utilisateurs vers votre app
  2. Attribution — Identifiez précisément quel canal, campagne ou publicité a généré chaque installation
  3. Engagement — Suivez les actions in-app (événements) pour mesurer la qualité des utilisateurs acquis
  4. Monétisation — Calculez la LTV, le ROAS et le payback pour optimiser vos dépenses publicitaires
  5. Rétention — Analysez les cohortes pour comprendre quand et pourquoi les utilisateurs partent
Le principe fondamental
Toute la plateforme repose sur une chaîne de données : clic → redirection → installation → événements in-app. Le serveur enregistre chaque clic. Le SDK dans l'app remonte les événements. Le dashboard croise les deux pour produire l'attribution, les cohortes, la LTV et le ROAS. Sans événements remontés par le SDK, les pages de suivi (Entonnoir, Attribution, Cohortes, LTV, Parrainages) n'ont rien à afficher.

D'où viennent les données ?

Chaque page du dashboard tire ses données d'une ou plusieurs sources. Comprendre ces sources est essentiel pour savoir pourquoi une page affiche des résultats ou reste vide.

Les 4 sources de données

SourceQui l'alimenteQue contient-ellePages qui l'utilisent
Clics (table clicks) Enregistré automatiquement par le serveur à chaque visite sur un lien DeepLink Horodatage, IP, User-Agent, plateforme, pays, fingerprint, lien source, campagne, source, medium Vue d'ensemble, Realtime, Liens, Explorateur, Entonnoir, Attribution, Cohortes
Événements (table events) Envoyés par le SDK mobile, le SDK serveur, le Web Tracker, ou l'API directe Nom (purchase, signup…), propriétés JSON, revenu, devise, fingerprint, user_id Événements, Entonnoir, Attribution, Cohortes, LTV & ROAS, Parrainages
Dépenses pub (table ad_spend) Importées manuellement via le dashboard (bouton "+ Ad spend") ou l'API Date, réseau (Meta, Google…), campagne, montant dépensé, devise Attribution par canal, LTV/CAC, Payback, ROAS
Bannières (table banner_events) Enregistrées automatiquement par le script banner.js embarqué sur votre site Impressions, clics, variante, bannière, groupe A/B Bannières intelligentes, A/B Tests (type bannière)

Les événements : le carburant du suivi

Les événements sont la donnée la plus importante de la plateforme après les clics. Sans eux, les pages suivantes restent vides :

Événements essentiels à configurer
Au minimum, configurez ces événements dans votre app :
signup — inscription d'un nouvel utilisateur
login — connexion (mesure la rétention)
purchase — achat, avec revenue en paramètre (alimente la LTV)
tutorial_complete — fin du tutoriel (mesure l'engagement initial)

Comment envoyer des événements

Il y a 4 façons d'envoyer des événements à DeepLink :

1. Via le SDK mobile (recommandé)

Chaque SDK (iOS, Android, React Native, Flutter, Unity, KMP) expose une méthode trackEvent :

// Événement simple
DeepLink.trackEvent("signup")

// Événement avec propriétés
DeepLink.trackEvent("add_to_cart", properties: [
  "product_id": "SKU-789",
  "category": "electronics"
])

// Événement avec revenu (alimente la LTV)
DeepLink.trackEvent("purchase", properties: [
  "product_id": "SKU-789",
  "order_id": "ORD-001"
], revenue: 49.99)

Le SDK rattache automatiquement le fingerprint, le sdk_instance_id et le user_id (si identify() a été appelé). C'est ce qui permet au serveur de relier l'événement au clic d'origine.

2. Via le Web Tracker (dataLayer)

Le Web Tracker est un script JavaScript autonome qui intercepte les événements du dataLayer Google Tag Manager et les transmet à DeepLink. C'est la façon la plus simple de capter les conversions web sans modifier votre code :

<script src="https://votre-serveur/deeplink-tracker.js"
        data-tenant="votre-slug"
        data-events="purchase,signup,add_to_cart"
        async></script>

Comment ça marche :

  1. Le script est chargé sur votre site web
  2. Il intercepte dataLayer.push() (monkey-patch transparent)
  3. Chaque push dont le nom d'événement est dans la liste data-events est capturé
  4. L'événement est envoyé à POST /api/v1/events avec le tenant slug, le nom, les propriétés, et un visitor_id persisté en localStorage
  5. Le cookie dl_vid (posé par le redirect DeepLink) est lu pour l'attribution — ce qui permet de relier un achat web à un clic DeepLink
Cas d'usage typique
Vous avez un site e-commerce et une app mobile. Un utilisateur clique sur un lien DeepLink → arrive sur le site web (pas l'app) → achète. Le Web Tracker capte le purchase du dataLayer et l'attribue au lien DeepLink d'origine grâce au cookie dl_vid.

Attributs du script :

AttributObligatoireDescription
data-tenantOuiSlug du tenant
data-eventsNonListe d'événements à capturer (séparés par virgule). Si omis, TOUS les événements dataLayer sont capturés.
data-serverNonURL du serveur DeepLink (par défaut : l'origine du script)

3. Via un tag Google Tag Manager

Le fichier gtm-tag-template.js est un template de tag GTM custom. Il permet de configurer le tracking DeepLink directement dans l'interface GTM, sans code. Les variables GTM (ecommerce, custom dimensions) sont automatiquement mappées vers les propriétés d'événement DeepLink.

4. Via l'API directe (serveur-à-serveur)

Pour les événements côté serveur (webhook Stripe, backend batch), utilisez l'API REST :

POST /api/v1/events
{
  "tenant_slug": "votre-slug",
  "name": "purchase",
  "revenue": 49.99,
  "currency": "EUR",
  "user_id": "user_123",
  "event_id": "evt_abc123",  // pour la déduplication
  "link_slug": "promo-ete",   // pour l'attribution au lien
  "properties": { "order_id": "ORD-001" }
}

Endpoint batch pour les files d'attente offline : POST /api/v1/events/batch (max 100 événements par requête).

L'identification : le lien entre clic et événement

Pour que le serveur puisse relier un événement à un clic (et donc attribuer la conversion au bon lien/campagne), il utilise une chaîne d'identité par priorité :

IdentifiantComment il arriveFiabilitéImpact sur le suivi
user_id Appelé manuellement via identify("user_123") dans le SDK Excellent Identifie l'utilisateur de façon certaine, même après changement d'IP ou de device. Cohortes et LTV précises.
sdk_instance_id Généré automatiquement par le SDK à la première utilisation Bon Unique par appareil. Ne survit pas à une réinstallation. Bon pour les apps sans système de login.
ip_hash Calculé automatiquement par le serveur (SHA-256 de l'IP) Faible Partagé entre tous les utilisateurs d'un même réseau WiFi. Peut changer (réseau mobile). Génère des faux positifs dans les cohortes (un utilisateur qui change de réseau apparaît comme un nouvel utilisateur).
Alerte qualité
Le dashboard affiche un bandeau d'alerte sur les pages Cohortes et LTV si plus de 20% de vos utilisateurs sont identifiés uniquement par IP. Appelez identify(userId) dans votre SDK dès que l'utilisateur se connecte pour améliorer la précision.

Concepts clés

Tenant

Un tenant est un espace isolé : ses propres liens, événements, utilisateurs, clés API, configuration. Chaque tenant a un slug unique (ex: demo-10ty40v7) utilisé dans les URL. Un super-admin peut gérer plusieurs tenants depuis le même dashboard.

Un lien DeepLink est une URL courte (ex: https://links.example.com/demo/photo-earth) qui redirige intelligemment selon la plateforme :

Attribution

L'attribution répond à la question : "quel clic a généré cette conversion ?". DeepLink supporte 5 modèles :

ModèleLogiqueUsage recommandé
Last-touch100% du crédit au dernier clicPar défaut. Simple et intuitif.
First-touch100% au premier point de contactMesurer la notoriété et la découverte
LinéaireCrédit réparti égalementVision équilibrée du parcours
Time-decayPlus de crédit aux contacts récentsCampagnes avec cycle de décision long
Data-drivenPondération automatique basée sur les donnéesQuand vous avez assez de volume

Paramètres dynamiques & Custom Data

Chaque lien peut porter des données supplémentaires qui sont transmises à l'app via le SDK au moment de la résolution. Il y a deux mécanismes :

Paramètres d'URL dynamiques

Ajoutés à la volée dans l'URL du lien lors du partage :

https://links.example.com/demo/promo-ete?promo_code=SUMMER24&variant=blue

Le serveur capture ces paramètres au moment du clic et les stocke. Le SDK les reçoit lors de la résolution (/resolve ou /match). Utile pour :

Custom Data (JSON)

Défini lors de la création du lien dans le dashboard (champ custom_data). Ce JSON est transmis tel quel au SDK :

{
  "screen": "product_detail",
  "product_id": "SKU-789",
  "campaign_variant": "hero_image_v2"
}

Page Params dynamiques dans le dashboard

La page Outils → Params dynamiques fournit une analyse des paramètres réellement utilisés :

Filtrez par lien et par période pour analyser l'usage des params sur une campagne spécifique.

Le Dashboard

Page Realtime — flux SSE des événements live
Page Realtime — flux Server-Sent Events des clics et événements en direct.

Toutes les pages du dashboard

Mapping <div id="page-X"> dans dashboard.html vers la sidebar :

ID HTMLSidebarRôle
page-overviewSuivi → OverviewKPIs globaux + chart période + top liens
page-mydashSuivi → My DashboardLayout drag-drop personnalisable user
page-realtimeSuivi → RealtimeFlux SSE événements temps réel
page-segmentsSuivi → SegmentsDéfinition + analyse cohortes filtrées
page-explorerSuivi → ExplorerOLAP table multi-dimensions (pays × OS × source)
page-cohortSuivi → Cohortes & rétentionHeatmap rétention + courbes par dimension
page-funnelSuivi → FunnelsAnalyse tunnel conversion multi-step
page-ltvSuivi → LTVCustomer lifetime value par cohorte/canal
page-costSuivi → Coûts & ROICoûts ad-platforms × revenus = ROAS
page-attributionSuivi → AttributionModèles multi-touch (last-click, linear, time-decay)
page-testerOutils → TesterTest live d'un deeplink (preview UA + résolution)
page-usersOutils → UsersGestion users tenant + invitations + rôles
page-workflowsOutils → WorkflowsBuilder workflows (triggers + actions)
page-templatesOutils → TemplatesCRUD link templates réutilisables
page-dynparamsOutils → Dynamic paramsGestion query params dynamiques par lien
page-bannersOutils → Smart BannersCRUD bannières iOS/Android web→app
page-ab-testsOutils → A/B TestsCRUD A/B + promotion variant gagnant
page-auditOutils → Audit logJournal mutations + filtres + FTS search
page-settingsSettings (12 onglets)Cf. section Réglages

Vue d'ensemble

Page d'accueil après connexion. Source de données : table clicks + events (revenu).

Realtime

Source : table clicks (dernières 24h) + SSE (Server-Sent Events). Rafraîchi toutes les 5 secondes.

Explorateur

Requêteur interactif. Source : requêtes SQL générées dynamiquement sur clicks + events.

Sélectionnez des métriques (clics, installations, conversion, revenu) et des dimensions (plateforme, pays, campagne, source), ajoutez des filtres, puis visualisez en graphique ou tableau. Export CSV disponible. Les requêtes peuvent être sauvegardées comme widget sur votre tableau de bord personnalisé.

Mon tableau de bord

Dashboard personnalisable avec widgets glisser-déposer :

Liste des liens — colonnes slug, destination, campagne, statut, clics
Vue liste des liens. Filtres par statut/plateforme/tag, KPIs en haut (liens actifs, clics 7j, CTR moyen, conversions).

Depuis la page Contenu → Liens, cliquez Nouveau lien.

ChampDescriptionImpact
slugIdentifiant court dans l'URL. Auto-généré si vide.Définit l'URL finale du lien
title / description / image_urlMétadonnées Open GraphAperçu dans les partages sociaux (iMessage, WhatsApp, Twitter)
ios_uri_schemeURI scheme iOS (ex: myapp://product/123)Permet d'ouvrir l'app au bon écran
android_uri_schemeURI scheme AndroidIdem pour Android
web_urlURL de fallback web/desktopOù va l'utilisateur s'il n'a pas l'app et n'est pas sur mobile
campaign / source / mediumParamètres UTMAlimentent l'explorateur, l'attribution, les filtres
tagsTags libres (séparés par virgule)Filtrage dans le tableau des liens
custom_dataJSON libre transmis au SDKL'app reçoit ces données au moment de la résolution (navigation contextuelle)
expires_at / max_clicksLimites de validitéLe lien renvoie une erreur 410 une fois expiré ou cappé

Chaque lien affiche : slug (badge + copie URL), destinations (chips iOS/Android/Web), campagne, statut, clics 7j, CTR, sparkline de tendance. Filtrez par statut, plateforme ou tag. Triez par colonne. Sélection multiple pour les actions en masse (dupliquer, désactiver, supprimer, tagger).

Popup accessible depuis le bouton en haut de page. Teste une URL en simulant différents User-Agents. Affiche une trace d'exécution : résolution DNS, TLS, réponse 301, Universal Link match, deferred deep link, fallback store — chaque étape avec un indicateur pass/warn/fail.

Chaque lien dispose d'un QR code généré automatiquement. Accessible depuis l'icône QR dans les actions du tableau.

Les modèles (page Outils → Modèles) stockent des presets réutilisables (URI schemes, campaign, custom_data). Appliquez un modèle en un clic lors de la création d'un lien. Affichés en galerie avec preview.

Bannières intelligentes

Liste des bannières avec preview mobile à droite
Bannières intelligentes — variants bar/floating/fullscreen/interstitial, preview live à droite, KPIs impressions/CTR.

Principe

Éléments JavaScript embarqués sur votre site web qui incitent les visiteurs mobile à installer votre app. Source de données : impressions et clics enregistrés par le script banner.js.

4 variantes : Bar (bande haut/bas), Interstitial (modal overlay), Fullscreen (plein écran + image), Floating (carte d'angle discrète).

Éditeur

Cliquez sur une bannière pour ouvrir l'éditeur (gauche) avec l'aperçu live (droite, phone mockup). Sections : Général (nom, lien, variante, position), Contenu (texte, bouton, icône), Look & feel (couleurs, rayon, padding), Ciblage (groupe A/B).

Installation

<script src="https://votre-domaine/banner.js"
        data-tenant="votre-slug"
        async></script>

A/B Tests

Liste des A/B tests en cours — variantes et uplift
A/B tests sur liens ou bannières. Métrique CTR / conversion / revenu, statut significatif calculé automatiquement.

Principe

Comparez des variantes de liens ou bannières. L'assignation est persistante (hash SHA-256 déterministe : un même visiteur voit toujours la même variante).

Source de données : clics (test de lien) ou impressions/clics de bannière (test de bannière). Le test compare les taux de conversion entre variantes.

Créer un test

  1. Type : test de lien ou de bannière
  2. Métrique : CTR, conversion ou revenu
  3. Au moins 2 variantes parmi vos liens/bannières existants
  4. Répartition du trafic (%, somme = 100%)

Résultats

La liste affiche : statut (En cours/Terminé/En pause), uplift (toujours un %, jamais N/A), confiance (barre + % — vert si ≥ 95%), sparkline. Cliquez une ligne pour le détail : tableau par variante, graphique daily, snippet d'intégration.

Significativité : z-test bilatéral, minimum 100 échantillons par variante, uplift > 5%. Niveaux de confiance : 95% et 99%.

Suivi & Analytics

Funnel analysis — visualisation de tunnel de conversion multi-step
Funnel — visualisation des étapes de conversion (impression → clic → install → first-event → purchase) et taux de drop-off.
Cohort retention — heatmap de rétention par jour/semaine
Cohort & rétention — heatmap par cohorte d'install. Chaque ligne = un groupe d'utilisateurs, chaque colonne = J+N.
Attribution multi-touch — répartition du crédit entre touchpoints
Attribution multi-touch. Modèles disponibles : last-click, first-click, linear, time-decay, position-based.
Top sources — UTM source/medium/campaign
Sources & campagnes — découpage UTM avec drilldown (source × medium × campaign).
Heatmap géographique des clics
Géographique — heatmap des clics par pays, drilldown par région/ville.
Prérequis pour tout le suivi
Les pages de cette section n'affichent des données que si des événements sont remontés par le SDK ou le Web Tracker. Si les pages sont vides, vérifiez que votre app appelle bien trackEvent() et que le tenant_slug est correct. Voir la section Comment envoyer des événements.

Événements

Source : table events. Les schémas sont auto-découverts : dès qu'un nouvel événement arrive avec un nom inconnu, le serveur crée automatiquement le schéma.

La page affiche : catalogue des événements avec nom, nombre de propriétés, volume 7j, sparkline de tendance, statut de validation du schéma (VALID/WARN), date de dernière ingestion.

Déduplication : si un event_id est fourni dans la requête, les doublons sont ignorés (réponse 200 avec deduplicated: true).

Entonnoir de conversion

Source : jointure clicks + events. Le funnel suit le parcours : Redirect → App Open → Deferred → Events.

Chaque étape montre : numéro, nom, drop-off (chip rouge "-X% DROP"), nombre absolu, pourcentage, barre de progression. Deux vues : Barres (design system) et Sankey (diagramme de flux avec drop-off visuel).

Si l'étape "Events" affiche 0, c'est que votre app ne remonte pas d'événements.

Funnel UX — builder drag-drop, saved cards, glossary

Au-delà du funnel par défaut Click → App Open → Events, le Custom builder (FNL-UX livré 2026-05-01) permet de construire des entonnoirs sur mesure.

  1. Onglet "Custom" dans la page Funnel → + Nouveau funnel.
  2. Autocomplete events : tape un préfixe → liste des event names réels du tenant (issus de GET /events/names). Pas de duplication possible.
  3. Drag-drop steps : réordonne par drag natif HTML5. L'ordre détermine le flux de conversion.
  4. Templates : 4 templates pré-faits (E-commerce, SaaS onboarding, Mobile gaming, Acquisition pub) — clic = remplit le builder en 1 step.
  5. Save card : nomme et enregistre. Apparaît dans la sidebar "Saved cards".

Saved cards — 5 actions inline

ActionEffet
OpenAffiche le funnel. URL contient ?funnel_id=... partageable.
RenameModal _promptModal réutilisable (livré FNL-UX). Persistance immédiate.
DuplicateCrée une copie "X (copy)" qu'on peut éditer sans toucher l'original.
ShareCopie l'URL deeplink dans le clipboard.
DeleteDELETE /api/v1/funnels/:id avec confirm modal.

Funnel — glossaire des termes

TermeDéfinition
ClickRedirect HTTP de l'utilisateur sur le lien (avant install). Source = clicks table.
App OpenDéclenchement handleOpenURL() dans l'app native, après ouverture par le SDK. Source = clicks.source = 'resolve'.
WindowDélai max pour qu'un step soit attribué au step précédent. Default 30j (paramétrable par funnel).
Scope TenantMétriques tenant entier (toutes les sources confondues).
Scope LienMétriques d'un seul lien (drill-down). Sélectionnable via dropdown haut de page.
Drop-off% utilisateurs perdus entre 2 steps. Chip rouge "-X% DROP" si supérieur au seuil de la cellule.

Default tab et Custom tab partagent le rendu via le helper unifié _renderFunnelStepsBars (livré FNL-UX). KPIs incluent conversion globale, taux par step, comparaison previous_period (si donnée), TTS (Time-To-Step).

Workflows — automatisation par règles

Concept : "Si X arrive → faire Y". Analogie : Zapier ou IFTTT, mais triggéré par les événements DeepLink (clicks, events, deeplinks ouverts).

Anatomie d'un workflow (4 blocs) :

5 exemples concrets

  1. Welcome onboarding : install reçu → wait 1h → push notif "Bienvenue" → wait 24h → email tutorial.
  2. Cart abandon : event add_to_cart mais pas purchase à J+1 → email rappel produit + 10% promo.
  3. Re-engagement : pas de session J-30 → push "On vous a manqué" + lien deferred vers leur dernière page consultée.
  4. VIP upgrade : ≥3 purchase events en 30j → tag user "VIP" + accès feature beta + email gratitude.
  5. Churn warning : retention drop {'>'}40% sur cohort → alerte Slack ops avec liste users à risque.

UI builder : Settings → Workflows → + Nouveau workflow. Voir aussi le playbook 5 templates pour les workflows livrés clé-en-main.

Attribution

Source : clicks + events + optionnellement ad_spend.

Deux vues :

Cohortes & rétention

Source : clicks (date d'acquisition = date du premier clic par fingerprint) + events (activité de retour). La rétention est calculée comme : "parmi les utilisateurs acquis la semaine S, combien ont produit un événement à D1, D7, D14, D21, D30 ?"

Heatmap : lignes = cohortes (semaines), colonnes = fenêtres de rétention. Cellules colorées par opacité (accent oklch), texte blanc si > 50%. KPIs : D1 moyen, D7 moyen, D30 moyen.

Si la heatmap est vide, c'est que votre app ne remonte pas d'événements réguliers (login, session_start, etc.).

Méthodologie détaillée — comment c'est calculé

Page Suivi → Cohortes & rétention (#page-cohort, dashboard.html:894-940). Deux endpoints serveur :

  1. Endpoint A (heatmap par jour) — GET /api/v1/cohort/heatmap?days=30&windows=1,7,30. Renvoie [{ cohort_date, cohort_size, retention: { d1, d7, d30 } }]. La cohorte = users avec ≥ 1 clic ce jour-là (group by DATE(clicks.timestamp) + identité résolue via cascade).
  2. Endpoint B (rates par dimension) — GET /api/v1/cohort/rates?dim=source&windows=1,7,30. Renvoie [{ dim_value, total, retention_d1, d7, d30 }]. Permet de comparer les canaux (Facebook 5.6% D7 vs Organic 34.2%).

Identification de l'utilisateur (cascade)

Pour qu'un user d'aujourd'hui soit reconnu comme appartenant à la cohorte d'il y a 7 jours, il faut une identité stable. DeepLink utilise COALESCE(user_id, device_anchor_id, sdk_instance_id, visitor_id, fingerprint, ip_hash) étendue par les identity_aliases nightly (cf. § Architecture / Identity lifecycle).

Limites actuelles & chantier COHORT-PRO

Toutes adressées par chantier COHORT-PRO (statut 🟡 spec ready) — cf. BACKLOG.md.

LTV & ROAS

Source : clicks + events avec revenue + optionnellement ad_spend.

Si la LTV est à 0, c'est que vos événements n'incluent pas de paramètre revenue. Ajoutez-le dans vos appels trackEvent("purchase", ..., revenue: 29.99).

Parrainages

Source : tables referrals + referral_claims.

Fonctionnement :

  1. Un admin crée un code de parrainage (ex: SUMMER24) via le dashboard ou l'API. Le code est associé à un referrer_id et optionnellement à un type de récompense.
  2. Le code génère une URL courte (/r/SUMMER24) que le parrain partage.
  3. Quand un filleul clique, s'inscrit et convertit, l'app appelle POST /api/v1/referrals/claim avec le code et le referee_id.
  4. Le dashboard affiche les KPIs : codes actifs, parrainages 30j, claims non réglés, taux de conversion. Les claims peuvent être marqués "réglés" par un admin.

SDKs — Intégration dans l'app

SDKs disponibles

SDKLangagePlateformeFonctions clés
iOSSwiftiOS 15+Universal Links, deferred, identify, trackEvent, offline queue
AndroidKotlinAPI 24+App Links, deferred, identify, trackEvent, offline queue
KMPKotlin MultiplatformiOS + AndroidCode partagé iOS/Android
React NativeTypeScriptRN 0.73+Bridge natif, même API que les SDK natifs
FlutterDartFlutter 3.19+Plugin avec channels natifs
Web JSJavaScriptNavigateursidentify, trackEvent, cookie attribution
UnityC#Unity 2022+Deep links, identify, trackEvent, offline queue
Node.jsJavaScriptServeurtrackEvent serveur-à-serveur
PythonPython 3.8+ServeurtrackEvent serveur-à-serveur
GoGo 1.21+ServeurtrackEvent serveur-à-serveur

Flux d'intégration (4 étapes)

  1. Initialiser le SDK avec votre tenant_slug et l'URL du serveur. Le SDK génère un sdk_instance_id et le persiste localement.
  2. Identifier l'utilisateur dès qu'il se connecte : identify("user_123"). Le SDK attache cet ID à tous les événements et appels ultérieurs.
  3. Gérer les deep links entrants : le SDK intercepte l'URL, appelle /resolve (Universal Link) ou /match (deferred), et retourne les custom_data du lien pour que l'app navigue au bon écran.
  4. Tracker les événements : appelez trackEvent("purchase", {product: "abc"}, 29.99) à chaque action significative. Le SDK rattache automatiquement le fingerprint et l'identité.

Deferred deep linking — pas à pas

Scénario : l'utilisateur n'a pas l'app installée

1. L'utilisateur clique sur un lien DeepLink
2. Le serveur enregistre le clic avec fingerprint = SHA256(IP + User-Agent)
3. Le serveur redirige vers l'App Store / Play Store
4. L'utilisateur installe l'app et l'ouvre
5. Le SDK appelle POST /api/v1/match avec le fingerprint de l'appareil
6. Le serveur compare avec les clics des dernières 48h (même IP + UA similaire)
7. Match trouvé → le serveur retourne les custom_data du lien
8. L'app navigue vers le bon contenu (ex: page produit spécifique)

Queue offline

Le SDK stocke les événements localement quand il n'y a pas de connexion. Dès que le réseau revient, il les envoie en batch via POST /api/v1/events/batch (max 100 par requête). La déduplication par event_id garantit qu'un événement n'est jamais compté deux fois, même en cas de retry.

Segments d'audience

Page Segments — définition de cohortes filtrées
Segments — composer des cohortes par filtres (pays, OS, source, événement déclenché, valeur LTV…) puis exporter ou cibler.

Les segments (page Outils → Segments) permettent de définir des groupes d'utilisateurs basés sur des critères : pays, plateforme, campagne, source, type de source, période. Ils servent de filtres pour l'explorateur et les rapports. Chaque segment stocke sa définition et peut être prévisualisé avant sauvegarde.

Réglages

Page Réglages — vue d'ensemble des sections
Réglages — entrée pour configurer Brand, Mobile (Universal/App Links), Webhooks, SSO, Exports, API Keys, Users…
Réglages Mobile — Apple Team ID, bundle ID, Android package, SHA-256
Réglages → Mobile. Pose les valeurs qui alimentent /.well-known/apple-app-site-association et /.well-known/assetlinks.json.
Réglages SSO — OIDC + SAML 2.0
Réglages → SSO. OIDC (Okta, Auth0, Google Workspace, Entra) + SAML 2.0 — kill switch local-login pour forcer SSO.

Accessibles depuis Admin → Réglages. Navigation dédiée organisée en sections.

Mon compte

Profil (nom, email), changement de mot de passe, 2FA (TOTP). Validation des clics : TTL, seuil de fraude, IPs bloquées.

SSO / SAML

SAML 2.0 pour le SSO d'entreprise (Okta, Azure AD, Google Workspace). Config : Metadata URL + Entity ID. Côté IdP : ACS URL = /api/v1/auth/saml/callback.

Marque

Logo URL + couleur primaire. Utilisés sur la page de redirection, les emails et les bannières. Aperçu live dans les réglages.

Utilisateurs

CRUD complet : créer (mot de passe ou lien d'invitation par email), promouvoir/rétrograder (User/Admin), réinitialiser mot de passe, supprimer.

Clés API

Portées : Full access ou Read-only. La clé n'est affichée qu'une fois à la création. Rotation (nouvelle clé, ancienne invalidée). Révocation définitive.

Webhooks

Multi-endpoint. Chaque endpoint : URL, secret HMAC (X-Deeplink-Signature), API Key (X-Api-Key), filtre d'événements, pause/activation. Pub/Sub en parallèle. Historique des livraisons avec rejeu.

Événements routés : redirect, resolve, deferred, event.*, referral.claim, banner.click, banner.impression, test.ping.

Domaines

CNAME vers le serveur Cloud Run. Vérification DNS intégrée.

Apps mobiles

iOS : Apple Team ID + Bundle ID → génère AASA. Android : Package + SHA-256 → génère assetlinks. Boutons de test intégrés.

Data Warehouse & Export (Sinks)

Les Sinks permettent d'exporter les données vers 6 destinations : BigQuery (streaming), Google Cloud Storage (batch), Amazon S3 (batch), Google Pub/Sub (streaming), email (rapport HTML) et webhook (HTTP).

Modes de déclenchement :

Bouton "Tester la connexion" : dans le formulaire de création ou d'édition d'un Sink, chaque destination dispose d'un bouton pour tester la connexion avant d'enregistrer. Accessible aux admin (anciennement super-admin uniquement).

Note : les destinations BigQuery et Pub/Sub nécessitent le package @google-cloud/bigquery / @google-cloud/pubsub installé côté serveur.

Intégrations

Segment (Write Key), Amplitude (API Key), Mixpanel (Project Token). Les événements sont forwardés en temps réel.

RGPD & conformité

Rétention configurable, purge automatique, demande d'effacement, audit log, IP allowlist, rapports de bugs, logs plateforme.

Flux de redirection complet

L'utilisateur clique sur https://links.example.com/demo/photo-earth?promo=SUMMER

1. Le serveur reçoit GET /demo/photo-earth?promo=SUMMER
2. Il cherche le lien en base (slug=photo-earth, tenant=demo)
3. Il vérifie : actif ? non expiré ? max_clicks non atteint ?
4. Il détecte la plateforme via User-Agent
5. Il enregistre un clic : fingerprint, IP, pays, device, params dynamiques (promo=SUMMER)
6. Il dispatche vers les webhooks (tous les endpoints actifs + Pub/Sub)
7. Il redirige :
   iOS avec app    → Universal Link → l'app s'ouvre, SDK appelle /resolve
   iOS sans app   → Page de redirection (logo + couleur marque) → App Store
   Android        → App Link ou Intent → Play Store si pas installé
   Desktop        → web_url (https://example.com/product/123)

8. Le SDK dans l'app appelle /resolve (ou /match si deferred)
9. Le serveur retourne : { link_slug, custom_data, params: {promo: "SUMMER"} }
10. L'app navigue au bon écran et applique le code promo

Permission matrix (RBAC)

5 rôles disponibles, attribués au niveau du tenant. Le rôle super-admin est exclusif au tenant main.

Actionsuper-adminadmineditorviewerbilling
Lire les liens / analytics
Créer / modifier liens
Supprimer liens
Inviter / supprimer users
Modifier rôles users
API keys (CRUD)
Settings tenant
Webhooks (CRUD)
Workflows (CRUD)
Audit log (lecture)✅ (cross-tenant)✅ (own tenant)
Bug reports
Export (GCS / BigQuery)
Stripe billing portal
Voir factures
Switch tenant (super-admin)
Cloud Logging viewer
Webhook DLQ replay
Run scheduled job manually
💡
Custom roles — pas supportés actuellement. Les 5 rôles sont fixes. Customisation par scope sur API keys uniquement (read:links, write:events, etc.).

KPIs & métriques — glossaire

Tous les KPIs affichés dans le dashboard, avec leur source DB et leur formule de calcul.

KPIDéfinitionSource / Formule
ClicksNombre de redirections via un lienCOUNT(*) FROM clicks
Unique clicksClics uniques par fingerprintCOUNT(DISTINCT fingerprint_hash)
App opensOuvertures d'app captées par le SDKCOUNT(*) FROM events WHERE event_type='app_open'
InstallsPremières app_opens jamais vues pour un deviceapp_open avec sdk_instance_id jamais vu auparavant
Conversion rate% de clics qui aboutissent à un app_openapp_opens / clicks
Match rate (deferred)% de clicks deferred raccrochés à un installSUM(matched=true) / SUM(deferred)
RevenueSomme des montants des events avec revenueSUM(revenue) FROM events
ARPUAverage Revenue Per Userrevenue / unique_users
LTV (D30)Revenu cumulé par cohorte d'acquisition à J+30cf. § Cohortes
CACCustomer Acquisition Costad_spend / installs par campagne
ROASReturn On Ad Spendrevenue / ad_spend
Payback periodJours pour que la LTV dépasse le CACpremière date où cumulative_revenue >= CAC
Retention D1/D7/D30% de la cohorte revenue à J+Ncf. § Cohortes
Funnel conversion% qui passe d'une étape à la suivantestep_n / step_(n-1)
CTR (Smart Banner)Click-through rate de la bannièrebanner_clicks / banner_impressions
Time-to-deeplink (TTD)Délai click → app_openapp_open.timestamp - click.timestamp (ms)
Suspicious rate% de clics flaggés suspiciousSUM(suspicious=true) / COUNT(*)
p95 / p99 latencyLatence redirection au percentile 95/99histogramme des durées /redirect (Cloud Monitoring)

Plans & pricing (SaaS managé)

Pricing public — auto-hébergement = open source gratuit (cf. Installation).

Free

€0/mois

  • 10 000 clics/mois
  • 5 liens actifs
  • 1 user
  • Sous-domaine *.deeplink.app
  • Rétention analytics : 30 jours
  • Support communauté

Starter

€49/mois

  • 100 000 clics/mois
  • Liens illimités
  • 3 users
  • Custom domain (1)
  • Webhooks
  • Rétention 90 jours
  • Support email (J+2)

Pro

€199/mois

  • 1 M clics/mois
  • 10 users
  • Custom domain (1) + SSL
  • Workflows + DLQ
  • A/B tests
  • Smart Banners
  • Export GCS / S3
  • Rétention 12 mois
  • Support email (J+1) + Slack

Enterprise

Sur devis

  • Volume illimité
  • Users illimités
  • Multi-domaines
  • SCIM provisioning
  • OIDC SSO
  • SAML SSO
  • BigQuery export
  • Rétention 24+ mois
  • SLA 99.9%
  • DPA signé + audit RSSI
  • Support dédié + onboarding
💳
Billing — Stripe Customer Portal pour Free/Starter/Pro (self-service). Enterprise = facture annuelle, paiement par virement. Pas de surconsommation cachée : si vous dépassez votre quota, on vous notifie avant blocage (soft cap).

Glossaire

TermeDéfinition
Deep linkURL qui ouvre un contenu spécifique dans une app mobile
Deferred deep linkDeep link qui fonctionne même si l'app n'est pas installée — le contexte est récupéré après installation via fingerprint matching
Universal LinkMécanisme iOS (AASA) qui associe un domaine à une app sans redirection navigateur
App LinkÉquivalent Android des Universal Links (assetlinks.json)
FingerprintHash SHA-256 de l'IP + User-Agent, utilisé pour le matching deferred
AttributionProcessus qui détermine quel canal/campagne a généré une conversion
CohorteGroupe d'utilisateurs acquis sur la même période (semaine, mois)
LTVLifetime Value — revenu total cumulé par utilisateur sur sa durée de vie
ROASReturn On Ad Spend — revenu / dépense publicitaire. Un ROAS de 3× signifie que chaque euro dépensé en pub a généré 3€ de revenu.
CPACost Per Acquisition — dépense / nombre d'installations
CTRClick-Through Rate — taux de clic (app_opens / redirects pour les liens, clics / impressions pour les bannières)
dataLayerObjet JavaScript standard de Google Tag Manager. Le Web Tracker DeepLink intercepte ses push pour capturer les conversions web.
Custom DataJSON libre attaché à un lien, transmis au SDK quand l'utilisateur ouvre l'app
Params dynamiquesParamètres d'URL ajoutés au lien au moment du partage (?promo=X), capturés par le serveur et transmis au SDK
WebhookAppel HTTP POST envoyé en temps réel vers une URL externe à chaque événement
HMACCode d'authentification de message basé sur un hash — vérifie l'intégrité des webhooks
TenantEspace isolé dans la plateforme (multi-tenant) avec sa propre config, ses clés API et ses données
AASAApple App Site Association — fichier JSON servi sur /.well-known/ qui permet à iOS d'ouvrir une app directement depuis une URL
SKAdNetworkFramework Apple pour l'attribution post-install avec respect de la vie privée (pas de fingerprint)
IncrementalityMesure de l'effet additionnel d'une campagne (combien de conversions n'auraient pas eu lieu sans la pub) — distingue les conversions causées de celles attribuées par hasard. Mesure rigoureuse via groupes de contrôle (holdout), Bayesian uplift, geo experiments. Cf. analytics destinations (DEF-W4-02 roadmap).
MMPMobile Measurement Partner — plateforme tierce qui agrège l'attribution mobile cross-réseaux (ex. AppsFlyer, Adjust, Branch). DeepLink se positionne comme alternative MMP open-source/self-hostable, multi-tenant SaaS ou on-prem.
IDFAIdentifier for Advertisers — identifiant publicitaire iOS (UUID 36 caractères type 6D92078A-8246-4BA4-AE5B-76104861E7DC). Depuis iOS 14.5 (ATT), nécessite consentement explicite utilisateur. Utilisé par les SDKs ad networks (Meta, Google, TikTok) et Apple Search Ads pour l'attribution post-install. Si non-disponible : fallback fingerprint + SKAdNetwork.
GAIDGoogle Advertising ID (anciennement AAID) — équivalent Android de l'IDFA. Disponible via Google Play Services (com.google.android.gms.ads.identifier.AdvertisingIdClient). Reset possible par l'utilisateur dans les paramètres Android. Depuis Android 13, demande de permission com.google.android.gms.permission.AD_ID.
ASAApple Search Ads — régie publicitaire d'Apple sur l'App Store. Fournit l'attribution post-install via le SDK iAd / AdServices framework. Tokens ASA capturés côté SDK iOS et envoyés au serveur DeepLink pour résoudre la campagne (cf. ad-networks).
HeadlessMode d'utilisation API-only sans dashboard UI. Un client "headless" intègre DeepLink uniquement via l'API REST + SDKs, sans utiliser le dashboard web. Cas d'usage : agences qui white-labellent, intégration backend pure, automation CI/CD. Cf. api-platform.
View-through attributionAttribution donnée à un canal qui a affiché une pub sans clic, suivi d'une conversion plus tard. Window typique : 24h. Génère beaucoup de faux positifs (corrélation ≠ causation) — DeepLink l'attribue avec un poids dégradé via le modèle time_decay (cf. attribution pédagogie).
Fingerprint accuracyTaux de bonnes correspondances click→install via fingerprint IP+UA en l'absence d'IDFA/GAID. Précision typique 60-75% selon le volume + la fenêtre temporelle. Plus la window est courte (≤6h) et le volume faible (≤100 clicks/min/IP), plus la précision augmente. Cf. match.js + STORY-01 fuzzy matching.
SAML vs OIDCDeux protocoles SSO distincts : SAML (Security Assertion Markup Language) — XML-based, ancien, largement utilisé enterprise (Okta, Entra, ADFS) ; OIDC (OpenID Connect) — JSON/JWT-based, moderne, layer au-dessus d'OAuth 2.0 (Google, Auth0, Cognito). DeepLink supporte OIDC nativement (livré). SAML deferred (DEF-W2-09).