Send Custom Usage Metrics¶
Use the custom usage metering API to submit idempotent usage events for a subscription or Resource instance. First obtain a temporary, organization-scoped metrics endpoint and token from Omnistrate, then send your usage events to that endpoint.
How the Integration Works¶
- Call the Omnistrate organization API with your Omnistrate bearer token.
- Receive a complete metrics endpoint URL, a temporary token, and its expiration time.
- Send a JSON array of custom usage events to the returned endpoint with the temporary token.
Warning
Keep both tokens secret. Do not place credentials in source control, logs, screenshots, or client-side application code. Request a new metrics token before the current token reaches its expiresAt time.
Prerequisites¶
Before sending custom usage metrics, you need:
- A SaaS Provider API token authorized to access your organization.
- An existing
subscription-idorinstance-idowned by that organization. - A unique
idempotency-idfor every logical usage event. - An RFC 3339 timestamp and one or more integer metrics for every event.
curlfor the examples below. The optional shell automation example also usesjq.
Get the Metrics Endpoint and Token¶
Call the organization API with your Omnistrate bearer token. The optional expiresInSeconds query parameter requests the lifetime of the metrics token. Its value must be at least 1 and cannot exceed the maximum configured by Omnistrate.
export OMNISTRATE_API_TOKEN="<your-omnistrate-api-token>"
curl --silent --show-error --request GET \
"https://api.omnistrate.cloud/2022-09-01-00/custom-metrics/endpoint?expiresInSeconds=86400" \
--header "Authorization: Bearer ${OMNISTRATE_API_TOKEN}" \
--header "Accept: application/json"
Example response¶
{
"endpoint": "https://metrics.example.com/v1/customUsageMetering/",
"expiresAt": "2026-09-23T00:00:00Z",
"token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.example.signature"
}
endpoint: The complete URL for submitting custom metrics. Use it exactly as returned; do not construct or append the API path yourself.token: A temporary bearer token scoped to the authenticated SaaS Provider organization.expiresAt: The token expiration time. Refresh the endpoint credentials before this RFC 3339 timestamp.
Load the response into shell variables¶
CREDENTIALS="$(curl --silent --show-error --fail \
"https://api.omnistrate.cloud/2022-09-01-00/custom-metrics/endpoint?expiresInSeconds=86400" \
--header "Authorization: Bearer ${OMNISTRATE_API_TOKEN}" \
--header "Accept: application/json")"
export METRICS_ENDPOINT="$(printf '%s' "${CREDENTIALS}" | jq -r '.endpoint')"
export METRICS_TOKEN="$(printf '%s' "${CREDENTIALS}" | jq -r '.token')"
export METRICS_TOKEN_EXPIRES_AT="$(printf '%s' "${CREDENTIALS}" | jq -r '.expiresAt')"
Send a Custom Usage Event¶
Send an HTTP POST request to the exact URL returned in endpoint. Authenticate with the temporary metrics token, not the Omnistrate API token used to obtain the credentials.
Note
The request body is always an array. Even when sending one event, enclose the event object in square brackets. The body must not exceed 4 MiB and may contain at most 100 events.
Use a subscription ID¶
curl --silent --show-error --request POST \
"${METRICS_ENDPOINT}" \
--header "Authorization: Bearer ${METRICS_TOKEN}" \
--header "Content-Type: application/json" \
--data '[
{
"idempotency-id": "usage-event-001",
"subscription-id": "subscription-123",
"timestamp": "2026-08-23T14:30:00Z",
"metrics": {
"requests": 1250,
"storage-bytes": 4096
}
}
]'
The subscription must belong to the SaaS Provider organization represented by the token.
Use an instance ID¶
If you provide only an instance-id, the API resolves its subscription automatically.
[
{
"idempotency-id": "usage-event-002",
"instance-id": "instance-123",
"timestamp": "2026-08-23T14:31:00Z",
"metrics": {
"requests": 42
}
}
]
The instance must belong to the SaaS Provider organization represented by the token and must have a registered subscription.
Required event fields¶
idempotency-id: A non-empty client-generated retry key, scoped to the authenticated organization and limited to 256 characters.timestamp: An RFC 3339 timestamp within the previous or current UTC clock hour. The service stores it in UTC with second precision and uses it to determine the UTC billing period.metrics: A non-empty object containing at most 100 metric names mapped to signed 64-bit integers. Metric names are limited to 256 characters; decimal values are rejected.- Target: Supply an existing
subscription-id, an existinginstance-id, or both. Each identifier is limited to 256 characters. If both are supplied, the instance must belong to the subscription.
Warning
Preserve integer precision. If your programming language cannot safely represent the full signed 64-bit integer range, use a JSON library or numeric type that preserves integer values exactly.
Registration response¶
A processed request returns 200 OK with separate successful and failed arrays. Always inspect both arrays because a 200 response can contain rejected events.
{
"successful": [
{
"event-id": "0c4596cb-b85f-4e6d-bdb8-4cd16ed95b3e",
"idempotency-id": "usage-event-001",
"subscription-id": "subscription-123",
"timestamp": "2026-08-23T14:30:00Z",
"billing-period": "20260823",
"metrics": {
"requests": 1250,
"storage-bytes": 4096
},
"created-at": "2026-08-23T14:31:00Z",
"updated-at": "2026-08-23T14:31:00Z",
"version": 1
}
],
"failed": []
}
The service generates event-id, billing-period, created-at, updated-at, and version. Do not send or depend on client-provided values for these fields.
Send Multiple Events in One Request¶
Place multiple event objects in the same JSON array. You can mix subscription-based and instance-based events.
[
{
"idempotency-id": "usage-event-003",
"subscription-id": "subscription-123",
"timestamp": "2026-08-23T14:32:00Z",
"metrics": {
"requests": 100
}
},
{
"idempotency-id": "usage-event-004",
"instance-id": "instance-456",
"timestamp": "2026-08-23T14:32:00Z",
"metrics": {
"storage-bytes": 4096
}
}
]
Batch failure behavior¶
- A syntactically malformed body, invalid JSON field type, empty batch, or request-limit violation rejects the complete request before storage with
400 Bad Requestor413 Payload Too Large. - A decodable event that fails required-field, timestamp-window, ownership, target, metric-definition, or idempotency validation is added to
failed. Other valid events in the batch continue processing. - Existing events are never updated. An
idempotency-idthat already exists with identical content is added tosuccessful; different content is added tofailedand leaves the stored event unchanged. - Target and idempotency throughput controls add affected events to
failed. They do not change the HTTP status or add aRetry-Afterheader. - Events are stored sequentially. If an infrastructure failure occurs after earlier events were stored, the request returns
500 Internal Server Errorwithout a partial result. Retry the complete batch with the same idempotency IDs; stored events return their original records and remaining events are attempted again.
Retries, Idempotency, and Throughput¶
Safe retry behavior¶
- Retry an event with the same
idempotency-idand identical content. - After the one-second retry window, an identical retry returns the original event, including its
event-idand timestamps. - Reusing an ID with different content adds the event to
failedin the200 OKresponse. - Existing events are never updated.
Throughput limits¶
The API applies these limits independently for each authenticated SaaS Provider organization:
- Up to 10 HTTP requests per second. Exceeding this request-level limit returns
429 Too Many RequestswithRetry-After: 1before any event is processed. - Up to one accepted HTTP request per second containing the same target, with only one such request processed at a time.
- Up to one accepted HTTP request per second containing the same
idempotency-id, with only one such request processed at a time.
For rate limiting, the target is the instance-id when present; otherwise it is the subscription-id. Requests for different targets can run concurrently within the organization-level limit.
Target and idempotency limits return the affected events in failed as part of a 200 OK response. Wait at least one second before retrying those events. Limits are maintained independently by each monitoring-service process.
Recommended retry logic¶
- Keep the original event body and
idempotency-id. - Inspect
failedafter every200 OK. Correct validation failures and wait at least one second before retrying target or idempotency throughput failures. - For
429, wait for the number of seconds inRetry-After; no event in that request was processed. - For transient
500responses, retry with exponential backoff and jitter. - For an expired metrics token, request fresh endpoint credentials and retry with the same event content and idempotency ID.
Troubleshooting¶
Getting the endpoint and token¶
400 Bad Request:expiresInSecondsis invalid or exceeds the configured maximum.401 Unauthorized: The Omnistrate bearer token is missing or invalid.403 Forbidden: The authenticated identity is not authorized for this operation.500 Internal Server Error: Endpoint credentials could not be generated. Retry later or contact support.
Sending custom metrics¶
200 OK: The body contains per-record results. Record validation, ownership, target, metric-definition, idempotency, and event-level throughput failures appear infailed.400 Bad Request: The JSON is malformed, the array is empty or exceeds 100 events, an event exceeds 100 metrics, a field has an invalid JSON type, or an identifier or metric name exceeds 256 characters.401 Unauthorized: The temporary metrics bearer token is missing, invalid, or expired.413 Payload Too Large: The request body exceeds 4 MiB.429 Too Many Requests: The SaaS Provider request limit of 10 HTTP requests per second was exceeded before processing.500 Internal Server Error: The request failed internally. Retry safely with the same idempotency IDs.504 Gateway Timeout: Request processing exceeded the configured server timeout.
Quick Reference¶
- Credential endpoint:
GET https://api.omnistrate.cloud/2022-09-01-00/custom-metrics/endpoint - Metrics endpoint: Use the complete URL returned in the credential response.
- Authentication:
Bearer <token>(send as theAuthorizationheader value) - Content type:
application/json - Request shape: A JSON array containing 1–100 events, with at most 100 metrics per event and a total body size no greater than 4 MiB.
- Event retention: Controlled by the service configuration; the default is seven days.
For the complete API operation reference, see Get custom metrics endpoint.