Skip to content

dragstor/go-plausible

Repository files navigation

go-plausible

go-plausible banner

Zero-dependency Go client for the Plausible Stats API v2 (/api/v2/query). Typed queries, friendly helpers, and tidy responses.

Go Reference Go Report Card License: MIT


Table of Contents


Features

  • One endpoint, many shapes: Aggregate, Timeseries, Breakdown, and a small Realtime helper-all via POST /api/v2/query.
  • Typed request/response models with helpers (MetricInt, MetricFloat, MetricRevenue).
  • Query builders: NewAggregate, NewTimeseries, NewBreakdown.
  • Options: WithFilters, WithOrder, WithTimeLabels, WithImports, WithTotalRows, WithPagination, WithDimensions.
  • Zero dependencies (stdlib only).
  • Unit tests with httptest.Server.
  • Usage examples in code comments and examples_test.go.

Install

go get github.com/dragstor/go-plausible

Import:

import "github.com/dragstor/go-plausible"

Quick start

client := plausible.NewClient("YOUR-API-KEY", nil) // nil => http.DefaultClient

q := plausible.NewAggregate(
    "example.com",
    []string{"visitors", "pageviews"},
    plausible.Preset("30d"),
)

resp, err := client.Query(ctx, q)
if err != nil { /* handle */ }

for _, row := range resp.Results {
    v, _ := row.MetricInt(0) // visitors
    p, _ := row.MetricInt(1) // pageviews
    _ = v; _ = p
}

API overview

Tiny mental model:

flowchart LR
    A[Your App] -->|Query| B[go-plausible Client]
    B -->|POST /api/v2/query| C[Plausible API v2]
    C -->|results + meta + query| B --> A
Loading

Aggregate

q := plausible.NewAggregate("example.com",
    []string{"visitors", "pageviews"},
    plausible.Preset("7d"),
)
resp, _ := client.Query(ctx, q)

Timeseries

q := plausible.NewTimeseries("example.com",
    []string{"visitors"},
    plausible.Preset("7d"),
    "time:day",
    plausible.WithTimeLabels(),
)
resp, _ := client.Query(ctx, q)

Breakdown

q := plausible.NewBreakdown("example.com",
    []string{"pageviews"},
    plausible.Preset("30d"),
    []string{"event:page"},
    plausible.WithOrder("pageviews", "desc"),
    plausible.WithPagination(100, 0),
)
resp, _ := client.Query(ctx, q)

Filters & options

q := plausible.NewBreakdown("example.com",
    []string{"visitors"},
    plausible.Preset("month"),
    []string{"visit:country_name"},
    plausible.WithFilters(
        plausible.Is("visit:country_name", "Serbia", "Germany"),
        plausible.Contains("event:page", "/pricing"),
        plausible.HasDone("event:goal", "Signup"), // behavioral filter
    ),
    plausible.WithTotalRows(),
)
resp, _ := client.Query(ctx, q)
Date ranges
plausible.Preset("7d")              // "7d", "month", "all", etc.
plausible.Range(startTime, endTime) // RFC3339 timestamps
plausible.DayRange("2025-09-01", "2025-09-30")
Realtime helper
current, _ := client.RealtimeVisitors(ctx, "example.com") // last 5 minutes

Live example (optional)

If you want to run against the real API, provide two env vars:

export PLAUSIBLE_API_KEY=your-api-key
export PLAUSIBLE_TEST_SITE=example.com

Then run your own snippet (see Quick start) or wire a tiny cmd/live-query of your choice.
Tip: prefer shell env first; only fall back to a local .env if you use one.


Example output

Screenshot (out.png) from a sample run:

Sample CLI output

Plain text:

== Aggregate (last 7 days) ==
Aggregate: got 1 row(s)
Aggregate metrics:
- visitors: 208
- pageviews: 278

== Realtime (last 5 minutes) ==
Current visitors: 0

== Timeseries (daily, last 7 days) ==
Timeseries: 7 data points
2025-09-21: 12 visitors
2025-09-22: 11 visitors
2025-09-23: 29 visitors
2025-09-24: 19 visitors
2025-09-25: 35 visitors
2025-09-26: 39 visitors
2025-09-27: 64 visitors

== Custom range (last hour) ==

Custom range results:
Range: 2025-09-28T20:39:50Z to 2025-09-28T21:39:50Z
Rows:

Row 1
- visitors: 1

All examples finished.

Contact & projects

Maintainer
Nikola Stojković

🦋 Bluesky: https://bsky.app/profile/brka.io · ✖️ X: https://x.com/IT_mafija

Not affiliated with Plausible.

I also build HostedStatus.page — uptime monitoring, incident management, and public status pages: https://hostedstatus.page

Open-source


Use cases

This library is intentionally small and zero-dependency, so it fits into many developer workflows. Common use cases include:

  • Embedded site dashboards - fetch aggregates or timeseries and render them in a web dashboard. For example, you can back an "Open Startup" page using NewAggregate or NewTimeseries to drive widgets that show visitors, pageviews, etc.
  • Integrating with Go web frameworks - call the client from HTTP handlers in frameworks like Gin (https://github.com/gin-gonic/gin), Chi (https://github.com/go-chi/chi), or Echo (https://github.com/labstack/echo) to expose metrics on pages or APIs.
  • Background jobs and cron tasks - use the client from scheduled workers to fetch stats, persist snapshots, or send alerts when thresholds are crossed.
  • Command-line tools and scripts - build small CLI utilities that query Plausible.io and print reports (CSV/JSON) or feed other tools.
  • Serverless functions and workers - the zero-dependency design keeps binary size small for serverless deployments (AWS Lambda, Cloud Run, etc.).
  • Testing and CI - because the test suite uses httptest.Server, it's straightforward to mock responses in unit tests or CI pipelines.

Because this client focuses on the Stats API v2 POST /api/v2/query endpoint, it works well for dashboards, automation, and embedded site displays where typed, reproducible query results are required.

License

MIT - see LICENSE.

About

A tiny, zero-dependency Go client for Plausible Stats API v2 (POST /api/v2/query).

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages