Skip to content

Create a bot route rule

POST
/domains/{domain}/rules/bot-route/
curl --request POST \
--url https://api.nsin.ir/domains/example.com/rules/bot-route/ \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "record_id": 1, "record_ids": [ 1 ], "enabled": true, "priority": 100, "host_pattern": "example", "host_match_type": "", "action_mode": "enforce", "bot_kinds": [ "*" ], "require_verified": true, "action": "block", "status": 200, "body": "example", "alt_dest": "example", "alt_port": 1, "alt_scheme": "http" }'

Acts on classified bot traffic — block it, serve alternative content, send it to a different origin, or just tag it in telemetry.

Requires rules.edit.

domain
required
string

The domain name (for example example.com) — not a numeric id.

Example
example.com
Media type application/json
object
record_id

Deprecated single-record scope. Prefer record_ids.

integer
nullable
record_ids

Scope the rule to these proxied records. Omit or send an empty array for a zone-wide rule. Every id must belong to this domain.

Array<integer>
enabled
boolean
default: true
priority
integer
default: 100
host_pattern
string
host_match_type

How host_pattern is matched. The empty string means “no host filter”, and is the only valid value when host_pattern is empty — the two fields are set and cleared together.

string
Allowed values: "" exact wildcard regex
action_mode
  • enforce — the rule acts (block, redirect, challenge, …).
  • dry_run — the rule matches and is logged as “would have acted”, but the request reaches the origin unchanged. Use it to test a rule safely.

Not every rule type honours this; cache ignores it.

string
Allowed values: enforce dry_run
bot_kinds

Which bots this rule matches. Must not be empty.

Array<string>
Allowed values: * gptbot oai-searchbot chatgpt-user claudebot claude-user perplexitybot perplexity-user googlebot google-extended bingbot ccbot bytespider meta-externalagent amazonbot applebot duckduckbot yandexbot ahrefsbot semrushbot mj12bot generic-bot
require_verified

Only match bots whose identity was verified (by reverse DNS or published IP ranges), not merely self-declared in the user agent.

boolean
action
  • block — refuse the request.
  • alt_content — serve body with status instead of the origin.
  • alt_origin — proxy to alt_dest:alt_port over alt_scheme.
  • tag — let it through, but tag it in telemetry.
string
Allowed values: block alt_content alt_origin tag
status

Status code for alt_content.

integer
default: 200
body

Response body for alt_content.

string
alt_dest

Origin address for alt_origin.

string
alt_port

Origin port for alt_origin.

integer
alt_scheme

Scheme used to reach alt_dest.

string
Allowed values: http https

Rule created.

Media type application/json
object
id
integer
domain_id
integer
record_id

Deprecated single-record scope. Prefer record_ids. Absent for zone-wide rules.

integer
record_ids

The proxied DNS records this rule applies to. Empty or absent means zone-wide — every proxied record of the domain.

Array<integer>
type
string
Allowed values: cache drop redirect rewrite waf captcha rate_limit bot_route origin_pool origin_route fingerprint error_page
enabled
boolean
priority

Evaluation order; lower runs first. Defaults to 100.

integer
host_pattern

Optional hostname filter. Empty means the rule is not host-scoped.

string
host_match_type

How host_pattern is matched. The empty string means “no host filter”, and is the only valid value when host_pattern is empty — the two fields are set and cleared together.

string
Allowed values: "" exact wildcard regex
action_mode
  • enforce — the rule acts (block, redirect, challenge, …).
  • dry_run — the rule matches and is logged as “would have acted”, but the request reaches the origin unchanged. Use it to test a rule safely.

Not every rule type honours this; cache ignores it.

string
Allowed values: enforce dry_run
created_at
string format: date-time
updated_at
string format: date-time
bot_kinds

Which bots this rule matches. Must not be empty.

Array<string>
Allowed values: * gptbot oai-searchbot chatgpt-user claudebot claude-user perplexitybot perplexity-user googlebot google-extended bingbot ccbot bytespider meta-externalagent amazonbot applebot duckduckbot yandexbot ahrefsbot semrushbot mj12bot generic-bot
require_verified

Only match bots whose identity was verified (by reverse DNS or published IP ranges), not merely self-declared in the user agent.

boolean
action
  • block — refuse the request.
  • alt_content — serve body with status instead of the origin.
  • alt_origin — proxy to alt_dest:alt_port over alt_scheme.
  • tag — let it through, but tag it in telemetry.
string
Allowed values: block alt_content alt_origin tag
status

Status code for alt_content.

integer
default: 200
body

Response body for alt_content.

string
alt_dest

Origin address for alt_origin.

string
alt_port

Origin port for alt_origin.

integer
alt_scheme

Scheme used to reach alt_dest.

string
Allowed values: http https
Example
{
"type": "cache",
"host_match_type": "",
"action_mode": "enforce",
"bot_kinds": [
"*"
],
"action": "block",
"status": 200,
"alt_scheme": "http"
}

Malformed body, an invalid field value, or record_ids containing a record that does not belong to this domain.

Media type application/json

The single error shape used by every endpoint.

object
error
required

Human-readable description of what went wrong.

string
Examples
Example foreignRecords
{
"error": "record_ids do not belong to this domain"
}

Missing, malformed, revoked or expired API key — or the owning account is inactive.

Media type application/json

The single error shape used by every endpoint.

object
error
required

Human-readable description of what went wrong.

string
Examples
Example invalidKey
{
"error": "invalid API key"
}

The key is read-only, or the domain’s plan does not include this rule type or allows fewer rules of it than you already have.

Media type application/json

The single error shape used by every endpoint.

object
error
required

Human-readable description of what went wrong.

string
Example
{
"error": "read-only API key"
}

No such domain, or your role on it does not permit this operation. The rules endpoints deliberately answer 404 rather than 403 for an insufficient role, so they never confirm that a domain exists to someone who cannot use it.

Media type application/json

The single error shape used by every endpoint.

object
error
required

Human-readable description of what went wrong.

string
Examples
Example notFound
{
"error": "not found"
}

The key exceeded its request budget (300 requests per minute by default).

Media type application/json

The single error shape used by every endpoint.

object
error
required

Human-readable description of what went wrong.

string
Examples
Example limited
{
"error": "rate limit exceeded"
}