How to Export Billings
Export billing records for your organization. Supports both synchronous query (JSON response) and asynchronous export (CSV file download).
Sync Query API
Query billing records with pagination. Returns JSON response directly. Limited to 100,000 records.
Endpoint
POST https://api.wavespeed.ai/api/v3/scheduler/billings/queryRequest
curl -X POST "https://api.wavespeed.ai/api/v3/scheduler/billings/query" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"year_month": "2025-01",
"page": 1,
"page_size": 100
}'Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| year_month | string | Yes | Billing month in format YYYY-MM (e.g., “2025-01”) |
| page | integer | No | Page number, default 1 |
| page_size | integer | No | Records per page, default 100, max 1000 |
Note: Organization is automatically determined from your API key.
Response
{
"code": 200,
"message": "success",
"data": {
"page": 1,
"total": 515,
"items": [
{
"uuid": "fdb619395f9247a8b7b973527ec7f687",
"billing_type": "deduct",
"price": -0.25,
"created_at": "2025-01-02T09:18:42.663Z",
"updated_at": "2025-01-02T09:18:42.663Z",
"access_key_name": "my-api-key",
"prediction": {
"uuid": "fd4924a6c8cb4b3f95f72ccd58e610b5",
"model_uuid": "wavespeed-ai/flux-dev",
"status": "completed"
}
}
]
}
}Response Fields
| Field | Type | Description |
|---|---|---|
| page | integer | Current page number |
| total | integer | Total number of records |
| items | array | Array of billing records |
| items[].uuid | string | Billing record UUID |
| items[].billing_type | string | Type: “deduct” or “refund” |
| items[].price | number | Amount in USD (negative for deduct, positive for refund) |
| items[].created_at | string | Creation timestamp (ISO 8601) |
| items[].access_key_name | string | Name of the access key used |
| items[].prediction | object | Associated prediction information |
Python Example
import requests
response = requests.post(
"https://api.wavespeed.ai/api/v3/scheduler/billings/query",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
},
json={
"year_month": "2025-01",
"page": 1,
"page_size": 100
}
)
data = response.json()
print(f"Total records: {data['data']['total']}")
for item in data['data']['items']:
print(f"{item['prediction']['uuid']}: ${item['price']}")JavaScript Example
const response = await fetch("https://api.wavespeed.ai/api/v3/scheduler/billings/query", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({
year_month: "2025-01",
page: 1,
page_size: 100
})
});
const data = await response.json();
console.log(`Total records: ${data.data.total}`);Async Export API
Export large billing datasets as CSV files. Recommended for datasets exceeding 100,000 records.
Step 1: Create Export Task
Endpoint
POST https://api.wavespeed.ai/api/v3/scheduler/billings/exportRequest
curl -X POST "https://api.wavespeed.ai/api/v3/scheduler/billings/export" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"year_month": "2025-01"
}'Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| year_month | string | Yes | Billing month in format YYYY-MM (e.g., “2025-01”) |
Note: Organization is automatically determined from your API key.
Response
{
"code": 200,
"message": "success",
"data": {
"task_id": "26dd31a2-4b8e-4c41-87c2-2da871a99a05",
"status": "pending",
"total_count": 13838450,
"message": "Export task created, please query status later"
}
}Step 2: Query Task Status
Endpoint
GET https://api.wavespeed.ai/api/v3/scheduler/billings/export/{task_id}Request
curl -X GET "https://api.wavespeed.ai/api/v3/scheduler/billings/export/26dd31a2-4b8e-4c41-87c2-2da871a99a05" \
-H "Authorization: Bearer YOUR_API_KEY"Response (Processing)
{
"code": 200,
"message": "success",
"data": {
"task_id": "26dd31a2-4b8e-4c41-87c2-2da871a99a05",
"status": "processing",
"progress": 45,
"total_count": 13838450,
"created_at": "2025-01-09T02:06:02Z",
"updated_at": "2025-01-09T02:10:15Z"
}
}Response (Completed)
{
"code": 200,
"message": "success",
"data": {
"task_id": "26dd31a2-4b8e-4c41-87c2-2da871a99a05",
"status": "completed",
"progress": 100,
"total_count": 13838450,
"file_count": 139,
"download_url": "https://cdn.wavespeed.ai/exports/billings/12345/2025-01.zip",
"created_at": "2025-01-09T02:06:02Z",
"updated_at": "2025-01-09T02:45:30Z"
}
}Task Status Response Fields
| Field | Type | Description |
|---|---|---|
| task_id | string | Unique task identifier |
| status | string | Task status: “pending”, “processing”, “completed”, “failed” |
| progress | integer | Progress percentage (0-100) |
| total_count | integer | Total number of records to export |
| file_count | integer | Number of CSV files generated (available when completed) |
| download_url | string | URL to download the ZIP file (available when completed) |
| message | string | Error message (available when failed) |
| created_at | string | Task creation timestamp |
| updated_at | string | Last update timestamp |
CSV File Format
The exported ZIP file contains CSV files with the following columns:
| Column | Description |
|---|---|
| AccessKey Name | Name of the access key used |
| Prediction ID | UUID of the prediction |
| Model | Model identifier (e.g., “wavespeed-ai/flux-dev”) |
| Date | Timestamp of the billing record |
| Amount ($) | Amount in USD (negative for charges, positive for refunds) |
Python Example (Async Export)
import requests
import time
# Step 1: Create export task
response = requests.post(
"https://api.wavespeed.ai/api/v3/scheduler/billings/export",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
},
json={
"year_month": "2025-01"
}
)
task_id = response.json()['data']['task_id']
print(f"Task created: {task_id}")
# Step 2: Poll for completion
while True:
status_response = requests.get(
f"https://api.wavespeed.ai/api/v3/scheduler/billings/export/{task_id}",
headers={"Authorization": "Bearer YOUR_API_KEY"}
)
data = status_response.json()['data']
print(f"Status: {data['status']}, Progress: {data.get('progress', 0)}%")
if data['status'] == 'completed':
print(f"Download URL: {data['download_url']}")
break
elif data['status'] == 'failed':
print(f"Export failed: {data.get('message')}")
break
time.sleep(10) # Wait 10 seconds before next pollJavaScript Example (Async Export)
// Step 1: Create export task
const createResponse = await fetch("https://api.wavespeed.ai/api/v3/scheduler/billings/export", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({
year_month: "2025-01"
})
});
const { data: { task_id } } = await createResponse.json();
console.log(`Task created: ${task_id}`);
// Step 2: Poll for completion
const pollStatus = async () => {
const response = await fetch(
`https://api.wavespeed.ai/api/v3/scheduler/billings/export/${task_id}`,
{ headers: { "Authorization": "Bearer YOUR_API_KEY" } }
);
const { data } = await response.json();
console.log(`Status: ${data.status}, Progress: ${data.progress || 0}%`);
if (data.status === 'completed') {
console.log(`Download URL: ${data.download_url}`);
return data.download_url;
} else if (data.status === 'failed') {
throw new Error(`Export failed: ${data.message}`);
}
await new Promise(resolve => setTimeout(resolve, 10000));
return pollStatus();
};
const downloadUrl = await pollStatus();Error Responses
| Code | Description |
|---|---|
| 400 | Invalid parameters (e.g., invalid year_month format) |
| 401 | Invalid API key |
| 404 | Task not found |
| 500 | Internal server error |
Limits
| Limit | Value |
|---|---|
| Sync query max page size | 1,000 |
| CSV file max rows | 100,000 per file |
| Export file retention | 7 days |
Notes
- Use pagination to query large datasets (max 1,000 records per page).
- For bulk download, use the async export API to get CSV files.
- Exported files are automatically compressed as ZIP archives.
- Files are retained for 7 days and then automatically deleted.
- Historical data (previous quarters) is retrieved from archive database.