Overview

Reporting usage

await fetch(`${APP_URL}/api/usage`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${apiKeyOrOauthToken}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    idempotencyKey,  // stable across retries, derived from the MCP request ID
    endpoint: "search_documents",
    units: 1,
    status: "completed", // "completed" | "partial" | "failed"
  }),
});

The fields#

Field Purpose
idempotencyKey Unique per logical call. Derive it from the MCP request ID so retries reuse it.
endpoint Which tool was called. Shows up in the usage dashboard and in Stripe.
units How much to bill. Calls, tokens, whatever your meter measures.
status completed, partial or failed. Controls billability.

What is billable#

Only status: "completed" is billable by default. partial and failed are always recorded in Postgres for auditing, but never reported to Stripe unless you change BILLABLE_STATUSES.

Do not skip the call#

When a call dies halfway, send status: "partial" rather than sending nothing. The event gets logged, and you decide later whether partials are billable. Silence loses the audit trail.

Read the reasoning: billing decisions.