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.
creem events, creem meters, and creem customer-credits.
Units and pricing
Meters and credit accounts both count units. A meter’sunit_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.
Step 1: Define a meter
A meter needs aname, 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.
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 a422 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_idis the Creem customer ID. If it doesn’t belong to a customer in your store, the whole batch is rejected.external_customer_idis your own ID for the customer. Set it once asexternal_idwhen you create or update the customer, then send it with events without looking up the Creem ID. External IDs are unique per store.
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
A202 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.event_id, so the event and the debit point at the same request:
TypeScript
API key scopes
Usage endpoints need scoped API keys. Give each key only the scopes its job needs. An ingestion worker, for example, needs onlyevents:write.