Configuration d'une source d'entrepôt de données
Utilisez cette compétence quand l'utilisateur souhaite connecter une source de données externe à l'entrepôt de données de PostHog pour la première fois. La configuration suit un flux à trois étapes spécifiques (wizard → db-schema → create) — sauter des étapes entraîne des sources défaillantes et des utilisateurs confus.
Quand utiliser cette compétence
- L'utilisateur souhaite connecter une nouvelle source : « connecter Stripe », « importer ma table de commandes Postgres », « synchroniser les contacts Hubspot »
- L'utilisateur n'est pas sûr quels types de sources PostHog supporte
- L'utilisateur dispose des identifiants mais ne sait pas comment structurer le payload
schemas - L'utilisateur souhaite des conseils sur la méthode de synchronisation à choisir par table
Outils disponibles
| Outil | Objectif |
|---|---|
external-data-sources-wizard |
Découvrir les types de sources existants et les champs requis par chacun |
external-data-sources-db-schema |
Valider les identifiants et lister les tables avec les méthodes de synchronisation disponibles par table |
external-data-sources-create |
Créer la source — nécessite un array schemas construit à partir de la réponse db-schema |
external-data-sources-check-cdc-prerequisites-create |
Vérification préalable Postgres CDC (optionnel, uniquement pour Postgres CDC) |
external-data-sources-webhook-info-retrieve |
Vérifier si une source supporte les webhooks et si l'un a été enregistré |
external-data-sources-create-webhook-create |
Enregistrer un webhook auprès du service externe après la création de la source |
external-data-sources-update-webhook-inputs-create |
Fournir manuellement le secret de signature quand l'enregistrement automatique a échoué |
external-data-sources-list |
Après création, confirmer que la source est listée et voir son statut initial |
external-data-schemas-list |
Voir le statut de synchronisation par table une fois la source créée |
Le flux à trois étapes
Chaque configuration de source suit la même structure. N'essayez pas de raccourcir vers external-data-sources-create — vous avez besoin de la
réponse db-schema pour construire un payload schemas valide.
┌────────────────────┐
│ 1. wizard │ Quels types de sources existent ? Quels champs chacun nécessite-t-il ?
└────────┬───────────┘
▼
┌────────────────────┐
│ 2. db-schema │ Valider les identifiants. Lister les tables + méthodes de synchronisation disponibles par table.
└────────┬───────────┘
▼
┌────────────────────┐
│ 3. create │ Envoyer source_type + identifiants + schemas[] pour créer réellement.
└────────────────────┘
Flux de travail
Étape 1 — Découvrir le type de source
Appelez external-data-sources-wizard (aucun paramètre). La réponse est un dictionnaire indexé par type de source. Chaque entrée décrit :
name— la chaîne source_type canonique que vous passerez aux appels ultérieurs (par ex."Postgres","Stripe","Hubspot").label/caption— lisible par l'humain.fields— les champs de configuration nécessaires (host, port, database, api_key, client_id/secret, ...). Chacun aname,type(input, password, switch, select, file-upload), etrequired.featured,unreleasedSource— à utiliser pour évaluer la maturité. Ignorer les sources marquéesunreleasedSource: truesauf si l'utilisateur en a explicitement demandé un aperçu.
Associez la demande de l'utilisateur à une source. S'il a dit « Postgres », cherchez Postgres. S'il a dit quelque chose d'ambigu
comme « database », présentez les correspondances pertinentes principales (Postgres, MySQL, MongoDB, BigQuery, Snowflake, Redshift) et laissez
le choisir.
Pour les sources basées sur OAuth (Hubspot, Salesforce, Google Ads), l'entrée du wizard indique un flux OAuth. Ces sources ont généralement besoin que l'utilisateur autorise via l'interface de PostHog plutôt que de coller des identifiants — expliquez cela et dirigez-le vers la page de configuration de la source plutôt que de essayer de collecter des tokens en chat. OAuth concerne l'authentification, pas le flux des données ; les sources OAuth utilisent toujours une synchronisation en masse par interrogation, pas des webhooks.
Recueillez les identifiants requis auprès de l'utilisateur. Ne demandez jamais plus de champs que l'entrée du wizard ne dit que c'est nécessaire —
demander un port inutile quand la source n'en a pas besoin confond les utilisateurs.
Étape 2 — Valider les identifiants et découvrir les tables
Appelez external-data-sources-db-schema avec source_type plus tous les champs d'identifiants. Cela fait deux choses à la fois :
- Valide les identifiants contre la source en direct. Retourne 400 avec un
messagesi quelque chose est incorrect (mauvais host, mauvais mot de passe, permission refusée). Montrez l'erreur verbatim — elle est souvent actionnelle (« password authentication failed for user 'x' »). - Si valide, retourne un array d'entrées de tables. Chaque entrée :
{
"table": "orders",
"should_sync": false,
"rows": 1_250_000,
"incremental_available": true, # peut faire sync_type=incremental
"append_available": true, # peut faire sync_type=append
"cdc_available": true, # peut faire sync_type=cdc (null = pas activé pour l'équipe)
"supports_webhooks": false, # peut faire sync_type=webhook pour push en temps réel
"incremental_fields": [ # candidats : généralement updated_at, created_at, id
{"field": "updated_at", "type": "datetime", "label": "updated_at", ...},
{"field": "created_at", "type": "datetime", ...},
{"field": "id", "type": "integer", ...}
],
"detected_primary_keys": ["id"],
"available_columns": [{"field": "id", "type": "integer", "nullable": false}, ...],
"description": "..."
}
Présentez cela à l'utilisateur. Ne videz pas le JSON brut — résumez : quelles tables ont été trouvées, comptages de lignes, et la recommandation de méthode de synchronisation par défaut par table (voir guide de décision sync-type).
Étape 3 — Confirmer la configuration de synchronisation par table
Pour chaque table que l'utilisateur souhaite synchroniser, choisissez un sync_type. Voir le guide de décision sync-type pour les règles détaillées, mais la version courte est :
- Tables petites / dimension (<50k lignes, aucune colonne de tri naturelle) :
full_refresh— simple et toujours correct. - Tables grandes avec un
updated_at/modified_at:incremental— beaucoup moins cher par synchronisation. - Tables immuables et ajout seul (logs, événements) :
appendsi disponible — préserve l'historique. - Postgres avec CDC activé et vous avez besoin de quasi temps réel :
cdc— nécessite des clés primaires et des prérequis Postgres. - Sources qui supportent les webhooks (actuellement Stripe) : pour l'ingestion quasi temps réel définez
sync_type: "webhook"sur les tables oùsupports_webhooks: true, puis enregistrez le webhook comme étape post-création (voir étape 6 ci-dessous). Les tables qui ne supportent pas les webhooks sur la même source ont toujours besoin d'un sync_type de synchronisation en masse.
Pour chaque schéma qui utilisera incremental/append/cdc, vous avez aussi besoin de :
incremental_field— quelle colonne suivre pour le tri de la limite supérieure. Choisissez dans la listeincremental_fieldsretournée par db-schema. Préférezupdated_atàcreated_at(updated_at capture les mises à jour tardives ; created_at les manque). Pour les tables avec seulement des entiers, utilisez la clé primaire monotone croissante.incremental_field_type— doit correspondre au type du champ choisi (datetime,timestamp,date,integer,numeric,objectid).primary_key_columns— nécessaire pour CDC. Utilisezdetected_primary_keysde db-schema.
Étape 4 — Choisir un bon préfixe
Le prefix de la source est préfixé aux noms de table en HogQL. Les tables se retrouvent comme {prefix}_{table_name}.
- Par défaut, le type de source en minuscules s'il n'y a qu'une seule source de ce type :
stripe,postgres. - Si l'utilisateur a déjà une source Postgres, choisissez quelque chose de distinctif :
postgres_prod,postgres_analytics. - Utilisez les minuscules, séparés par des traits de soulignement. Le préfixe devient une partie de chaque requête HogQL que l'utilisateur écrira.
Confirmez le préfixe avec l'utilisateur avant de créer — le changer plus tard est possible mais renomme chaque table.
Étape 5 — Créer la source
Appelez external-data-sources-create avec :
{
"source_type": "Postgres",
"prefix": "postgres_prod",
"payload": {
"host": "...",
"port": "5432",
"dbname": "...",
"user": "...",
"password": "...",
"schema": "public",
"schemas": [
{
"name": "orders",
"should_sync": true,
"sync_type": "incremental",
"incremental_field": "updated_at",
"incremental_field_type": "datetime",
"primary_key_columns": ["id"]
},
{
"name": "users",
"should_sync": true,
"sync_type": "full_refresh"
},
{
"name": "audit_log",
"should_sync": false
}
]
}
}
Règles pour l'array schemas :
- Chaque table retournée par db-schema doit être incluse, même celles que l'utilisateur ne souhaite pas (définez
should_sync: false). Les tables que l'utilisateur n'a pas mentionnées ont par défautshould_sync: false. sync_typeest nécessaire uniquement quandshould_sync: true.incremental_field/incremental_field_typedoivent être présents quandsync_typeestincrementalouappend.primary_key_columnsdoit être présent quandsync_typeestcdc.
En cas de succès, vous recevrez une source avec un nouvel id. La première synchronisation est déclenchée automatiquement.
Étape 6 — Enregistrer un webhook (uniquement quand un schéma est sync_type: "webhook")
Les schémas de type webhook ne commencent pas à recevoir de données en existant simplement — le service externe doit savoir où POSTer
les événements, et PostHog doit savoir comment les vérifier. C'est un deuxième appel après la création de la source, pas une partie du
payload external-data-sources-create. Faites cela avant de dire à l'utilisateur que la configuration est terminée, sinon il
entend « les synchronisations sont en cours » tandis que le canal de push n'est toujours pas enregistré.
Seulement nécessaire quand au moins un schéma sur la source a sync_type: "webhook" et should_sync: true. Actuellement seul
Stripe implémente ce flux ; pour tout le reste ignorez cette étape.
Avant d'appeler create-webhook, vérifiez external-data-sources-webhook-info-retrieve({id}). Si cela retourne déjà
exists: true, N'APPELEZ PAS create-webhook à nouveau — chaque appel réussi enregistre un nouvel endpoint externe et
causerait des livraisons dupliquées.
-
Appelez
external-data-sources-create-webhook-create({id}). PostHog :- crée la HogFunction qui recevra les POSTs webhook,
- construit un schema_mapping à partir des types d'événements externes vers les ids de schéma PostHog,
- appelle l'API de la source (par ex. Stripe) pour enregistrer l'URL du webhook et s'abonner aux événements pertinents,
- sur Stripe, capture automatiquement le
signing_secretet le stocke de manière sécurisée.
Retourne
{success, webhook_url, error}. En cas de succès, signalez l'webhook_urlà l'utilisateur pour ses dossiers — mais il n'a pas besoin de le coller partout ; l'enregistrement est déjà fait. -
Si
success: falseavec une erreur de permissions comme « API key doesn't have permission to create webhooks » :- La HogFunction est toujours créée, juste désactivée.
- Demandez à l'utilisateur de créer le webhook manuellement dans le tableau de bord de la source en utilisant l'
webhook_urlretournée. - Faites-lui copier le secret de signature à partir des paramètres du webhook de la source.
- Appelez
external-data-sources-update-webhook-inputs-create({id}, {inputs: {signing_secret: "whsec_..."}})pour le stocker. La HogFunction le récupère et vérifie les payloads entrants.
-
Vérifiez avec
external-data-sources-webhook-info-retrieve({id}). Un webhook sain aexists: true,external_status.status: "enabled", et aucunerror.
Les webhooks sont supplémentaires à la synchronisation en masse. Le chargement initial d'un schéma activé par webhook est toujours fait via interrogation
(initial_sync_complete bascule à true quand c'est fait) ; après cela, le webhook devient le chemin d'ingestion principal. Un schéma webhook aura toujours
une sync_frequency qui programme une actualisation en masse périodique comme filet de sécurité. C'est attendu — pas quelque chose à « corriger ».
Étape 7 — Confirmer et expliquer ce qui se passe ensuite
Après la création (et, pour les schémas webhook, après l'étape 6) :
- Appelez
external-data-schemas-listpour montrer à l'utilisateur l'état initial. - Expliquez : chaque schéma activé entre en
Running, puis se déplace versCompletedquand la première synchronisation se termine. Les premières synchronisations peuvent prendre de quelques secondes à plusieurs heures selon le nombre de lignes — une table de plusieurs millions de lignes est correcte, juste lente. - Dites-lui comment faire une requête :
SELECT * FROM {prefix}_{table_name} LIMIT 10en HogQL. - Proposez de vérifier dans quelques minutes pour confirmer que les premières synchronisations ont réussi.
Configuration CDC pour Postgres (optionnel, quand demandé)
Si l'utilisateur souhaite une réplication quasi temps réel depuis Postgres :
- Avant d'appeler db-schema, exécutez
external-data-sources-check-cdc-prerequisites-createavec ses identifiants Postgres. Cela retourne{valid, errors[]}listant tout ce qui manque (wal_level, replication slot, publication, permissions). - Si
valid: false, présentez les erreurs et demandez à l'utilisateur de corriger côté Postgres. N'essayez pas de créer une source CDC qui échouera immédiatement. - Une fois les prérequis passés, procédez à db-schema et create. Définez
sync_type: "cdc"sur les tables qui en ont besoin, et incluezprimary_key_columnspour chacune (CDC les nécessite).
Notes importantes
- Validez toujours les identifiants avec db-schema avant create. L'endpoint create acceptera les identifiants invalides et échouera
ensuite de manière asynchrone — la source apparaît dans la liste avec le statut
Erroret aucune tables. Sauter l'étape de validation pousse juste l'échec en arrière-plan. - Présentez la liste des tables avant de créer. Les grandes bases de données peuvent avoir des centaines de tables. Ne les sélectionnez pas automatiquement — les comptages de lignes et la pertinence importent pour la facturation. Laissez l'utilisateur s'inscrire explicitement.
- N'inventez pas de schémas. Chaque entrée dans l'array
schemasdoit correspondre à une vraie table de la réponse db-schema. Vous ne pouvez pas « aussi ajouter une table orders » sauf si db-schema en a trouvé une. - Le préfixe est important. C'est une partie de chaque requête HogQL que l'utilisateur écrira jamais contre ces tables. Choisissez quelque chose de court, descriptif, et pas déjà pris.
- Les sources OAuth sont différentes. Hubspot, Salesforce, Google Ads etc. ont besoin que l'utilisateur autorise via l'interface de PostHog. Dirigez-le là — n'essayez pas de collecter des tokens OAuth en chat.
- Les webhooks sont une étape séparée après create. Défini
sync_type: "webhook"sur un schéma n'enregistre pas le webhook — l'appelcreate-webhookle fait. Suivez toujours create → create-webhook → webhook-info pour les schémas de type webhook, et ne laissez jamais un schéma webhook en suspens sans enregistrement (il ne recevra simplement pas d'événements). - Le support des webhooks est spécifique à la source et clairsemé. Actuellement seul Stripe implémente
WebhookSource. Ne promettez pas de webhooks pour Hubspot, Salesforce, ou Postgres — ils utiliseront la synchronisation par interrogation. - Les comptages de lignes pilotent la facturation. La synchronisation d'entrepôt est mesurée par les lignes synchronisées. Une table
d'événements bavarde de 500M de lignes synchronisée toutes les heures est très différente d'une table de dimension de 10k lignes synchronisée quotidiennement.
Signalez les tables grandes et proposez des fréquences de synchronisation plus longues (
sync_frequency: "24hour") par défaut.