Analytics API overview
The Analytics API is experimental. Its routes, query semantics, and response shapes may change or be removed without notice, and it is not covered by the v2 backwards-compatibility guarantees. Avoid building production-critical integrations against it yet.
The Analytics API lets you run read-only SQL queries directly against your Paid data — usage signals, AI costs, revenue, credits, and delivered value — so you can build your own dashboards, reports, and in-product analytics without exporting data first.
Every query is automatically scoped to your organization: you can only ever see your own data, and no organization filter is needed (or possible) in your SQL.
Prerequisites
- Have your API key ready.
The data model
Your data is exposed as a small star schema
of dimension tables (dim_*, describing entities) and fact tables
(fact_*, describing events and transactions). Facts join to dimensions on
*_id columns.
See the Schema reference for every column, and the Query cookbook for ready-to-use examples.
Endpoints
The base URL is https://api.agentpaid.io/api/v2/experimental/analytics. All
endpoints authenticate with your API key via the Authorization: Bearer header.
POST /query
Run a single SQL statement. The request body is { "query": "<sql>" }.
The response gives you typed columns, rows in column order, and metadata:
GET /schema
Returns the queryable views with their columns, types, and descriptions — the same information as the Schema reference, live from your account. Useful for discovery and for building tooling.
GET /signals/metadata
Signals carry a free-form JSON data payload whose shape you define. This
endpoint lists the JSON paths (and their observed types) present in your
signals, grouped by signal name, so you know what you can filter and group on.
Writing queries
The API speaks ClickHouse SQL. A few rules and conventions:
- Read-only. Only a single
SELECT(orWITH … SELECT) statement is accepted. Anything else is rejected. - No org filter needed. Queries are automatically restricted to your
organization. Reference tables by their unqualified name (
FROM fact_signal), notanalytics.fact_signalordefault.*. - Money is in cents. All monetary columns are integer cents — divide by 100
for display (e.g.
total_incl_tax / 100). - 64-bit integers come back as strings. Counts, sums, amounts, and large
ids (
UInt64/Int64) are returned as JSON strings to preserve precision beyond 2^53. Parse them client-side as needed. Smaller integers, floats, booleans, and dates serialize natively.
Limits
These limits are guardrails for interactive analytics. The API is not a bulk
export mechanism — for large extracts, aggregate or paginate with
LIMIT/WHERE on an indexed column such as created_at.
Errors
Errors return a JSON body with an error, a machine-readable code, and
usually a details message.