API

The v1 API exposes a set of read-only endpoints for your analytics data, each gated by an API key bound to your workspace. This page covers everything: which plan you need, creating a key, authentication, the shared parameters, all seven endpoints, errors, rate limits, and the llms.txt manifest.

The API is read-only: you use it to fetch your own analytics data, never to send data in.

Let an AI set this up for you

Copy the prompt below into Claude, ChatGPT or any other AI. It carries everything the AI needs: where to get your key, the base URL, the auth header, the parameters and every endpoint. It asks you for your key first, then writes and runs the requests.

I use TrueMetriks, a server-side tracking and conversion attribution platform.
Help me pull my own analytics out of it through its read-only REST API, and
then answer questions about that data.

BEFORE YOU WRITE ANY CODE, ask me for these two things and wait for my reply:

  1. My TrueMetriks API key.
  2. My site_id (a whole number).

Tell me exactly where to find them:

  - Sign in at https://app.truemetriks.com
  - Open "Settings" for the site you want (the site's OWN settings, NOT
    Account Settings), then click the "Integrations" tab.
  - In the tile grid, after "Webhooks", click the "API Keys" tile.
  - Under "Create API key", type a name (for example "ai-assistant"), click
    "Create", and copy the key from the dialog that appears.
  - IMPORTANT: the key is shown ONCE and cannot be looked up again. Tell me to
    paste it somewhere safe, such as a password manager, before closing the
    dialog. If it is lost, the only fix is to create a new key.
  - API access requires the Unlimited plan. If the API Keys tile is greyed out
    with a padlock reading UNLIMITED, I am on a lower plan and cannot use the
    API until I upgrade.
  - My site_id is the number in the dashboard URL while that site is open, for
    example https://app.truemetriks.com/42/main means site_id is 42. It is also
    in the settings URL: /settings/websites/42/integrations.

Never print my key back to me in full, never paste it into a public place, and
never commit it to a repository. Read it from an environment variable such as
TM_API_KEY instead of hard coding it.

HOW THE API WORKS

Base URL: https://app.truemetriks.com/v1
Auth:     send this header on every request
          Authorization: Bearer <MY_API_KEY>
Method:   every endpoint is GET and read-only. Responses are JSON.

Shared query parameters, accepted by every endpoint:

  site_id    REQUIRED. Whole number. My site.
  period     Optional shorthand. One of: today, yesterday, last_7d, last_30d,
             last_90d, last_365d. If given, it overrides from/to.
  from, to   Optional explicit dates, YYYY-MM-DD, both or neither. Inclusive.
  timezone   Optional IANA timezone, for example America/New_York. Default UTC.

  If neither period nor from/to is given, the range defaults to the last 30
  days. The range may not exceed 366 days. There are NO start_date or end_date
  parameters: sending them does nothing and you silently get the last 30 days.
  There is no previous-period shortcut, so to compare two periods call the
  endpoint twice with explicit from/to ranges.

All money fields come back as decimal dollars (for example 4590.50), never
cents, rounded to 2 decimal places.

THE SEVEN ENDPOINTS

GET /v1/overview
  Top-level KPIs plus a per-source breakdown. The only endpoint that returns
  per-source SESSION counts, so use it for revenue-per-session questions.
  Extra params: none.
  Returns: period{from,to,timezone},
           totals{sessions,unique_visitors,pageviews,revenue,leads,purchases},
           by_source[{source,channel,sessions,revenue,leads,purchases}]

GET /v1/revenue
  Any "how much money" question.
  Extra params: none.
  Returns: period, totals{revenue,purchases,average_order_value},
           by_source[{source,channel,revenue,purchases,conversion_rate_pct}],
           by_product[{sku,product_name,revenue,units}],
           by_day[{date,revenue,purchases}]
  Note: conversion_rate_pct is sessions-to-purchase for that source, NOT
  leads-to-purchase. For leads-to-purchase, divide /v1/revenue
  totals.purchases by /v1/leads totals.leads.

GET /v1/leads
  Lead counts with source attribution. This returns COUNTS, not a list of
  people, and no personal data.
  Extra params: none.
  Returns: period, totals{leads}, by_source[{source,channel,leads}]

GET /v1/pages
  Top pages by pageviews. No source breakdown, by design.
  Extra params: limit (1 to 100, default 25).
  Returns: period,
           pages[{path,pageviews,unique_visitors,avg_time_on_page_seconds,
                  bounce_rate_pct}]

GET /v1/products
  Per-product revenue and units.
  Extra params: none.
  Returns: period,
           products[{sku,product_name,units_sold,revenue,average_price}],
           by_source[{source,channel,top_product_sku,top_product_name,revenue}]

GET /v1/users
  Visitor counts and segmentation. Aggregate counts only, not a list of people.
  Extra params: none.
  Returns: period,
           totals{unique_visitors,returning_visitors,new_visitors},
           by_source[{source,channel,visitors}],
           by_country[{country,visitors}]

GET /v1/funnels
  The site's saved funnels with per-step counts and conversion rates. The
  funnels array is empty if none are defined.
  Extra params: none.
  Returns: period,
           funnels[{id,name,overall_conversion_pct,
                    steps[{step_name,visitors,conversion_from_previous_pct}]}]

ERRORS TO EXPECT

  401 AUTH_REQUIRED         no Authorization header
  401 INVALID_API_KEY       key not found, expired or revoked
  403 TIER_NO_API_ACCESS    my plan does not include API access
  403 SITE_ACCESS_DENIED    key is valid but has no access to that site_id
  400 MISSING_SITE_ID       site_id was not supplied
  400 BAD_DATE_FORMAT       dates are not YYYY-MM-DD, or only one of from/to
  400 RANGE_TOO_WIDE        range is longer than 366 days
  429 RATE_LIMITED          200 requests per minute per key was exceeded
  504 QUERY_TIMEOUT         query took over 10 seconds, narrow the range

WHAT TO DO

1. Ask me for the key and site_id, as described above.
2. Write a script (bash with curl, or Python with requests) that reads the key
   from the TM_API_KEY environment variable.
3. Start with a single call to /v1/overview for period=last_7d to confirm the
   key works, and show me the result.
4. Then ask what I actually want to know, and use the endpoints above to answer
   it. If a question needs two date ranges, call the endpoint twice.

If you are in a chat-only tool with no way to run code or make HTTP requests,
say so, then give me a ready-to-run script I can run myself and paste the
output back to you.

You need the Unlimited plan

API access is on the Unlimited plan only. On Starter and Growth the API Keys tile is greyed out with a padlock chip reading UNLIMITED, so no key can be created.

NEW

MCP (AI access)

UNLIMITED

NEW

API Keys

UNLIMITED

On Starter and Growth both tiles are greyed out and the status line is replaced by a padlock chip reading UNLIMITED.

If a workspace drops to a lower plan, its keys stay in place but every request is refused:

{
  "error": "API access is available on the Unlimited plan. Please upgrade to use the API.",
  "code": "TIER_NO_API_ACCESS"
}

Upgrading restores access immediately, with the same key.

Creating an API key

API keys live on the site's own Integrations tab. They are no longer in Account Settings.

  1. Open Settings for the site you want (the site's settings, not Account Settings).
  2. Click the Integrations tab.
  3. After Webhooks, click the API Keys tile. Its status line reads No keys yet, 1 key or N keys.

Integrations

Connect third-party data sources to fire events into TrueMetriks.

Typeform

Typeform

Connected

Calendly

Calendly

Connected

Microsoft Clarity

Configured (1 project)

stripe

Stripe

Connected

Whop

Not connected

PayPal

PayPal

Not connected

Webhooks

Receiving 4, sending 2

NEW

MCP (AI access)

No key yet

NEW

API Keys

No keys yet

Settings for your site, the Integrations tab. The highlighted API Keys tile sits after Webhooks, marked NEW.
  1. Type a name under Create API key and click Create. Name it after where it will be used, like reporting-script, so you can revoke just that one later.

Back to Integrations

API Keys

Read your analytics from your own code over the v1 REST API.

Using the API

Endpoints, authentication and rate limits.

Read the API guide

Create API key

Name it after where it will be used, so you can revoke just that one later.

API Key Name Create

Your API keys

Name Key Created Actions
reporting-script tm_live_… Aug 3, 2026, 10:41 AM Delete
looker-connector tm_live_… Aug 4, 2026, 6:11 AM Delete
Settings, Integrations, API Keys. Name a key, click Create, and it appears under Your API keys. Delete revokes it immediately. Keys minted by the WordPress plugin and the MCP key are deliberately not listed here.

The full key is shown once, in a dialog. Copy it then and store it somewhere safe. Afterwards the list keeps only a masked preview, and a lost key cannot be recovered: you have to create a new one.

API Key Created

Save this API key securely. You won't be able to see it again.

Your API Key

tm_live_8f2c41d9b7e64a0a93c15d7f2ab6e084 Copy
Important: Store this key securely. It won't be displayed again.
Done
The full key is shown once, right after you create it. Copy it now: afterwards the list keeps only a masked preview and the key cannot be recovered.

Click Delete next to a key to revoke it. Revocation is immediate and cannot be undone.

What the key list does not show

This list shows only the keys created on this page. Deliberately hidden: keys from the WordPress plugin (named wp-plugin...), the MCP key, and revoked keys.

Never delete a wp-plugin key. It would break that site's plugin. It is hidden here precisely so that cannot happen by accident.

Keys are scoped to one workspace and inherit your site access, so a key can only read sites you can already see.

Base URL

https://app.truemetriks.com/v1

There is no separate API hostname. Every endpoint sits under the same origin as the dashboard.

Authentication

Every request requires an Authorization header with your key as a Bearer token:

Authorization: Bearer YOUR_API_KEY

A missing or malformed header returns 401 AUTH_REQUIRED. A key that is unknown, expired or revoked returns 401 INVALID_API_KEY. A valid key asking for a site you cannot access returns 403 SITE_ACCESS_DENIED.

Keep the key out of your source code. Read it from an environment variable instead:

export TM_API_KEY="your_key_here"
curl -H "Authorization: Bearer $TM_API_KEY" \
  "https://app.truemetriks.com/v1/overview?site_id=42&period=last_7d"

Common query parameters

Every endpoint accepts these:

Param Required Description
site_id yes The site you are querying, as a whole number
period no today, yesterday, last_7d, last_30d, last_90d, last_365d. Overrides from/to
from no Start date, YYYY-MM-DD, inclusive. Must be paired with to
to no End date, YYYY-MM-DD, inclusive. Must be paired with from
timezone no IANA timezone for date bucketing, for example America/New_York. Default UTC

Before your first request:

  • There is no start_date or end_date. Sending them has no effect, and since the range is optional you get the default last 30 days back with no error to warn you.
  • Send neither period nor from/to and the range defaults to the last 30 days.
  • from and to come as a pair. Sending one returns 400 BAD_DATE_FORMAT.
  • The range may not exceed 366 days (400 RANGE_TOO_WIDE), and from must not be later than to (400 INVERTED_RANGE).
  • There is no previous-period shortcut. To compare two periods, call the endpoint twice.

Every response echoes the range it used, so you can confirm what you got:

"period": { "from": "2026-07-06", "to": "2026-08-05", "timezone": "UTC" }

Money and rounding

All monetary fields are returned as decimal dollars, for example 4590.50, never cents. Values are rounded to 2 decimal places on the server.

Caching

Responses are cached for 60 seconds per unique set of parameters. The X-Cache response header reads HIT or MISS. To force a fresh read, send Cache-Control: no-cache.

Endpoints

All seven endpoints are GET and read-only.

GET /v1/overview

Top-level KPIs for the period plus a per-source breakdown. This is the only endpoint that returns per-source session counts, so use it whenever you need revenue per session or sessions per lead.

Parameters: the common parameters only.

curl -H "Authorization: Bearer $TM_API_KEY" \
  "https://app.truemetriks.com/v1/overview?site_id=42&period=last_7d"
{
  "period": { "from": "2026-05-08", "to": "2026-05-15", "timezone": "UTC" },
  "totals": {
    "sessions": 4321,
    "unique_visitors": 3210,
    "pageviews": 12345,
    "revenue": 4590.50,
    "leads": 287,
    "purchases": 32
  },
  "by_source": [
    { "source": "facebook", "channel": "Paid Social", "sessions": 2100, "revenue": 2750.00, "leads": 140, "purchases": 18 },
    { "source": "google",   "channel": "Paid Search", "sessions": 1100, "revenue":  900.50, "leads":  70, "purchases":  9 }
  ]
}

channel is the marketing ecosystem the session was classified into at ingest, the same grouping the dashboard Main page uses.

GET /v1/revenue

Revenue totals with breakdowns by source, by product and by day. Use it for any "how much money" question.

Parameters: the common parameters only.

curl -H "Authorization: Bearer $TM_API_KEY" \
  "https://app.truemetriks.com/v1/revenue?site_id=42&period=last_30d"
{
  "period": { "from": "2026-04-15", "to": "2026-05-15", "timezone": "UTC" },
  "totals": { "revenue": 23790.00, "purchases": 255, "average_order_value": 93.29 },
  "by_source": [
    { "source": "facebook", "channel": "Paid Social", "revenue": 12450.00, "purchases": 134, "conversion_rate_pct": 4.2 }
  ],
  "by_product": [
    { "sku": "TM-PRO-001", "product_name": "Premium Subscription", "revenue": 11900.00, "units": 100 }
  ],
  "by_day": [
    { "date": "2026-05-14", "revenue": 412.50, "purchases": 5 }
  ]
}

conversion_rate_pct is sessions to purchase for that source: purchases from the source divided by sessions from the source, times 100. It is not leads to purchase. For that, divide this endpoint's totals.purchases by /v1/leads totals.leads.

GET /v1/leads

Lead counts with source attribution. This returns counts, not a list of people, so no personal data comes back from it.

Parameters: the common parameters only.

curl -H "Authorization: Bearer $TM_API_KEY" \
  "https://app.truemetriks.com/v1/leads?site_id=42&period=last_30d"
{
  "period": { "from": "2026-04-15", "to": "2026-05-15", "timezone": "UTC" },
  "totals": { "leads": 287 },
  "by_source": [
    { "source": "facebook", "channel": "Paid Social", "leads": 140 },
    { "source": "google",   "channel": "Paid Search", "leads":  70 }
  ]
}

GET /v1/pages

Top pages by pageviews for the period. There is no source breakdown here by design.

Parameters (common parameters plus):

Param Description
limit Rows to return, 1 to 100. Default 25
curl -H "Authorization: Bearer $TM_API_KEY" \
  "https://app.truemetriks.com/v1/pages?site_id=42&period=last_7d&limit=5"
{
  "period": { "from": "2026-05-08", "to": "2026-05-15", "timezone": "UTC" },
  "pages": [
    { "path": "/", "pageviews": 5400, "unique_visitors": 3200, "avg_time_on_page_seconds": 32, "bounce_rate_pct": 41.2 }
  ]
}

GET /v1/products

Per-product revenue and units, plus the top product per source. Covers any Purchase event that shipped product details.

Parameters: the common parameters only.

curl -H "Authorization: Bearer $TM_API_KEY" \
  "https://app.truemetriks.com/v1/products?site_id=42&period=last_30d"
{
  "period": { "from": "2026-04-15", "to": "2026-05-15", "timezone": "UTC" },
  "products": [
    { "sku": "TM-PRO-001", "product_name": "Premium Subscription", "units_sold": 100, "revenue": 11900.00, "average_price": 119.00 }
  ],
  "by_source": [
    { "source": "facebook", "channel": "Paid Social", "top_product_sku": "TM-PRO-001", "top_product_name": "Premium Subscription", "revenue": 8700.00 }
  ]
}

GET /v1/users

Visitor counts and segmentation: new against returning, by source, and by country. These are aggregate counts, not a list of people.

Parameters: the common parameters only.

curl -H "Authorization: Bearer $TM_API_KEY" \
  "https://app.truemetriks.com/v1/users?site_id=42&period=last_30d"
{
  "period": { "from": "2026-04-15", "to": "2026-05-15", "timezone": "UTC" },
  "totals": { "unique_visitors": 8200, "returning_visitors": 1100, "new_visitors": 7100 },
  "by_source": [
    { "source": "facebook", "channel": "Paid Social", "visitors": 4100 }
  ],
  "by_country": [
    { "country": "US", "visitors": 5200 },
    { "country": "DE", "visitors":  410 }
  ]
}

GET /v1/funnels

Your saved funnels with per-step visitor counts and conversion rates. If the site has no funnels defined, funnels comes back as an empty array.

Parameters: the common parameters only.

curl -H "Authorization: Bearer $TM_API_KEY" \
  "https://app.truemetriks.com/v1/funnels?site_id=42&period=last_30d"
{
  "period": { "from": "2026-04-15", "to": "2026-05-15", "timezone": "UTC" },
  "funnels": [
    {
      "id": 1,
      "name": "Checkout Funnel",
      "steps": [
        { "step_name": "Product Page", "visitors": 1000, "conversion_from_previous_pct": 100 },
        { "step_name": "Add to Cart",  "visitors":  350, "conversion_from_previous_pct": 35.0 },
        { "step_name": "Purchase",     "visitors":   50, "conversion_from_previous_pct": 14.29 }
      ],
      "overall_conversion_pct": 5.0
    }
  ]
}

conversion_from_previous_pct compares each step with the step before it, while overall_conversion_pct compares the last step with the first.

Errors

Every error returns a JSON body with an error message and a machine-readable code.

Status Code Meaning
401 AUTH_REQUIRED No Authorization: Bearer header
401 INVALID_API_KEY Key not found, expired, or revoked
403 TIER_NO_API_ACCESS The workspace's plan does not include API access
403 SITE_ACCESS_DENIED Key valid but the caller has no access to site_id
400 MISSING_SITE_ID site_id was not supplied
400 BAD_SITE_ID site_id is not a positive whole number
400 BAD_DATE_FORMAT Dates are not YYYY-MM-DD, or only one of from/to was sent
400 INVERTED_RANGE from is later than to
400 RANGE_TOO_WIDE The range is longer than 366 days
400 BAD_PERIOD period is not one of the six accepted values
400 BAD_TIMEZONE timezone is not a valid IANA name
429 RATE_LIMITED Per-key rate limit hit
504 QUERY_TIMEOUT The query took longer than 10 seconds. Narrow the date range
500 INTERNAL Something failed on our side

Rate limits

Keys created on the Unlimited plan allow 200 requests per minute, measured over a rolling 60 second window. Going over returns 429 RATE_LIMITED; wait for the window to roll and retry.

The 60 second cache in front of every endpoint means a script that polls the same query repeatedly costs you far less than it looks: repeated identical requests inside that window come back from cache.

Building something bigger

The prompt at the top of this page suits an ordinary AI chat. For an agentic coding tool that can create files and run commands, like Claude Code or Codex, copy the whole page instead.

Open it in an empty folder, paste, and say what you want (for example, "fetch my revenue for last month and save it to a CSV"). Everything it needs is here.

Then paste it into Claude Code or Codex and tell it what data you want.

llms.txt

For LLM crawlers and code-completion tools, we publish a flat, summary-only index of this docs site at:

https://docs.truemetriks.com/llms.txt

It lists one line per docs page (title, URL, one-sentence description), grouped by section. It excludes long-form page bodies, the blog, and any anonymized customer data. A companion file, llms-full.txt, carries the full text of every page. Both regenerate on every docs deploy, and are byte-identical to the previous deploy when nothing changed.

That file describes the documentation. For the API itself there is a separate machine-readable manifest, served by the app rather than the docs site, which an AI can fetch directly:

https://app.truemetriks.com/api-docs/llms.txt
https://app.truemetriks.com/api-docs/openapi.json

The OpenAPI file is what you point a ChatGPT Custom GPT at when you want it to call the API as an Action.

Frequently asked questions

Is the API read-only?

Yes. The API is read-only: you use it to fetch your own analytics data, never to send data in. All endpoints are GET.

Where do I create an API key?

On the site's own Integrations tab, not in Account Settings. Open Settings for your site, click the Integrations tab, then click the API Keys tile and create a key there. The key is shown once, so copy it straight away.

Which plan do I need for API access?

The Unlimited plan. On Starter and Growth the API Keys tile is greyed out with an UNLIMITED padlock, and any request to a v1 endpoint is refused with 403 TIER_NO_API_ACCESS.

What are the rate limits?

200 requests per minute per key on the Unlimited plan, measured over a rolling 60 second window. Going over returns 429 RATE_LIMITED.

Why do I need to send start_date and end_date?

You do not. The v1 API uses period, or from and to, for its date range. There are no start_date or end_date parameters, and sending them is simply ignored, which silently gives you the default last 30 days.

Need help with this?

Reach us instantly on WhatsApp, or send us a message and we will get back to you. On workdays we usually respond in less than 24 hours.

or send us a message