Core concepts
Five ideas explain the whole API: the resource hierarchy, consumer-level credits, how a credit pool behaves, the lifecycle of each resource, and how state stays consistent across regions.
Resource hierarchy
A customer (you) can own many projects; each project is an isolated workspace with its own root key. Inside a project you create APIs (the services you meter), plans (optional credit templates), and consumers (your customers). Each consumer owns one or more keys.
ProjectYour workspace. Addressed by a rootKey; owns everything below it.
APIA service you meter. Keys can be scoped to specific APIs by apiId.
PlanA reusable bundle of credit limit + refill + overage + pricing.
ConsumerOne of your customers. Owns the credit pool. This is where billing lives.
KeyAn auth token your customer sends. Shares its consumer’s pool; no credits of its own.
Consumer-level credits
The single most important rule in ReqKey: credits live on the consumer, not the key. If a consumer has a 5,000-credit pool, then every key it owns — one or fifty — draws from that same 5,000. This prevents the classic billing leak where five keys silently multiply a plan into five separate quotas.
When you create a consumer, you choose one of three credit modes (in priority order):
1 · Direct
Pass a credits object. Highest priority.
{
"name": "Acme Corp",
"credits": {
"limit": 5000,
"shadowLimit": 500
}
}2 · From a plan
Pass a planId to inherit its credits.
{
"name": "Acme Corp",
"planId": "plan_enterprise"
}3 · Unlimited
Omit both. Validation never enforces a limit.
{
"name": "Internal Team"
}/consumer/update, or add credits without changing the limit via /key/recharge. Downgrading a plan? Send credits.used: 0 so remaining never goes negative.Credit mechanics
A consumer’s credit object is made of a few moving parts:
limitTotal pool size. remaining = limit − used.
usedCredits consumed so far. Deducted on each successful validation.
shadowLimitA soft threshold below the hard limit — fires low-credit warnings before the customer is cut off.
refillAuto top-up on an interval: { interval: "month", amount: 5000 }. Intervals: hour, day, week, month.
overageControlled spillover past the limit: { enabled: true, limit: 500 }.
expiresAtOptional millisecond timestamp after which the credits expire.
On /key/validate the requested credit amount (default 1) is deducted from the pool. Non-integer amounts round down; credits: 0 does a free check with no deduction.
States & lifecycle
Consumers and keys move through a small set of states. A consumer’s status is a master switch: set a consumer to disabled and every one of its keys stops validating instantly — without touching each key — which is exactly what you want on a failed payment. Flip it back to active and they all resume.
activeNormal operation. Validates and deducts credits.
disabledBlocked from validation. On a consumer, this blocks all its keys.
pendingCreated but not yet enabled (keys only).
deletedSoft-deleted and recoverable — 7 days for consumers & keys, 30 days for APIs.
permanent: true. Restore a consumer (and its keys) by updating its status back to active within the recovery window. Hard delete is irreversible and also clears credit state.Regions & consistency
Validation runs in whichever region is closest to your servers, so answers come back in single-digit milliseconds. Behind it, ReqKey’s credit engine keeps every region’s balances in step through a global sync layer, and a reconciler heals any missed update within about a second. Recharges and limit changes propagate to all regions immediately — you never have to think about which region a key was created in.