Create Routing Rule
Add a routing rule to an endpoint. Rules sit between the public URL and the agents — every incoming request is evaluated against rules in priority order, and the first matching rule's target_agent_id / target_agent_tags determines which agent gets the request.
Common patterns:
- Canary deployment: route requests with
X-Canary: trueto agents taggedcanary,v2; everything else hits prod. - API split: route
/api/payments/*to a hardened payment service, the rest to the main app. - Geo routing: route by client IP CIDR to nearest-region agents.
Plan-gated: requires the endpoint_routing_rules entitlement.
Path parameters
uuid string (uuid) Req
The endpoint's
uuid from /endpoints.Request body
name string Req
Free-form label. Used for dashboard display and audit logs.
priority int
Match order. Lower = earlier. Default
0. Pick wide gaps (10, 20, 30) so you can insert new rules without renumbering.target_agent_id string
Specific agent ID to route to. Mutually exclusive with
target_agent_tags — at least one is required.target_agent_tags string
Comma-separated agent tags. Any agent with all listed tags is eligible (load-balanced across).
enabled boolean
true = active immediately, false = saved but skipped during evaluation. Useful for staging.fallback boolean
When the target agent is offline:
true = route to any healthy agent of the endpoint instead; false (default) = answer 502.conditions array Req
At least one condition. Each:
•
•
•
•
•
Set
{condition_type, condition_key?, pattern, negate?}:•
path: glob/regex pattern matched against the request path. condition_key unused.•
header: condition_key = header name, pattern = value pattern.•
cookie: condition_key = cookie name, pattern = value pattern.•
client_ip: pattern = CIDR (10.0.0.0/8) or single IP.•
method: pattern = HTTP verb (GET, POST, …).Set
negate: true to invert.Response (201 Created)
The rule as stored, read back after the write: its assigned uuid, its created_at / updated_at, and its conditions as saved. Same shape as list entries.
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 (Rule name is required), empty conditions (At least one condition is required) or a null entry in it (Invalid condition: conditions[N] is null), neither target_agent_id nor target_agent_tags set (Either target_agent_id or target_agent_tags is required), invalid JSON, or an application endpoint (Routing rules are not supported for agentless (static hosting) endpoints. — there is no agent to route to).401 Unauthorized
Missing auth.
403 Forbidden
Plan doesn't include
endpoint_routing_rules entitlement, or the account is at its plan's routing-rule limit.404 Not Found
Endpoint doesn't exist or doesn't belong to the calling account.
409 Conflict
The endpoint is paused over your plan's limits (
"code": "quota_paused").Request — canary by header
curl -X POST "https://api.ngris.com/v1/endpoints/019bb1e4-e785-77d2-9966-c3cff31d0a0e/routing-rules" \
-H "X-API-KEY: <your_api_key>" \
-H "Content-Type: application/json" \
-d '{
"name": "canary-5pct",
"priority": 10,
"target_agent_tags": "canary,v2",
"enabled": true,
"conditions": [
{"condition_type": "header", "condition_key": "X-Canary", "pattern": "true"}
]
}'
Python — split by path
from ngris import Ngris
client = Ngris(api_key="<your_api_key>")
rule = client.routing_rules.create("019bb1e4-e785-77d2-9966-c3cff31d0a0e", {
"name": "payments-isolated",
"priority": 5,
"target_agent_id": "payments-prod-1",
"enabled": True,
"conditions": [
{"condition_type": "path", "pattern": "/api/payments/*"},
],
})
print(f"Created rule {rule['uuid']}")
Response — 201 Created
{
"uuid": "019b962b-971a-77df-97b0-e3905fa06cd4",
"endpoint_uuid": "019bb1e4-e785-77d2-9966-c3cff31d0a0e",
"name": "canary-5pct",
"priority": 10,
"target_agent_tags": "canary,v2",
"enabled": true,
"fallback": false,
"conditions": [
{"rule_uuid": "019b962b-971a-77df-97b0-e3905fa06cd4", "condition_type": "header", "condition_key": "X-Canary", "pattern": "true", "negate": false}
],
"created_at": "2026-04-29T13:00:00Z",
"updated_at": "2026-04-29T13:00:00Z"
}
Was this helpful?