Update Rate Limit Rule

PUT /v1/firewall/rate-limits/{uuid}

Edit a rate-limit rule. This is a full-record PUT, not a patch: name is always required, and any field you omit reverts to its zero value / default (e.g. an omitted action coerces to block, an omitted requests_per_window resets to 100, omitted conditions clears them). Send the complete intended state.

Counters in Redis aren't reset by changes — bumping requests_per_window from 100 to 200 means clients currently throttled (counter ≥ 100) stay throttled until the window rolls. To reset, delete and recreate.

Changes are pushed to the edges when you save and take effect within seconds. Each edge's cached copy also expires on its own after about a minute, which only matters if a change notice is lost.

Path parameters

uuid string (uuid) Req
The rule's uuid from /firewall/rate-limits.

Deprecated: the legacy integer id is still accepted in the path until the sunset, answered with Deprecation and Sunset headers. Use the uuid.

Request body

The mutable fields are name (required), description, conditions, requests_per_window, window_size_seconds, action, status, and priority. Conditions use the same vocabulary as firewall policies (source_ip, country, asn, browser, user_agent, endpoint, path, method, header, cookie, protocol, port) and fully replace the rule's existing conditions — send the complete set every time (an empty/omitted array clears them). The legacy single-IP source_ip field is still accepted and auto-promoted to a source_ip condition.

The endpoint is fixed at creation — the rule's original endpoint is always preserved, so it cannot be changed via update. Unknown JSON fields (including endpoint_uuid) are rejected with 400.

Response (200 OK)

The rule as stored, read back after the write (full record, with uuid, endpoint_uuid, user_uuid, account_uuid, its real created_at / updated_at), with the conditions it now has as saved (omitted when none). description and the legacy source_ip are omitted when unset. Its match statistics are the ones its list row shows, over the same 7-day window: hit_count, and last_matched / hits_daily (both omitted when the rule hasn't matched in the window).

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
Invalid field value, malformed source_ip, unknown JSON field, or an integer id after the sunset (integer_id_unsupported).
401 Unauthorized
Missing auth.
403 Forbidden
Plan doesn't include custom_rate_limits.
404 Not Found
Rule doesn't exist or belongs to another account (both read Rate limit rule not found).
Request — bump cap
curl -X PUT "https://api.ngris.com/v1/firewall/rate-limits/019b344f-6477-7b07-8dac-7d370474eab1" \ -H "X-API-KEY: <your_api_key>" \ -H "Content-Type: application/json" \ -d '{ "name": "anti-abuse", "requests_per_window": 2000, "window_size_seconds": 60 }'
Request — switch to throttle for one /24
curl -X PUT "https://api.ngris.com/v1/firewall/rate-limits/019b344f-6477-7b07-8dac-7d370474eab1" \ -H "X-API-KEY: <your_api_key>" \ -H "Content-Type: application/json" \ -d '{ "name": "scrape-defense", "source_ip": "203.0.113.0/24", "action": "throttle" }'
Python
from ngris import Ngris client = Ngris(api_key="<your_api_key>") client.firewall.update_rate_limit("019b344f-6477-7b07-8dac-7d370474eab1", { "name": "anti-abuse", "requests_per_window": 2000, "window_size_seconds": 60, })
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": 2000, "window_size_seconds": 60, "action": "block", "status": "active", "priority": 0, "created_at": "2026-04-01T00:00:00Z", "updated_at": "2026-05-10T13:05:00Z", "hit_count": 12, "last_matched": "2026-05-10T12:58:10Z", "hits_daily": [0, 2, 1, 0, 4, 3, 2] }
Was this helpful?
On this page
Update Rate Limit Rule
Was this helpful?