PostHog Endpoints: Turn Your Analytics Queries Into a Real API

PostHog
PostHog Endpoints: Turn Your Analytics Queries Into a Real API

If you've ever built customer-facing analytics the hard way (e.g using Google APIs), you know the flow. Write a query, wrap it in a route, add caching logic, hope nothing times out under load, and do it all again when someone wants a slightly different number.

PostHog New Feature: Endpoints handles most of that for you.

What Endpoints Actually Are

The idea is simple: you have an insight or SQL query in PostHog that returns data you want to expose. Endpoints turns that query into a stable API URL you can call from anywhere, with built-in caching, rate limits, versioning, and performance tooling already wired up.

Real Use Cases

Customer-facing analytics. Say you want each user in your app to see their own usage stats. You write a SQL query that counts events filtered by user_id, add a variable for that ID, and create an endpoint. Your backend passes the current user's ID at call time, gets back their count, and renders it in your UI. The query never changes. The endpoint never changes. You just pass a different variable per user.

PostHog's own docs show this pattern with a simple button click counter, but the same approach works for anything: emails sent, files processed, API calls made, seats used. Any per-user metric you'd otherwise build a separate reporting service for.
that points to

Internal tools in Retool. If your team uses Retool, you can wire PostHog data directly into your dashboards without writing a custom backend route. Create a REST API resource in Retool that points to your PostHog project, add your API key as a header, and then call any endpoint by name. Retool AI can even scaffold the chart for you: tell it to query pageviews_by_os/run and display the results, and it sets up the query and visualization. You get live PostHog data sitting next to your other admin tools in a few minutes.

Landing page metrics. If you want to show live numbers on a marketing page, the old approach was either to hardcode stale data or to build a microservice. With Endpoints, you define the query in PostHog, create an endpoint, and call it from your page on load. No caching layer to maintain, because the endpoint handles it.
don't need to update the query string every time the underlying SQL changes

AI agents and scheduled jobs. Any agent or job that needs to pull aggregated event data on a schedule can call a stable endpoint URL instead of reconstructing the query each time. The endpoint name doesn't change between versions, so you don't need to update the query string every time the underlying SQL changes.

Why Not Just Use the Query API

The Query API already exists and is free, so this is worth addressing directly. For exploration and one-off pulls, it's fine. For anything running in production, it has real problems. PostHog says so themselves: because the query isn't known ahead of time, they can't optimize it. Monitoring is manual. Future pricing is coming for it.

Endpoints flip all of that. Because the query is predefined, PostHog can run it faster, monitor it automatically through a built-in Usage tab, and give you higher rate limits. You also get versioning and OpenAPI spec generation that don't exist in the Query API at all.

Use the Query API while figuring out what you need. Once the query is settled, move it to an endpoint.

The Performance Story

Two things drive performance: caching and materialization.

Caching is the lighter option. Results get cached, and you configure how long that cache stays valid. When it ages out, the endpoint re-runs the query and stores the new result. You don't need to build your own caching layer.

Materialization goes further. PostHog pre-computes the query result and stores it in S3. When someone hits the endpoint, they get the stored result instead of a live query. Response times drop significantly. The trade-off is freshness: you choose a sync schedule, ranging from hourly to weekly. If your query is expensive and real-time data isn't a requirement, materialization is the right call. And if materialization fails, the endpoint automatically falls back to direct execution. You don't have to build that fallback yourself.

Variables and Versioning

Variables are what make one endpoint work for many callers. Without them, you'd need a separate endpoint per customer, per filter, per date range. With them, you define the query once with placeholders, and each caller passes their own values at runtime. That's also how the per-user analytics pattern works: one endpoint, one variable, every user gets their own data.

Versioning means you can update a query without breaking existing callers. Push a new version, and existing integrations keep running on the old one until you cut them over. Basic API behavior, and it's good to have it built in from the start.

One Security Note

PostHog flags this clearly: never expose your API key client-side. For customer-facing analytics, always proxy the endpoint call through your backend. Your backend authenticates with PostHog, passes the user's variable value, and returns the result to the frontend. That way, users only see data scoped to their own ID, and your API key stays server-side.

Where This Fits

Endpoints is still in beta, though PostHog confirmed GA is close. It's free for now, with a commitment to notify users before pricing changes.

If you're already using PostHog and building anything that needs analytics data outside the PostHog UI, set up an endpoint before you hand-build something you'll regret maintaining.

Put this into practice

Manage your agency smarter

SmartMetrics gives agencies the tools to track client health, automate reporting, run audits, and deliver a fully branded client experience — all in one place.

  • No credit card required
  • Setup in minutes
  • Cancel anytime