Usage Tracking
Query aggregated usage statistics across services for customers and IP addresses. Usage tracking helps monitor consumption against subscription tier limits.
Get Aggregated User Usage
Retrieve aggregated usage statistics across all services for the authenticated user’s customer account.
Endpoint: https://apis.threatwinds.com/api/billing/v1/usage
Method: GET
Parameters
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
Required role: owner, admin, or user
All authenticated customer members can query their usage statistics.
Request
To retrieve user usage, use a GET request:
curl -X 'GET' \
'https://apis.threatwinds.com/api/billing/v1/usage' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <token>'
Or using API key and secret:
curl -X 'GET' \
'https://apis.threatwinds.com/api/billing/v1/usage' \
-H 'accept: application/json' \
-H 'api-key: your-api-key' \
-H 'api-secret: your-api-secret'
Response
A successful response will return aggregated usage statistics organized by service.
Success Response (200 OK)
{
"identifier": "550e8400-e29b-41d4-a716-446655440000",
"identifierType": "user",
"totalFeatures": 5,
"fetchedAt": 1704067200,
"services": {
"search-api": {
"serviceName": "search-api",
"features": [
{
"featureKey": "max_searches_per_minute",
"tierName": "Professional",
"window": "minute",
"currentUsage": 45,
"limit": 100,
"remaining": 55,
"resetAt": 1704067260,
"isLocked": false
}
]
},
"ingest-api": {
"serviceName": "ingest-api",
"features": [
{
"featureKey": "max_ingests_per_hour",
"tierName": "Professional",
"window": "hour",
"currentUsage": 200,
"limit": 500,
"remaining": 300,
"resetAt": 1704070800,
"isLocked": false
}
]
}
}
}
Response Schema
| Field | Type | Description |
|---|---|---|
| identifier | string (UUID) | User/Customer unique identifier |
| identifierType | string | Type of identifier: “user” or “customer” |
| totalFeatures | integer | Total number of features tracked |
| fetchedAt | integer | Unix timestamp when usage was fetched |
| services | object | Usage statistics by service |
| services.{service} | object | Service-specific usage data |
| services.{service}.serviceName | string | Service identifier |
| services.{service}.features | array | Array of feature usage details |
| features[].featureKey | string | Feature/limit key name |
| features[].tierName | string | Subscription tier name |
| features[].window | string | Time window: “minute”, “hour”, “day”, “month” |
| features[].currentUsage | integer | Current usage count |
| features[].limit | integer | Maximum allowed (-1 for unlimited) |
| features[].remaining | integer | Remaining quota (-1 for unlimited) |
| features[].resetAt | integer | Unix timestamp when usage resets |
| features[].isLocked | boolean | Whether feature is locked due to limit exceeded |
Business Logic
- Aggregates usage from all services that user has accessed
- Compares current usage against tier limits
- Returns remaining quota and reset time
- Continues if individual services fail (graceful degradation)
- Useful for displaying usage dashboards and warnings
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 | Database error or service unavailable |
Get Aggregated IP Usage
Retrieve aggregated usage statistics across all services for the requester’s IP address. This is a public endpoint that doesn’t require authentication.
Endpoint: https://apis.threatwinds.com/api/billing/v1/usage/ip
Method: GET
Authentication
This is a public endpoint and does not require authentication. The endpoint automatically detects the requester’s IP address.
Request
To retrieve IP usage, use a GET request:
curl -X 'GET' \
'https://apis.threatwinds.com/api/billing/v1/usage/ip' \
-H 'accept: application/json'
Response
Success Response (200 OK)
{
"identifier": "192.168.1.100",
"identifierType": "ip",
"totalFeatures": 2,
"fetchedAt": 1704067200,
"services": {
"search-api": {
"serviceName": "search-api",
"features": [
{
"featureKey": "max_searches_per_minute",
"tierName": "Free",
"window": "minute",
"currentUsage": 8,
"limit": 10,
"remaining": 2,
"resetAt": 1704067260,
"isLocked": false
}
]
}
}
}
Response Schema
| Field | Type | Description |
|---|---|---|
| identifier | string | IP address being queried |
| identifierType | string | Always “ip” for this endpoint |
| totalFeatures | integer | Total number of features tracked |
| fetchedAt | integer | Unix timestamp when usage was fetched |
| services | object | Usage statistics by service |
| services.{service} | object | Service-specific usage data |
| services.{service}.serviceName | string | Service identifier |
| services.{service}.features | array | Array of feature usage details |
| features[].featureKey | string | Feature/limit key name |
| features[].tierName | string | Tier name (typically “Free” for IPs) |
| features[].window | string | Time window: “minute”, “hour”, “day”, “month” |
| features[].currentUsage | integer | Current usage count |
| features[].limit | integer | Maximum allowed |
| features[].remaining | integer | Remaining quota |
| features[].resetAt | integer | Unix timestamp when usage resets |
| features[].isLocked | boolean | Whether feature is locked due to limit exceeded |
Business Logic
- Public endpoint for checking IP-based usage
- Useful for rate limit monitoring
- Helps identify when IP is approaching or exceeding rate limits
- Does not require authentication (IP-based tracking)
Error Codes
| Status Code | Description | Possible Cause |
|---|---|---|
| 200 | OK | Request successful |
| 400 | Bad Request | Invalid IP address format |
| 500 | Internal Server Error | Database error or service unavailable |
Usage Monitoring Best Practices
For Application Developers
- Monitor Proactively: Check usage regularly before hitting limits
- Display to Users: Show usage statistics in dashboards
- Set Warnings: Alert users at 80% and 90% of limits
- Graceful Degradation: Handle 402 Payment Required errors gracefully
Example: Usage Dashboard
# 1. Get customer limits
curl -X 'GET' \
'https://apis.threatwinds.com/api/billing/v1/limits' \
-H 'Authorization: Bearer <token>'
# 2. Get current usage
curl -X 'GET' \
'https://apis.threatwinds.com/api/billing/v1/usage' \
-H 'Authorization: Bearer <token>'
# 3. Calculate percentage and display:
# - Green: 0-70%
# - Yellow: 71-90%
# - Red: 91-100%
# - Show upgrade option when approaching limits
Example: IP Rate Limit Check
# Check if your IP is rate limited before making requests
curl -X 'GET' \
'https://apis.threatwinds.com/api/billing/v1/usage/ip' \
-H 'accept: application/json'
# If status shows "rate_limited", implement backoff strategy
Common Usage Scenarios
Scenario 1: Preventing Limit Overages
1. User performs action that consumes quota (search query, API call, etc.)
↓
2. Application checks current usage via GET /usage
↓
3. If approaching limit (>90%), show warning
↓
4. If at limit (100%), show upgrade prompt
↓
5. User upgrades tier via Stripe Customer Portal
↓
6. New limits immediately available
Scenario 2: IP Rate Limit Management
1. Public API receives request from IP
↓
2. Check IP usage via GET /usage/ip
↓
3. If within limits, process request
↓
4. If approaching limit, add rate limit headers to response
↓
5. If rate limited, return 429 Too Many Requests
↓
6. Client implements exponential backoff
Scenario 3: Usage Analytics
1. Admin wants to analyze customer usage patterns
↓
2. Query usage for customer via GET /usage
↓
3. Compare against tier limits
↓
4. Identify customers approaching limits
↓
5. Proactively reach out with upgrade suggestions
↓
6. Improve tier pricing based on usage patterns
Integration with Limits
Usage tracking works in conjunction with the Limits API:
| Limits Endpoints | Purpose | Usage Endpoints | Purpose |
|---|---|---|---|
GET /limits | Get tier limits | GET /usage | Get current usage |
GET /limits/{service} | Get service limits | Compare usage vs limits | Calculate percentage |
GET /limits/ip | Get IP rate limits | GET /usage/ip | Check IP usage |
Example: Complete Limit Check
# 1. Get current usage
curl 'https://apis.threatwinds.com/api/billing/v1/usage' \
-H 'Authorization: Bearer <token>'
# Response includes all usage details:
# {
# "services": {
# "search-api": {
# "features": [{
# "featureKey": "max_searches_per_minute",
# "currentUsage": 85,
# "limit": 100,
# "remaining": 15,
# "window": "minute"
# }]
# }
# }
# }
# 2. Calculate: 85 / 100 = 85% used
# 3. Display warning: "You've used 85% of your per-minute search quota"
# 4. Show resetAt timestamp: "Resets in 15 seconds"