Usage Tracking
Monitor your current consumption against subscription tier limits. Usage tracking shows real-time counters for rate-limited features across all services.
Get Aggregated User Usage
Retrieve usage statistics across all services for the authenticated user’s customer account.
Endpoint: GET https://apis.threatwinds.com/api/billing/v1/limits/usage
Headers
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Optional* | Bearer token for session authentication |
| api-key | string | Optional* | API key for key-based authentication |
| api-secret | string | Optional* | API secret for key-based authentication |
Note: You must use either Authorization header OR API key/secret combination.
Required Roles
owner, admin, or user
Request
curl -X GET \
'https://apis.threatwinds.com/api/billing/v1/limits/usage' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <token>'
Response (200 OK)
{
"identifier": "550e8400-e29b-41d4-a716-446655440000",
"identifierType": "user",
"totalFeatures": 5,
"fetchedAt": 1744185600,
"services": {
"ai-api": {
"serviceName": "ai-api",
"features": [
{
"identifier": "550e8400-e29b-41d4-a716-446655440000",
"identifierType": "user",
"featureKey": "chat_completions_per_month",
"tierName": "Pro",
"window": "month",
"currentUsage": 1250,
"limit": 5000,
"remaining": 3750,
"resetAt": 1746057600,
"isLocked": false
},
{
"identifier": "550e8400-e29b-41d4-a716-446655440000",
"identifierType": "user",
"featureKey": "embeddings_per_month",
"tierName": "Pro",
"window": "month",
"currentUsage": 80,
"limit": 5000,
"remaining": 4920,
"resetAt": 1746057600,
"isLocked": false
}
]
},
"search-api": {
"serviceName": "search-api",
"features": [
{
"identifier": "550e8400-e29b-41d4-a716-446655440000",
"identifierType": "user",
"featureKey": "simple_search_per_minute",
"tierName": "Pro",
"window": "minute",
"currentUsage": 12,
"limit": 60,
"remaining": 48,
"resetAt": 1744185660,
"isLocked": false
}
]
}
}
}
Response Schema
| Field | Type | Description |
|---|---|---|
| identifier | string | Customer ID or IP address |
| identifierType | string | "user" or "ip" |
| totalFeatures | integer | Total number of features tracked |
| fetchedAt | integer | Unix timestamp when usage was fetched |
| services.{service}.features[] | array | Array of feature usage details |
| features[].featureKey | string | Feature key name |
| features[].tierName | string | Subscription tier name |
| features[].window | string | Time window: minute, hour, day, month |
| features[].currentUsage | integer | Current usage count in this window |
| features[].limit | integer | Maximum allowed (-1 for unlimited) |
| features[].remaining | integer | Remaining before limit is hit (-1 for unlimited) |
| features[].resetAt | integer | Unix timestamp when the counter resets |
| features[].isLocked | boolean | Whether the feature is currently rate-limited |
Get Aggregated IP Usage
Retrieve usage statistics for the requester’s IP address. Public endpoint, no authentication required.
Endpoint: GET https://apis.threatwinds.com/api/billing/v1/limits/usage/ip
Request
curl -X GET \
'https://apis.threatwinds.com/api/billing/v1/limits/usage/ip' \
-H 'accept: application/json'
Response (200 OK)
{
"identifier": "203.0.113.42",
"identifierType": "ip",
"totalFeatures": 2,
"fetchedAt": 1744185600,
"services": {
"search-api": {
"serviceName": "search-api",
"features": [
{
"identifier": "203.0.113.42",
"identifierType": "ip",
"featureKey": "entity_lookup_per_minute",
"tierName": "Public",
"window": "minute",
"currentUsage": 7,
"limit": 10,
"remaining": 3,
"resetAt": 1744185660,
"isLocked": false
}
]
}
}
}
Usage Monitoring Best Practices
Building a Usage Dashboard
# 1. Get current usage with remaining counts
curl -X GET \
'https://apis.threatwinds.com/api/billing/v1/limits/usage' \
-H 'Authorization: Bearer <token>'
# 2. Calculate percentage: currentUsage / limit * 100
# 3. Display thresholds:
# - Green: 0-70%
# - Yellow: 71-90%
# - Red: 91-100%
# 4. Use resetAt to show "Resets in X minutes/hours"
Handling Rate Limit Errors
When your application receives a 429 Too Many Requests response:
- Check the
resetAtfield from the usage endpoint to know when the limit resets - Implement exponential backoff for retries
- Consider upgrading to a higher tier for increased limits
- For IP-based limits, authenticate your requests to use your tier limits instead
Error Codes
| Status Code | Description | Possible Cause |
|---|---|---|
| 200 | OK | Request successful |
| 400 | Bad Request | Invalid request |
| 401 | Unauthorized | Missing or invalid authentication |
| 403 | Forbidden | Insufficient permissions |
| 500 | Internal Server Error | Server error |