openapi: 3.0.1 info: title: Metronome Alerts Usage API version: 1.0.0 description: '[Alerts](https://docs.metronome.com/connecting-metronome/alerts/) monitor customer spending, balances, and other billing factors. Use these endpoints to create, retrieve, and archive customer alerts. To view sample alert payloads by alert type, navigate [here.](https://docs.metronome.com/manage-product-access/create-manage-alerts/#webhook-notifications)' servers: - url: https://api.metronome.com description: Production server security: - bearerAuth: [] tags: - name: Usage description: '[Usage events](https://docs.metronome.com/connecting-metronome/send-usage-data/) are the basis for billable metrics. Use these endpoints to send usage events to Metronome and retrieve aggregated event data.' paths: /v1/ingest: post: description: "The ingest endpoint is the primary method for sending usage events to Metronome, serving as the foundation for all billing calculations in your usage-based pricing model. This high-throughput endpoint is designed for real-time streaming ingestion, supports backdating 34 days, and is built to handle mission-critical usage data with enterprise-grade reliability. Metronome supports 100,000 events per second without requiring pre-aggregation or rollups and can scale up from there. See the [Send usage events](/guides/events/send-usage-events) guide to learn more about usage events.\n\n### Use this endpoint to:\nCreate a customer usage pipeline into Metronome that drives billable metrics, credit drawdown, and invoicing. Track customer behavior, resource consumption, and feature usage\n\n### What happens when you send events:\n- Events are validated and processed in real-time\n- Events are matched to customers using customer IDs or customer ingest aliases\n- Events are matched to billable metrics and are immediately available for usage and spend calculations\n\n### Usage guidelines:\n- Historical events can be backdated up to 34 days and will immediately impact live customer spend\n- Duplicate events are automatically detected and ignored (34-day deduplication window)\n\n#### Event structure:\nUsage events are simple JSON objects designed for flexibility and ease of integration:\n```json\n{\n \"transaction_id\": \"2021-01-01T00:00:00Z_cluster42\",\n \"customer_id\": \"team@example.com\",\n \"event_type\": \"api_request\",\n \"timestamp\": \"2021-01-01T00:00:00Z\",\n \"properties\": {\n \"endpoint\": \"/v1/users\",\n \"method\": \"POST\",\n \"response_time_ms\": 45,\n \"region\": \"us-west-2\"\n }\n}\n```\n\nLearn more about [usage event structure definitions](/guides/events/design-usage-events).\n\n#### Transaction ID\n The transaction_id serves as your idempotency key, ensuring events are processed exactly once. Metronome maintains a 34-day deduplication window - significantly longer than typical 12-hour windows - enabling robust backfill scenarios without duplicate billing.\n - Best Practices:\n - Use UUIDs for one-time events: uuid4()\n - For heartbeat events, use deterministic IDs\n - Include enough context to avoid collisions across different event sources\n\n#### Customer ID\nIdentifies which customer should be billed for this usage. Supports two identification methods:\n - Metronome Customer ID: The UUID returned when creating a customer\n - Ingest Alias: Your system's identifier (email, account number, etc.) \n\nIngest aliases enable seamless integration without requiring ID mapping, and customers can have multiple aliases for flexibility.\n\n#### Event Type:\nCategorizes the event type for billable metric matching. Choose descriptive names that aligns with the product surface area.\n\n#### Properties:\nFlexible metadata also used to match billable metrics or to be used to serve as group keys to create multiple pricing dimensions or breakdown costs by novel properties for end customers or internal finance teams measuring underlying COGs.\n" operationId: ingest-v1 summary: Ingest events x-nlb-domain-variable: ingestnlbDomain x-vpc-connection-id-variable: ingestvpcLinkId x-slo-tier: 1 tags: - Usage responses: '200': description: Success requestBody: content: application/json: schema: type: array minItems: 1 maxItems: 100 items: $ref: '#/components/schemas/Event' example: - transaction_id: 2021-01-01T00:00:00Z_cluster42 customer_id: team@example.com event_type: heartbeat timestamp: '2021-01-01T00:00:00Z' properties: cluster_id: '42' cpu_seconds: 60 region: Europe /v1/usage/seats: post: x-mint: groups: - ff:seats description: Fetch seats usage data for the specified customer, broken into intervals of the specified length. operationId: getSeatsUsage-v1 summary: Get seats usage data parameters: - $ref: '#/components/parameters/PageLimit' - $ref: '#/components/parameters/NextPage' requestBody: description: The seats query to run content: application/json: schema: $ref: '#/components/schemas/SeatsUsageQueryPayload' example: customer_id: 04ca7e72-4229-4a6e-ab11-9f7376fccbcb seat_metric_id: 222796fd-d29c-429e-89b2-549fabda4ed6 starting_on: '2023-01-01T00:00:00Z' ending_before: '2023-01-03T00:00:00Z' window_size: day usage_type: max tags: - Usage responses: '200': description: Success content: application/json: schema: type: object required: - data - next_page properties: data: type: array items: $ref: '#/components/schemas/SeatsUsageAggregate' next_page: type: string nullable: true example: data: - starting_on: '2023-01-01T00:00:00Z' ending_before: '2023-01-02T00:00:00Z' value: 1234 - starting_on: '2023-01-02T00:00:00Z' ending_before: '2023-01-03T00:00:00Z' value: 567 next_page: null /v1/usage/groups: post: description: "Retrieve granular usage data for a specific customer and billable metric, with the ability to break down usage by custom grouping dimensions. This endpoint enables deep usage analytics by segmenting data across attributes like region, user, model type, or any custom dimension defined in your billable metrics.\n\n### Use this endpoint to:\n- Analyze usage patterns broken down by specific attributes (region, user, department, etc.)\n- Build detailed usage dashboards with dimensional filtering\n- Identify high-usage segments for optimization opportunities\n\n### Request parameters\nUse [`group_key`](#body-group-key) and [`group_filters`](#body-group-filters) to group by one or more dimensions. This is required for compound group keys and recommended for all new integrations:\n```json\n{\n \"group_key\": [\"region\", \"team\"],\n \"group_filters\": {\n \"region\": [\"US-East\", \"US-West\"]\n }\n}\n```\nImportant: For compound group keys, you must pass the complete set of keys that make up the compound key. Partial key combinations are not supported. For example, if your billable metric has a compound group key [region, team, environment], you must pass all three keys in group_key—you cannot pass just `[region]` or `[region, team]`.\n\n### Key response fields:\nAn array of `PagedUsageAggregate` objects containing:\n- `starting_on` and `ending_before`: Time window boundaries\n- `group`: Object mapping group keys to their values\n - For simple groups, this will be a map with a single key-value pair (e.g., `{\"region\": \"US-East\"}`)\n - For compound groups, this will be a map with multiple key-value pairs (e.g., `{\"region\": \"US-East\", \"team\": \"engineering\"}`)\n- `value`: Aggregated usage for this group and time window\n- `next_page`: Pagination cursor for large datasets\n\n### Usage guidelines:\n- Required parameters: Must specify `customer_id`, `billable_metric_id`, and `window_size`\n- Time windows: Set `window_size` to hour, day, or none for different granularities\n- Group filtering: Use `group_key` and `group_filters` to specify groups and group filters\n- Limits: When using compound group keys (2+ keys in `group_key`), the default and max limit is 100\n- Pagination: Use limit and `next_page` for large result sets\n- Null handling: Group values may be null for events missing the group key property\n" operationId: getPagedUsage-v1 summary: Get usage data with paginated groupings x-slo-tier: 1 parameters: - $ref: '#/components/parameters/PageLimit' - $ref: '#/components/parameters/NextPage' requestBody: description: The usage query to run content: application/json: schema: $ref: '#/components/schemas/PagedUsageQueryPayload' examples: using_simple_group_key: summary: Simple (single key) group_key value: customer_id: 04ca7e72-4229-4a6e-ab11-9f7376fccbcb billable_metric_id: 222796fd-d29c-429e-89b2-549fabda4ed6 starting_on: '2021-01-01T00:00:00Z' ending_before: '2021-01-03T00:00:00Z' window_size: day group_key: - region group_filters: region: - us-east1 - us-west1 using_compound_group_key: summary: Compound (multi-key) group_key with group_filters value: customer_id: 04ca7e72-4229-4a6e-ab11-9f7376fccbcb billable_metric_id: 222796fd-d29c-429e-89b2-549fabda4ed6 starting_on: '2021-01-01T00:00:00Z' ending_before: '2021-01-03T00:00:00Z' window_size: day group_key: - region - team group_filters: region: - us-east1 - us-west1 team: - ui tags: - Usage responses: '200': description: Success content: application/json: schema: type: object required: - data - next_page properties: data: type: array items: $ref: '#/components/schemas/PagedUsageAggregate' next_page: type: string nullable: true examples: using_simple_group_key: summary: Response using single-key group_key value: data: - starting_on: '2021-01-01T00:00:00Z' ending_before: '2021-01-02T00:00:00Z' group_key: region group_value: us-east1 group: region: us-east1 value: 1234 - starting_on: '2021-01-01T00:00:00Z' ending_before: '2021-01-02T00:00:00Z' group_key: region group_value: us-west1 group: region: us-west1 value: 567 next_page: null using_compound_group_key: summary: Response using compound group_key and group_filters value: data: - starting_on: '2021-01-01T00:00:00Z' ending_before: '2021-01-02T00:00:00Z' group_key: null group_value: null group: region: us-east1 team: ui value: 1234 - starting_on: '2021-01-01T00:00:00Z' ending_before: '2021-01-02T00:00:00Z' group_key: null group_value: null group: region: us-west1 team: ui value: 890 next_page: null /v1/usage: post: description: "Retrieve aggregated usage data across multiple customers and billable metrics in a single query. This batch endpoint enables you to fetch usage patterns at scale, broken down by time windows, making it ideal for building analytics dashboards, generating reports, and monitoring platform-wide usage trends.\n\n### Use this endpoint to:\n- Generate platform-wide usage reports for internal teams\n- Monitor aggregate usage trends across your entire customer base\n- Create comparative usage analyses between customers or time periods\n- Support capacity planning with historical usage patterns\n\n### Key response fields:\nAn array of `UsageBatchAggregate` objects containing:\n\n- `customer_id`: The customer this usage belongs to\n- `billable_metric_id` and `billable_metric_name`: What was measured\n- `start_timestamp` and `end_timestamp`: Time window for this data point\n- `value`: Aggregated usage amount for the period\n- `groups` (optional): Usage broken down by group keys with values\n- `next_page`: Pagination cursor for large result sets\n\n### Usage guidelines:\n- Time windows: Set `window_size` to `hour`, `day`, or `none` (entire period)\n- Required parameters: Must specify `starting_on`, `ending_before`, and `window_size`\n- Filtering options:\n - `customer_ids`: Limit to specific customers (omit for all customers)\n - `billable_metrics`: Limit to specific metrics (omit for all metrics)\n- Pagination: Use `next_page` cursor to retrieve large datasets\n- Null values: Group values may be null when no usage matches that group\n" operationId: getUsageBatch-v1 summary: Get batched usage data parameters: - $ref: '#/components/parameters/NextPage' requestBody: description: The usage query to run content: application/json: schema: $ref: '#/components/schemas/UsageBatchQueryPayload' example: window_size: day starting_on: '2021-01-01T00:00:00Z' ending_before: '2021-01-03T00:00:00Z' tags: - Usage responses: '200': description: Success content: application/json: schema: type: object required: - data - next_page properties: data: type: array items: $ref: '#/components/schemas/UsageBatchAggregate' next_page: type: string nullable: true example: data: - customer_id: d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc billable_metric_id: 9570e4f3-d1da-4b95-ba81-bd40ee002727 billable_metric_name: CPU hours start_timestamp: '2021-01-01T00:00:00Z' end_timestamp: '2021-01-02T00:00:00Z' value: 1234 - customer_id: d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc billable_metric_id: 9570e4f3-d1da-4b95-ba81-bd40ee002727 billable_metric_name: CPU hours start_timestamp: '2021-01-02T00:00:00Z' end_timestamp: '2021-01-03T00:00:00Z' value: 1234 next_page: null /v1/events/search: post: description: "This endpoint retrieves events by transaction ID for events that occurred within the last 34 days. It is specifically designed for sampling-based testing workflows to detect revenue leakage. The Event Search API provides a critical observability tool that validates the integrity of your usage pipeline by allowing you to sample raw events and verify their matching against active billable metrics. \n\nWhy event observability matters for revenue leakage:\nSilent revenue loss occurs when events are dropped, delayed, or fail to match billable metrics due to:\n- Upstream system failures\n- Event format changes\n- Misconfigured billable metrics\n\n### Use this endpoint to:\n- Sample raw events and validate they match the expected billable metrics\n- Build custom leakage detection alerts to prevent silent revenue loss\n- Verify event processing accuracy during system changes or metric updates\n- Debug event matching issues in real-time\n\n### Key response fields:\n- Complete event details including transaction ID, customer ID, and properties\n- Matched Metronome customer (if any)\n- Matched billable metric information (if any)\n- Processing status and duplicate detection flags\n\n### Usage guidelines:\n⚠️ Important: This endpoint is heavily rate limited and designed for sampling workflows only. Do not use this endpoint to check every event in your system. Instead, implement a sampling strategy to randomly validate a subset of events for observability purposes.\n" operationId: searchEvents-v1 summary: Search events tags: - Usage requestBody: description: Search events request content: application/json: schema: type: object required: - transactionIds properties: transactionIds: type: array items: type: string description: The transaction IDs of the events to retrieve example: transactionIds: - 2021-01-01T00:00:00Z_cluster42 responses: '200': description: Success content: application/json: schema: type: array items: type: object required: - id - transaction_id - customer_id - event_type - timestamp properties: id: type: string customer_id: type: string description: The ID of the customer in the ingest event body event_type: type: string properties: type: object additionalProperties: true timestamp: type: string format: date-time transaction_id: type: string is_duplicate: type: boolean processed_at: type: string format: date-time matched_customer: type: object description: The customer the event was matched to if a match was found properties: id: type: string format: uuid name: type: string matched_billable_metrics: type: array items: $ref: '#/components/schemas/BillableMetricForEventsSearch' example: - id: 123e4567-e89b-12d3-a456-426614174000 transaction_id: 2021-01-01T00:00:00Z_cluster42 customer_id: team@example.com event_type: heartbeat timestamp: '2021-01-01T00:00:00Z' properties: cluster_id: '42' cpu_seconds: 60 region: Europe processed_at: '2021-01-01T00:00:05Z' is_duplicate: false matched_customer: id: 98765432-10fe-cba9-8765-432109876543 name: Acme Corp matched_billable_metrics: - id: 8deed800-1b7a-495d-a207-6c52bac54dc9 name: CPU Hours /v1/customers/{customer_id}/purchasedSeats: get: x-mint: groups: - ff:seats description: Returns the number of seats purchased for the current period. operationId: getPurchasedSeats-v1 summary: Get purchased seats parameters: - $ref: '#/components/parameters/CustomerId' tags: - Usage responses: '200': description: Success content: application/json: schema: type: object required: - data properties: data: type: array items: type: object required: - charge_id - seat_count properties: charge_id: type: string format: uuid seat_count: type: integer '404': $ref: '#/components/responses/NotFound' components: schemas: PagedUsageQueryPayload: required: - billable_metric_id - customer_id - window_size type: object properties: customer_id: type: string format: uuid billable_metric_id: type: string format: uuid window_size: type: string description: A window_size of "day" or "hour" will return the usage for the specified period segmented into daily or hourly aggregates. A window_size of "none" will return a single usage aggregate for the entirety of the specified period. enum: - hour - day - none - HOUR - DAY - NONE - Hour - Day - None starting_on: type: string format: date-time ending_before: type: string format: date-time group_by: type: object description: Use group_key and group_filters instead. Use a single group key to group by. Compound group keys are not supported. deprecated: true required: - key properties: key: type: string description: The name of the group_by key to use values: type: array description: Values of the group_by key to return in the query. Omit this if you'd like all values for the key returned. minItems: 1 items: type: string minLength: 1 group_key: $ref: '#/components/schemas/GroupKey' group_filters: $ref: '#/components/schemas/GroupFilter' current_period: type: boolean description: If true, will return the usage for the current billing period. Will return an error if the customer is currently uncontracted or starting_on and ending_before are specified when this is true. PropertyFilter: type: object required: - name properties: name: type: string description: The name of the event property. exists: type: boolean description: Determines whether the property must exist in the event. If true, only events with this property will pass the filter. If false, only events without this property will pass the filter. If null or omitted, the existence of the property is optional. in_values: type: array items: type: string description: Specifies the allowed values for the property to match an event. An event will pass the filter only if its property value is included in this list. If undefined, all property values will pass the filter. Must be non-empty if present. not_in_values: type: array items: type: string description: Specifies the values that prevent an event from matching the filter. An event will not pass the filter if its property value is included in this list. If null or empty, all property values will pass the filter. Must be non-empty if present. GroupKeysArray: type: array items: type: array items: type: string description: Property names that are used to group usage costs on an invoice. Each entry represents a set of properties used to slice events into distinct buckets. AggregationTypeForEventsSearch: type: string enum: - count - Count - COUNT - latest - Latest - LATEST - max - Max - MAX - sum - Sum - SUM - unique - Unique - UNIQUE - custom_sql description: Specifies the type of aggregation performed on matching events. Includes "custom_sql" for events search endpoint responses. BillableMetricForEventsSearch: allOf: - $ref: '#/components/schemas/BillableMetricBase' - type: object properties: aggregation_type: $ref: '#/components/schemas/AggregationTypeForEventsSearch' SeatsUsageQueryPayload: required: - seat_metric_id - customer_id - window_size - usage_type type: object properties: customer_id: type: string format: uuid seat_metric_id: type: string format: uuid usage_type: type: string description: The type of usage to return, max or latest value. enum: - max - latest - MAX - LATEST - Max - Latest window_size: type: string description: A window_size of "day" or "hour" will return the usage for the specified period segmented into daily or hourly aggregates. A window_size of "none" will return a single usage aggregate for the entirety of the specified period. enum: - hour - day - none - HOUR - DAY - NONE - Hour - Day - None starting_on: type: string format: date-time ending_before: type: string format: date-time current_period: type: boolean description: If true, will return the usage for the current billing period. Will return an error if the customer is currently uncontracted or starting_on and ending_before are specified when this is true. EventTypeFilter: type: object properties: in_values: type: array items: type: string description: A list of event types that are explicitly included in the billable metric. If specified, only events of these types will match the billable metric. Must be non-empty if present. not_in_values: type: array items: type: string description: A list of event types that are explicitly excluded from the billable metric. If specified, events of these types will not match the billable metric. Must be non-empty if present. description: An optional filtering rule to match the 'event_type' property of an event. GroupKey: type: array description: 'Group key to group usage by. Supports both simple (single key) and compound (multiple keys) group keys. For simple group keys, provide a single key e.g. `["region"]`. For compound group keys, provide multiple keys e.g. `["region", "team"]`. For streaming metrics, the keys must be defined as a simple or compound group key on the billable metric. For compound group keys, all keys must match an exact compound group key definition — partial matches are not allowed. Cannot be used together with `group_by`. ' items: type: string minLength: 1 minItems: 1 example: - region - team Event: required: - customer_id - event_type - timestamp - transaction_id type: object properties: transaction_id: type: string minLength: 1 maxLength: 128 customer_id: type: string minLength: 1 event_type: type: string minLength: 1 timestamp: type: string description: RFC 3339 formatted properties: type: object additionalProperties: true PagedUsageAggregate: required: - starting_on - ending_before - group_key - group_value - value type: object properties: starting_on: type: string format: date-time ending_before: type: string format: date-time group_key: type: string nullable: true description: Use `group` instead. The group key for single-key grouping. deprecated: true group_value: type: string nullable: true description: Use `group` instead. The group value for single-key grouping. deprecated: true group: type: object additionalProperties: type: string description: 'Map of group key to their value for this usage aggregate. For simple group keys, this should be a single key e.g. `{"region": "US-East"}` For compound group keys, this should contain the values of each group key that forms the compound e.g. `{"region": "US-East", "team": "engineering"}` ' value: type: number nullable: true AggregationKey: type: string description: A key that specifies which property of the event is used to aggregate data. This key must be one of the property filter names and is not applicable when the aggregation type is 'count'. CustomField: type: object description: 'Custom fields to be added eg. { "key1": "value1", "key2": "value2" }' additionalProperties: type: string Error: required: - message type: object properties: message: type: string BillableMetricBase: required: - name - id type: object properties: group_by: type: array description: (DEPRECATED) use group_keys instead items: type: string description: A list of keys that can be used to additionally segment the values of the billable metric when making usage queries group_keys: $ref: '#/components/schemas/GroupKeysArray' name: type: string id: type: string format: uuid aggregate: type: string description: (DEPRECATED) use aggregation_type instead aggregate_keys: type: array description: (DEPRECATED) use aggregation_key instead items: type: string filter: type: object description: (DEPRECATED) use property_filters & event_type_filter instead additionalProperties: true aggregation_key: $ref: '#/components/schemas/AggregationKey' event_type_filter: $ref: '#/components/schemas/EventTypeFilter' property_filters: $ref: '#/components/schemas/PropertyFiltersArray' custom_fields: x-cf-entity: billable_metric $ref: '#/components/schemas/CustomField' sql: type: string description: The SQL query associated with the billable metric archived_at: type: string format: date-time description: RFC 3339 timestamp indicating when the billable metric was archived. If not provided, the billable metric is not archived. PropertyFiltersArray: type: array items: $ref: '#/components/schemas/PropertyFilter' description: A list of filters to match events to this billable metric. Each filter defines a rule on an event property. All rules must pass for the event to match the billable metric. UsageBatchQueryPayload: required: - window_size - starting_on - ending_before type: object properties: customer_ids: type: array description: A list of Metronome customer IDs to fetch usage for. If absent, usage for all customers will be returned. items: type: string format: uuid billable_metrics: type: array description: A list of billable metrics to fetch usage for. If absent, all billable metrics will be returned. items: type: object required: - id properties: id: type: string format: uuid group_by: type: object required: - key properties: key: type: string description: The name of the group_by key to use values: type: array description: Values of the group_by key to return in the query. If this field is omitted, all available values will be returned, up to a maximum of 200. minItems: 1 maxItems: 200 items: type: string minLength: 1 window_size: type: string description: A window_size of "day" or "hour" will return the usage for the specified period segmented into daily or hourly aggregates. A window_size of "none" will return a single usage aggregate for the entirety of the specified period. enum: - hour - day - none - HOUR - DAY - NONE - Hour - Day - None starting_on: type: string format: date-time ending_before: type: string format: date-time UsageBatchAggregate: required: - customer_id - billable_metric_id - billable_metric_name - start_timestamp - end_timestamp - value type: object properties: customer_id: type: string format: uuid billable_metric_id: type: string format: uuid billable_metric_name: type: string start_timestamp: type: string format: date-time end_timestamp: type: string format: date-time value: type: number nullable: true groups: type: object additionalProperties: type: number nullable: true description: Values will be either a number or null. Null indicates that there were no matches for the group_by value. GroupFilter: type: object description: 'Object mapping group keys to arrays of values to filter on. Only usage matching these filter values will be returned. Keys must be present in group_key. Omit a key or use an empty array to include all values for that dimension. ' additionalProperties: type: array items: type: string minLength: 1 example: region: - us-east1 - us-west1 team: - UI SeatsUsageAggregate: required: - starting_on - ending_before - value type: object properties: starting_on: type: string format: date-time ending_before: type: string format: date-time value: type: number nullable: true responses: NotFound: description: The specified resource was not found content: application/json: schema: $ref: '#/components/schemas/Error' parameters: NextPage: name: next_page in: query description: Cursor that indicates where the next page of results should start. required: false schema: type: string CustomerId: name: customer_id in: path required: true schema: type: string format: uuid example: d7abd0cd-4ae9-4db7-8676-e986a4ebd8dc PageLimit: name: limit in: query description: Max number of results that should be returned required: false schema: type: integer minimum: 1 maximum: 100 securitySchemes: bearerAuth: type: http scheme: bearer