Skip to main content

How it fits together

Your app sends usage events to Creem, and meters total them per customer. As you serve each request, you also debit the customer’s prepaid credit balance at your price.

Events

One customer’s usage at one moment, for example 512 tokens for cust_abc123.

Meters

Match events by name, filter them on their properties, and aggregate them with count, sum, average, min, max, or unique.

Credits

A prepaid balance per customer. Credit it when they buy, and debit it when they use your product.
The CLI covers the same operations under creem events, creem meters, and creem customer-credits.

Units and pricing

Meters and credit accounts both count units. A meter’s unit_label names what it counts (“tokens”, “requests”), and a credit account has its own unit_label (“credits”). Your price is the conversion between the two, for example 1 credit per 1,000 tokens, and you apply it when you debit. The API sends amounts as strings so large counts keep full precision. When Creem settles usage for you (Step 5), the credit bucket holds minor units of your product currency: a €10 pack is 1000 credits, and a usage price’s unit_price is minor units per meter unit. unit_price may be fractional, so a rate of €0.004 per request is 0.4. Creem rounds the running total for the billing window to the nearest minor unit, never each request.

Step 1: Define a meter

A meter needs a name, the event_name it counts, an aggregation, and a unit_label. Every aggregation except count also needs aggregation_property, the key in the event’s properties to aggregate. Add filter clauses to count only some events.
Check a definition before you create it. POST /v1/meters/preview runs a meter definition against your recently ingested events without storing anything, and POST /v1/meters/{id}/preview does the same for an existing meter.
Archive a meter to stop counting with it, and unarchive it to start again. Creem keeps the raw events while a meter is archived, so unarchiving adds that usage back into any billing period still inside its late-event window.

Step 2: Ingest events

Send up to 100 events per request. Creem validates the whole batch before storing anything. If any event is invalid, the request fails with a 422 that names the event and field (for example events[3].customer_id), and nothing is stored. Otherwise it returns 202.

Identify the customer

Set exactly one of these fields on each event:
  • customer_id is the Creem customer ID. If it doesn’t belong to a customer in your store, the whole batch is rejected.
  • external_customer_id is your own ID for the customer. Set it once as external_id when you create or update the customer, then send it with events without looking up the Creem ID. External IDs are unique per store.
Both resolve to the same Creem customer, so you can switch from one to the other without splitting that customer’s usage.

Event fields

event_id is your idempotency key and must be unique within your store. Re-sending an event_id your store already accepted records nothing, so you can retry a batch after a timeout without counting it twice. If you leave event_id out, Creem generates a new one for every request, and a retried event is counted again. timestamp is when the usage happened (ISO 8601) and defaults to the time Creem receives the event. Usage counts toward the billing period its timestamp falls in. Once that period’s late-event window closes, the period is finalized: new events for it are stored but don’t change its totals, and the response includes a warning. properties holds the event’s attributes. Meter filters and aggregation_property read their keys from here. It accepts up to 50 keys, keys up to 40 characters, and string or serialized-object values up to 500 characters.

Warnings

A 202 means Creem stored the events. Whether a meter counts them shows up in the per-event warnings in the response, so a misconfigured meter surfaces on the first request instead of at the end of the month:

Step 3: Verify ingestion

Check that your events arrive and your meters count them:

Step 4: Charge with credits

Customers buy credits up front, and you draw the balance down as they use your product. Customer Credits handles the accounts and the transaction history.
1

Create an account per customer

Call POST /v1/customer-credits/accounts with the unit_label your customers see, such as “credits” or “renders”. Use initial_balance to include free trial credits.
2

Credit on purchase

When a customer buys a credit pack, call POST /v1/customer-credits/accounts/{id} /credit with your order ID as the reference and an idempotency_key. If your purchase webhook is retried, the same key credits the account only once.
3

Debit on each request

When you serve a request, call POST /v1/customer-credits/accounts/{id} /debit with the amount at your price. Use the request’s event_id in the reference and idempotency_key, so a retried request debits only once.
4

Prompt the top-up

If the balance is too low, the debit fails with 422 and the error code insufficient_balance, and nothing is debited. To warn customers earlier, listen for the credits.consumed webhook. Each one carries balance_after_minor_units, the balance left after the debit.
Debit with the same ID you sent as event_id, so the event and the debit point at the same request:
TypeScript

Step 5: Let Creem settle usage against credits

Instead of debiting on every request yourself, attach the meter to a product as a prepaid usage price. Subscribers to that product are then debited automatically as their usage aggregates: units past the free allowance are multiplied by the unit price and drawn from the credit bucket the price names. You keep ingesting events; Creem does the settlement. Both the metered product and the credit top-up that funds it can be created from the API:
On update, usage_prices and features are the product’s complete set: omit them to leave charges and credit features untouched, send [] to remove them, include an id to edit one in place. GET /v1/products/{id} echoes both, so you can read back what you attached. Settlement emits credits.consumed per billing window; when the bucket cannot cover a charge, customer_credits.exhausted fires once per episode, and a customer who has consented to auto-refill is charged for the top-up product on their saved card.

Worked example: pay-as-you-go API with a prepaid wallet

You run a map API. A vector tile costs €0.004 and a geocoding lookup costs €0.04. Customers prepay: a €10 monthly plan includes €10 of usage, and they can buy €25 top-up packs. Creem meters both operations and draws the cost from one wallet.
1

One meter per operation

Meter what happened, not what it costs. Each operation gets a count meter with its own unit label, so the rate can change later without touching your events.
If you batch usage before sending it, for example one event per customer per hour, use sum over a count property instead of count, and put the batch total in properties.count.
2

A plan that carries the rates and includes credits

The plan’s base price is €10 a month. Its credits feature grants 1000 credits into the customer’s default wallet each time the subscription is paid, which is €10 at one credit per cent. Its two usage prices name the meters and the rates in minor units per unit: 0.4 for a tile, 4 for a lookup.
The dashboard quotes these rates per 1,000 units: “€4.00 per 1,000 tiles” and “€40.00 per 1,000 lookups”.
3

A top-up pack

A one-time product whose only job is to fund the same wallet. Its amount equals its price in minor units.
4

Send events and let Creem settle

Ingest tile_served and geocode events with the customer’s id. Each meter totals them per customer per calendar month, and every time a total changes Creem recomputes the charge for that month and debits the difference.Each debit shows up as a credits.consumed webhook with the balance after it.

When the wallet runs out

A charge the wallet cannot cover is refused, the customer gets an email, and you receive customer_credits.exhausted once, with the shortfall. Nothing is lost: the charge is the running total for the month, so the next event in that month collects everything outstanding. A top-up on its own does not trigger a settlement, so usage at the very end of a month with no later event stays uncollected until an event arrives. Customers who opt in to auto-refill have the top-up pack re-purchased for them.

Things to know

  • Prepaid windows are calendar months (UTC). For prepaid settlement, every meter totals usage per customer per calendar month, independent of the subscription’s billing date, and settlement charges the difference each time a month’s total changes.
  • Paused subscriptions are not settled. Metering continues while a subscription is paused. Resuming does not trigger a settlement on its own: the month’s accumulated charge is collected by the next event that arrives in that same month, and a month that ends with no event after the resume stays uncollected. Pausing is not a way to keep debiting while skipping the monthly fee.
  • Usage prices need a live subscription. Customers who only buy packs fund the wallet but are not debited automatically. Debit them through the credits API yourself until a plan without a base fee is available.
  • Use free_allowance on a usage price for units per month that should not be charged at all, and cap to bound a customer’s monthly usage charge.

API key scopes

Usage endpoints need scoped API keys. Give each key only the scopes its job needs. An ingestion worker, for example, needs only events:write.