How to Check Billings
Search billing records with optional filters such as billing type, prediction UUIDs, sort order, and time range. Returns paginated results.
Very recent billing activity may take a short time to appear. If you are checking a request that just finished, retry the search after a brief delay.
Endpoint
POST https://api.wavespeed.ai/api/v3/billings/searchTeam organizations: Keys created by a current Owner, Admin, Developer, or Billing member can all search organization-wide billing records. Records are no longer scoped to the key that generated them. Invoices, payment records, and payment methods are not available through any API key. These restrictions do not apply to personal organizations.
Request
curl --fail-with-body --connect-timeout 10 --max-time 60 --request POST 'https://api.wavespeed.ai/api/v3/billings/search' \
--header "Authorization: Bearer ${WAVESPEED_API_KEY}" \
--header 'Content-Type: application/json' \
--data-raw '{
"page": 1,
"page_size": 10
}'Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
billing_type | string | No | - | Filter by billing type (e.g., deduct) |
order_id | string | No | - | Filter by an exact related order UUID |
prediction_uuids | array | No | - | Filter by up to 10 related prediction UUIDs |
sort | string | No | - | Sort order: created_at ASC or created_at DESC |
start_time | string | No | - | Start of time range as Unix seconds, milliseconds, nanoseconds, YYYY-MM-DD, YYYY-MM-DD HH:MM:SS, or RFC 3339 |
end_time | string | No | - | End of time range in the same formats as start_time |
access_key_uuid | string | No | - | Filter by the public UUID of an access key |
model_uuid | string | No | - | Filter by model ID, such as wavespeed-ai/z-image/turbo |
page | integer | No | 1 | Page number (1 or greater) |
page_size | integer | No | 100 | Items per page (1-100) |
Unless order_id or prediction_uuids supplies an exact lookup, each request is limited to a three-calendar-month window ending at end_time, or at the current time when end_time is omitted. If start_time is omitted or older than that window, the server advances it to the start of the three-month window. To backfill older billing history, query consecutive non-overlapping windows of three months or less. Exact order and prediction lookups are not subject to this history-window limit.
Response
{
"code": 200,
"message": "success",
"data": {
"page": 1,
"has_more": false,
"items": [
{
"uuid": "1113382d696d4677a036540a9bbb88b4",
"access_key_uuid": "6f8cfbf889fa4fbf88960e938c1b0d13",
"access_key_name": "aboy",
"billing_type": "deduct",
"price": 0.04,
"created_at": "2026-04-23T12:23:30.933Z",
"updated_at": "2026-04-23T12:23:30.933Z",
"order": {
"uuid": "ca1224af40134dada3943d1ed8e3404b",
"state": "pre",
"price": 0.04,
"origin_price": 0.04,
"status": ""
},
"prediction": {
"uuid": "0cbf014f272a461faab2d19929ccf759",
"model_uuid": "bytedance/seedream-v4.5",
"status": "created"
}
},
{
"uuid": "e16f36a848e24ed795a7c4e61d66d22a",
"access_key_uuid": "",
"access_key_name": "",
"billing_type": "deduct",
"price": 0.0031,
"created_at": "2026-08-17T12:23:30.933Z",
"updated_at": "2026-08-17T12:23:30.933Z",
"consumption": {
"request_id": "req_01k2z7n0vks6c8m2t9b3",
"type": "llm",
"consumption_type": "llm",
"model_name": "openai/gpt-5.6-sol",
"service": "llm-server",
"input_tokens": 1240,
"output_tokens": 318,
"total_tokens": 1558,
"timestamp": "2026-08-17T12:23:30.120Z"
}
}
]
}
}Response Fields
| Field | Type | Description |
|---|---|---|
data.page | integer | Current page number |
data.has_more | boolean | Whether another page is available |
data.items | array | Billing records for the current page, up to page_size items |
The response does not include an exact total. When data.has_more is true, increment page and send the same filters again to fetch the next page.
Billing Record Object
| Field | Type | Description |
|---|---|---|
uuid | string | Billing record UUID |
access_key_uuid | string | Public UUID of the access key used |
access_key_name | string | Name of the access key used |
billing_type | string | Type of billing (e.g., deduct) |
price | float | Amount in USD |
created_at | string | Creation timestamp (ISO 8601) |
updated_at | string | Last update timestamp (ISO 8601) |
order | object | Related order information, when the billing record came from a prediction |
prediction | object | Related prediction information, when the billing record came from a prediction |
consumption | object | LLM token usage and request metadata, when the billing record came from LLM consumption |
LLM Consumption Metadata
Billing records backed by LLM consumption include a consumption object with token usage and request metadata. Prediction-backed and other billing records do not include this object. When consumption is present, the response uses the schema below.
| Field | Type | Description |
|---|---|---|
consumption.service | string | Service that generated the charge; currently llm-server for LLM usage |
consumption.type | string | Canonical consumption category; llm for LLM usage |
consumption.consumption_type | string | Compatibility alias of consumption.type |
consumption.model_name | string | Model used for the request |
consumption.request_id | string | Related LLM request ID |
consumption.input_tokens | integer | Input tokens billed |
consumption.output_tokens | integer | Output tokens billed |
consumption.total_tokens | integer | Total tokens billed; falls back to input plus output tokens when the source total is unavailable |
consumption.timestamp | string | Usage timestamp in ISO 8601 format |
billings/search does not currently accept an LLM-only filter. To isolate LLM usage, paginate through the results and select records where consumption.type is llm. For aggregated spend, request, and token trends, use LLM Monitor. For individual request details, use LLM Logs.
Python Example
import os
import requests
api_key = os.environ["WAVESPEED_API_KEY"]
def get_billings(page=1, page_size=10, billing_type=None):
payload = {
"page": page,
"page_size": page_size
}
if billing_type:
payload["billing_type"] = billing_type
response = requests.post(
"https://api.wavespeed.ai/api/v3/billings/search",
headers={
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
},
json=payload,
timeout=(10, 60),
)
response.raise_for_status()
body = response.json()
if body.get("code") != 200:
raise RuntimeError(body.get("message", "Failed to list billings"))
return body["data"]
# Get all available pages of recent billings
page = 1
while True:
billings = get_billings(page=page)
for item in billings["items"]:
print(f"{item['created_at']}: ${item['price']} ({item['billing_type']})")
consumption = item.get("consumption")
if consumption and consumption.get("type") == "llm":
print(
f" {consumption['model_name']}: "
f"{consumption['input_tokens']} input + "
f"{consumption['output_tokens']} output tokens "
f"(request {consumption['request_id']})"
)
if not billings["has_more"]:
break
page += 1Filter by Type
curl --fail-with-body --connect-timeout 10 --max-time 60 --request POST 'https://api.wavespeed.ai/api/v3/billings/search' \
--header "Authorization: Bearer ${WAVESPEED_API_KEY}" \
--header 'Content-Type: application/json' \
--data-raw '{
"billing_type": "deduct",
"page": 1,
"page_size": 10
}'Filter by Time Range
curl --fail-with-body --connect-timeout 10 --max-time 60 --request POST 'https://api.wavespeed.ai/api/v3/billings/search' \
--header "Authorization: Bearer ${WAVESPEED_API_KEY}" \
--header 'Content-Type: application/json' \
--data-raw '{
"start_time": "1759317210051",
"end_time": "1759317227408",
"sort": "created_at DESC",
"page": 1,
"page_size": 10
}'Filter by Prediction
curl --fail-with-body --connect-timeout 10 --max-time 60 --request POST 'https://api.wavespeed.ai/api/v3/billings/search' \
--header "Authorization: Bearer ${WAVESPEED_API_KEY}" \
--header 'Content-Type: application/json' \
--data-raw '{
"prediction_uuids": ["cb54bb552ff94e1ea6a5c2976fe1c0c1"],
"page": 1,
"page_size": 10
}'