scribasedocs

Control API /v1

Usage meters

Usage meters answer "how much did customer X actually use" without a separate billing vendor. Enable them once per environment, record one event per metered action, and read back the aggregate per customer per meter — all on your own project's database, under row level security.

Neither Supabase nor Neon ships a usage-metering primitive: a team on either one wires up a separate product (Stripe metering, Lago, Orb, Metronome) before it can answer that question at all. This is the same event-per-metric model Scribase runs for its own flat-rate billing internally, exposed directly as a customer-facing feature.


POST /v1/organizations/{org}/projects/{project}/environments/{env}/usage-meters

Sets usage meters up in the environment: creates public.scribase_usage_meter_events (row-level-secured), the public.scribase_usage_meter_totals aggregate view, and a scribase_record_usage RPC an end user can call for their own usage. Idempotent — safe to call again. Requires an owner or admin role.

Terminal
curl -X POST "$SCRIBASE_API_URL/v1/organizations/acme/projects/store/environments/production/usage-meters" \
  -H "Authorization: Bearer $SCRIBASE_ACCESS_TOKEN"

Response: the same shape as the status endpoint below, immediately after setup.

GET /v1/organizations/{org}/projects/{project}/environments/{env}/usage-meters

Whether usage meters are set up, and how many events, distinct customers and distinct meters the environment has recorded so far. Any project member can call this.

JSON
{ "enabled": true, "events": 1842, "customers": 37, "meters": 3 }

An environment where usage meters were never set up answers { "enabled": false, "events": 0, "customers": 0, "meters": 0 } rather than a 404.

POST /v1/organizations/{org}/projects/{project}/environments/{env}/usage-meters/record

Records one usage event for one of the project's own customers — a Dodo/Stripe/Creem customer id, an org id, anything the project already bills by. This is the call a backend makes on every metered action (an AI call, an API request, a GB stored). Requires an owner, admin or developer role.

Field Type Notes
meter string Required. Lowercase, dotted metric code, e.g. ai_tokens or api.calls. At most 64 characters.
external_customer_id string Required. 1–200 printable characters — your own customer id, not a Scribase one.
quantity number Required. Non-negative.
properties object Optional. Up to 4000 bytes JSON, kept with the event for later inspection.
transaction_id string Optional. Supply your own for idempotency; otherwise one is generated. A repeated transaction_id is a no-op, not a duplicate event.
Terminal
curl -X POST "$SCRIBASE_API_URL/v1/organizations/acme/projects/store/environments/production/usage-meters/record" \
  -H "Authorization: Bearer $SCRIBASE_ACCESS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "meter": "ai_tokens",
    "external_customer_id": "cus_8f2a1c",
    "quantity": 2140,
    "transaction_id": "req_9d3e7b21"
  }'

Response:

JSON
{ "recorded": true, "transaction_id": "req_9d3e7b21" }

"recorded": false means this transaction_id was already recorded; the quantity was not added again. Answers 409 usage_meters_not_enabled if the environment hasn't had usage meters set up yet.

GET /v1/organizations/{org}/projects/{project}/environments/{env}/usage-meters/summary

The aggregated quantity and event count per meter per customer, most-used first (up to 200 rows). Any project member can call this.

JSON
[
  { "external_customer_id": "cus_8f2a1c", "meter": "ai_tokens", "total_quantity": 418290, "event_count": 212 },
  { "external_customer_id": "cus_19b0aa", "meter": "api.calls", "total_quantity": 9034, "event_count": 9034 }
]

An environment where usage meters haven't been set up answers [], not an error.


From inside your own app

The scribase_record_usage RPC the setup call creates lets a signed-in user record their own usage directly through supabase-js, with your existing RLS policies deciding what they're allowed to see back:

TypeScript
await supabase.rpc('scribase_record_usage', {
  p_meter: 'ai_tokens',
  p_quantity: 2140,
});

Use the REST endpoints above from your backend when the event is keyed by a billing customer id rather than a signed-in Scribase user, or when the write needs to happen from a server you control (a webhook handler, a cron job, a queue worker).