Usage Query API

Last update:2025-08-28 13:55:16

The Object Storage Usage Query API provides programmatic access to detailed usage and billing data. It is designed to help partners and resellers automate consumption monitoring at the sub-account or individual bucket level.

Overview

The API can retrieve a wide range of usage metrics, including:

  • Storage Usage: Standard, Infrequent Access, and Archive storage classes.
  • Request Counts: Read and Write requests.
  • Data Retrieval: Traffic for Infrequent Access and Archive tiers.
  • Traffic and Bandwidth: CDN Origin Traffic, Egress Traffic, and Cross-Region Replication Traffic.
  • File Operations: Total count of file operations.

Endpoint Details

All requests should be sent to the production endpoint using the POST method.

  • Method: POST
  • Production URL: https://wos.cdnetworks.com/api/usage/statistics

Note: The production environment requires HTTPS. Requests made via HTTP will be redirected and may fail.

API Request Workflow

  1. Prerequisites: Generate a secret apikey and provide it to our support team for backend configuration.
  2. Authentication: Construct the required Date and Authorization headers for your request.
  3. Request: Build your JSON request body with the desired query parameters.
  4. Execution: Send a POST request to the production endpoint.
  5. Response: Parse the JSON response to get your usage data.

Authentication

The API uses a custom HMAC-SHA256 authentication scheme. Every API request must include Date and Authorization headers.

To use the API, you will need a username and an apikey. The apikey is a secret key that you generate. To enable API access, you must provide this key to our support team for backend configuration.

Authentication Steps

  1. Get the Current Time: Format the current time according to the RFC1123 specification (e.g., Thu, 21 Jul 2025 07:54:00 GMT). This string will be used in the Date header.
  2. Calculate the Signature: Generate an HMAC-SHA256 signature using your apikey as the key and the Date string as the message. The result must be Base64 encoded.
    • Formula: password = Base64(HMAC-SHA256(UTF-8(apikey), UTF-8(Date)))
  3. Construct the Authorization String:
    • Create a string in the format username:password.
    • Base64 encode the entire username:password string.
  4. Set the Authorization Header: The final header value is the string Basic followed by the Base64-encoded string from the previous step.
    • Format: Authorization: Basic <Base64(username:password)>

Data Units

The API returns usage data in specific units based on the metric type:

  • Storage Metrics (storageSize): Returned in Megabytes (MB), calculated using a base-1024 system (binary), where 1 MB = 1024 KB.
  • Traffic and Bandwidth Metrics (outTraffic, innerBandwidth, etc.): Returned in Megabytes (MB) and Megabits per second (Mbps) respectively, calculated using a base-1000 system (decimal).
  • Request and Operation Counts: Returned as integers.

Headers

Header Required Description
Authorization Yes The authentication token generated via the process described above.
Date Yes The current time in RFC1123 format (e.g., Thu, 21 Jul 2025 07:54:00 GMT).
Content-Type Yes Must be set to application/json.

Request Body Parameters

Parameter Required Description
startDate Yes The start date for the query period. Format: YYYY-MM-DD.
endDate Yes The end date for the query period. Format: YYYY-MM-DD.
statisticsType Yes The type of usage data to query. See the “Statistics Types” section below for valid options.
storageRegion No A comma-separated list of storage regions (e.g., CN,US,SG). If omitted, data from all regions is returned.
storageType No The storage class. Valid options: Standard, InfrequentAccess, Archive. Only one type can be specified at a time.
bucket No A comma-separated list of bucket names. If omitted, returns data for all accessible buckets.
isGroupByBucket No Set to 1 to get a per-bucket breakdown of usage data. Omit or set to 0 for a summarized total.
groupBy No The time granularity for the data. Options are day (default) or hour.
day: Returns a single value for each day. For storageSize, this is the daily peak value. For traffic and requests, this is the daily cumulative total.
hour: Returns an hourly breakdown for all metric types.
timeZone No Specifies the time zone for the query.
Supported Values: GMT-12 to GMT+12 (e.g., GMT+8, GMT-5).
Default: GMT+8.
Note: The response data will be calculated based on the specified time zone. Invalid values will result in a 400 error.
bandwidthAlgorithm No Specifies the bandwidth calculation method. This parameter is only effective when statisticsType is innerBandwidth or outBandwidth. Valid options:
ninetyFivePeak (default): 95th percentile peak.
avgPeak: Average of daily peak values.
fourthPeak: The 4th highest peak value.
firstPeak: The highest peak value.

Statistics Types (statisticsType)

Category statisticsType Value Description
Storage & Requests storageSize The amount of data stored in a bucket, categorized by storage class (Standard, Infrequent Access, Archive). Data is updated hourly. Note: Storage capacity is calculated using a base-1024 system (1 TB = 1024 GB).
numberOfRequests The number of API requests. This includes both read (GET, HEAD) and write (POST, PUT, DELETE) requests. Write requests also include actions like lifecycle deletions and storage class transitions. Both successful and failed requests are counted.
Data Retrieval & Deletion infrequentAccessRestore The amount of data retrieval traffic generated when accessing files in Infrequent Access storage.
infrequentDelete The amount of data deleted from Infrequent Access storage before the 30-day minimum storage period has been met.
archiveRestore The amount of data retrieval traffic generated after a file in Archive storage has been restored (unfrozen).
archiveDelete The amount of data deleted from Archive storage before the 60-day minimum storage period has been met.
Traffic & Bandwidth innerTraffic CDN Origin Traffic generated when a CDNetworks CDN product (e.g., Content Acceleration, Media Acceleration) uses Object Storage as an origin. Traffic is calculated using a base-1000 system (1 TB = 1000 GB).
outTraffic Egress traffic generated when data is downloaded from Object Storage to the public internet. Traffic is calculated using a base-1000 system (1 TB = 1000 GB).
innerBandwidth CDN Origin Bandwidth. The returned value depends on the bandwidthAlgorithm specified in the request. Defaults to the 95th percentile peak.
outBandwidth Egress bandwidth to the public internet. The returned value depends on the bandwidthAlgorithm specified in the request. Defaults to the 95th percentile peak.
crossRegionTraffic Egress traffic from the source bucket generated by cross-region replication. Traffic is calculated using a base-1000 system (1 TB = 1000 GB).
Operations fileOpNumber The total number of file operations performed.

Usage Examples

Example 1: Query Summarized Storage Usage

This request queries the total daily peak storage size for standard storage in the US and SG regions.

Request:

curl -X POST \
  https://wos.cdnetworks.com/api/usage/statistics \
  -H 'Authorization: Basic YOUR_AUTH_STRING' \
  -H 'Date: Thu, 21 Jul 2025 07:54:00 GMT' \
  -H 'Content-Type: application/json' \
  -d '{
    "startDate": "2025-07-10",
    "endDate": "2025-07-11",
    "storageRegion": "US,SG",
    "storageType": "Standard",
    "statisticsType": "storageSize"
}'

Response:

{
    "code": "200",
    "message": "OK",
    "statisticsType": "storageSize",
    "data": [
        {
            "dataTime": "2025-07-10",
            "storage": "5120"
        },
        {
            "dataTime": "2025-07-11",
            "storage": "5180"
        }
    ]
}

Note: The storage value represents the daily peak storage in Megabytes (MB).

Example 2: Query Request Counts Per Bucket

This request queries the daily read and write request counts, broken down by bucket.

Request:

curl -X POST \
  https://wos.cdnetworks.com/api/usage/statistics \
  -H 'Authorization: Basic YOUR_AUTH_STRING' \
  -H 'Date: Thu, 21 Jul 2025 07:54:00 GMT' \
  -H 'Content-Type: application/json' \
  -d '{
    "startDate": "2025-07-10",
    "endDate": "2025-07-11",
    "statisticsType": "numberOfRequests",
    "isGroupByBucket": "1"
}'

Response:

{
    "code": "200",
    "message": "OK",
    "statisticsType": "numberOfRequests",
    "data": [
        {
            "dataTime": "2025-07-10",
            "readRequests": {
                "bucket1": "15000",
                "bucket2": "25000"
            },
            "writeRequests": {
                "bucket1": "3000",
                "bucket2": "5000"
            }
        },
        {
            "dataTime": "2025-07-11",
            "readRequests": {
                "bucket1": "16500",
                "bucket2": "27500"
            },
            "writeRequests": {
                "bucket1": "3200",
                "bucket2": "5300"
            }
        }
    ]
}

Error Codes

Status Code Error Message Reason
400 Date In Headers Is Invalid The Date header is missing or incorrectly formatted.
400 StartDate Invalid, Valid Format Is YYYY-MM-DD The startDate parameter is incorrectly formatted.
400 StatisticsType Invalid The value for statisticsType is not an allowed option.
401 Authorization Invalid The Authorization header is missing, malformed, or incorrect.
403 StartDate Can't Be Greater Than EndDate The startDate is later than the endDate.
404 Bucket xx Not Found A specified bucket does not exist.

Python Code Example

import datetime
import hmac
import base64
import requests
import json
from hashlib import sha256

class UsageApiDemo:
    def get_gmt_date(self):
        """Generates the current time in RFC1123 format."""
        gmt_format = '%a, %d %b %Y %H:%M:%S GMT'
        return datetime.datetime.utcnow().strftime(gmt_format)

    def get_auth_string(self, username, apikey, date_str):
        """Generates the full 'Authorization' header value."""
        # Step 1: Create the HMAC-SHA256 signature.
        signature = hmac.new(apikey.encode('utf-8'), date_str.encode('utf-8'), sha256).digest()

        # Step 2: Base64 encode the signature to create the 'password'.
        password = base64.b64encode(signature).decode('utf-8')

        # Step 3: Create and Base64 encode the 'username:password' string.
        combined_str = f"{username}:{password}"
        encoded_auth_str = base64.b64encode(combined_str.encode('utf-8')).decode('utf-8')

        # Step 4: Prepend 'Basic ' to create the final header value.
        return f"Basic {encoded_auth_str}"

    def send_request(self, url, headers, body_params):
        """Sends a POST request to the API and prints the response."""
        try:
            response = requests.post(url, data=json.dumps(body_params), headers=headers)
            response.raise_for_status()  # Raises an exception for bad status codes

            print(f"Status Code: {response.status_code}")
            print("Response Body:")
            print(json.dumps(response.json(), indent=4))

        except requests.exceptions.RequestException as e:
            print(f"An error occurred: {e}")

if __name__ == '__main__':
    # --- User Configuration ---
    USERNAME = 'your_username'
    APIKEY = 'your_apikey'
    API_HOST = 'https://wos.cdnetworks.com'
    API_URI = '/api/usage/statistics'

    # --- Construct the Request ---
    api_demo = UsageApiDemo()

    # 1. Get Date
    date_header = api_demo.get_gmt_date()

    # 2. Get Authorization
    auth_header = api_demo.get_auth_string(USERNAME, APIKEY, date_header)

    # 3. Define Headers
    request_headers = {
        'Date': date_header,
        'Authorization': auth_header,
        'Content-Type': 'application/json'
    }

    # 4. Define Body
    request_body = {
        "startDate": "2025-04-01",
        "endDate": "2025-04-02",
        "statisticsType": "storageSize",
        "storageType": "Standard"
    }

    # 5. Send Request
    full_url = API_HOST + API_URI
    api_demo.send_request(full_url, request_headers, request_body)

Is the content of this document helpful to you?
Yes
I have suggestion
Submitted successfully! Thank you very much for your feedback, we will continue to strive to do better!