API7 Docs

Create Rate Limit Policy

POST /environments/{env_id}/rate_limits

POST /environments/{env_id}/rate_limits

Interactive request editor loads with JavaScript.

Authorization

BearerAdminToken
AuthorizationBearer <token>

Organization-scoped admin token. Read operations require a valid token, and write operations require a token with write permission.

In: header

Path Parameters

env_id*string

Environment ID that scopes the request.

Formatuuid

Request Body

application/json

Create-policy body — exactly one of two forms (mixing their fields is rejected):

  • classic: scope + scope_ref + window required, with at least one of max_requests / max_tokens;
  • conditional: limits required (at least one field), optionally with conditions, group_by and action.

schedules is form-neutral and accepted with either form.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "$AISIX_CP/environments/$ENV_ID/rate_limits" \  -H "Authorization: Bearer $AISIX_TOKEN" \  -H "Content-Type: application/json" \  -d '{    "name": "string"  }'

Created

{
  "rate_limit_policy": {
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "env_id": "3f917d0d-4dff-42f3-97c4-6a5455dfe8c2",
    "name": "string",
    "scope": "api_key",
    "scope_ref": "fd2cd345-6167-46ad-9a1c-db888c907bfa",
    "window": "second",
    "max_requests": 0,
    "max_tokens": 0,
    "schedules": [
      {
        "timezone": "string",
        "days_of_week": [
          "mon"
        ],
        "dates": [
          "string"
        ],
        "start_time": "string",
        "end_time": "string"
      }
    ],
    "conditions": [
      {
        "dimension": "team",
        "operator": "==",
        "negate": true,
        "value": "string",
        "logic": "and",
        "children": [
          {}
        ]
      }
    ],
    "group_by": [
      "team"
    ],
    "limits": {
      "rps": 1,
      "rpm": 1,
      "rph": 1,
      "rpd": 1,
      "tpm": 1,
      "tpd": 1,
      "concurrency": 1
    },
    "action": "reject",
    "created_at": "2019-08-24T14:15:22Z",
    "updated_at": "2019-08-24T14:15:22Z"
  },
  "warnings": [
    {
      "code": "field_ignored",
      "field": "string",
      "min_dp_version": "string",
      "affected_dp_count": 0,
      "affected_dp_versions": [
        "string"
      ]
    }
  ]
}
Complete operation details and schema variants

POST /environments/{env_id}/rate_limits

Create Rate Limit Policy

Create a rate limit policy in an environment. Each policy pins one scope and scope_ref pair, and a second policy for the same pair is rejected. At least one of max_requests or max_tokens must be set, and max_tokens is only accepted with window: minute or window: day — the gateway has no per-second or per-hour token counter.

Parameters

  • env_id (path, string, required): Environment ID that scopes the request.

Request body

Content type: application/json

  • name (string, required): Human-readable policy name.

  • scope (string, optional): Dimension the limit buckets on. api_key counts traffic per caller API key, model per model, team as one shared bucket for a team, and member per organization member. team_member references a team but gives every member of that team an independent quota of the same size. Fixed at creation.

  • scope_ref (string, optional): ID of the resource the policy applies to, matching scope. One policy per scope + scope_ref pair per environment. Classic form only.

  • window (string, optional): Length of the window the limits count against. Token caps (max_tokens) are only enforced for minute and day.

  • max_requests (integer, optional): Maximum number of requests allowed per window. Classic form only.

  • max_tokens (integer, optional): Maximum total tokens consumed per window. Only accepted with a minute or day window. Classic form only.

  • schedules (array, optional): Recurring suspension windows the policy starts with. Omitted = always enforced. Accepted on both policy forms.

  • schedules[].timezone (string, required): IANA timezone the wall-clock fields are interpreted in (e.g. Asia/Shanghai).

  • schedules[].days_of_week (array, optional): Weekly selector: the window opens on each listed day. Mutually exclusive with dates.

  • schedules[].dates (array, optional): Explicit calendar dates (YYYY-MM-DD, in timezone) the window opens on — for holidays and other irregular days. Mutually exclusive with days_of_week.

  • schedules[].start_time (string, required): Window start, HH:MM wall clock (inclusive).

  • schedules[].end_time (string, required): Window end, HH:MM wall clock (exclusive); 24:00 means end of day. Must differ from start_time; an end before the start crosses into the following day.

  • oneOf variant 1

  • oneOf variant 2

  • conditions (array, optional): Condition node tree (top-level nodes AND together; capped at 3 nesting levels and 16 leaves). Omitted or empty = match every request in the environment. Conditional form only.

  • conditions[].dimension (string, optional): Request dimension a condition leaf matches on. Identity dimensions carry resource UUIDs (team, member, api_key, model) and admit the equality/set operators; the string dimensions model_name (model display name) and provider additionally admit the regex operators.

model and model_name match the dispatched model and — when the caller addressed a routing group, semantic router, or ensemble — the addressed parent as well. Either identity satisfies a positive operator (==/in/regex): a group's own id selects every request routed through it, and a member's id selects that member whether called directly or through a group. ~= is true only when BOTH identities differ (preserving a ~= b = !(a == b)), and negate inverts the combined leaf result — so a negated in excludes a request when either identity is listed, and negate + ~= matches when either identity equals the value.

  • conditions[].operator (string, optional): Condition operator, mirroring lua-resty-expr tokens. ==/~= compare equal/not-equal, in tests list membership, ~~/~* are case-sensitive/insensitive regexes (string dimensions only). has, the numeric comparisons and ipmatch are reserved for future dimensions and rejected on every current one.

  • conditions[].negate (boolean, optional): Invert the leaf (lua-resty-expr !, e.g. negate + in = "not in") or the group (!AND / !OR). A request missing the leaf's dimension matches neither the condition nor its negation.

  • conditions[].value (object, optional): Comparison value: in takes 1–64 strings, every other operator a single string. Identity dimensions take resource UUIDs; model_name takes display-name strings or (for ~~/~*) a regex of at most 256 characters; provider takes provider catalog ids.

  • oneOf variant 1

  • oneOf variant 2

  • conditions[].logic (string, optional): Group combinator — lua-resty-expr AND / OR.

  • conditions[].children (array, optional): Nested condition nodes (group shape only).

  • group_by (array, optional): Dimensions the counters split on — each distinct value combination gets an independent bucket with the same limits. Omitted or empty = one shared bucket. A request missing a group_by dimension (e.g. a key with no team) is not subject to the policy. Conditional form only.

  • limits (object, optional): Conditional-form limits — the same 7-field shape as the inline model / API-key rate limits. At least one field must be set.

  • limits.rps (integer, optional): Requests per second.

  • limits.rpm (integer, optional): Requests per minute.

  • limits.rph (integer, optional): Requests per hour.

  • limits.rpd (integer, optional): Requests per day.

  • limits.tpm (integer, optional): Total tokens per minute.

  • limits.tpd (integer, optional): Total tokens per day.

  • limits.concurrency (integer, optional): Maximum concurrent in-flight requests. Capped at the data plane's 32-bit counter range.

  • action (string, optional): What the policy does past its limits. Only reject (HTTP 429) is available; the field reserves the enum for future actions.

Responses

  • 201: Created
  • rate_limit_policy (object, required): A rate limit rule the gateway enforces per request. Requests over the limit are rejected with HTTP 429 at the gateway.

A policy is exactly one of two forms, fixed at creation. The classic form targets one subject via scope + scope_ref with window + max_requests / max_tokens. The conditional form matches requests with a conditions tree, splits counters by group_by, and caps with the 7-field limits; its classic fields read as null. The conditional fields are only present on conditional-form policies.

  • rate_limit_policy.id (string, required): Rate limit policy ID.

  • rate_limit_policy.env_id (string, required): Environment ID that owns this policy.

  • rate_limit_policy.name (string, required): Human-readable policy name.

  • rate_limit_policy.scope (object, required):

  • allOf variant 1

  • rate_limit_policy.scope_ref (string, required): ID of the resource the policy applies to, matching scope: a caller API key ID, model ID, team ID, or member ID. team_member policies reference a team ID. Fixed at creation. null on conditional-form policies.

  • rate_limit_policy.window (object, required):

  • allOf variant 1

  • rate_limit_policy.max_requests (integer, required): Maximum number of requests allowed per window. null when the policy has no request cap.

  • rate_limit_policy.max_tokens (integer, required): Maximum total tokens consumed per window. null when the policy has no token cap.

  • rate_limit_policy.schedules (array, required): Recurring suspension windows: while the current time falls in any listed window the gateway skips this policy, and enforcement resumes automatically afterwards. Empty when the policy is always enforced. Present on both policy forms.

  • rate_limit_policy.schedules[].timezone (string, required): IANA timezone the wall-clock fields are interpreted in (e.g. Asia/Shanghai).

  • rate_limit_policy.schedules[].days_of_week (array, optional): Weekly selector: the window opens on each listed day. Mutually exclusive with dates.

  • rate_limit_policy.schedules[].dates (array, optional): Explicit calendar dates (YYYY-MM-DD, in timezone) the window opens on — for holidays and other irregular days. Mutually exclusive with days_of_week.

  • rate_limit_policy.schedules[].start_time (string, required): Window start, HH:MM wall clock (inclusive).

  • rate_limit_policy.schedules[].end_time (string, required): Window end, HH:MM wall clock (exclusive); 24:00 means end of day. Must differ from start_time; an end before the start crosses into the following day.

  • oneOf variant 1

  • oneOf variant 2

  • rate_limit_policy.conditions (array, optional): Condition node tree the request must satisfy (top-level nodes combine as AND; an empty list matches every request in the environment). Conditional form only.

  • rate_limit_policy.conditions[].dimension (string, optional): Request dimension a condition leaf matches on. Identity dimensions carry resource UUIDs (team, member, api_key, model) and admit the equality/set operators; the string dimensions model_name (model display name) and provider additionally admit the regex operators.

model and model_name match the dispatched model and — when the caller addressed a routing group, semantic router, or ensemble — the addressed parent as well. Either identity satisfies a positive operator (==/in/regex): a group's own id selects every request routed through it, and a member's id selects that member whether called directly or through a group. ~= is true only when BOTH identities differ (preserving a ~= b = !(a == b)), and negate inverts the combined leaf result — so a negated in excludes a request when either identity is listed, and negate + ~= matches when either identity equals the value.

  • rate_limit_policy.conditions[].operator (string, optional): Condition operator, mirroring lua-resty-expr tokens. ==/~= compare equal/not-equal, in tests list membership, ~~/~* are case-sensitive/insensitive regexes (string dimensions only). has, the numeric comparisons and ipmatch are reserved for future dimensions and rejected on every current one.

  • rate_limit_policy.conditions[].negate (boolean, optional): Invert the leaf (lua-resty-expr !, e.g. negate + in = "not in") or the group (!AND / !OR). A request missing the leaf's dimension matches neither the condition nor its negation.

  • rate_limit_policy.conditions[].value (object, optional): Comparison value: in takes 1–64 strings, every other operator a single string. Identity dimensions take resource UUIDs; model_name takes display-name strings or (for ~~/~*) a regex of at most 256 characters; provider takes provider catalog ids.

  • oneOf variant 1

  • oneOf variant 2

  • rate_limit_policy.conditions[].logic (string, optional): Group combinator — lua-resty-expr AND / OR.

  • rate_limit_policy.conditions[].children (array, optional): Nested condition nodes (group shape only).

  • rate_limit_policy.group_by (array, optional): Dimensions the counters split on; empty = one shared bucket for every matched request. Conditional form only.

  • rate_limit_policy.limits (object, optional): Conditional-form limits — the same 7-field shape as the inline model / API-key rate limits. At least one field must be set.

  • rate_limit_policy.limits.rps (integer, optional): Requests per second.

  • rate_limit_policy.limits.rpm (integer, optional): Requests per minute.

  • rate_limit_policy.limits.rph (integer, optional): Requests per hour.

  • rate_limit_policy.limits.rpd (integer, optional): Requests per day.

  • rate_limit_policy.limits.tpm (integer, optional): Total tokens per minute.

  • rate_limit_policy.limits.tpd (integer, optional): Total tokens per day.

  • rate_limit_policy.limits.concurrency (integer, optional): Maximum concurrent in-flight requests. Capped at the data plane's 32-bit counter range.

  • rate_limit_policy.action (string, optional): What the policy does past its limits. Only reject (HTTP 429) is available; the field reserves the enum for future actions.

  • rate_limit_policy.created_at (string, required): Time when the policy was created.

  • rate_limit_policy.updated_at (string, required): Time when the policy was last updated.

  • warnings (array, optional): Present on save operations when some data plane nodes in the environment run a gateway version that will not execute part of the saved policy. Never present on reads.

  • warnings[].code (string, required): How affected nodes treat the saved resource. field_ignored: the resource stays in service on those nodes but the named field has no effect there — beware when the field is restrictive, since the restriction is silently not enforced. row_rejected: those nodes refuse the whole resource, so it stops serving there entirely (or, if a previously accepted version exists, they keep serving the old values).

  • warnings[].field (string, required): Dot-separated path of the field that triggered the warning, as delivered to gateway nodes.

  • warnings[].min_dp_version (string, required): Oldest gateway version that fully executes the field. The literal value unreleased means no released gateway version executes it yet.

  • warnings[].affected_dp_count (integer, required): Number of currently registered nodes in the environment running an older gateway version than min_dp_version.

  • warnings[].affected_dp_versions (array, required): Distinct gateway versions reported by the affected nodes, capped at five entries. Nodes that report no version appear as unknown.

  • 400: Request body or parameters failed validation.

  • error (object, required): Error details.

  • error.code (string, required): Machine-readable identifier. Examples: UNAUTHENTICATED, INVALID_REQUEST, MASTER_KEY_UNSET, INTERNAL.

  • error.message (string, required): Human-readable explanation; safe to surface to operators.

  • 401: Missing or invalid bearer. Response fields (application/json): identical to POST /environments/{env_id}/rate_limits, response 400 above.

  • 403: Authenticated request is not permitted. Response fields (application/json): identical to POST /environments/{env_id}/rate_limits, response 400 above.

  • 404: Resource not found. Response fields (application/json): identical to POST /environments/{env_id}/rate_limits, response 400 above.

  • 409: Request conflicts with current resource state. Response fields (application/json): identical to POST /environments/{env_id}/rate_limits, response 400 above.

cURL

curl -X POST '$AISIX_CP/environments/{env_id}/rate_limits' -H 'Authorization: Bearer $AISIX_TOKEN'