Skip to main content

Usage

View your month-to-date API usage and historical hourly rollups.

Written by Support

Two endpoints to see what your store has consumed and project what you'll need next month.

GET /v1/usage

Current calendar month, grouped by endpoint type.

Auth: platform key with usage:read.

Response 200

{
  "data": {
    "period": "2026-04",
    "tier":   "enterprise",
    "usage": {
      "request": { "total": 31, "billable": 0 },
      "signup":  { "total": 3,  "billable": 2 }
    },
    "limits": {
      "requests_per_month":  -1,
      "signups_per_month":   -1,
      "webhooks_per_month":  -1,
      "requests_per_minute": 600
    }
  }
}

Field reference

Field

Meaning

period

Always YYYY-MM — the current month in Africa/Algiers time (UTC+01:00, no DST). Totals are month-to-date, counted from the 1st at 00:00.

tier

Your current rate-limit tier — always enterprise (the API is Enterprise-only).

usage.<group>.total

All requests in that group, including duplicates / rejections.

usage.<group>.billable

Only counted requests (e.g. duplicate signups don't bill).

limits

The effective limits — tier_limits overridden by any per-store override. -1 means unlimited.

usage is sparse — only groups with recorded activity this calendar month appear (in practice request, plus signup / event for public-key traffic). If the store has no usage at all, usage serialises as an empty JSON array [], not an object. Default missing groups to zero client-side and tolerate []; a strictly-typed deserialiser will otherwise fail.

Endpoint groups

Group

What counts

request

Every call that passed key authentication, counted before the request is processed — so 4xx/5xx responses and scope rejections count too. Always billable: 0. GET /v1/ping is unauthenticated and never counted, and cache hits (X-Cache: HIT) are not counted either.

signup

Each /v1/signups call. Duplicates are counted in total but not billable.

event

Each /v1/events call. Only newly-recorded events are counted — duplicates (same store + nonce) are dropped and appear in neither total nor billable. This differs from signup.

webhook

Reserved. Outbound deliveries are not metered at v1, so this group never appears in the response.

GET /v1/usage/history

Hourly rollups over a date range — useful for charts and trend analysis.

Auth: platform key with usage:read.

Query parameters

Param

Type

Default

Notes

from

ISO date

7 days ago

Inclusive

to

ISO date

now

Exclusive

Range cap: 90 days. from is inclusive and to is exclusive, and both are floored to the top of the hour for the query — the from / to echoed in the response are your inputs as parsed, unfloored. Common date and date-time formats are accepted (2026-04-01, 2026-04-01T12:00:00Z, -7 days, …); an unparseable value or to earlier than from returns 400 bad_request ("from/to must be valid date strings, to >= from"), and a range over 90 days returns 400 ("range too large (max 90 days)").

period_hour buckets are whole hours, stamped in Africa/Algiers time (UTC+01:00) at the moment each call is counted.

Errors

HTTP

Code

Cause

400

bad_request

"from/to must be valid date strings, to >= from"

400

bad_request

"range too large (max 90 days)"

403

forbidden

"Missing scope: usage:read"

usage:read is one of the few scopes v1 actually enforces. It is granted by default on every minted platform key, so it only bites keys that support issued with a reduced scope set.

Request

curl 'https://api.dzbuild.app/v1/usage/history?from=2026-04-01&to=2026-05-01' \
  -H "Authorization: Bearer $DZ_KEY"

Response 200

{
  "data": {
    "from": "2026-04-01T00:00:00+01:00",
    "to":   "2026-05-01T00:00:00+01:00",
    "rows": [
      { "period_hour": "2026-04-30 19:00:00", "endpoint_group": "request", "count": 26, "billable_count": 0 },
      { "period_hour": "2026-04-30 20:00:00", "endpoint_group": "request", "count": 5,  "billable_count": 0 },
      { "period_hour": "2026-04-30 20:00:00", "endpoint_group": "signup",  "count": 3,  "billable_count": 2 }
    ]
  }
}

Rows are returned in ascending period_hour order. Hours with zero usage in any group are omitted (sparse).

Plotting tips

  • Daily aggregates: group rows by the first 10 characters of period_hour (the date prefix).

  • Stacked area: group by endpoint_group, then by hour for the X-axis.

  • Quota burn rate: divide signup.billable_count cumulative by the elapsed fraction of the month, project to month-end.

A simple Python example:

import collections, datetime, requests, osr = requests.get('https://api.dzbuild.app/v1/usage/history',
    params={'from': '2026-04-01', 'to': '2026-05-01'},
    headers={'Authorization': f"Bearer {os.environ['DZ_KEY']}"})
rows = r.json()['data']['rows']by_day = collections.defaultdict(lambda: collections.Counter())
for row in rows:
    day = row['period_hour'][:10]
    by_day[day][row['endpoint_group']] += row['count']for day, counts in sorted(by_day.items()):
    print(day, dict(counts))
Did this answer your question?