Create Rate Limit Rule

POST /v1/firewall/rate-limits

Create a per-endpoint rate-limit rule. Each rule has 0..N conditions joined by AND/OR — same vocabulary as firewall policies (source_ip, country, asn, browser, user_agent, endpoint, path, method, header, cookie, protocol, port). A request is counted only when its conditions resolve to true; the counter is then keyed by client IP. Once the counter exceeds requests_per_window within window_size_seconds, the configured action applies until the window rolls over.

Counters live in the platform's hot-path Redis. A new rule is pushed to the edges when you save it and takes effect within seconds. Each edge's cached copy of the endpoint's rules also expires on its own after about a minute, which only matters if a change notice is lost.

A rule with no conditions matches every request to its endpoint (legacy behaviour).

Request body

name string Req
Rule name.
endpoint_uuid string (uuid) Req
The endpoint this rule applies to: its uuid from /endpoints.
description string
Free-form description.
conditions array
Match conditions joined by AND/OR. Each entry is {condition_type, operator, condition_value, logical_operator} with the same vocabulary as firewall policies — see firewall policies for the full type/operator matrix and per-type value rules (ISO country codes, uppercase HTTP methods, IP/CIDR, etc.). The logical_operator on a condition is the OUTGOING connector to the next condition. Empty / omitted = "match every request to this endpoint".
source_ip string? Deprecated
Pre-#172 single-IP filter, kept for backwards compatibility. When you post a rule with source_ip set and an empty conditions array, the api-server auto-promotes it into a single {type:"source_ip", operator:"equals", value:<ip>} condition. New code should use conditions directly.
requests_per_window int
Requests allowed per window. A negative value returns 400; 0 (or omitted) defaults to 100.
window_size_seconds int
Sliding window length. A value ≤ 0 (or omitted) defaults to 3600. Common values: 60 (per minute), 3600 (per hour), 86400 (per day).
action string
block (default — return 429) or throttle (delay subsequent requests instead of dropping them). Any other value is coerced to block.
status string
active (default), inactive, or disabled. Only active rules are evaluated.
priority int
Lower numbers evaluated first. Stored as sent; defaults to 0 when omitted (no server-side default or clamp).

Deprecated: the old name endpoint_id (it carries the same endpoint uuid string) is still accepted. Send endpoint_uuid.

Response (200 OK)

The newly-created rule with its uuid, endpoint_uuid, user_uuid, account_uuid, created_at / updated_at, hit_count (0) and its conditions array (each condition carries uuid and rule_uuid; omitted when the rule has none). description and the legacy source_ip are omitted when you didn't send them.

Deprecated: until the sunset this response also carries the legacy integer id and *_id fields. Don't use them; read uuid and the *_uuid fields.

Errors

400 Bad Request
Missing name, malformed source_ip, negative requests_per_window, an invalid conditions entry (bad type/operator/value), or an unknown JSON field. Unknown fields are rejected — there is no key, scope, limit, or window_seconds on this endpoint; use the names documented above.
401 Unauthorized
Missing auth.
403 Forbidden
Plan doesn't include custom_rate_limits.
404 Not Found
Endpoint doesn't exist or belongs to another account (both read Endpoint not found).
Request — 1000 req/min for all IPs on one endpoint
curl -X POST "https://api.ngris.com/v1/firewall/rate-limits" \ -H "X-API-KEY: <your_api_key>" \ -H "Content-Type: application/json" \ -d '{ "name": "anti-abuse", "endpoint_uuid": "019bb1e4-e785-77d2-9966-c3cff31d0a0e", "requests_per_window": 1000, "window_size_seconds": 60, "action": "block" }'
Request — 50 req/min throttle for one corporate /24
curl -X POST "https://api.ngris.com/v1/firewall/rate-limits" \ -H "X-API-KEY: <your_api_key>" \ -H "Content-Type: application/json" \ -d '{ "name": "scrape-defense", "endpoint_uuid": "019bb1e4-e785-77d2-9966-c3cff31d0a0e", "source_ip": "203.0.113.0/24", "requests_per_window": 50, "window_size_seconds": 60, "action": "throttle", "priority": 50 }'
Python
from ngris import Ngris client = Ngris(api_key="<your_api_key>") client.firewall.create_rate_limit({ "name": "anti-abuse", "endpoint_uuid": "019bb1e4-e785-77d2-9966-c3cff31d0a0e", "requests_per_window": 1000, "window_size_seconds": 60, "action": "block", })
Response — 200 OK
{ "uuid": "019b344f-6477-7b07-8dac-7d370474eab1", "endpoint_uuid": "019bb1e4-e785-77d2-9966-c3cff31d0a0e", "user_uuid": "019a52c2-ca1e-78ba-ab5c-50362cc29134", "account_uuid": "019a68b9-1a79-7820-a884-41f554aba6bd", "name": "anti-abuse", "requests_per_window": 1000, "window_size_seconds": 60, "action": "block", "status": "active", "priority": 0, "created_at": "2026-05-10T13:00:00Z", "updated_at": "2026-05-10T13:00:00Z", "hit_count": 0 }
Was this helpful?
On this page
Create Rate Limit Rule
Was this helpful?