Rules
On this page, we'll dive into the different rule endpoints you can use to manage rules programmatically. Rules can be attached either to an upstream or to a single custom domain. We'll look at how to query, create, update, and delete rules, as well as how to reorder them.
The rule model
The rule model contains all the information about your rules. Rules allow you to define custom behavior based on request patterns. Each rule consists of matchers (conditions) and handlers (actions). Rules are evaluated in order based on their position, and the first matching rule is applied. A rule can be scoped either to an upstream — in which case it applies to every custom domain on that upstream — or to a single custom domain. See Rule scopes for details.
Properties
- Name
uuid- Type
- string
- Description
Unique identifier for the rule.
- Name
name- Type
- string
- Description
Human-readable name for the rule.
- Name
active- Type
- boolean
- Description
Whether the rule is currently active.
- Name
position- Type
- integer
- Description
Position of the rule in the evaluation order (lower numbers are evaluated first).
- Name
matchers- Type
- array
- Description
An array of conditions that determine when the rule should be applied. Matchers define the criteria for matching incoming requests based on path, HTTP method, headers, or query parameters. Multiple matchers are combined with AND logic, meaning all conditions must be met for the rule to match.
- Name
handlers- Type
- array
- Description
An array of actions to execute when the rule matches. Handlers define what happens to the request or response when all matchers are satisfied. This can include rewriting URLs, returning static responses, modifying response headers, or replacing content in the response body.
- Name
scope- Type
- string
- Description
The resource the rule is attached to. Either
upstream(the rule applies to every custom domain on the upstream) ordomain(the rule applies to a single custom domain).
- Name
upstream_uuid- Type
- string
- Description
UUID of the upstream this rule belongs to. For domain-scoped rules, this is the UUID of the upstream that the custom domain belongs to.
- Name
custom_domain_uuid- Type
- string
- Description
UUID of the custom domain this rule belongs to. This is
nullfor upstream-scoped rules.
- Name
account_uuid- Type
- string
- Description
UUID of the account that owns this rule.
- Name
created_at- Type
- timestamp
- Description
The date and time when the rule was created.
- Name
updated_at- Type
- timestamp
- Description
The date and time when the rule was last updated.
Rule scopes
Rules can be attached at two different scopes:
- Upstream rules are attached to an upstream and apply to every custom domain on that upstream. They are managed under the
/upstreams/:upstream_uuid/rulespath. - Domain rules are attached to a single custom domain and apply only to that domain. They are managed under the
/upstreams/:upstream_uuid/custom_domains/:custom_domain_uuid/rulespath.
Upstream rules are evaluated before a domain's own rules, so a matching upstream rule takes precedence. Within each scope, rules are evaluated in order based on their position, and the first matching rule is applied.
The rule model, matcher types, and handler types are identical for both scopes; only the endpoint paths differ.
Matcher Types
Rules can include the following matcher types:
Path Matcher
Match requests based on the URL path component.
- Name
type- Type
- string
- Description
Must be set to "path".
- Name
value- Type
- string
- Description
The path value to match against.
- Name
operator- Type
- string
- Description
The comparison operator to use. Possible values:
is- Exact path matchis_not- Path does not match exactlystarts_with- Path starts with the valueends_with- Path ends with the valuecontains- Path contains the valuedoes_not_contain- Path does not contain the valuehas_any_value- Path exists (any value)is_unknown- Path does not exist
{
"type": "path",
"value": "/blog",
"operator": "starts_with"
}
Method Matcher
Match requests based on the HTTP method (GET, POST, PUT, DELETE, etc.).
- Name
type- Type
- string
- Description
Must be set to "method".
- Name
value- Type
- string
- Description
The HTTP method to match against (e.g., "GET", "POST").
- Name
operator- Type
- string
- Description
The comparison operator to use. Possible values:
is- Method matches exactlyis_not- Method does not matchhas_any_value- Any methodis_unknown- No method (rare/impossible in HTTP)
{
"type": "method",
"value": "POST",
"operator": "is"
}
Header Matcher
Match requests based on the presence or value of HTTP headers.
- Name
type- Type
- string
- Description
Must be set to "header".
- Name
header_params- Type
- array
- Description
Array of header parameters to match against.
Each header parameter has the following properties:
- Name
name- Type
- string
- Description
The name of the header.
- Name
value- Type
- string
- Description
The value to match against.
- Name
operator- Type
- string
- Description
The comparison operator to use. Possible values:
is- Header value matches exactlyis_not- Header value does not matchstarts_with- Header value starts with the valueends_with- Header value ends with the valuecontains- Header value contains the valuedoes_not_contain- Header value does not contain the valuehas_any_value- Header exists (any value)is_unknown- Header does not exist
{
"type": "header",
"header_params": [
{
"name": "User-Agent",
"value": "Mozilla",
"operator": "contains"
},
{
"name": "Accept-Language",
"value": "en",
"operator": "starts_with"
}
]
}
Query Matcher
Match requests based on query string parameters in the URL.
- Name
type- Type
- string
- Description
Must be set to "query".
- Name
query_params- Type
- array
- Description
Array of query parameters to match against.
Each query parameter has the following properties:
- Name
key- Type
- string
- Description
The name of the query parameter.
- Name
value- Type
- string
- Description
The value to match against.
- Name
operator- Type
- string
- Description
The comparison operator to use. Possible values:
is- Query parameter value matches exactlyis_not- Query parameter value does not matchstarts_with- Query parameter value starts with the valueends_with- Query parameter value ends with the valuecontains- Query parameter value contains the valuedoes_not_contain- Query parameter value does not contain the valuehas_any_value- Query parameter exists (any value)is_unknown- Query parameter does not exist
{
"type": "query",
"query_params": [
{
"key": "version",
"value": "v2",
"operator": "is"
},
{
"key": "debug",
"operator": "has_any_value"
}
]
}
Country Matcher
Match requests based on the client's country code, determined through GeoIP lookup.
- Name
type- Type
- string
- Description
Must be set to "country".
- Name
operator- Type
- string
- Description
The comparison operator to use. Possible values:
is- Client's country code matches one of the specified codesis_not- Client's country code does not match any of the specified codesis_unknown- Client's country code could not be determinedhas_any_value- Client's country code exists and is not unknown
- Name
country_codes- Type
- array
- Description
Array of ISO 3166-1 alpha-2 country codes to match against (e.g., "US", "GB", "FR"). Required for
isandis_notoperators.
{
"type": "country",
"operator": "is",
"country_codes": ["US", "CA"]
}
Handler Types
Rules can include the following handler types:
Static Response Handler
Return a custom HTTP response without forwarding the request to the upstream server.
- Name
type- Type
- string
- Description
Must be set to "static_response".
- Name
status_code- Type
- integer
- Description
The HTTP status code to return.
- Name
body- Type
- string
- Description
The response body to return.
{
"type": "static_response",
"status_code": 200,
"body": "<!DOCTYPE html><html><body><h1>Hello World!</h1></body></html>"
}
Rewrite Handler
Modify the request URL before forwarding it to the upstream server.
- Name
type- Type
- string
- Description
Must be set to "rewrite".
- Name
uri- Type
- string
- Description
The URI to rewrite the request to. You can use placeholders in your rewrite URI (see below).
Rewrite URI Placeholders
The following placeholders can be used in the rewrite URI:
{http.request.uri}
The full request URI{http.request.uri.path}
The path component (e.g. /old-path){http.request.uri.path.dir}
The directory (excluding the filename){http.request.uri.path.file}
The filename (excluding the directory){http.request.uri.query}
The query string (without ?){
"type": "rewrite",
"uri": "https://blog.example.com{http.request.uri.path}?source=proxy&{http.request.uri.query}"
}
Replace Response Handler
Modify the response body content by replacing text patterns.
- Name
type- Type
- string
- Description
Must be set to "replace_response".
- Name
replacements- Type
- array
- Description
Array of replacements to apply to the response body.
Each replacement has the following properties:
- Name
search- Type
- string
- Description
The string to search for.
- Name
replace- Type
- string
- Description
The string to replace matches with.
{
"type": "replace_response",
"replacements": [
{
"search": "example.com",
"replace": "customdomain.com"
},
{
"search": "Original Content",
"replace": "Modified Content"
}
]
}
Set Response Header Handler
Add or modify headers in the HTTP response.
- Name
type- Type
- string
- Description
Must be set to "set_response_header".
- Name
headers- Type
- array
- Description
Array of headers to set in the response.
Each header has the following properties:
- Name
name- Type
- string
- Description
The name of the header.
- Name
value- Type
- string
- Description
The value to set for the header.
{
"type": "set_response_header",
"headers": [
{
"name": "X-Custom-Header",
"value": "custom-value"
},
{
"name": "Cache-Control",
"value": "max-age=3600"
}
]
}
Delete Response Header Handler
Remove specific headers from the HTTP response.
- Name
type- Type
- string
- Description
Must be set to "delete_response_header".
- Name
headers- Type
- array
- Description
Array of headers to delete from the response.
Each header has the following properties:
- Name
name- Type
- string
- Description
The name of the header to delete.
{
"type": "delete_response_header",
"headers": [
{
"name": "Server"
},
{
"name": "X-Powered-By"
}
]
}
Redirect Handler
Redirect the request to a different URL with a specified HTTP status code.
- Name
type- Type
- string
- Description
Must be set to "redirect".
- Name
location- Type
- string
- Description
The URL to redirect to. Must be a valid URL starting with http:// or https://. You can use placeholders in your redirect location (see below).
- Name
status_code- Type
- integer
- Description
The HTTP status code to use for the redirect. Must be either 301 (permanent) or 302 (temporary).
The following placeholders can be used in the Redirect Location URI:
{http.request.uri}
The full request URI{http.request.uri.path}
The path component (e.g. /old-path){http.request.uri.path.dir}
The directory (excluding the filename){http.request.uri.path.file}
The filename (excluding the directory){http.request.uri.query}
The query string (without ?){
"type": "redirect",
"location": "https://new-location.example.com{http.request.uri.path}?source=redirect&{http.request.uri.query}",
"status_code": 301
}
List Upstream Rules
This endpoint allows you to retrieve a paginated list of all rules for an upstream.
Optional attributes
- Name
active- Type
- boolean
- Description
Filter rules by active status.
- Name
sort- Type
- string
- Description
Field to sort by (e.g.,
position,name,created_at).
- Name
direction- Type
- string
- Description
Sort direction (
ascordesc).
- Name
page- Type
- integer
- Description
Page number for pagination.
- Name
items- Type
- integer
- Description
Number of items per page.
Request
curl -G https://app.saascustomdomains.com/api/v1/accounts/acc_123abc/upstreams/upstream_456def/rules \
-H "Authorization: Bearer {token}" \
-d active=true
Response
{
"data": [
{
"uuid": "rule_01234abc",
"name": "Block legacy API",
"active": true,
"position": 1,
"matchers": [
{
"type": "path",
"value": "/api/v1",
"operator": "starts_with"
}
],
"handlers": [
{
"type": "static_response",
"status_code": 410,
"body": "Gone"
}
],
"scope": "upstream",
"upstream_uuid": "upstream_456def",
"custom_domain_uuid": null,
"account_uuid": "acc_123abc",
"created_at": "2023-01-01T12:00:00Z",
"updated_at": "2023-01-01T12:00:00Z"
},
{
"uuid": "rule_56789def",
// ...
}
],
"pagination": {
"page": 1,
"count": 10,
"items": 25,
"pages": 1
}
}
Get an Upstream Rule
This endpoint allows you to retrieve a single upstream rule by its UUID.
Request
curl https://app.saascustomdomains.com/api/v1/accounts/acc_123abc/upstreams/upstream_456def/rules/rule_01234abc \
-H "Authorization: Bearer {token}"
Response
{
"uuid": "rule_01234abc",
"name": "Block legacy API",
"active": true,
"position": 1,
"matchers": [
{
"type": "path",
"value": "/api/v1",
"operator": "starts_with"
}
],
"handlers": [
{
"type": "static_response",
"status_code": 410,
"body": "Gone"
}
],
"scope": "upstream",
"upstream_uuid": "upstream_456def",
"custom_domain_uuid": null,
"account_uuid": "acc_123abc",
"created_at": "2023-01-01T12:00:00Z",
"updated_at": "2023-01-01T12:00:00Z"
}
Create an Upstream Rule
This endpoint allows you to create a new rule for an upstream. The rule will be assigned the next available position and will apply to every custom domain on the upstream.
Required attributes
- Name
name- Type
- string
- Description
Human-readable name for the rule.
- Name
matchers- Type
- array
- Description
At least one matcher must be provided.
- Name
handlers- Type
- array
- Description
At least one handler must be provided.
Optional attributes
- Name
active- Type
- boolean
- Description
Whether the rule is active. Default is
true.
Request
curl https://app.saascustomdomains.com/api/v1/accounts/acc_123abc/upstreams/upstream_456def/rules \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"name": "Block legacy API",
"active": true,
"matchers": [
{
"type": "path",
"value": "/api/v1",
"operator": "starts_with"
}
],
"handlers": [
{
"type": "static_response",
"status_code": 410,
"body": "Gone"
}
]
}'
Response
{
"uuid": "rule_01234abc",
"name": "Block legacy API",
"active": true,
"position": 1,
"matchers": [
{
"type": "path",
"value": "/api/v1",
"operator": "starts_with"
}
],
"handlers": [
{
"type": "static_response",
"status_code": 410,
"body": "Gone"
}
],
"scope": "upstream",
"upstream_uuid": "upstream_456def",
"custom_domain_uuid": null,
"account_uuid": "acc_123abc",
"created_at": "2023-01-01T12:00:00Z",
"updated_at": "2023-01-01T12:00:00Z"
}
Update an Upstream Rule
This endpoint allows you to update an existing upstream rule.
Optional attributes
- Name
name- Type
- string
- Description
Human-readable name for the rule.
- Name
active- Type
- boolean
- Description
Whether the rule is active.
- Name
matchers- Type
- array
- Description
Conditions that determine when the rule should be applied.
- Name
handlers- Type
- array
- Description
Actions to take when the rule matches.
Request
curl -X PATCH https://app.saascustomdomains.com/api/v1/accounts/acc_123abc/upstreams/upstream_456def/rules/rule_01234abc \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"name": "Updated rule name",
"active": false
}'
Response
{
"uuid": "rule_01234abc",
"name": "Updated rule name",
"active": false,
"position": 1,
"matchers": [
{
"type": "path",
"value": "/api/v1",
"operator": "starts_with"
}
],
"handlers": [
{
"type": "static_response",
"status_code": 410,
"body": "Gone"
}
],
"scope": "upstream",
"upstream_uuid": "upstream_456def",
"custom_domain_uuid": null,
"account_uuid": "acc_123abc",
"created_at": "2023-01-01T12:00:00Z",
"updated_at": "2023-01-01T12:30:00Z"
}
Delete an Upstream Rule
This endpoint allows you to delete an upstream rule.
Request
curl -X DELETE https://app.saascustomdomains.com/api/v1/accounts/acc_123abc/upstreams/upstream_456def/rules/rule_01234abc \
-H "Authorization: Bearer {token}"
Response
{
"message": "Rule rule_01234abc (Block legacy API) deleted."
}
Update Upstream Rule Positions
This endpoint allows you to update the positions of multiple upstream rules at once.
Required attributes
- Name
rule_positions- Type
- array
- Description
Array of rule position updates.
Each rule position update has the following properties:
- Name
uuid- Type
- string
- Description
The UUID of the rule.
- Name
position- Type
- integer
- Description
The new position for the rule.
Request
curl -X PATCH https://app.saascustomdomains.com/api/v1/accounts/acc_123abc/upstreams/upstream_456def/rules/update_positions \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"rule_positions": [
{
"uuid": "rule_01234abc",
"position": 2
},
{
"uuid": "rule_56789def",
"position": 1
}
]
}'
Response
{
"message": "Rule positions updated successfully."
}
List Domain Rules
This endpoint allows you to retrieve a paginated list of all rules for a custom domain.
Optional attributes
- Name
active- Type
- boolean
- Description
Filter rules by active status.
- Name
sort- Type
- string
- Description
Field to sort by (e.g.,
position,name,created_at).
- Name
direction- Type
- string
- Description
Sort direction (
ascordesc).
- Name
page- Type
- integer
- Description
Page number for pagination.
- Name
items- Type
- integer
- Description
Number of items per page.
Request
curl -G https://app.saascustomdomains.com/api/v1/accounts/acc_123abc/upstreams/upstream_456def/custom_domains/domain_789ghi/rules \
-H "Authorization: Bearer {token}" \
-d active=true
Response
{
"data": [
{
"uuid": "rule_01234abc",
"name": "Redirect to blog",
"active": true,
"position": 1,
"matchers": [
{
"type": "path",
"value": "/blog",
"operator": "starts_with"
}
],
"handlers": [
{
"type": "rewrite",
"uri": "https://blog.example.com{path}"
}
],
"scope": "domain",
"upstream_uuid": "upstream_456def",
"custom_domain_uuid": "domain_789ghi",
"account_uuid": "acc_123abc",
"created_at": "2023-01-01T12:00:00Z",
"updated_at": "2023-01-01T12:00:00Z"
},
{
"uuid": "rule_56789def",
// ...
}
],
"pagination": {
"page": 1,
"count": 10,
"items": 25,
"pages": 1
}
}
Get a Domain Rule
This endpoint allows you to retrieve a single rule by its UUID.
Request
curl https://app.saascustomdomains.com/api/v1/accounts/acc_123abc/upstreams/upstream_456def/custom_domains/domain_789ghi/rules/rule_01234abc \
-H "Authorization: Bearer {token}"
Response
{
"uuid": "rule_01234abc",
"name": "Redirect to blog",
"active": true,
"position": 1,
"matchers": [
{
"type": "path",
"value": "/blog",
"operator": "starts_with"
}
],
"handlers": [
{
"type": "rewrite",
"uri": "https://blog.example.com{path}"
}
],
"scope": "domain",
"upstream_uuid": "upstream_456def",
"custom_domain_uuid": "domain_789ghi",
"account_uuid": "acc_123abc",
"created_at": "2023-01-01T12:00:00Z",
"updated_at": "2023-01-01T12:00:00Z"
}
Create a Domain Rule
This endpoint allows you to create a new rule for a custom domain. The rule will be assigned the next available position.
Required attributes
- Name
name- Type
- string
- Description
Human-readable name for the rule.
- Name
matchers- Type
- array
- Description
At least one matcher must be provided.
- Name
handlers- Type
- array
- Description
At least one handler must be provided.
Optional attributes
- Name
active- Type
- boolean
- Description
Whether the rule is active. Default is
true.
Request
curl https://app.saascustomdomains.com/api/v1/accounts/acc_123abc/upstreams/upstream_456def/custom_domains/domain_789ghi/rules \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"name": "Redirect to blog",
"active": true,
"matchers": [
{
"type": "path",
"value": "/blog",
"operator": "starts_with"
}
],
"handlers": [
{
"type": "rewrite",
"uri": "https://blog.example.com{path}"
}
]
}'
Response
{
"uuid": "rule_01234abc",
"name": "Redirect to blog",
"active": true,
"position": 1,
"matchers": [
{
"type": "path",
"value": "/blog",
"operator": "starts_with"
}
],
"handlers": [
{
"type": "rewrite",
"uri": "https://blog.example.com{path}"
}
],
"scope": "domain",
"upstream_uuid": "upstream_456def",
"custom_domain_uuid": "domain_789ghi",
"account_uuid": "acc_123abc",
"created_at": "2023-01-01T12:00:00Z",
"updated_at": "2023-01-01T12:00:00Z"
}
Update a Domain Rule
This endpoint allows you to update an existing rule.
Optional attributes
- Name
name- Type
- string
- Description
Human-readable name for the rule.
- Name
active- Type
- boolean
- Description
Whether the rule is active.
- Name
matchers- Type
- array
- Description
Conditions that determine when the rule should be applied.
- Name
handlers- Type
- array
- Description
Actions to take when the rule matches.
Request
curl -X PATCH https://app.saascustomdomains.com/api/v1/accounts/acc_123abc/upstreams/upstream_456def/custom_domains/domain_789ghi/rules/rule_01234abc \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"name": "Updated rule name",
"active": false
}'
Response
{
"uuid": "rule_01234abc",
"name": "Updated rule name",
"active": false,
"position": 1,
"matchers": [
{
"type": "path",
"value": "/blog",
"operator": "starts_with"
}
],
"handlers": [
{
"type": "rewrite",
"uri": "https://blog.example.com{path}"
}
],
"scope": "domain",
"upstream_uuid": "upstream_456def",
"custom_domain_uuid": "domain_789ghi",
"account_uuid": "acc_123abc",
"created_at": "2023-01-01T12:00:00Z",
"updated_at": "2023-01-01T12:30:00Z"
}
Delete a Domain Rule
This endpoint allows you to delete a rule.
Request
curl -X DELETE https://app.saascustomdomains.com/api/v1/accounts/acc_123abc/upstreams/upstream_456def/custom_domains/domain_789ghi/rules/rule_01234abc \
-H "Authorization: Bearer {token}"
Response
{
"message": "Rule rule_01234abc (Redirect to blog) deleted."
}
Update Domain Rule Positions
This endpoint allows you to update the positions of multiple rules at once.
Required attributes
- Name
rule_positions- Type
- array
- Description
Array of rule position updates.
Each rule position update has the following properties:
- Name
uuid- Type
- string
- Description
The UUID of the rule.
- Name
position- Type
- integer
- Description
The new position for the rule.
Request
curl -X PATCH https://app.saascustomdomains.com/api/v1/accounts/acc_123abc/upstreams/upstream_456def/custom_domains/domain_789ghi/rules/update_positions \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"rule_positions": [
{
"uuid": "rule_01234abc",
"position": 2
},
{
"uuid": "rule_56789def",
"position": 1
}
]
}'
Response
{
"message": "Rule positions updated successfully."
}
Error Responses
When an error occurs, the API will return an appropriate HTTP status code and a JSON response with error details:
{
"error": "Rule not found.",
"error_code": "not_found"
}
Common error codes:
not_found- The requested resource was not foundfeature_not_enabled- The rules feature is not enabled for this account (upstream rules additionally require the upstream rules feature to be enabled)invalid_position- The requested position is invalid- Various validation errors (e.g.,
name_blank,matchers_invalid)