Usage Events (Beta)
Let you account manager know if you would like to participate in our new Usage API Beta.
Overview
The Usage API provides:
- A single endpoint for all usage ingestion
- A single endpoint for deleting a usage event
- An endpoint for fetching all events, with filters
- Strong idempotency with 45-day deduplication
- Low-latency ingestion designed for high-throughput workloads
- Clear error responses for validation, rate limiting, authentication, and transient failures
Endpoint Summary
| Method | Path | Description |
|---|---|---|
POST | /v1/events | Submit a single usage event |
GET | /v1/events | Get all usage events |
DELETE | /v1/events/{idempotencyKey} | Delete a single usage event |
All ingestion is HTTP + JSON. The API is fully idempotent.
Authentication
Requests use API key authentication via the Authorization header.
Header
Authorization: <API_KEY>
Key properties
- Keys identify the merchant and scopes they are allowed to access.
- The
manufacturerIdassociated with the key must match the event’smanufacturerId. - Keys can be revoked at any time; revoked keys return
401 Unauthorizedafter it is evicted from hourly cache.
Failure Modes
| Status | When Returned |
|---|---|
| 401 Unauthorized | Missing or invalid API key |
Idempotency
Every request must include an idempotencyKey within the request as part of the schema.
Format
idempotencyKey: <UUIDv4>
Idempotency is scoped per manufacturer:
- A given
(manufacturerId, idempotencyKey)pair is accepted once. - The idempotency key is evicted from the cache after 45 days.
- Concurrent submissions with the same key return 409 Conflict.
Request Body
JSON Schema
{
"customerId": "uuidv4",
"eventTypeId": "event_type_id",
"datetime": "2025-01-01T12:00:00Z",
"value": 12345,
"idempotencyKey": "uuidv4",
"differentiator": "test",
"invoiceSplitKey": "optional-string"
}
Field Descriptions
| Field | Type | Required | Description |
|---|---|---|---|
customerId | UUIDv4 | Yes | Tabs Customer ID |
eventTypeId | String | Yes | Type of event being recorded |
datetime | ISO-8601 | Yes | Timestamp when the event occurred |
value | Number | Yes | Unique key to prevent duplicate event processing |
idempotencyKey | UUIDv4 | No | Numeric value of the event |
differentiator | String | No | Optional key to separate events with the same event type and customer into different invoice line items |
invoiceSplitKey | String | No | Optional key to split events into a new invoice |
metaData | Object: |
- newKey (string)
- Value (string) | No | Optional metadata field to store supplemental information about the event |
Response Semantics
Successful Response
{
"success": true,
"message": "Event deleted successfully",
"data": {
"events": {
"customerId": "550e8400-e29b-41d4-a716-446655440000",
"eventTypeId": "550e8400-e29b-41d4-a716-446655440000",
"datetime": "2024-01-15T10:30:00Z",
"idempotencyKey": "018c1234-5678-7abc-def0-123456789abc",
"value": -1,
"parentEventId": "018c1234-5678-7abc-def0-123456789000"
}
}
}Guaranteed Behavior
- A 200 OK is only returned after the event has been successfully ingested.
- If Tabs cannot confirm durable write, no idempotency record is finalized and you receive an error.
Response Codes
| Status | Meaning |
|---|---|
| 200 OK | Event accepted and durably persisted |
| 400 Bad Request | Invalid JSON, schema, timestamp, eventType, or rule violation, Idempotency key already used (duplicate) |
| 401 Unauthorized | Bad/expired/revoked credentials |
| 429 Too Many Requests | Rate limits exceeded (edge or service) |
| 503 Service Unavailable | Transient failure (e.g., Kafka timeout, Valkey degrade). Safe to retry. |
Validation Rules
Tabs validates every event using pre-cached configuration for the (manufacturer, customer) pair.
Validation includes:
- Allowed
eventTypeId - Allowed
customerId - Schema format correctness
If validation fails → 400 Bad Request.
Rate Limit
Rate limit is at 10,000 RPM per merchant. The API uses a fixed-window rate-limiting strategy, which permits a specified number of requests per 60 second window. The request count resets automatically when the next window begins.
In-App Behavior
Configuration
- Set up event types, which can be done via the Tabs UI or the vs/events/types endpoints. Event types exist globally for a merchant.
- Set up usage-based obligations for a customer that are linked to an associated event type. This is done at the customer level, and a customer can bill for as many event types as needed.
- Note: Usage events can only be billed for if they have an obligation set up with a service period that encompasses the date of an event.
Invoice Updates
- When events are ingested into Tabs, they are validated based on
customerIDandeventType, as well as other schema validation. - If successful, events are created in the database and represented on the Events page in Tabs.
- Every hour, invoices with line items that encompass a
datetimeof events that have been ingested for that customer will be updated.- Note: This hourly job has a look back period of 1 hour (inclusive of the current second), and will not include events with a
datetimefurther back than 1 hour or in the future.
- Note: This hourly job has a look back period of 1 hour (inclusive of the current second), and will not include events with a
Safe Usage Patterns
Recommended:
- Generate a UUIDv4 for each event
- Retry only on 503/429/network errors
- Send events chronologically when meaningful
Avoid:
- Reusing idempotency keys
- Sending over 10,000 requests per minute
Updated 11 days ago
