Skip to main content
Two credentials, two halves of this page. Start with ingest, because it needs nothing but a key.

Write: post a payload

Get an ingest key from the dashboard — see Create a key.
You get 202 with an empty body, before the write happens. That is the contract: nothing makes your server wait on our database.
A 202 does not mean every item was accepted. Invalid items are dropped silently and the batch still succeeds — see Ingest for why.

Read: the overview

Reads take a Supabase access token, not an ingest key. The dashboard holds one in the browser; grab it from your session to try this by hand.
Omit from and to for the last 30 days ending today. See Date ranges.

What the overview returns

Five fields are worth understanding before you read the rest:

Narrow to a tool

Blanks are dropped and duplicates collapsed, so a trailing comma is harmless rather than a 400 — the filter is built by a URL, and URLs are edited by hand. Every metric route takes clients as well, because tool_hours is keyed by client — ?tools=search_orders&clients=cursor is one tool as read by one model. Blanks and duplicates are dropped rather than rejected, since a filter built by a URL is a URL edited by hand, and unknown selects calls that arrived without a client name. Under a tool filter, sessions, calls_per_session and cost_per_session_usd come back null: a session belongs to the server, not to a tool. A client filter narrows everything, sessions included. See The overview.

Then

Insights

GET /v1/mcps/{id}/insights — what is wrong, with numbers.

Errors

The shape every failure comes back in.