Skip to content

Create Usage Limit Plan

Create a reusable Plan and its first draft. Empty rules are allowed until publication.

POST /v1/projects/:project_id/usage-limit-plans

Requires usage_control:write. project_id is the owning project; id (when present) is its Plan ID. The API key supplies the tenant scope. Resources outside that tenant/project are not returned.

There are no query parameters.

{
"name": "pro",
"title": "Pro daily budget",
"description": "Default allowance",
"rules": [
{
"currency": "USD",
"measure": "amount",
"selector_type": "all",
"period": "day",
"limit_amount": "100",
"timezone": "UTC",
"action": "block",
"webhook_event": "usage_limit.exceeded"
}
]
}
Field Contract
name Required only on creation; the Plan name cannot be edited.
title Required, nonempty.
description Optional; omission or an empty string clears it.
rules Complete rule array; an empty array can be saved but cannot be published.

Each rule has this contract:

Field Contract
limit_key Omit for a new rule; the server generates it. Echo the original value when editing an existing rule to preserve continuity.
measure Required: amount or quantity.
selector_type Required: all, unit, or metric.
selector_value Required for unit or metric.
metric_scope Optional measurement scope.
currency Required for amount, normalized to uppercase; optional for quantity.
period Required: hour, day, week, month, lifetime, or an anchored duration of at least an hour such as 5h or 2 day. Minutes are unsupported.
limit_amount Required positive decimal amount/quantity; a string is recommended.
timezone Optional IANA timezone for the period.
action Optional limit action, for example block.
webhook_event Optional limit event name.

Do not submit system-managed root IDs, revision, status, tenant/project IDs, or rule id, plan_version_id, or timestamps.

HTTP 201.

{
"id": "ulpv_pro_v1",
"tenant_id": "t_001",
"project_id": "proj_gateway",
"plan_id": "ulp_pro",
"name": "pro",
"revision": 1,
"status": "draft",
"title": "Pro daily budget",
"description": "Default allowance",
"created_at": 1784889000,
"updated_at": 1789722000,
"rules": [
{
"id": "ulpr_budget_v1",
"tenant_id": "t_001",
"project_id": "proj_gateway",
"plan_version_id": "ulpv_pro_v1",
"limit_key": "ulrk_budget",
"currency": "USD",
"measure": "amount",
"selector_type": "all",
"period": "day",
"limit_amount": "100",
"timezone": "UTC",
"action": "block",
"webhook_event": "usage_limit.exceeded",
"created_at": 1784890000,
"updated_at": 1784890000
}
],
"referenced_by_count": 0
}

Version fields: id (original version ID), tenant_id, project_id, plan_id, name, revision, status, title, optional description, original published_at (omitted for drafts), created_at, Plan updated_at, rules, and referenced_by_count. Detail/list reads can also include has_unpublished_changes and live_revision, derived from actual draft status. Reference counts are populated by detail/list reads; history and mutation responses do not calculate them. Each rule returns the business fields above plus its original id, plan_version_id, ownership, and creation/update timestamps. Empty optional fields may be omitted; timestamps are Unix seconds.

Missing/out-of-scope resources return 404, invalid inputs/lifecycle transitions 400, name/revision conflicts 409, insufficient permission 403, and internal/infrastructure failures 5xx. Failed write transactions leave Plan/history/rules unchanged; cache errors explicitly marked committed are the exception.

Lifecycle and window behavior · Get Usage Limit Plan · Update Usage Limit Plan Draft · Publish Usage Limit Plan · Roll Back Usage Limit Plan · List Usage Limit Plan Revisions