Skip to main content

Bill

Usage metering and the monthly invoice. Count calls, tokens, orders or outcomes as they happen, and close each month into one statement per customer, charged through Collect.

3 min read
View MarkdownEdit on GitHub

Test projects

Bill is open to Test projects and Test keys. A Live project or a Live key gets 404 on every Bill route until Live opens.

Thousands of small events cannot become thousands of charges. Bill counts each event as it happens and closes the month into one statement per customer: one line your customer understands, charged once.

The routes are /v1/meters and /v1/meter-events. In the dashboard, Bill is the Bill screen of a project.

Bill was called Meter until October 2026; the routes kept their names. Post-paid pricing on a Gate paywall, which the old Meter page described, is now Metered pricing.

The flow

your code ──POST /v1/meter-events──▶ counted on its meter, per customer
                                     │ the month runs (America/Sao_Paulo)
                                     │ D+2, 06:00: the cycle closes
                                     │ one statement per customer and channel
                                     │ invoice numbered, due on day 5
                                     └──▶ one Collect link for the statement

Meters

A meter prices one usage event of your project. Create it once:

curl -X POST https://api.codespar.dev/v1/meters \
  -H "Authorization: Bearer $CODESPAR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "event_name": "research.calls",
    "aggregation": "count",
    "price": "0.0019",
    "channel": "invoice"
  }'
FieldWhat it sets
event_nameWhat your code sends as event. Unique in the project
aggregationHow a cycle adds up per customer: count (each event is 1), sum (of value), max (the largest value) or last (the latest value by event time)
priceBRL per per_units units, up to six decimals
per_units1 (default) or 1000
channelHow the usage is charged: invoice (the monthly invoice), collect (a Collect link) or gate (a 402 on a Gate paywall)

Recording usage

Send one event per unit of work, with your own customer id:

curl -X POST https://api.codespar.dev/v1/meter-events \
  -H "Authorization: Bearer $CODESPAR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "event": "research.calls",
    "customer": "cus_orbital",
    "event_id": "req_9k2f41"
  }'

value is required on sum, max and last meters and left out on a count meter. timestamp is the event's own time, default now. It decides the cycle, and it must fall in the current or the previous cycle, at most 5 minutes ahead.

The call is idempotent on event_id. Sending the same event again answers 200 with duplicate: true and counts it once, so a retry never bills twice. A different payload under a known id is refused with 409 meter_event_id_conflict.

The cycle

A cycle is a calendar month in America/Sao_Paulo. GET /v1/meters and GET /v1/meters/cycle read the running totals; their amounts are forecasts, usage times price, and nothing is charged before the close.

The cycle closes on D+2 at 06:00 Sao Paulo, D being its last day. The close freezes one statement per customer and channel. GET /v1/meters/statements?period=YYYY-MM reads them.

An event of the previous cycle that arrives after its close is late. It is recorded and kept out of the closed cycle: a late count or sum event is charged by the next close as an adjustment naming its cycle of origin, and a late max or last event is held for review and never charged automatically.

The invoice

On the invoice and collect channels, a statement is charged through Collect, once:

  • At or above the minimum (R$ 5,00): the statement is charged by one Collect link, received into your project's account. Your project is the issuer and creditor. On the invoice channel the statement is also the monthly invoice: numbered once, and due on day 5 of the next month.
  • Below the minimum: the balance carries to the next cycle and is never charged on its own.
  • Collect not yet able to issue for the project: the statement waits, and a later pass charges it once Collect can.

The link's URL is on the statement. You deliver it to your customer; CodeSpar sends nothing. A repeated close answers the same link, so one obligation never gets a second charge. The statement shows paid only on the bank's confirmation of the payment.

On the gate channel, Bill records the usage and requests no charge: the paywall already charged each call.

In Test, every statement says so: the invoice number starts with TESTE- and the statement carries test_document: true.

Keys

A key with every scope reaches all of Bill. A narrow key needs meters:read for the reads and meters:write to create a meter or record an event.

Bill | CodeSpar