---
title: "Read the hourly usage breakdown with rate-limit utilization"
method: GET
path: "/v1/usage/hourly"
tags: ["usage"]
---

# Read the hourly usage breakdown with rate-limit utilization

`GET /v1/usage/hourly`

## Request

- Base URL: `https://api.skanqrcode.com`
- URL: `https://api.skanqrcode.com/v1/usage/hourly`
- Auth: HTTP bearer

Returns hour-by-hour usage for one month (default: the current month, UTC) so you can see when traffic happened and how close it came to the per-minute rate limit. Each hour reports `capacityUsedPercent` against `hourlyCapacity` (the plan's requests-per-minute limit times 60) and how many requests were blocked in that hour for exceeding the per-minute limit or the monthly quota. `hourlyCapacity` is a reading aid: no hourly quota exists, limits are enforced per minute.

## Query parameters

- `month` string: Calendar month (UTC) as YYYY-MM. Defaults to the current month.

## Response `200`

Hourly usage for the month.

- HourlyUsageResponse
  - `tenantId` string, required
  - `month` string, required
  - `rpmLimit` integer, required: The plan's requests-per-minute limit.
  - `hourlyCapacity` integer, required: rpmLimit * 60: the most requests one hour can hold at the per-minute limit. A reading aid only, not a separate quota; limits are enforced per minute.
  - `hours` HourlyUsageEntry[], required
    - `hour` string, required: Start of the hour (UTC), RFC 3339.
    - `mode` 'url' | 'ip', required
    - `total` integer, required: Requests served in this hour.
    - `capacityUsedPercent` number, required: The hour's requests across both modes (url and ip) / hourlyCapacity * 100, one decimal: the rate limit counts both, so an hour with url and ip rows shows the same value on each. Near 100 means this hour ran at the per-minute rate limit.
    - `blockedRpm` integer, required: Requests blocked in this hour for exceeding the per-minute rate limit.
    - `blockedQuota` integer, required: Requests blocked in this hour for exceeding the monthly quota.
    - `malicious` integer, required
    - `suspicious` integer, required
    - `notMalicious` integer, required
    - `cached` integer, required

## Other responses

- `400`: The request failed validation (malformed JSON, bad field, unparseable target, or a body over 8 KB).
- `401`: The API key is missing, malformed, unknown or revoked.
- `402`: The tenant is suspended for non-payment.
- `403`: The request is not allowed: the key lacks the required scope or the account has been blocked (`forbidden`), or the plan does not include the feature (`plan_feature_unavailable`).
- `429`: The per-minute rate limit (`rate_limited`) or the monthly quota (`quota_exceeded`) was exceeded. Blocked requests are not billed. Back off for `Retry-After` seconds.
- `500`: Unexpected failure. Never contains stack traces, internal hostnames or upstream error bodies.
- `503`: Authentication is temporarily unavailable for a key that has not been seen recently. Retry shortly.

---

[API](https://skmtc.dev/skanqrcode/apis/skanqrcode-api.md) · [All operations](https://skmtc.dev/skanqrcode/apis/skanqrcode-api/llms.txt) · [OpenAPI document](https://skmtc.dev/skanqrcode/apis/skanqrcode-api/revisions/f307ade24b00?raw)
