Skip to content

Errors

Every non-2xx response carries { "error": "<code>" }. The tables give the HTTP status, the meaning, and the recommended reaction. Definitive verdicts are server decisions about the license itself; act on them. Transient ones are about the network or load; keep the customer working and retry.

error Status Meaning What to do
invalid-key 404 No such key. Ask the customer to re-enter it.
revoked 403 The license was revoked (refund, chargeback, support action). On /v1/demo: an operator revoked this machine’s demo. Drop the stored token and key now. Do not retry.
expired 403 The license is past its end date and grace window. Drop the token; point the customer to renew.
blocked 403 The license’s customer is on the merchant’s block list. Treat exactly like revoked.
not-activated 404 /v1/heartbeat for a device that never activated this key. Clear the stored token and ask the customer to activate.
demo-already-used 403 This machine’s demo has run out. Show the purchase prompt.
product-mismatch 403 The key is for a different product than the productId sent. A configuration bug on your side, or the wrong key; check the product ID.
product-id-required 403 The product has strict binding on and the request omitted productId. Send productId on activate and heartbeat.
product-not-found 403 / 404 The productId is unknown (404 on /v1/demo, 403 elsewhere). Check the product ID against the Integration page.
merchant-inactive 403 The merchant’s Waveform subscription is not active. New devices are refused; already-registered devices can still re-activate. Tell the customer to contact the software vendor.
error Status Meaning What to do
seat-limit 409 Device cap reached. The body lists devices. Offer to deactivate one, then retry.
activation-limit 409 The distinct-machine budget for the rolling window is used up. Body: distinctMachines, windowDays. Do not offer a swap; it cannot succeed. Say “contact support”.
support-limit 409 A remote device release exceeded the budget (deactivate policy). Body: used, limit, windowDays. Show the numbers and tell the customer to contact support.
session-limit 409 Online products: too many concurrent sessions. Body: sessions, max. Offer to end another session, or deny.
rate-limited 429 Too many requests from this IP. Carries a Retry-After header. Back off for Retry-After seconds. Cache validate results.
(usage) allowed: false 429 /v1/usage: the period’s metered limit would be exceeded. Show an upgrade prompt. The counter was not incremented.
error Status Meaning
bad-request 400 A required field is missing, empty, or too long.

A connection failure, a timeout, or a 5xx is not a verdict. The SDK reports these as error: "network". Keep the customer working, keep the stored token, and retry later. The hosted API can cold-start after idle, so use generous timeouts and retry (see Rate limits and reliability).

These come from verifying a token locally, not from the API. See Token format for what triggers each.

reason Meaning
malformed-token, malformed-payload The token is not in the expected format.
bad-signature The signature does not verify: forged, tampered, or signed by a different key.
unknown-key The token names a signing key your build does not hold. Ship a build that accepts the new key, or re-activate.
alg-mismatch, unsupported-version Not Ed25519 / schema version 1. Downgrade attempt.
invalid-claims The signature is good but a claim has the wrong type or an out-of-range value.
product-mismatch A token for a different product.
fingerprint-mismatch, fingerprint-required The token is bound to another machine, or no fingerprint was supplied (fail closed).
not-yet-valid iat is more than five minutes in the future.
expired Past the lease, license end, and grace.
online-check-required The SDK’s offline gate: the app ran longer than maxOfflineDays without a check-in.