Skip to content

Get usage

GET https://api.noptcha.com/v1/usage

Native API (v1). Guide. Operation ID getUsage.

Task counts and amounts per hour or day, by task type or by key (needs usage:read). Amounts are what was actually taken from the balance, after corrections. Only periods with data are returned (no zero rows), ordered by time and then type or key; the rows always add up to totals.

from is rounded down and to up to period boundaries (to is exclusive). Without to: the end of the current period; without from: 24 hours (hourly) or 30 days (daily) before to. Ranges: hourly at most 7 days, daily at most 92 days; from not before 2026-01-01 and not in the future. group_by=key covers the last 90 days only: an earlier from is moved to the first available day (the response shows the effective from), a range entirely before that is 400. Results over 10,000 rows (or over the query's resource limits) are 400 instead of being truncated; narrow the range or use granularity=day. Each parameter may be given once.

Rate limit per organization: 20 per minute, bursts of 5 (test keys counted separately), with RateLimit-Policy: "usage";q=20;w=60. 503 when usage is temporarily unavailable (or only the per-key breakdown is, then with Retry-After: 30; group_by=type still works) and when too many usage queries are running (Retry-After: 5).

Test keys get an empty report with "sandbox": true (parameters are still checked and rate limited).

Request

Authentication: Authorization: Bearer <key> (Keys).

ParameterInDescription
from
optional
query

Start, RFC 3339 or YYYY-MM-DD (UTC).

string · e.g. 2026-11-01
to
optional
query

End (exclusive), RFC 3339 or YYYY-MM-DD (UTC).

string
granularity
optional
querystring
group_by
optional
querystring

Responses

200

Usage.

Headers: Noptcha-Request-Id, RateLimit (optional), RateLimit-Policy (optional).

Content: application/json

FieldTypeDescription
currency
required
const "USD"
data
required
array of UsageRow
data.[item]
optional
object

One period and type (group_by=type) or key (group_by=key).

data.[item].amount
required
string

cash + promo.

pattern: ^-?[0-9]+\.[0-9]{6}$
data.[item].billed
required
integer

Tasks charged.

data.[item].cash
required
string

Decimal US dollars with 6 places.

pattern: ^-?[0-9]+\.[0-9]{6}$
data.[item].promo
required
string

Decimal US dollars with 6 places.

pattern: ^-?[0-9]+\.[0-9]{6}$
data.[item].unbilled
required
integer

Tasks not charged (unsolvable, timed out, cancelled).

data.[item].end
required
stringformat: date-time · pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}Z$
data.[item].key
optional
one of | null

With group_by=key. null is the unattributed remainder (the difference between the ledger and the per-key task log; usually zero, briefly non-zero while events are being processed).

one of: object
data.[item].start
required
stringformat: date-time · pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}Z$
data.[item].type
optional
string

With group_by=type.

data.[item].variant
optional
string

With group_by=type.

from
required
string

Effective start (after rounding and the 90-day limit of group_by=key).

format: date-time · pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}Z$
granularity
required
enumone of "hour", "day"
group_by
required
enumone of "type", "key"
object
required
const "usage"
sandbox
required
boolean

True for test keys (always an empty report).

to
required
string

Effective end (exclusive).

format: date-time · pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}Z$
totals
required
object
totals.amount
required
string

cash + promo.

pattern: ^-?[0-9]+\.[0-9]{6}$
totals.billed
required
integer

Tasks charged.

totals.cash
required
string

Decimal US dollars with 6 places.

pattern: ^-?[0-9]+\.[0-9]{6}$
totals.promo
required
string

Decimal US dollars with 6 places.

pattern: ^-?[0-9]+\.[0-9]{6}$
totals.unbilled
required
integer

Tasks not charged (unsolvable, timed out, cancelled).

400

invalid_request: the body is not valid JSON or misses a field, a parameter is wrong, callback_url is not a string, the result would be too large (usage). unsupported_type: the task type does not exist or is not available.

Headers: Noptcha-Request-Id, RateLimit (optional), RateLimit-Policy (optional).

Content: application/problem+json

FieldTypeDescription
code
required
string

Machine-readable error code (see the table).

detail
optional
string

Human-readable explanation of this occurrence.

request_id
required
string

Same as the Noptcha-Request-Id header.

status
required
integer

The HTTP status code.

title
required
string
type
required
stringformat: uri

401

unauthorized: the key is malformed, unknown, revoked or expired.

Headers: Noptcha-Request-Id, RateLimit (optional), RateLimit-Policy (optional).

Content: application/problem+json

FieldTypeDescription
code
required
string

Machine-readable error code (see the table).

detail
optional
string

Human-readable explanation of this occurrence.

request_id
required
string

Same as the Noptcha-Request-Id header.

status
required
integer

The HTTP status code.

title
required
string
type
required
stringformat: uri

403

forbidden: the key lacks the scope this endpoint needs, the client IP is not in the key's allowlist, the key may not use this task type, or the organization is suspended (detail says which). Also returned, without detail, when the request did not pass through our edge network.

Headers: Noptcha-Request-Id, RateLimit (optional), RateLimit-Policy (optional).

Content: application/problem+json

FieldTypeDescription
code
required
string

Machine-readable error code (see the table).

detail
optional
string

Human-readable explanation of this occurrence.

request_id
required
string

Same as the Noptcha-Request-Id header.

status
required
integer

The HTTP status code.

title
required
string
type
required
stringformat: uri

413

request_too_large: the body exceeds the limit (1 MB for image types, 64 KB otherwise). Any request with a body over 1 MB gets this, GET requests included.

Headers: Noptcha-Request-Id, RateLimit (optional), RateLimit-Policy (optional).

Content: application/problem+json

FieldTypeDescription
code
required
string

Machine-readable error code (see the table).

detail
optional
string

Human-readable explanation of this occurrence.

request_id
required
string

Same as the Noptcha-Request-Id header.

status
required
integer

The HTTP status code.

title
required
string
type
required
stringformat: uri

429

rate_limited: too many tasks created per second by this key, the same task polled too often, the sandbox's per-organization rate, usage queried too often, the catalog fetched too often from this IP, or this IP sent too many invalid keys. concurrency_limited: the organization has too many tasks in flight for this captcha family (or, with a test key, too many sandbox tasks still processing). Wait Retry-After seconds.

Headers: Noptcha-Request-Id, RateLimit (optional), RateLimit-Policy (optional), Retry-After.

Content: application/problem+json

FieldTypeDescription
code
required
string

Machine-readable error code (see the table).

detail
optional
string

Human-readable explanation of this occurrence.

request_id
required
string

Same as the Noptcha-Request-Id header.

status
required
integer

The HTTP status code.

title
required
string
type
required
stringformat: uri

500

internal: an error on our side.

Headers: Noptcha-Request-Id, RateLimit (optional), RateLimit-Policy (optional).

Content: application/problem+json

FieldTypeDescription
code
required
string

Machine-readable error code (see the table).

detail
optional
string

Human-readable explanation of this occurrence.

request_id
required
string

Same as the Noptcha-Request-Id header.

status
required
integer

The HTTP status code.

title
required
string
type
required
stringformat: uri

503

service_unavailable: no capacity right now (all solvers busy or failing, the gateway is overloaded, a dependency is unavailable). For POST /v1/tasks nothing was created or charged. Wait Retry-After.

Headers: Noptcha-Request-Id, RateLimit (optional), RateLimit-Policy (optional), Retry-After.

Content: application/problem+json

FieldTypeDescription
code
required
string

Machine-readable error code (see the table).

detail
optional
string

Human-readable explanation of this occurrence.

request_id
required
string

Same as the Noptcha-Request-Id header.

status
required
integer

The HTTP status code.

title
required
string
type
required
stringformat: uri

Header descriptions and every schema: Schemas. Machine-readable: openapi.json, openapi.yaml.