BetterIAM
Server API

quotas

API usage plans: throttles (a token bucket of ratePerSecond holding at most burst) and period limits (per minute, hour, day, week or month) on a meter you name…

API usage plans: throttles (a token bucket of ratePerSecond holding at most burst) and period limits (per minute, hour, day, week or month) on a meter you name, such as requests or exports. Plans apply to API keys, agents, identities and groups, or to everyone in the tenant as the meter's default. Applications count use with iam.quotas.consume / enforce (the request's credential) or consumeFor (a subject your code identified), and callers read what is left with status. Counters are stored in the database, so every server instance agrees. The repository guide is docs/quotas.md.

Which plan applies

For each meter, the most specific plan wins: the API key the request presents, then the acting agent of a delegated session, the identity, one of its groups (highest priority, then name), and finally the tenant's default plan. A meter no plan covers is unlimited (plan: null). With scope: 'tenant' everyone the plan covers shares one set of counters; with scope: 'subject' each API key, agent or person has their own.

Methods12
Serveriam.api.quotas
Clientclient.quotas
HTTPPOST /api/iam/quotas/*
MethodWhat it doesAccess
assignAssigns a plan to an API key (subjectType: 'apiKey' with the key's credentialId), an identity, or a group, replacing the subject's plan for the same meter.Credential
consumeCounts cost (default 1) units of a meter for the caller's own session, or refuses without counting anything when the throttle or a period limit would be exceeded: allowed: false with reason (throttle or the period) and retryAfterMs (absent when the cost can never fit).Credential
createPlanDefines a plan for a meter with a throttle, limits, or both.Credential
deletePlanDeletes a plan with its assignments and counters.Credential
getPlanOne plan.Credential
listAssignmentsAssignments, optionally of one plan, with each subject's name (an API key's label).Credential
listPlansEvery plan of the tenant, by name, with how many subjects are assigned to each.Credential
resetStarts one subject's counters and throttle over (as usage names it), or every subject's when none is given.Credential
statusThe caller's own plan for a meter and what is left in each window, without counting.Credential
unassignRemoves a subject's plan for a meter; removed says whether there was one.Credential
updatePlanChanges a plan; fields left out keep their value, throttle: null and description: null clear them, and limits replaces the list. The meter cannot change. Windows in progress keep their counts under the new limits.Credential
usageEvery subject's use of a plan in the current windows, the most used first. Subjects are named identity:{id}, key:{credentialId}, or tenant for a tenant-scoped plan.Credential

assign

Assigns a plan to an API key (subjectType: 'apiKey' with the key's credentialId), an identity, or a group, replacing the subject's plan for the same meter.

POST/api/iam/quotas/assign
client.quotas.assign()Credential

Used inAPI quotas

  • Permission: iam:quotas:manage on iam/quotas/{plan}.
  • Audited as: quota:assign.
  • Errors: NOT_FOUND (404) for an unknown plan, a subject outside the tenant, a deleted identity, or a session that is not an API key; INVALID_INPUT for another subjectType.
Input

Prop

Type

Returns

A QuotaAssignmentView object:

Prop

Type

Example HTTP request

Only the required fields are shown; replace each <placeholder>. The response is { "data": … } on success or { "error": { "code", "message" } }.

curl -X POST "$IAM_URL/api/iam/quotas/assign" \
  -H "Authorization: Bearer $BETTER_IAM_TOKEN" \
  -H "Content-Type: application/json" \
  -H "X-Better-IAM: 1" \
  -d '{
  "tenantId": "<tenantId>",
  "plan": "<plan>",
  "subjectType": "identity",
  "subjectId": "<subjectId>"
}'
Signature
iam.api.quotas.assign(
  credential: CredentialInput,
  input: {
    tenantId: string;
    plan: string;
    subjectType: QuotaSubjectType;
    subjectId: string;
  },
): Promise<QuotaAssignmentView>

consume

Counts cost (default 1) units of a meter for the caller's own session, or refuses without counting anything when the throttle or a period limit would be exceeded: allowed: false with reason (throttle or the period) and retryAfterMs (absent when the cost can never fit).

POST/api/iam/quotas/consume
client.quotas.consume()Credential

Used inAPI quotas

  • Permission: None beyond a session of the tenant.
  • Audited as: quota:threshold when use first reaches an alert threshold in a window, and quota:exceeded (outcome deny) at a window's first refusal.
  • Errors: ACCESS_DENIED for a session of another tenant; INVALID_INPUT for a malformed meter or a cost outside 1 to 1,000,000,000.
Input

Prop

Type

Returns

A QuotaDecision object:

Prop

Type

Example HTTP request

Only the required fields are shown; replace each <placeholder>. The response is { "data": … } on success or { "error": { "code", "message" } }.

curl -X POST "$IAM_URL/api/iam/quotas/consume" \
  -H "Authorization: Bearer $BETTER_IAM_TOKEN" \
  -H "Content-Type: application/json" \
  -H "X-Better-IAM: 1" \
  -d '{
  "tenantId": "<tenantId>",
  "meter": "<meter>"
}'
Signature
iam.api.quotas.consume(
  credential: CredentialInput,
  input: { tenantId: string; meter: string; cost?: number },
): Promise<QuotaDecision>

createPlan

Defines a plan for a meter with a throttle, limits, or both.

POST/api/iam/quotas/createPlan
client.quotas.createPlan()Credential

Used inAPI quotas

  • Permission: iam:quotas:manage on iam/quotas/{name}.
  • Audited as: quota:plan-create.
  • Errors: CONFLICT (409) when the name is taken or the tenant already has a default plan for the meter; INVALID_INPUT without a throttle or limits, for two limits of one period, a limit below 1, an unknown period or time zone, a malformed name or meter, or more than five alertThresholds.

Day, week (Monday to Sunday) and month windows start at local midnight in timeZone (default UTC); minutes and hours are UTC. alertThresholds are percentages of each period limit recorded once per window as quota:threshold.

Input

Prop

Type

Returns

A QuotaPlanView object:

Prop

Type

Example HTTP request

Only the required fields are shown; replace each <placeholder>. The response is { "data": … } on success or { "error": { "code", "message" } }.

curl -X POST "$IAM_URL/api/iam/quotas/createPlan" \
  -H "Authorization: Bearer $BETTER_IAM_TOKEN" \
  -H "Content-Type: application/json" \
  -H "X-Better-IAM: 1" \
  -d '{
  "tenantId": "<tenantId>",
  "name": "<name>",
  "meter": "<meter>"
}'
Signature
iam.api.quotas.createPlan(
  credential: CredentialInput,
  input: {
    tenantId: string;
    name: string;
    meter: string;
    description?: string;
    throttle?: QuotaThrottle;
    limits?: QuotaLimit[];
    scope?: QuotaPlan['scope'];
    default?: boolean;
    priority?: number;
    timeZone?: string;
    alertThresholds?: number[];
  },
): Promise<QuotaPlanView>

deletePlan

Deletes a plan with its assignments and counters.

POST/api/iam/quotas/deletePlan
client.quotas.deletePlan()Credential
  • Permission: iam:quotas:manage on iam/quotas/{name}.
  • Audited as: quota:plan-delete, with how many assignments went.
Input

Prop

Type

Returns

Prop

Type

Example HTTP request

Only the required fields are shown; replace each <placeholder>. The response is { "data": … } on success or { "error": { "code", "message" } }.

curl -X POST "$IAM_URL/api/iam/quotas/deletePlan" \
  -H "Authorization: Bearer $BETTER_IAM_TOKEN" \
  -H "Content-Type: application/json" \
  -H "X-Better-IAM: 1" \
  -d '{
  "tenantId": "<tenantId>",
  "name": "<name>"
}'
Signature
iam.api.quotas.deletePlan(
  credential: CredentialInput,
  input: { tenantId: string; name: string },
): Promise<{ deleted: true; assignments: number }>

getPlan

One plan.

POST/api/iam/quotas/getPlan
client.quotas.getPlan()Credential
  • Permission: iam:quotas:read on iam/quotas/{name}.
  • Errors: NOT_FOUND (404).
Input

Prop

Type

Returns

A QuotaPlanView object:

Prop

Type

Example HTTP request

Only the required fields are shown; replace each <placeholder>. The response is { "data": … } on success or { "error": { "code", "message" } }.

curl -X POST "$IAM_URL/api/iam/quotas/getPlan" \
  -H "Authorization: Bearer $BETTER_IAM_TOKEN" \
  -H "Content-Type: application/json" \
  -H "X-Better-IAM: 1" \
  -d '{
  "tenantId": "<tenantId>",
  "name": "<name>"
}'
Signature
iam.api.quotas.getPlan(
  credential: CredentialInput,
  input: { tenantId: string; name: string },
): Promise<QuotaPlanView>

listAssignments

Assignments, optionally of one plan, with each subject's name (an API key's label).

POST/api/iam/quotas/listAssignments
client.quotas.listAssignments()Credential
  • Permission: iam:quotas:read on iam/quotas.
Input

Prop

Type

Returns

An array of QuotaAssignmentView.

Prop

Type

Example HTTP request

Only the required fields are shown; replace each <placeholder>. The response is { "data": … } on success or { "error": { "code", "message" } }.

curl -X POST "$IAM_URL/api/iam/quotas/listAssignments" \
  -H "Authorization: Bearer $BETTER_IAM_TOKEN" \
  -H "Content-Type: application/json" \
  -H "X-Better-IAM: 1" \
  -d '{
  "tenantId": "<tenantId>"
}'
Signature
iam.api.quotas.listAssignments(
  credential: CredentialInput,
  input: { tenantId: string; plan?: string },
): Promise<QuotaAssignmentView[]>

listPlans

Every plan of the tenant, by name, with how many subjects are assigned to each.

POST/api/iam/quotas/listPlans
client.quotas.listPlans()Credential
  • Permission: iam:quotas:read on iam/quotas.
Input

Prop

Type

Returns

An array of QuotaPlanView.

Prop

Type

Example HTTP request

Only the required fields are shown; replace each <placeholder>. The response is { "data": … } on success or { "error": { "code", "message" } }.

curl -X POST "$IAM_URL/api/iam/quotas/listPlans" \
  -H "Authorization: Bearer $BETTER_IAM_TOKEN" \
  -H "Content-Type: application/json" \
  -H "X-Better-IAM: 1" \
  -d '{
  "tenantId": "<tenantId>"
}'
Signature
iam.api.quotas.listPlans(
  credential: CredentialInput,
  input: { tenantId: string },
): Promise<QuotaPlanView[]>

reset

Starts one subject's counters and throttle over (as usage names it), or every subject's when none is given.

POST/api/iam/quotas/reset
client.quotas.reset()Credential
  • Permission: iam:quotas:manage on iam/quotas/{plan}.
  • Audited as: quota:reset, with how many counters went.
Input

Prop

Type

Returns

Prop

Type

Example HTTP request

Only the required fields are shown; replace each <placeholder>. The response is { "data": … } on success or { "error": { "code", "message" } }.

curl -X POST "$IAM_URL/api/iam/quotas/reset" \
  -H "Authorization: Bearer $BETTER_IAM_TOKEN" \
  -H "Content-Type: application/json" \
  -H "X-Better-IAM: 1" \
  -d '{
  "tenantId": "<tenantId>",
  "plan": "<plan>"
}'
Signature
iam.api.quotas.reset(
  credential: CredentialInput,
  input: { tenantId: string; plan: string; subject?: string },
): Promise<{ reset: number }>

status

The caller's own plan for a meter and what is left in each window, without counting.

POST/api/iam/quotas/status
client.quotas.status()Credential

Used inAPI quotas

  • Permission: None beyond a session of the tenant.
  • Audited as: Not audited.
  • Errors: ACCESS_DENIED for a session of another tenant.
Input

Prop

Type

Returns

A QuotaDecision object:

Prop

Type

Example HTTP request

Only the required fields are shown; replace each <placeholder>. The response is { "data": … } on success or { "error": { "code", "message" } }.

curl -X POST "$IAM_URL/api/iam/quotas/status" \
  -H "Authorization: Bearer $BETTER_IAM_TOKEN" \
  -H "Content-Type: application/json" \
  -H "X-Better-IAM: 1" \
  -d '{
  "tenantId": "<tenantId>",
  "meter": "<meter>"
}'
Signature
iam.api.quotas.status(
  credential: CredentialInput,
  input: { tenantId: string; meter: string },
): Promise<QuotaDecision>

unassign

Removes a subject's plan for a meter; removed says whether there was one.

POST/api/iam/quotas/unassign
client.quotas.unassign()Credential
  • Permission: iam:quotas:manage on iam/quotas.
  • Audited as: quota:unassign when something was removed.
Input

Prop

Type

Returns

Prop

Type

Example HTTP request

Only the required fields are shown; replace each <placeholder>. The response is { "data": … } on success or { "error": { "code", "message" } }.

curl -X POST "$IAM_URL/api/iam/quotas/unassign" \
  -H "Authorization: Bearer $BETTER_IAM_TOKEN" \
  -H "Content-Type: application/json" \
  -H "X-Better-IAM: 1" \
  -d '{
  "tenantId": "<tenantId>",
  "meter": "<meter>",
  "subjectType": "identity",
  "subjectId": "<subjectId>"
}'
Signature
iam.api.quotas.unassign(
  credential: CredentialInput,
  input: {
    tenantId: string;
    meter: string;
    subjectType: QuotaSubjectType;
    subjectId: string;
  },
): Promise<{ removed: boolean }>

updatePlan

Changes a plan; fields left out keep their value, throttle: null and description: null clear them, and limits replaces the list. The meter cannot change. Windows in progress keep their counts under the new limits.

POST/api/iam/quotas/updatePlan
client.quotas.updatePlan()Credential
  • Permission: iam:quotas:manage on iam/quotas/{name}.
  • Audited as: quota:plan-update.
  • Errors: NOT_FOUND (404); CONFLICT (409) when making it the default and another plan already is; INVALID_INPUT as for createPlan.
Input

Prop

Type

Returns

A QuotaPlanView object:

Prop

Type

Example HTTP request

Only the required fields are shown; replace each <placeholder>. The response is { "data": … } on success or { "error": { "code", "message" } }.

curl -X POST "$IAM_URL/api/iam/quotas/updatePlan" \
  -H "Authorization: Bearer $BETTER_IAM_TOKEN" \
  -H "Content-Type: application/json" \
  -H "X-Better-IAM: 1" \
  -d '{
  "tenantId": "<tenantId>",
  "name": "<name>"
}'
Signature
iam.api.quotas.updatePlan(
  credential: CredentialInput,
  input: {
    tenantId: string;
    name: string;
    description?: string | null;
    throttle?: QuotaThrottle | null;
    limits?: QuotaLimit[];
    scope?: QuotaPlan['scope'];
    default?: boolean;
    priority?: number;
    timeZone?: string;
    alertThresholds?: number[];
  },
): Promise<QuotaPlanView>

usage

Every subject's use of a plan in the current windows, the most used first. Subjects are named identity:{id}, key:{credentialId}, or tenant for a tenant-scoped plan.

POST/api/iam/quotas/usage
client.quotas.usage()Credential
  • Permission: iam:quotas:read on iam/quotas/{plan}.
Input

Prop

Type

Returns

An array of QuotaUsageView.

Prop

Type

Example HTTP request

Only the required fields are shown; replace each <placeholder>. The response is { "data": … } on success or { "error": { "code", "message" } }.

curl -X POST "$IAM_URL/api/iam/quotas/usage" \
  -H "Authorization: Bearer $BETTER_IAM_TOKEN" \
  -H "Content-Type: application/json" \
  -H "X-Better-IAM: 1" \
  -d '{
  "tenantId": "<tenantId>",
  "plan": "<plan>"
}'
Signature
iam.api.quotas.usage(
  credential: CredentialInput,
  input: { tenantId: string; plan: string },
): Promise<QuotaUsageView[]>

Was this page helpful?

Better IAM is created by Sean Filimon

Last updated

On this page