Dernière mise à jour : novembre 2025 · Niveau : avancé

Pourquoi se passer du SDK Meta

Sur mobile, la plupart des équipes confient le tracking Meta au SDK officiel : il collecte les informations de l’appareil, identifie l’utilisateur, gère l’attribution et envoie les événements à Meta. Un mode « CAPI seule », sans SDK dans l’application, a pourtant de bonnes raisons d’exister :

Le revers : le SDK Meta fait énormément de choses automatiquement. Sans lui, vous devez recréer à la main une grande partie de son travail. Il faut aussi, côté Meta, un dataset rattaché à votre app dans Events Manager (obligatoire avant d’envoyer des événements d’app, une seule app par dataset).

Ce que le SDK fait pour vous et que vous devez désormais gérer

Sans SDK, tout cela est à collecter, formater et envoyer vous-même.

Architecture

Le flux tient en quatre étapes : l’app collecte les données brutes, les envoie en HTTPS à votre backend, qui valide, hache et enrichit, puis votre serveur appelle Meta sur graph.facebook.com/v25.0/{dataset_id}/events.

Règle clé sur les données personnelles : envoyez-les en clair de l’app vers votre backend (en HTTPS), et hachez uniquement côté serveur. Ne hachez jamais dans l’app : des implémentations différentes d’une plateforme à l’autre cassent la correspondance.

Paramètre n°1 : les identifiants d’appareil (madid et anon_id)

Le MADID (Mobile Advertising ID) est l’identifiant principal d’attribution : IDFA sur iOS, GAID sur Android.

iOS : récupérer l’IDFA

Depuis iOS 14.5, il faut demander l’autorisation via le framework App Tracking Transparency (ATT). Si l’utilisateur refuse, l’IDFA vaut 00000000-0000-0000-0000-000000000000 : on bascule alors sur l’identifiant anonyme.

ATTrackingManager.requestTrackingAuthorization { status in
    switch status {
    case .authorized:
        let idfa = ASIdentifierManager.shared().advertisingIdentifier.uuidString
        self.sendToBackend(idfa: idfa)
    case .denied, .restricted, .notDetermined:
        // IDFA = 00000000-... : on utilise l'identifiant anonyme
        self.sendToBackend(anonId: self.getOrCreateAnonymousId())
    @unknown default: break
    }
}

Android : récupérer le GAID

Pas de fenêtre d’autorisation, mais les apps ciblant Android 13+ doivent déclarer la permission AD_ID. Un identifiant supprimé par l’utilisateur revient en zéros : on le filtre comme l’IDFA nul, et on respecte le « limit ad tracking ».

Format attendu par Meta

function formatMADID(madid) {
    if (!madid || madid === '00000000-0000-0000-0000-000000000000') return null;
    return madid.toLowerCase(); // on garde les tirets, jamais de hachage
}

anon_id : le secours indispensable

Quand l’IDFA ou le GAID n’est pas disponible, il faut générer un anon_id : un UUIDv4 créé au premier lancement, conservé localement (UserDefaults, Keychain, AsyncStorage, SharedPreferences) et envoyé avec chaque événement sans MADID.

{
    "user_data": {
        "madid": "38400000-8cf0-11bd-b23e-10b96e40000d",
        "anon_id": "a1b2c3d4-e5f6-7890-1234-567890abcdef"
    }
}

Envoyez les deux quand ils existent, un seul sinon. Quand l’ATT est refusé, envoyez uniquement anon_id.

Paramètre n°2 : le tableau extinfo

extinfo est un tableau à positions fixes, de 16 valeurs, généré automatiquement par le SDK. Il est obligatoire pour les événements d’app : sans lui, Meta rejette l’événement ou ne peut pas l’exploiter.

PositionContenuExemple
0Version d’extinfo (« a2 » Android, « i2 » iOS)i2
1Package / bundle IDcom.myapp
2Version courte de l’app1.2.3
3Version longue (build)456
4Version de l’OS17.2.1
5Modèle d’appareiliPhone14,2
6Localeen_US
7Abréviation du fuseauCET
8OpérateurOrange
9-10Largeur et hauteur d’écran1170 / 2532
11Densité d’écran3
12Nombre de cœurs CPU6
13-14Stockage total et libre (Go)256 / 120
15Fuseau de l’appareilEurope/Paris

L’article d’origine fournit les implémentations complètes en React Native (avec react-native-device-info), en Swift et en Kotlin. Les règles à retenir :

Paramètre n°3 : l’Advanced Matching (données personnelles hachées)

L’Advanced Matching permet à Meta de rattacher un événement à un utilisateur même sans IDFA ni GAID. C’est décisif sur iOS 14.5+, où la majorité des utilisateurs refusent l’ATT. Sans SDK, vous devez normaliser, hacher en SHA-256 et envoyer vous-même.

ChampParamètreExemple (avant hachage)
E-mailemtest@example.com
Téléphoneph33612345678
Prénomfnjohn
Nomlndoe
Villectparis
Régionstiledefrance
Code postalzp75001
Payscountryfr
Genregem
Date de naissancedb19900515

Normaliser avant de hacher

Meta est très strict : un champ mal normalisé ne correspondra jamais.

Hacher côté serveur

Toujours sur le backend : une implémentation unique, plus simple à déboguer, et aucun secret dans l’app.

const crypto = require('crypto');
function hashSHA256(value) {
    if (!value) return null;
    return crypto.createHash('sha256').update(value).digest('hex');
}
hashSHA256(normalizeEmail("Test@Example.com"));
// "973dfe463ec85785f5f95af5ba3906eedb2d931c24e69824a89ea65dba4e813b"

Bonnes pratiques :

Paramètre n°4 : app_data

L’objet app_data décrit l’app et l’environnement de tracking. Les champs requis :

ChampTypeRôle
application_tracking_enabledentier 0/1Le tracking au niveau de l’app est-il autorisé ? Mettre 0 si l’utilisateur a refusé dans l’app ou n’a pas consenti (RGPD / CCPA).
advertiser_tracking_enabledentier 0/1Reflète l’ATT sur iOS : 1 seulement si le statut est « authorized » (1 par défaut avant iOS 14.5).
extinfotableauVoir paramètre n°2.

Champs optionnels : installer_package (Android seulement, par exemple com.android.vending ; Meta indique qu’il est « utilisé en interne par les SDK Android », donc à omettre sur iOS), url_schemes, consider_views et campaign_ids.

Paramètre n°5 : action_source

action_source dit à Meta d’où vient l’événement. Pour une app, la valeur est toujours "app". Les autres valeurs (website, email, phone_call, chat, physical_store, system_generated, other) servent à d’autres canaux. Avec « website » par erreur, Meta traite l’événement comme une conversion web : les campagnes d’installation mobile ne voient plus aucune conversion et l’attribution échoue.

Autres paramètres importants

Tester et déboguer

  1. Dans Events Manager, ouvrez « Test Events » et copiez le code de test (par exemple TEST12345).
  2. Ajoutez test_event_code à votre payload et envoyez l’événement.
  3. Vérifiez qu’il apparaît, sans avertissement ni erreur, avec tous les paramètres requis.

L’Event Match Quality n’est pas affichée pour les événements d’app : contrôlez la livraison et la correspondance dans Test Events et les diagnostics du dataset.

SymptômeCauses probables
Rien dans Test EventsMauvais dataset ou dataset non lié à l’app, token invalide, event_time en millisecondes, paramètres requis manquants.
Mauvaise correspondanceNi MADID ni anon_id, pas d’Advanced Matching, hachage sans normalisation, IP ou User Agent absents.
Événements visibles mais pas dans Ads Manageraction_source à « website », événement hors fenêtre d’attribution, utilisateur ayant refusé le tracking publicitaire.

Les huit pièges classiques

  1. Format du MADID : tirets retirés ou majuscules, au lieu de minuscules avec tirets.
  2. Hacher avant de normaliser : " Test@Example.com " haché tel quel ne correspondra à rien.
  3. Timestamp en millisecondes au lieu de secondes.
  4. Pas d’anon_id de secours : avec l’ATT refusé, le MADID vaut « 0000… » et l’événement est orphelin.
  5. action_source = « website » pour un événement d’app.
  6. extinfo incomplet : trois valeurs au lieu de seize.
  7. Pays non haché : Meta attend le SHA-256 du code ISO en minuscules.
  8. Lire l’IDFA sans demander l’ATT : il faut d’abord obtenir l’autorisation, et seulement si le statut est « authorized » lire l’IDFA.

Performance, montée en charge et supervision

Checklist avant la mise en production

Conclusion

La CAPI sans SDK apporte un contrôle total, un point unique pour appliquer le consentement, une app plus légère et une architecture unifiée web et mobile. En échange, elle demande de recréer à la main une grande partie du travail du SDK, avec un fort risque d’échec d’attribution au moindre paramètre erroné, et plus d’infrastructure à maintenir. Si vous débutez sur Meta Ads en mobile, utilisez le SDK. Si vous avez besoin de contrôle maximal, de conformité ou d’une architecture particulière, l’approche CAPI seule est puissante une fois bien en place.

À retenir : MADID plus anon_id (toujours un secours face à l’ATT), extinfo (ne pas l’omettre), normaliser puis hacher, action_source à « app », et beaucoup de tests avant la production.

Sources

Pour aller plus loin, lisez la version complète de l’article (en anglais) : The Complete Guide to Meta CAPI for Mobile Apps Without SDK.

Besoin d’aide sur ce sujet ? Consultant GA4 et audit analytics.

Vous doutez de votre tracking ?

Réserver un appel Ou commencez par l’audit analytics gratuit →