Sign up

API reference

API overview

On this page

The REST API sends events and payments from your server, reads every dashboard report, and manages chart notes, funnels, segments, settings, alerts and team members. Everything the dashboard, the CLI and the MCP server show comes from these endpoints.

Base URL

Every path on these pages is relative to https://metricraven.com/api/v1. Send JSON request bodies with Content-Type: application/json; every response is JSON, except 204 No Content.

terminal
curl 'https://metricraven.com/api/v1/stats/traffic?range=all' \
  --header "Authorization: Bearer $METRICRAVEN_SECRET_KEY"

Which key to use

Send a key as Authorization: Bearer …. How to create each one is in Authentication and access tokens.

CredentialUse it for
Site secret key (ana_sec_…)Your backend, for one website. The only key that sends events, identify calls, payments and crawler requests, and the only key besides the dashboard that deletes a person's data. Also reads every report and changes settings of its own website.
Account access token (mr_…)Scripts, the CLI and AI assistants. Acts as you across websites, limited to its scopes, its websites and your role. Required for /account, /websites, /members and notification preferences. Never sends events or payments.
Share link token (?share=…)Public and embedded dashboards. Read-only aggregate reports without names, emails or visitor IDs. Send it as the share query parameter instead of an Authorization header.

The site parameter

  • Account tokens must send exactly one site=WEBSITE_ID on every website endpoint. A missing, repeated or unknown site, or a website the token is limited away from, returns 401.
  • Site secret keys already identify their website, so site is optional. If you send it, it must be that key's website ID; any other value returns 401.
  • Website IDs look like ana_pub_1a2b3c4d5e6f7a8b. List yours with GET /websites.

Access levels

Each website endpoint needs one of four access levels. A credential that lacks it gets 401.

LevelSecret keyAccount tokenShare link
read: aggregate reports, funnelsYesread scopeYes
live: realtime, chart notes, commitsYesread scopeNo
private: people and private configurationYesvisitors scopeNo
write: changesYeswrite scope, admin or owner roleNo

Reports read with a share link, or with a token without the visitors scope, return null instead of customer names, emails, user IDs and visitor IDs. An account token on a website where you are a viewer can read but never write, whatever its scopes.

Endpoints

Send data (secret key only)

RequestReference
POST /eventsServer-side goals
POST /identifyIdentify users
POST /paymentsPayments API
POST /crawlsCrawler requests (below)
POST /collectThe browser script and SDKs; no key, checked against your domains and app IDs. See Proxy.

Reports

RequestAccessReference
GET /stats/trafficreadTraffic
GET /stats/breakdownreadBreakdown
GET /stats/filter-valuesreadFilter values
GET /stats/conversionsreadConversions and funnels
GET /stats/goalreadOne goal
GET /stats/insightsreadBuyer insights
GET /stats/revenuereadRevenue
GET /stats/subscriptionsreadSubscriptions
GET /stats/searchreadSearch Console
GET /stats/adsreadAd spend and ROAS, every network
GET /stats/meta-adsreadMeta Ads only (alias)
GET /stats/currenciesreadReporting currency and exchange rates
GET /stats/crawlersreadCrawlers
GET /stats/crawler-pagesreadCrawled pages search
GET /stats/x-referrersreadX links
GET /stats/mentionsreadSocial mentions
GET /stats/ai-visibilityreadAI visibility
GET /stats/overviewreadCompact overview
GET /stats/liveliveRealtime
GET /stats/live/replayliveRealtime replay
GET /stats/live/valueliveValue of visitors online
GET /stats/visitorsprivateVisitor search
GET /stats/journeysprivateJourneys

Website configuration and people

RequestAccessReference
GET /notesliveChart notes
POST /notes, PUT /notes/ID, DELETE /notes/IDwriteChart notes
GET /commitsliveGitHub commits
GET /funnelsreadFunnels
POST /funnels, PUT /funnels/ID, DELETE /funnels/IDwriteFunnels
GET /segmentsprivateSegments
POST /segments, PUT /segments/ID, DELETE /segments/IDwriteSegments
GET /siteprivateSettings
PUT /sitewriteSettings
GET, POST /site/keys; PATCH, DELETE /site/keys/ID; POST /site/keys/ID/rollwrite, no secret keySecret keys
GET /goals/customizationsread, no share linksGoal names and colours
PUT, DELETE /goals/customizationswriteGoal names and colours
GET /visitors/VISITOR_IDprivateVisitor profile
DELETE /peoplewrite, no tokensErase a person
DELETE /paymentswriteDelete payments
DELETE /eventswriteDelete goal events
GET, PUT, PATCH /bot-traffic/settings; GET, POST, PUT, DELETE /bot-traffic/token; GET /bot-traffic/usageread / write, account tokenBot traffic settings
GET, POST, DELETE /managed-proxy; POST /managed-proxy/check; GET /managed-proxy/dns-providerread / write, account tokenManaged proxy
GET, POST /alerts; GET, PUT, DELETE /alerts/ID; GET /alerts/historyread / write, no share linksConversion alerts
GET, PUT /notificationstoken or dashboard onlyEmail preferences

Account (account tokens only)

RequestReference
GET, PATCH /accountAccount API
GET, POST /websitesWebsites
GET, PATCH, DELETE /websites/IDUpdate or delete a website
GET, POST /tokens; DELETE /tokens/IDAccess tokens
GET, POST /members; PATCH, DELETE /members/USER_ID; POST, DELETE /members/invites/IDTeam members
GET /healthService status: ok, db and redis. No key.

Responses

Most endpoints return the object itself: a report, or a list under a named key such as { "notes": [...] } or { "funnels": [...] }. Alerts, notification preferences and team members wrap their result as { "status": "success", "data": ... }. Social mentions return data, pagination and meta.

  • Timestamps are ISO 8601 strings in UTC. Chart notes use calendar dates (YYYY-MM-DD).
  • Money is in major units of the report currency: 29 means $29.00. Rates and percentages are 0–100, rounded to two decimals.
  • A change between periods is a relative percentage, or null when the previous value is zero.
  • New fields can be added at any time; ignore those you don't know.

Errors

Errors have an HTTP status and a JSON body with a machine-readable error code. Many add a readable message; schema failures add details with the invalid fields.

400 response
{
  "error": "invalid_payload",
  "details": {
    "formErrors": [],
    "fieldErrors": { "currency": ["Invalid"] }
  }
}
StatusCommon error codes
400invalid_json, invalid_payload, invalid_range, invalid_breakdown_query, invalid_filter_query, invalid_visitor_query, invalid_goal, invalid_steps, invalid_hours, invalid_currency, invalid_note, invalid_funnel, invalid_segment, invalid_settings, invalid_domain, invalid_request.
401 unauthorizedMissing, mistyped, deleted or rotated key; missing or wrong site; a token without the scope; a website the token can't use; or a write your role doesn't allow.
402tracking_paused: the plan's monthly event allowance is used up, so new events and payments are refused until the cycle resets or you upgrade. website_limit and member_limit: plan limits on the account API.
403domain_not_allowed (crawler or browser event for a domain the website doesn't list), app_not_allowed, insufficient_scope or forbidden (account API), account_token_required (team endpoints called with a secret key), forbidden (account token on DELETE /people).
404not_found (note, funnel, segment, visitor or person), unknown_funnel, unknown_site (collect).
409note_limit, segment_limit, duplicate_segment_name, segment_changed (a stale segment revision: reload and retry).
429rate_limited or too_many_attempts; see rate limits below.

Rate limits

EndpointLimit
POST /collect120 requests a minute per visitor IP and website. Over it: 429 rate_limited with Retry-After: 60.
POST /members (invitations)30 an hour per IP: 429 too_many_attempts.
MCP (/api/mcp)240 requests a minute per token or site key.
Report, configuration and server ingestion endpointsNo fixed request limit. Keep to a few concurrent requests per website.

Reports are cached for 60 seconds per website, range and parameter set, so polling faster than once a minute returns the same numbers. Add fresh=1 to recompute.

Pagination and list sizes

Paginated endpoints take offset (rows to skip, default 0) and limit (1–100, default 50) and return total, offset and nextOffset. nextOffset is null on the last page.

terminal
curl --get 'https://metricraven.com/api/v1/stats/breakdown' \
  --header "Authorization: Bearer $METRICRAVEN_SECRET_KEY" \
  --data-urlencode 'range=all' \
  --data-urlencode 'dimension=page' \
  --data-urlencode 'limit=100' \
  --data-urlencode 'offset=100'
EndpointPaging
/stats/breakdown, /stats/filter-values, /stats/visitorsoffset, limit (1–100), total, nextOffset.
/stats/journeysoffset, limit (1–100, default 25) and total.
/stats/mentionsoffset, limit (1–1000, default 100) and pagination.hasMore.
Lists inside reportsTop 50 per breakdown in /stats/traffic (countries are complete), top 50 crawler pages, 200 X links, 500 commits, 500 realtime visitors and 1,000 notes. Use /stats/breakdown for complete tables.

Date ranges and time zones

ParameterMeaning
from, toUTC instants in ISO 8601 with a Z suffix, for example 2026-10-01T00:00:00.000Z. Offsets such as +02:00 and plain dates are rejected. from is inclusive and to exclusive; from must be before to, at most 36,600 days apart.
range=allInstead of from and to: from the start of the day of the website's first recorded event, payment or crawl, to now.
timezoneIANA zone such as Europe/Madrid (default UTC). Groups days, weeks and months, and the weekday/hour heatmaps, in that zone. It doesn't move from and to: send the UTC instants of your local midnight.
granularityauto, hour, day (default), week or month. Hourly becomes daily over 3 days, daily becomes weekly over 400 days and weekly becomes monthly over 4,000 days. The value used is returned in period.granularity.

Reports that compare periods use the window of the same length that ends at from. Chart notes, the subscriptions report and realtime endpoints take no range.

Send crawler requests

POST /crawls records one request by a crawler that your server or edge middleware handled. Crawlers rarely run JavaScript, so this is how AI and search bots reach /stats/crawlers. Ready-made middleware is in Bots and AI crawlers.

terminal
curl --request POST 'https://metricraven.com/api/v1/crawls' \
  --header "Authorization: Bearer $METRICRAVEN_SECRET_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "url": "https://example.com/pricing",
  "userAgent": "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)",
  "status": 200
}'
FieldTypeRequiredDescription
urlstringYesFull URL that was requested, up to 2,000 characters. Its host must be one of the website's domains.
userAgentstringYesThe request's User-Agent header, 1–1,000 characters.
statusintegerNoHTTP status you answered with, 100–599.
ResponseMeaning
200 { "ok": true, "bot": "GPTBot", "type": "ai-training" }Recorded.
200 { "ok": true, "ignored": "not_a_crawler" }Not a known crawler, for example a normal browser. Nothing is stored; you can send every request.
400 invalid_payloadMissing or invalid url, userAgent or status.
401 unauthorizedNot a site secret key.
403 domain_not_allowedThe URL's host isn't one of the website's domains.

Crawler types are ai-training, ai-search, ai-assistant, search-engine, seo, social-preview and other. Requests for robots.txt, llms.txt, llms-full.txt, sitemaps and Markdown files are also counted as special files. Crawler requests are metered separately from events and are never refused for plan limits.

Keys belong on your server. Never put a site secret key or an access token in browser code, a mobile app, a public repository or a URL.

Details

  • Responses for people (/stats/visitors, /stats/journeys, /visitors/…, realtime, settings and segments) are sent with Cache-Control: private, no-store.
  • The dashboard calls the same endpoints with a session cookie. Cookie writes are accepted only from metricraven.com pages, so scripts should always use a key.
  • Demo websites accept reads only; ingestion endpoints return 401 for them.
  • Repeated payments with the same transaction ID are ignored, so a payment can be retried safely. Events and crawler requests are not deduplicated: retry them only when the request failed.