---
title: Bill
description: 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.
---

import { Callout } from "fumadocs-ui/components/callout";

<Callout title="Test projects" type="info">
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.
</Callout>

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](/docs/concepts/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:

```bash
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"
  }'
```

| Field | What it sets |
|---|---|
| `event_name` | What your code sends as `event`. Unique in the project |
| `aggregation` | How 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) |
| `price` | BRL per `per_units` units, up to six decimals |
| `per_units` | `1` (default) or `1000` |
| `channel` | How the usage is charged: `invoice` (the monthly invoice), `collect` (a Collect link) or `gate` (a 402 on a [Gate](/docs/concepts/gate) paywall) |

## Recording usage

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

```bash
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](/docs/api/reference/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.

## Related

- [Collect](/docs/api/reference/collect): the payment link that charges the invoice.
- [Metered pricing](/docs/concepts/metered-pricing): per-call pricing after the
  fact on a Gate paywall, settled on-chain.
- [Meters API](/docs/api/reference/meters) and [Meter events API](/docs/api/reference/meter-events): the full field reference.
- [Test mode](/docs/concepts/test-mode): what a Test project can and cannot do.
