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/limits/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/limits/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/limits/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": [
        {
          "identifier": "550e8400-e29b-41d4-a716-446655440000",
          "identifierType": "user",
          "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": [
        {
          "identifier": "550e8400-e29b-41d4-a716-446655440000",
          "identifierType": "user",
          "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 unique identifier
identifierType string Type of identifier: “user” or “ip”
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[].identifier string User ID or IP address for this usage entry
features[].identifierType string Type of identifier: “user” or “ip”
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

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

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/limits/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/limits/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": [
        {
          "identifier": "192.168.1.100",
          "identifierType": "ip",
          "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[].identifier string IP address for this usage entry
features[].identifierType string Always “ip” for this endpoint
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

Error Codes

Status Code Description Possible Cause
200 OK Request successful
400 Bad Request Invalid IP address format
500 Internal Server Error Server error

Usage Monitoring Best Practices

For Application Developers

  1. Monitor Proactively: Check usage regularly before hitting limits
  2. Display to Users: Show usage statistics in dashboards
  3. Set Warnings: Alert users at 80% and 90% of limits
  4. 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/limits/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/limits/usage/ip' \
  -H 'accept: application/json'

# If status shows "rate_limited", implement backoff strategy

Integration with Limits

Usage tracking works in conjunction with the Limits API:

Limits Endpoints Purpose Usage Endpoints Purpose
GET /limits Get tier limits GET /limits/usage Get current usage
GET /limits/{service} Get service limits Compare usage vs limits Calculate percentage
GET /limits/ip Get IP rate limits GET /limits/usage/ip Get IP usage

Example: Complete Limit Check

# 1. Get current usage
curl 'https://apis.threatwinds.com/api/billing/v1/limits/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"