Skip to main content
Events are the core of Usage Based Billing. They represent some usage done by a customer in your application. Typical examples of events are:
  • A customer consumed AI LLM tokens
  • A customer streamed minutes of video
  • A customer uploaded a file to your application
Events are sent to Macropay using the Events Ingestion API and are stored in our database. An event consists of the following fields:
  • A name, which is a string that can be used to identify the type of event. For example, ai_usage, video_streamed or file_uploaded.
  • A customer_id or external_customer_id, which is Macropay’s customer ID or your user’s ID. This is used to identify the customer that triggered the event.
  • A metadata object, which is a JSON object that can contain any additional information about the event. This is useful for storing information that can be used to filter the events or compute the actual usage. For example, you can store the duration of the video streamed or the size of the file uploaded.
Here is an example of an event:

From event to invoice

Ingestion is the first hop in the usage-based pipeline. Once an event lands, a meter aggregates it, a metered price turns the aggregate into an amount, and Macropay bills the customer — handling sales tax and VAT as the merchant of record, so you never touch a tax return. Your only job is to emit clean events. A few rules shape how you should design that emission:
Ingestion never blocks. Every event you send is accepted and recorded, even when a customer is over their plan limit or out of credits. Enforcing balance — pausing an agent, rate-limiting a request, downgrading quality — is your application’s responsibility, not the meter’s.
Events are immutable. After ingestion an event cannot be edited or deleted, and it is permanently part of the customer’s billable record. Validate external_customer_id and name before you send, and put anything you might want to recompute later into metadata.

Send events with the SDK

The fastest path is one of our official SDKs (TypeScript, Python, PHP, Go). Pass an array — batching cuts round trips and is the recommended pattern for high-volume sources.
The metadata object is free-form JSON. Store whatever you may want to meter or filter on later — a model name, byte count, region, or the agent that produced the work — because you can’t add it after the fact.

Built for AI and agent billing

Usage events are how you charge for AI in any shape:
  • By usage — token counts, generated images, transcription minutes.
  • By activity — calls made, documents processed, rows enriched.
  • By outcome — tickets resolved, leads qualified, revenue attributed.
For LLM workloads, route traffic through the OpenAI-compatible AI proxy (POST /ai/v1/chat/completions) and Macropay captures token cost as cost events automatically — no manual ingestion required. For autonomous agents, the Signals API (POST /v1/signals) ingests activity and outcome signals attributed to a specific agent, so you can bill on results and read your agentic margin (billed revenue versus AI cost) per agent.

Pick an ingestion strategy

Calling the SDK directly is ideal for discrete, in-app actions. When events live elsewhere — a Kafka stream, an S3 export, or a meter that depends on elapsed time — a managed strategy does the plumbing for you. See ingestion strategies for setup details on each.

Reference

The SDK wraps the Events Ingestion API. Use that endpoint directly if you’re ingesting from a language without an official SDK or from an environment where adding a dependency isn’t practical.