Créer un endpoint
Cette compétence vous guide dans la création d'un nouvel endpoint avec la bonne configuration. Les endpoints exposent des requêtes HogQL ou insights sauvegardées en tant que routes HTTP appelables — les choix de configuration faits au moment de la création déterminent le coût, la latence et comment les appelants s'intègrent.
La plongée profonde sur la matérialisation se trouve à references/materializing.md. Consultez-la quand la décision de matérialisation n'est pas évidente.
Quand utiliser cette compétence
- « Créer un endpoint pour [requête] »
- « Exposer cet insight en tant qu'API »
- « Aide-moi à transformer ce HogQL en endpoint appelable »
- Un nouvel appelant (application mobile, dashboard client, pipeline aval) a besoin de données PostHog et l'utilisateur choisit comment les livrer
Décisions à prendre dans l'ordre
1. Cet endpoint est-il vraiment nécessaire ?
Les endpoints conviennent quand :
- Un système externe (le code de quelqu'un d'autre) doit appeler PostHog pour obtenir des données
- La requête est stable — pas une analyse exploratoire
- La forme est réutilisable — même requête avec différents paramètres
Les endpoints ne conviennent pas quand :
- Un dashboard ou insight interne PostHog a besoin des données — utilisez l'insight directement ; un endpoint ajoute seulement une surface API externe inutile en interne
- Analyse unique et exploratoire — utilisez l'outil
execute-sql(ou l'éditeur SQL) directement
L'agrégation lourde n'est pas une raison d'éviter un endpoint. Les endpoints sont eux-mêmes des requêtes sauvegardées, et une agrégation lourde appelée fréquemment est souvent le meilleur cas pour un endpoint avec matérialisation activée.
Si l'utilisateur hésite, demandez ce qui va appeler l'endpoint et quelle forme il attend.
2. Choisir un nom
Les noms sont sûrs pour les URLs (lettres, chiffres, tirets, traits de soulignement), commencent par une lettre, 128 caractères max, doivent être uniques dans le projet. Préférez :
- Descriptif plutôt que générique —
weekly_active_users_by_orgplutôt quemetrics - Snake_case — correspond à comment le nom apparaît dans les chemins de code et les URLs
- Pas de version dans le nom — les versions sont gérées par l'endpoint lui-même
- Pas d'« endpoint » dans le nom — redondant
Le nom apparaît dans l'URL : /api/projects/{team_id}/endpoints/{name}/run. Ce n'est pas trivialement renommable plus tard (les appelants dépendent du chemin) — faites-le correctement à la création.
3. Choisir le type de requête
Deux options existent :
- HogQL (
HogQLQuery) — SQL brut écrit par l'utilisateur. Variables définies via la syntaxe{variables.x}, mises en correspondance surcode_name. Recommandé pour les nouveaux endpoints quand l'appelant se soucie de la forme exacte des colonnes de la réponse. - Insight — enveloppe une définition d'insight existante. Meilleur support pour
TrendsQuery,LifecycleQueryetRetentionQuery: ceux-ci peuvent être matérialisés et la ventilation peut agir comme variable (Trends et Retention uniquement ; Lifecycle n'a pas de ventilation). D'autres types d'insights commeFunnelsQuerypeuvent s'exécuter inline mais ne peuvent pas être matérialisés et n'exposent pas de variables de ventilation — réécrivez ceux-ci en HogQL si vous en avez besoin.
HogQL est le choix plus flexible. Choisissez insight uniquement quand l'utilisateur republish vraiment un insight existant (voir « Créer à partir d'un insight existant » ci-dessous) plutôt que de construire une nouvelle requête.
4. Décider quelles entrées deviennent des variables
Tout ce qui doit changer par appelant va dans les variables ; le reste est codé en dur dans la requête.
Pour les endpoints HogQL, les variables sont déclarées dans la charge utile de requête avec code_name, type et default. Chaque appel d'exécution passe { "variables": { "<code_name>": valeur } }.
Motifs courants :
- Fenêtres de temps :
date_from,date_to, ou un entierlookback_daysunique - Filtres d'identité :
user_id,account_id,team_id - Contrôle de pagination au-delà de
limit/offset(ceux-ci sont de première classe sur l'endpoint run)
Pour les endpoints insight, la propriété de ventilation agit comme variable (Trends et Retention uniquement — Lifecycle n'a pas de ventilation). Passez le nom de la propriété de ventilation comme clé. date_from / date_to sont acceptés comme variables uniquement sur les endpoints insight non matérialisés — un endpoint matérialisé cuit sa plage de dates dans la vue, donc les appelants ne peuvent pas décaler la fenêtre.
Évitez :
- Variables qui changent la forme du résultat — gardez les colonnes stables. Si les appelants ont besoin de formes de résultats fondamentalement différentes, livrez des endpoints séparés.
- Variables qui contournent la sécurité — ne pas exposer une variable
where_clausequi laisse les appelants injecter du SQL arbitraire.
Créer à partir d'un insight existant
Il n'existe pas d'opération côté serveur « créer un endpoint à partir de l'insight N ». Pour ce faire : lisez la requête de l'insight (via les outils insight), passez cette requête à endpoint-create, et définissez derived_from_insight à l'id court de l'insight afin que l'origine soit enregistrée. L'endpoint possède alors sa propre copie de la requête — les modifications ultérieures de l'insight ne se propagent pas. Vous préférez partir de zéro ? Construisez la requête d'abord avec les outils insight / sql-variables, puis créez l'endpoint à partir de celle-ci.
5. Définir data_freshness_seconds
Ce seul champ fait deux jobs, alors définissez-le délibérément :
- TTL du cache — les résultats sont servis du cache jusqu'à ce qu'ils aient cet âge en secondes.
- Fréquence de rafraîchissement de la matérialisation — sur un endpoint matérialisé, c'est aussi la fréquence à laquelle l'entrepôt recalcule la vue matérialisée.
Donc une valeur inférieure signifie des données plus fraîches et un coût de recalcul/rafraîchissement plus fréquent ; une valeur supérieure est moins chère des deux côtés mais plus ancienne.
La valeur doit être parmi un ensemble fixe : 900 (15 min), 1800 (30 min), 3600 (1 h), 21600 (6 h), 43200 (12 h), 86400 (24 h, par défaut), 604800 (7 d). Il n'y a pas d'option sous 15 minutes — 900 est le minimum.
data_freshness_seconds |
Quand le choisir |
|---|---|
| 900–1800 | Le plus frais disponible — dashboards où l'ancienneté est visible |
| 3600–43200 | Plupart des cas — assez frais pour l'usage produit, peu coûteux à recalculer |
| 86400–604800 | Rapports, métriques hebdo/quotidiens, tout agrégé sur longues périodes |
Préférez les valeurs supérieures à moins que l'utilisateur n'ait explicitement besoin de données plus fraîches. Sur un endpoint matérialisé, souvenez-vous que cela définit aussi la cadence de rafraîchissement.
6. Décider de la matérialisation le premier jour
Consultez references/materializing.md pour l'arbre de décision complet. Version courte :
- Recommandez la matérialisation quand l'endpoint sera appelé fréquemment, la latence compte, et l'utilisateur peut tolérer une ancienneté égale à l'intervalle de rafraîchissement (généralement 5-15 minutes pour matérialisation planifiée, ou horaire).
- Ignorez la matérialisation pour les endpoints faible trafic, les nouveaux endpoints exploratoires (vous ne savez pas encore s'ils seront appelés), et les requêtes où la fraîcheur est critique.
En cas de doute, créez sans matérialisation et ajoutez is_materialized: true plus tard une fois que l'usage se stabilise. Cela évite de payer pour la matérialisation sur une requête que personne n'appelle finalement.
Workflow
- Confirmer le cas d'usage (étape 1 ci-dessus). Si ce n'est vraiment pas adapté à un endpoint, recommandez l'alternative.
- Convenir d'un nom avec l'utilisateur.
- Parcourir la requête — confirmer que c'est HogQL ou insight, et que les colonnes/forme ont du sens.
- Identifier ce qui devrait être une variable. Montrez à l'utilisateur la syntaxe de déclaration de variable.
- Choisir
data_freshness_secondsselon la requirement de fraîcheur de l'utilisateur (demandez si ce n'est pas clair) — en se souvenant que cela définit aussi la cadence de rafraîchissement de la matérialisation. - Faire l'appel de matérialisation. En cas de doute, livrez sans et revisitez plus tard.
- Appeler
endpoint-createavec la configuration convenue. - Confirmer en appelant
endpoint-runavec une charge utile d'exemple pour vérifier la forme de la réponse. - Transférer à
consuming-endpoints-from-client-codesi l'utilisateur s'apprête à le connecter.
Exemple d'interaction
Utilisateur : « Je veux exposer notre décompte des utilisateurs actifs mensuels en tant qu'API
pour notre partenaire analytics »
Agent :
- « Vérification rapide : le partenaire va-t-il appeler ceci à la demande, ou
devrions-nous lui envoyer les données ? Les endpoints sont pull-only. »
- Utilisateur : « À la demande »
- « Compris. Quelques choix :
- Nom : que diriez-vous de monthly_active_users ? Minuscules, descriptif,
sans bagages de version.
- La requête — c'est HogQL ou vous exposez un insight existant ?
HogQL vous donne le contrôle exact des colonnes ; insight réutilise ce que vous
avez déjà construit.
- Par quoi le partenaire devrait-il pouvoir filtrer ? Org, fenêtre de temps,
les deux ?
- Qu'il soit frais ? Si MAU dérape dans un jour, c'est bon, nous pouvons cacher
les résultats 1-24 heures et servir presque tout depuis le cache.
- Matérialisation : si le partenaire va frapper ceci plusieurs fois
par jour, le matérialiser ferait les réponses quasi-instantanées.
Le compromis est ~10-15 minutes d'ancienneté.
Quel est votre point de départ sur ces éléments ? »
[utilisateur choisit : HogQL, variables lookback_days + org_id, TTL 3600s,
pas encore matérialisé]
- endpoint-create monthly_active_users {requête, variables, ...}
- endpoint-run avec charge utile d'exemple {org_id: "test", lookback_days: 30}
- « Créé et testé. Voulez-vous de l'aide pour connecter le code client ?
C'est consuming-endpoints-from-client-code. »
Notes importantes
- Le nom vit dans l'URL. Le changer plus tard exige de migrer les appelants. Choisissez bien.
- Les endpoints HogQL sont plus flexibles que les endpoints insight. Préférez HogQL à moins que l'utilisateur n'ait une raison spécifique d'envelopper un insight existant.
- Les variables sans défaut échouent au moment de l'appel. Définissez toujours les défauts lors de la création afin que l'endpoint soit testable depuis le playground sans spécifier chaque variable.
- Les endpoints matérialisés exigent que toutes les variables soient passées. Les appels sans elles sont rejetés — c'est intentionnel (sécurité : empêche de retourner des données non filtrées). Associez la recommandation de matérialisation à une note pour l'utilisateur sur les variables qui deviennent obligatoires. (Les variables optionnelles/partielles sur les endpoints matérialisés sont une limitation connue que l'équipe PostHog prévoit de lever — si cela bloque l'utilisateur, encouragez-les via l'outil
agent-feedback.) - N'activez pas la matérialisation sur une requête qui n'est pas éligible. Utilisez d'abord
endpoints-materialization-previewpour confirmer l'éligibilité et voir la raison du rejet si applicable. - Les endpoints ne sont pas stables pour toujours. Quand l'utilisateur change la requête, une nouvelle version est créée automatiquement (l'ancienne version reste accessible via
?version=N).data_freshness_secondset la matérialisation sont par-version. Ajustez à mesure que l'endpoint évolue. - Recommandez aux appelants d'épingler une version. Dites à l'utilisateur d'appeler avec
?version=Nplutôt que de compter sur « latest » — de cette façon une future édition de requête (qui crée une nouvelle version) ne peut pas changer silencieusement leurs résultats. Ils font passer la version épinglée délibérément une fois qu'ils ont validé la nouvelle. - Partagez les frictions via
agent-feedback. Si une limitation se met en travers (règles d'éligibilité, variables obligatoires, l'enum TTL), envoyez à l'équipe PostHog une note — c'est comment le produit et ces outils s'améliorent.