Qu'est-ce qu'un Facebook Page-Scoped ID (PSID) et comment l'utiliser ?
25 mai 2026
·
12 min de lecture
Dans ce guide : Ce qu'est un PSID · PSID vs ASID vs IGSID · Le principe d'isolation · Où se trouve le PSID dans les payloads webhook · Envoyer des messages avec un PSID · Lookup via la Graph API · L'ID Matching API · Le cas particulier de la réinitialisation du PSID · Indexation en base de données · Le format normalisé SocialHook
Qu'est-ce qu'un Facebook Page-Scoped ID (PSID) ?
Un Page-Scoped ID (PSID) est une chaîne numérique unique que Facebook assigne pour représenter un utilisateur Facebook spécifique dans le contexte d'une Page Facebook spécifique. C'est ainsi que votre application identifie qui a envoyé un message via Facebook Messenger.
Voici ce qui le distingue d'un identifiant utilisateur classique :
Un PSID n'est pas le véritable identifiant utilisateur Facebook. Les vrais identifiants Facebook sont internes aux systèmes de Meta.
Un PSID est spécifique à une Page. Le même utilisateur a un PSID différent pour chaque Page Facebook avec laquelle il interagit via Messenger.
Un PSID est stable pour une paire utilisateur-Page donnée — jusqu'à ce que l'utilisateur bloque puis débloque votre Page (voir le cas particulier de réinitialisation ci-dessous).
Un PSID est opaque — il ne transporte aucune information intrinsèque sur l'utilisateur. C'est simplement une référence.
En pratique : quand un client envoie un message Facebook Messenger à votre entreprise, son PSID est l'identifiant que votre application utilise pour envoyer des réponses, consulter son historique et stocker l'enregistrement de sa conversation. C'est la clé primaire de tout utilisateur Messenger dans votre système.
PSID, ASID et IGSID : les trois types d'identifiants utilisateur Facebook
Facebook maintient trois systèmes d'identifiants scoped différents pour trois contextes différents. Savoir lequel vous manipulez évite toute une catégorie de bugs où vous mélangez par mégarde les identifiants utilisateur.
Messenger
Page-Scoped ID (PSID)
Identifie un utilisateur dans le contexte d'une Page Facebook spécifique. Apparaît dans les événements webhook Messenger sous sender.id. Utilisé pour envoyer des messages via la Send API. Différent pour chaque Page que l'utilisateur contacte.
sender.id dans le webhook
Facebook Login / Apps sociales
App-Scoped ID (ASID)
Identifie un utilisateur dans le contexte d'une App Facebook spécifique. Retourné quand les utilisateurs se connectent via Facebook Login (OAuth). Différent pour chaque app sur laquelle l'utilisateur s'authentifie. Utilisé dans les appels Graph API pour les apps sociales.
retourné par Facebook Login
DM Instagram
Instagram-Scoped ID (IGSID)
Identifie un utilisateur dans le contexte d'un compte Instagram Business spécifique. Apparaît dans les événements webhook des DM Instagram. Concept similaire au PSID mais pour Instagram. Utilisé pour envoyer des réponses via l'Instagram Messaging API.
sender.id dans le webhook IG
Ne mélangez jamais ces identifiants. Tenter d'envoyer un message Messenger à un ASID retourne une erreur. Tenter d'utiliser un PSID d'une Page Facebook pour envoyer un message via une autre Page échoue aussi — les PSID sont page-scoped et ne peuvent être utilisés qu'avec le Page Access Token de la Page qui les a générés. Stocker différents types d'identifiants dans la même colonne de base de données sans label de type est un bug courant.
Le principe d'isolation : pourquoi les PSID diffèrent selon la Page
Facebook a conçu le système des PSID spécifiquement pour empêcher le suivi des utilisateurs entre plateformes. Si chaque app et chaque opérateur de Page recevait le même identifiant utilisateur, les data brokers et acteurs malveillants pourraient corréler les identités d'utilisateurs entre des centaines d'entreprises différentes — exactement le type de collecte croisée de données qui a mené au scandale Cambridge Analytica.
L'isolation signifie : si votre entreprise opère deux Pages Facebook, le même utilisateur Facebook a des PSID différents sur chaque Page. Vous ne pouvez pas utiliser le PSID de la Page A pour consulter l'activité sur la Page B sans le consentement explicite de l'utilisateur et l'ID Matching API (couverte ci-dessous).
Même utilisateur Facebook
Alice Johnson (vrai ID FB : caché pour vous)
Votre Page Boutique principale
PSID : 12345678901234
Votre Page Support
PSID : 98765432109876
La Page de votre partenaire
PSID : 11223344556677
Alice a trois PSID complètement différents sur les trois Pages. Aucune corrélation n'est possible entre eux à partir des seules données. C'est voulu — et c'est pourquoi mettre en place des opérations Messenger multi-Pages demande une réflexion soignée sur le PSID qui appartient à quel contexte de Page.
Où se trouve le PSID dans les payloads webhook Messenger
Quand un utilisateur envoie un message à votre Page Facebook, la Messenger Platform déclenche un HTTP POST vers votre URL de webhook enregistrée. Le PSID se trouve à entry[0].messaging[0].sender.id dans le payload brut. Voici la structure complète :
Facebook Messenger webhook payload
messenger-webhook.json
{
"object": "page", // always "page" for Messenger webhooks"entry": [{
"id": "PAGE_ID", // your Facebook Page ID (not a PSID)"time": 1747231892123,
"messaging": [{
"sender": {
"id": "12345678901234"// ← THIS IS THE PSID — the user who sent the message
},
"recipient": {
"id": "PAGE_ID"// your Page ID — same as entry.id
},
"timestamp": 1747231892100,
"message": {
"mid": "m_abc123...", // unique message ID"text": "Hello! I need help with my order."
}
}]
}]
}
// PSID extraction path: body.entry[0].messaging[0].sender.id// Page ID path: body.entry[0].id (same as recipient.id)
Extraire le PSID correctement :
Node.js — PSID extraction from raw webhook
extractPsid.js
app.post('/webhook/facebook', (req, res) => {
res.sendStatus(200); // acknowledge firstconst body = req.body;
if (body.object !== 'page') return;
body.entry.forEach(entry => {
const pageId = entry.id; // your Page ID
entry.messaging.forEach(event => {
const psid = event.sender.id; // ← the PSIDconst pageId = event.recipient.id; // confirms which Page received itif (event.message) {
console.log(`Message from PSID ${psid} on page ${pageId}:`, event.message.text);
handleMessage(psid, pageId, event.message);
} else if (event.postback) {
handlePostback(psid, pageId, event.postback);
} else if (event.read) {
handleRead(psid, event.read.watermark);
}
});
});
});
Envoyer des messages en réponse en utilisant un PSID
Pour répondre à un utilisateur, vous faites un POST vers la Send API en utilisant son PSID comme destinataire. Le PSID est le seul identifiant dont vous avez besoin — Facebook résout l'utilisateur à partir de celui-ci et livre le message dans sa boîte de réception Messenger.
Node.js — send Messenger message by PSID
sendByPsid.js
constGRAPH = 'https://graph.facebook.com/v21.0';
const PAGE_ACCESS_TOKEN = process.env.FB_PAGE_ACCESS_TOKEN; // must match the Page that got the PSIDasync functionsendMessengerMessage(psid, messageText) {
const res = awaitfetch(
`${GRAPH}/me/messages?access_token=${PAGE_ACCESS_TOKEN}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
recipient: { id: psid }, // PSID goes here
message: { text: messageText },
messaging_type: 'RESPONSE', // within 24h window
}),
}
);
if (!res.ok) {
const err = await res.json();
if (err.error?.code === 551 || err.error?.code === 100) {
// PSID may be invalid/reset — user may have blocked and unblockedthrowObject.assign(newError('Invalid PSID'), { code: 'PSID_INVALID', psid });
}
thrownewError(`Messenger send error: ${JSON.stringify(err)}`);
}
returnawait res.json(); // { recipient_id: psid, message_id: "m_..." }
}
// Critical: use the Page Access Token from the Page that the user's PSID belongs to.// Using a different Page's token returns an error even if the PSID format is correct.
Récupérer les informations utilisateur via la Graph API en utilisant un PSID
Avec un PSID et votre Page Access Token, vous pouvez interroger la Graph API pour récupérer les informations de profil public de l'utilisateur — précisément son prénom, son nom et sa photo de profil. C'est utile pour personnaliser les réponses de votre bot et pré-remplir des fiches CRM.
Permissions requises : votre App Facebook doit avoir la permission pages_messaging approuvée pour lire le profil utilisateur via PSID. Sans elle, la Graph API ne retourne que le champ id. Les champs de profil (nom, photo) exigent que l'utilisateur ait explicitement envoyé un message à votre Page au préalable — vous ne pouvez pas faire de lookup sur des PSID arbitraires, uniquement sur ceux qui ont initié une conversation avec votre Page.
Node.js — Graph API user lookup by PSID
lookupByPsid.js
async functiongetUserProfile(psid) {
const fields = 'first_name,last_name,profile_pic,locale,timezone,gender';
const url = `${GRAPH}/${psid}?fields=${fields}&access_token=${PAGE_ACCESS_TOKEN}`;
const res = awaitfetch(url);
if (!res.ok) throw newError(`Profile lookup failed: ${await res.text()}`);
returnawait res.json();
// Returns: { id, first_name, last_name, profile_pic, locale, timezone }
}
// Usage — look up profile on first contact and store itasync functiononFirstContact(psid) {
const profile = awaitgetUserProfile(psid);
awaitupsertUser({
psid,
firstName: profile.first_name,
lastName: profile.last_name,
profilePic: profile.profile_pic,
locale: profile.locale, // e.g. "pt_BR" — useful for language routing
});
}
// Note: gender and timezone fields deprecated by Meta in v18.0+// Stick to first_name, last_name, profile_pic, locale for future-safe code
L'ID Matching API : convertir PSID ↔ ASID
Dans certains cas, vous pouvez avoir besoin de corréler un utilisateur Messenger (identifié par PSID) avec le même utilisateur authentifié via Facebook Login (identifié par ASID). Facebook fournit l'ID Matching API à cet effet — mais elle requiert la permission pages_user_ids ET ne fonctionne qu'entre applications appartenant au même Business Portfolio.
Le cas d'usage typique : un utilisateur authentifié avec Facebook Login (vous donnant son ASID) vous contacte plus tard via Messenger (vous donnant son PSID). Vous voulez lier les deux identifiants au même enregistrement utilisateur dans votre base de données.
Node.js — ID Matching API (PSID ↔ ASID)
idMatching.js
// Convert PSID → ASID (to find the same user who logged in via Facebook Login)async functiongetAsidFromPsid(psid) {
const url = `${GRAPH}/${psid}?fields=ids_for_apps&access_token=${PAGE_ACCESS_TOKEN}`;
const res = awaitfetch(url);
const data = await res.json();
// Returns array of app-scoped IDs for apps in the same Business Portfolioconst appIds = data.ids_for_apps?.data ?? [];
const match = appIds.find(a => a.app.id === process.env.FB_APP_ID);
return match?.id; // the ASID for this user on your app
}
// Convert ASID → PSID (to find the Messenger identity of a logged-in user)async functiongetPsidFromAsid(asid) {
const url = `${GRAPH}/${asid}?fields=ids_for_pages&access_token=${PAGE_ACCESS_TOKEN}`;
const res = awaitfetch(url);
const data = await res.json();
const pageIds = data.ids_for_pages?.data ?? [];
const match = pageIds.find(p => p.page.id === process.env.FB_PAGE_ID);
return match?.id; // the PSID for this user on your Page
}
// Requirements:// - App must have pages_user_ids permission (requires App Review)// - Both apps must be under the same Business Portfolio// - User must have interacted with both the Page and the App
Le cas particulier de la réinitialisation du PSID à gérer
Il existe un scénario où le PSID d'un utilisateur change : si l'utilisateur bloque votre Page Facebook puis la débloque plus tard. Lorsqu'il vous débloque et vous envoie à nouveau un message, il reçoit un tout nouveau PSID pour votre Page. Son ancien PSID est alors orphelin — tout message que vous tenterez de lui envoyer échouera.
Ce cas particulier est facile à manquer car il se produit silencieusement. L'utilisateur ne sait pas que son PSID a changé. Votre base de données contient toujours l'ancien PSID. Lorsque vous tentez de lui envoyer un message, vous obtenez une erreur. Voici comment le gérer correctement :
Node.js — PSID reset detection and update
psidReset.js
async functionhandleInboundMessage(event) {
const psid = event.sender.id;
const message = event.message;
// Look up this PSID in your databaselet user = await db.findByPsid(psid);
if (!user) {
// New PSID — either genuinely new user or a PSID reset after block/unblock// Check if we have a user with matching profile (name + profile pic)const profile = awaitgetUserProfile(psid);
const existing = await db.findByProfile(profile.first_name, profile.last_name);
if (existing) {
// Likely a PSID reset — update the stored PSIDawait db.updatePsid(existing.id, psid);
user = { ...existing, psid };
console.log(`PSID reset detected for user ${existing.id} — new PSID: ${psid}`);
} else {
// Genuinely new user
user = await db.createUser({ psid, ...profile });
}
}
awaitprocessMessage(user, message);
}
// Also: subscribe to the messaging_optins and messaging_optouts webhook events// messaging_optouts fires when a user blocks your page — flag the PSID as potentially stale
Indexation en base de données : la bonne manière de stocker les PSID
Les erreurs de stockage des PSID provoquent des bugs subtils et difficiles à diagnostiquer. Voici les bons patterns :
N'utilisez jamais le PSID comme clé primaire. Les PSID peuvent changer (scénario block/unblock). Utilisez un auto-increment interne ou un UUID comme clé primaire. Le PSID est un identifiant externe qui pointe vers votre utilisateur interne.
Stockez toujours le Page ID à côté du PSID. Un PSID n'a de sens que dans le contexte de la Page pour laquelle il a été généré. Si vous opérez plusieurs Pages, (psid, page_id) doit être une contrainte unique composite, pas psid seul.
Indexez la colonne PSID. Chaque message entrant nécessite un lookup PSID. Sans index, c'est un full table scan à chaque événement webhook.
Stockez le PSID en tant que chaîne. Les PSID sont des chaînes numériques mais peuvent dépasser la plage de l'entier sûr en JavaScript (Number.MAX_SAFE_INTEGER). Traitez-les toujours comme des chaînes, pas comme des nombres.
SQL — correct PSID schema
schema.sql
CREATE TABLE messenger_users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
psid VARCHAR(25) NOT NULL, -- string, not bigint
page_id VARCHAR(25) NOT NULL, -- which Facebook Page generated this PSID
first_name VARCHAR(100),
last_name VARCHAR(100),
profile_pic TEXT,
locale VARCHAR(10), -- e.g. 'pt_BR', 'en_US'
asid VARCHAR(25), -- linked App-Scoped ID (Facebook Login), nullable
is_active BOOLEAN DEFAULT TRUE, -- false if PSID became invalid
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE (psid, page_id) -- composite unique — PSID is page-scoped
);
CREATE INDEX idx_messenger_users_psid ON messenger_users (psid);
CREATE INDEX idx_messenger_users_page_id ON messenger_users (page_id);
CREATE INDEX idx_messenger_users_asid ON messenger_users (asid) WHERE asid IS NOT NULL;
-- Never store PSID as INTEGER or BIGINT-- Example PSID: '1234567890123456789' — exceeds JS Number.MAX_SAFE_INTEGER-- parseInt('1234567890123456789') === 1234567890123456800 — wrong!
Le PSID dans les événements Facebook Messenger normalisés de SocialHook
Quand vous utilisez SocialHook pour Facebook Messenger, le PSID est pré-extrait de l'enveloppe brute du webhook Messenger et livré au niveau supérieur de l'événement normalisé. Plus besoin de naviguer dans le chemin imbriqué entry[0].messaging[0].sender.id :
SocialHook normalized Facebook Messenger event
{
"platform": "facebook",
"event": "message.received",
"timestamp": 1747231892,
"from": "12345678901234", // ← this IS the PSID, ready to use"page_id": "PAGE_ID", // which Page received the message"conversation_id": "conv_fb_8j3k...",
"message": {
"type": "text",
"body": "Hello! I need help with my order.",
"id": "m_abc123..."
},
"signature_verified": true
}
// event.from === the PSID — same format as WhatsApp's event.from for phone numbers// event.page_id — use this for multi-page routing (PSID is specific to this page)// Same payload structure as WhatsApp and Instagram events — one handler for all channels
Le bénéfice clé pour les déploiements multi-canaux : SocialHook normalise le PSID (Facebook), le numéro de téléphone (WhatsApp) et l'IGSID (Instagram) tous dans le même champ from avec la même structure de payload. Votre code applicatif peut gérer les trois canaux avec une seule fonction de handler de messages, en différenciant par platform si nécessaire. Voir la payload reference pour la comparaison complète du schéma entre les trois canaux.
FAQ
Questions fréquentes
Qu'est-ce qu'un Facebook Page-Scoped ID (PSID) ?
Un PSID est une chaîne opaque unique que Facebook assigne pour représenter un utilisateur spécifique dans le contexte d'une Page Facebook spécifique. Quand quelqu'un envoie un message Messenger à votre Page Facebook, Facebook l'identifie auprès de votre application via son PSID — pas son véritable identifiant utilisateur Facebook. La même personne a un PSID différent pour chaque Page avec laquelle elle interagit, assurant une isolation de confidentialité entre opérateurs de Pages.
Où apparaît le PSID dans un payload webhook Facebook Messenger ?
Dans le webhook Messenger brut : body.entry[0].messaging[0].sender.id. Dans le format normalisé de SocialHook : event.from. Le champ sender.id est toujours le PSID de la personne qui a envoyé le message. Le champ recipient.id est votre Page ID (pas un PSID). Quand vous itérez sur plusieurs entries et tableaux messaging, utilisez toujours messaging[n].sender.id, pas entry[n].id.
Le PSID d'un utilisateur peut-il changer ?
Oui — quand un utilisateur bloque votre Page Facebook puis la débloque plus tard, il reçoit un nouveau PSID pour votre Page. Son ancien PSID devient invalide. Cela se produit silencieusement. Vérifiez toujours les erreurs PSID_INVALID lors de l'envoi de messages et mettez à jour votre base de données quand vous recevez un nouveau PSID d'un utilisateur dont le profil correspond à un enregistrement existant. N'utilisez jamais le PSID comme clé primaire pour cette raison.
Puis-je envoyer un message Messenger à un utilisateur dont je n'ai jamais reçu de message ?
Pas via la Send API standard sans un PSID. Vous avez besoin que l'utilisateur initie le contact (vous donnant son PSID) ou vous devez obtenir son PSID via l'ID Matching API (s'il a utilisé Facebook Login sur votre app et que vous avez la permission pages_user_ids). Vous ne pouvez pas faire de lookup sur des PSID d'utilisateurs arbitraires — les PSID n'existent que dans le contexte d'un utilisateur qui a interagi avec votre Page spécifique. C'est voulu pour des raisons de confidentialité.
Pourquoi devrais-je stocker le PSID comme chaîne et non comme entier ?
Les PSID sont des chaînes numériques qui peuvent dépasser Number.MAX_SAFE_INTEGER de JavaScript (9 007 199 254 740 991). Si vous parsez un PSID comme « 1234567890123456789 » en entier JavaScript, vous perdez en précision : parseInt('1234567890123456789') === 1234567890123456800 — les derniers chiffres sont faux. Stockez et passez toujours les PSID comme chaînes dans votre base de données (VARCHAR/TEXT) et dans votre code. Ne les castez jamais en nombres.
En quoi le PSID est-il différent de l'ASID ?
Le PSID (Page-Scoped ID) concerne Messenger — il identifie un utilisateur par Page Facebook. L'ASID (App-Scoped ID) concerne Facebook Login — il identifie un utilisateur par App Facebook. Le même utilisateur a un PSID différent pour chaque Page et un ASID différent pour chaque App. Vous pouvez convertir entre eux via l'ID Matching API, mais uniquement si la Page et l'App sont sous le même Business Portfolio et que vous avez la permission pages_user_ids.
Des PSID livrés propres. Aucun parsing nécessaire.
Connectez votre Page Facebook à SocialHook et recevez chaque événement Messenger avec le PSID pré-extrait dans event.from — aux côtés de vos événements WhatsApp et Instagram dans le même format normalisé. Un seul handler pour les trois canaux.
Arrêtez de gérer les API Meta. Commencez à construire.
Connectez votre premier compte Facebook, Instagram ou WhatsApp en moins de 2 minutes. Votre webhook reçoit son premier payload avant que votre café refroidisse.