Skip to main content
Events are the core of Usage Based Billing. They represent a single unit of consumption or usage done by a customer in your application. Typical examples of events include:
  • A customer consumed AI LLM tokens
  • A customer streamed minutes of video
  • A customer made an API request
Events are sent to Solifyn using the Events Ingestion API and are stored in our database. An event consists of the following fields:
  • event_id: A unique identifier for the event to ensure idempotency.
  • customer_id: The Solifyn customer ID associated with the usage event.
  • event_name: The string identifier matching a configured meter’s event name (e.g. api.request).
  • value: An optional numeric value representing the quantity of consumption (defaults to 1).
  • metadata: A JSON object containing custom key-value pairs used for filters or advanced aggregation.
  • timestamp: An optional ISO 8601 string representing when the event occurred.
Here is an example of a Solifyn event payload:
{
  "event_id": "evt_9Y3kP4qR7tU1vW2xZ5aB6c",
  "customer_id": "cus_8n7m6l5k4j3h2g1f0e9d8c",
  "event_name": "api.request",
  "value": 1,
  "metadata": {
    "region": "asia-southeast-1",
    "plan": "enterprise"
  },
  "timestamp": "2026-05-23T10:00:00.000Z"
}

Ingest events using the API

To record usage, send a POST request to the /meters/ingest endpoint. You must authenticate the request using your API Bearer token in the Authorization header and specify your active business context via the x-business-id header if managing multiple businesses.

Endpoint

POST /meters/ingest

Payload structure

The request payload accepts an array of events:
ParameterTypeRequiredDescription
eventsarrayYesAn array of event objects to ingest.
events[].event_idstringYesA unique UUID/string identifier for the event to ensure idempotency. If an event with the same ID is sent again, it will be skipped.
events[].customer_idstringYesThe ID of the customer associated with this usage.
events[].event_namestringYesThe event name that matches the eventName field configured on your Meter (e.g. api.request).
events[].valuenumberNoThe numeric amount of usage. Defaults to 1.
events[].metadataobjectNoCustom JSON properties to be used in advanced aggregations or filters.
events[].timestampstringNoISO 8601 timestamp representing when the usage occurred. Defaults to the server’s current time.

cURL Example

curl -X POST https://api.solifyn.com/meters/ingest \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "x-business-id: biz_..." \
  -H "Content-Type: application/json" \
  -d '{
    "events": [
      {
        "event_id": "evt_9Y3kP4qR7tU1vW2xZ5aB6c",
        "customer_id": "cus_8n7m6l5k4j3h2g1f0e9d8c",
        "event_name": "api.request",
        "value": 1,
        "metadata": {
          "endpoint": "/v1/inference",
          "region": "us-east"
        },
        "timestamp": "2026-05-23T10:00:00.000Z"
      }
    ]
  }'

TypeScript Example

async function ingestUsageEvent() {
  const response = await fetch("https://api.solifyn.com/meters/ingest", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${process.env.SOLIFYN_API_KEY}`,
      "x-business-id": process.env.SOLIFYN_BUSINESS_ID || "",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      events: [
        {
          event_id: `evt_${Date.now()}`,
          customer_id: "cus_8n7m6l5k4j3h2g1f0e9d8c",
          event_name: "api.request",
          value: 1,
          metadata: {
            method: "POST"
          }
        }
      ]
    })
  });

  const data = await response.json();
  console.log("Ingested successfully:", data);
}
Idempotency Guarantee Solifyn guarantees idempotency based on the event_id field. Sending multiple requests with the same event_id will safely result in only one usage event being registered, preventing accidental double-billing.

Good to know

Events are immutable

Once an event is successfully ingested, it cannot be modified or deleted. Ensure your value and metadata are accurate before transmitting them.