Update domain settings
const url = 'https://api.nsin.ir/domains/example.com';const options = { method: 'PUT', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"dns_mode":"managed","cache_l2_max_gb":1,"cache_l2_ttl_days":1,"cache_cap_mb":128,"sec_no_sniff":true,"sec_referrer_policy":true,"sec_strip_headers":true,"hsts_enabled":true,"hsts_max_age_sec":0,"hsts_include_subdomains":true,"hsts_preload":true,"min_tls_version":"1.2","markdown_for_agents":true,"origin_protocol":"http1","default_static_cache":true,"bot_cache_enabled":true,"bot_cache_fresh_sec":1,"bot_cache_max_age_sec":1,"bot_cache_kinds":["googlebot"],"bot_cache_path_excludes":["example"]}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request PUT \ --url https://api.nsin.ir/domains/example.com \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "dns_mode": "managed", "cache_l2_max_gb": 1, "cache_l2_ttl_days": 1, "cache_cap_mb": 128, "sec_no_sniff": true, "sec_referrer_policy": true, "sec_strip_headers": true, "hsts_enabled": true, "hsts_max_age_sec": 0, "hsts_include_subdomains": true, "hsts_preload": true, "min_tls_version": "1.2", "markdown_for_agents": true, "origin_protocol": "http1", "default_static_cache": true, "bot_cache_enabled": true, "bot_cache_fresh_sec": 1, "bot_cache_max_age_sec": 1, "bot_cache_kinds": [ "googlebot" ], "bot_cache_path_excludes": [ "example" ] }'Partial update — omitted fields are left unchanged. Requires the
domain.settings permission. Every edge node is told to reload the
domain’s configuration as soon as the change is saved.
Plan limits apply to three fields: cache_cap_mb, cache_l2_max_gb
and cache_l2_ttl_days may not exceed the ceilings of the domain’s
plan (403, with the ceiling in the body). Turning
markdown_for_agents on needs an active plan, and turning the bot
cache on — or changing a bot_cache_* setting while it is on — needs
a plan with the bot cache feature. Switching either off is never
refused. These two plan checks answer with a plain-text body, not
the usual JSON error.
Switching dns_mode keeps records, rules, certificates and the
plan, and puts the domain back to pending:
- to
managed— NSIN creates the zone, loads your records into it and waits for the nameservers to point at NSIN (activating straight away if they already do); - to
external— NSIN removes its zone and opens a fresh 3-day verification window (seessl_delegation/verificationin the response).
A banned domain cannot switch.
Authorizations
Section titled “Authorizations ”Parameters
Section titled “ Parameters ”Path Parameters
Section titled “Path Parameters ”The domain name (for example example.com) — not a numeric id.
Example
example.comRequest Body required
Section titled “Request Body required ”Every field is optional; omitted fields are left unchanged.
object
Switch how DNS is run. See the operation description for what happens.
Disk (L2) cache size cap in GB. At most the plan’s ceiling.
Disk cache entry lifetime in days. At most the plan’s ceiling.
Largest cacheable response body in MB. At most the plan’s ceiling.
See the sec_no_sniff field on Domain.
See the sec_referrer_policy field on Domain.
See the sec_strip_headers field on Domain.
See the hsts_enabled field on Domain. Cannot be undone for
browsers that have already seen the header.
See the hsts_max_age_sec field on Domain. May only be raised one
step per request; a bigger jump is rejected with 400 naming the
next allowed value.
See the hsts_include_subdomains field on Domain.
See the hsts_preload field on Domain. Rejected with 400 unless
hsts_enabled, hsts_include_subdomains and a hsts_max_age_sec
of 31536000 are all in place after this update.
See the min_tls_version field on Domain. TLSv1.3 and tls1.3 are accepted as spellings of 1.3.
See the markdown_for_agents field on Domain. Turning it on requires an active plan.
See the origin_protocol field on Domain. h1/h2/h3 and HTTP/2-style spellings are accepted too.
See the default_static_cache field on Domain.
See the bot_cache_enabled field on Domain. Turning it on, or
changing any bot_cache_* setting while it is on, requires the
plan flag (403 otherwise); turning it off never does.
See the bot_cache_fresh_sec field on Domain.
Must be at least bot_cache_fresh_sec.
Crawlers the bot cache serves. Case-insensitive; duplicates are dropped.
Wildcard path patterns (/api/*) never served from the bot cache. Blank entries are dropped. Replaces the whole list.
Responses
Section titled “ Responses ”Updated domain.
object
pending— waiting to be activated: a managed domain for its nameservers to point at NSIN (disabled after 28 days without that), an external-DNS domain for its verification record (3-day window).failed— an external-DNS domain whose 3-day verification window ran out. Start a new window withPOST /domains/{domain}/verify/retry.active— serving.moved— was active, but the delegation (managed) or the verification record (external) is gone. The domain keeps serving for a 3-day grace window, then is disabled; putting it back reactivates it at the next check.disabled— not serving: zone removed, records un-proxied, cache purged. Re-enable withPOST /domains/{domain}/enable.banned— administratively blocked.
managed — NSIN hosts the DNS zone. external — you host DNS
elsewhere and prove ownership with a TXT record.
Id of the owning user.
External-DNS domains: when the current 3-day verification window
opened (at creation, on a switch to external, on re-enable and on
verify/retry).
Per-domain cap on disk (L2) cache size, in GB.
How long a disk-cache entry may live, in days. Maximum 7.
Largest response body NSIN will buffer and cache, in MB. Bigger responses stream straight from origin and are never cached. The selectable ceiling depends on the domain’s plan.
While set and in the future, the edge bypasses cache reads and writes
for this domain and passes the origin’s own error responses through
(see POST /domains/{domain}/developer-mode). Absent when developer
mode is off.
When the domain last entered pending.
When the domain went moved; the 3-day grace window counts from here.
When the background nameserver checker will next look at this domain.
Last user-triggered nameserver check; these are limited to one per hour.
Last user-triggered verification check (POST /domains/{domain}/verify); limited to one per minute.
Under Attack Mode is switched on (see GET /domains/{domain}/under-attack).
Under Attack Mode’s bypass paths.
When Under Attack Mode was switched on.
When Under Attack Mode switches itself off; null = no timer.
Set when the default “NSIN Shield” WAF rule was deleted from this
domain. While set, the rule is not re-created automatically;
POST /domains/{domain}/rules/waf/shield/restore brings it back and
clears this.
Send X-Content-Type-Options: nosniff. Off by default — it can break
an origin that mislabels asset MIME types.
Send Referrer-Policy: strict-origin-when-cross-origin.
Strip origin fingerprint headers from responses.
Send Strict-Transport-Security, telling browsers to use HTTPS only
for this domain. Off by default.
This one cannot be undone. A browser that has seen the header
refuses plain HTTP for the whole hsts_max_age_sec even after the
header stops being sent; switching it off only stops new visitors
from being pinned. Enable it only when every path on the domain
works over HTTPS. The edge’s value replaces an origin’s own
Strict-Transport-Security header (a browser reads only the first
one it receives).
How long browsers keep enforcing HTTPS, in seconds. 0 is
“never set”. Only the listed values are accepted, and this API
raises it one step at a time — from 0 the only allowed next
value is 300, then 3600, and so on. Lowering it is always allowed
and is the way back out. The edge treats anything under 300 as off.
Turning hsts_enabled on while this is 0 sets it to 300.
Add includeSubDomains, applying the rule to every subdomain,
including ones created later. A subdomain not served over HTTPS
becomes unreachable for visitors who have seen the header.
Add the preload directive, the prerequisite for submitting the
domain at hstspreload.org. Requires hsts_enabled,
hsts_include_subdomains and hsts_max_age_sec of 31536000.
Effectively permanent: getting off the browser preload list means asking hstspreload.org to delist the domain and waiting for people to update their browsers. If a precondition is later removed, this flag is cleared with it.
Lowest TLS version a visitor may connect with. 1.2 (default)
accepts TLS 1.2 and 1.3; 1.3 refuses TLS 1.2 handshakes. Nothing
below 1.2 is offered on any domain. It is enforced during the TLS
handshake from the SNI, so a client below the minimum gets a
connection error rather than an HTTP response. HTTP/3 is TLS 1.3 by
definition and is unaffected.
Serve a Markdown rendering of eligible HTML pages to clients sending
Accept: text/markdown. Requires an active plan.
The NsinNabz <script> tag the edge inserts into this domain’s
HTML pages; empty when there is none. Set and removed through
/domains/{domain}/analytics-tag, not through this object.
When analytics_tag last changed. Absent when there is no tag.
HTTP version the edge speaks to this domain’s origins on the direct
path. Default http1, and deliberately so: over HTTP/2 an upload is
limited by the origin’s per-stream window (64 KB on nginx), which
caps each upload near 4 MB/s at a 16 ms edge-to-origin round trip.
http3 falls back to TCP per origin when the QUIC dial fails. The
tunnel path from Iranian edges to foreign origins is always HTTP/1.1.
Probe what your origin supports with GET /domains/{domain}/origin-protocols.
Cache static files (CSS, JavaScript, images, fonts, media, downloads)
at the edge automatically, even with no cache rule — the way
Cloudflare does for every proxied hostname. On by default. HTML is
never cached by this; your own cache rules always take precedence,
and any path you exclude in a rule is never cached by the default.
Freshness follows your origin’s Cache-Control; with none, 5 minutes.
Bot cache: keep an edge copy of every HTML page for verified
search-engine crawlers (Googlebot, Bingbot, Applebot, DuckDuckBot,
YandexBot) and serve them from it, regardless of the origin’s
Cache-Control. Human visitors are unaffected. A crawler must pass
the operator’s own verification (published IP ranges / reverse DNS);
a spoofed User-Agent never gets the copy. Requires a plan with
bot_cache_enabled; the edge switches it off automatically while
the plan lacks it.
Bot cache: seconds a copy is served without asking the origin (300–86400, default 3600). Older copies are still served and refreshed in the background with a conditional request.
Bot cache: seconds after which a copy is no longer served and is fetched again (300–86400, default 86400).
Crawlers the bot cache serves. A domain that never set it (empty) serves all of them; an update must list at least one.
Wildcard path patterns (/api/*) never served from the bot cache.
Edge addresses every proxied record of this domain is pinned to, instead of the platform default set. Set by NSIN support only (for example for a dedicated address); absent in the normal case.
Requests served by this domain’s gateway hostnames in the rolling 30-day window, as of gateway_quota_counted_at.
Egress bytes of the gateway hostnames over the same window. A meter for the gateway allowance, not a second charge — the bytes are already billed as the domain’s ordinary traffic.
The plan’s gateway allowance (requests or bytes) is spent, so the
gateway hostnames answer 429 until enough traffic ages out of the
window. The rest of the domain is unaffected.
When the gateway usage above was last recomputed. Absent before the first count.
Which gateway cap tripped. Absent while nothing has.
When this domain’s gateway terms of use were accepted (see
POST /domains/{domain}/gateways/terms/accept). Absent until then;
switching a gateway on is refused without it.
User id of whoever accepted the gateway terms.
The member nominated to pay for this domain. Absent when the owner pays (the normal case). Only the owner can set it, in the panel — API keys cannot change who pays.
User id of whoever made the current billing nomination.
When the current billing nomination took effect. Charges for a billing window that started earlier stay with the previous payer.
Notify the owner when a subdomain suffers a sustained origin outage.
Per-minute origin-error percentage that counts as “down”.
Minutes the domain must stay down before an incident opens.
Minimum origin-eligible requests in the window — the traffic floor below which no incident opens.
Minimum populated one-minute buckets required in the window.
Consecutive clear minutes before an incident resolves.
How the host filter — host_pattern, host_includes and
host_excludes — is matched. One strategy covers all three, exactly as
one path_match_type covers both path lists.
The empty string means “no host filter”, and is the only valid value
when the pattern and both lists are empty. Set a list without a match
type and the API defaults it to wildcard.
A wildcard entry matches subdomains, not the label itself:
*.example.com covers shop.example.com but not example.com — the
same reading as the DNS wildcard. Add the bare name as its own entry to
include it.
Subdomains the default whole-host uptime watch covers. Absent or
empty means every subdomain. Change with PUT /uptime/settings.
Subdomains the default uptime watch skips; an exclude always beats an include.
Paused for billing. The edge refuses the domain’s TLS handshake, so visitors get a connection error. Clears automatically once the wallet is no longer negative.
Always null — deleted domains are never returned.
The legacy TXT record that proves ownership of an external-DNS domain.
Still accepted, but new domains verify with the CNAME in
ssl_delegation, which also keeps their certificate renewing — prefer
that one.
object
Name to create the TXT record at.
Exact TXT value to publish.
Whether the domain has passed verification: false only while it is pending or failed.
End of the current 3-day verification window. Absent once verified.
Seconds left in the verification window.
When POST /domains/{domain}/verify may be called again (once a minute). Absent once verified, or if it never ran.
How often NSIN re-checks the record on its own, in seconds (300).
An external-DNS domain’s verification record: one CNAME, created once
and never rotated. It proves ownership (a pending domain activates when
it is found) and stays in place afterwards as the domain’s connection
to NSIN, which is what lets NSIN issue and renew the certificate for the
apex and its wildcard. Once it has passed, removing or changing it
marks the domain moved — it keeps serving for a 3-day grace period,
then is disabled — exactly as a managed domain whose nameservers leave.
object
Name to create the CNAME at, e.g. _acme-challenge.example.com.
The CNAME target, unique to this domain.
Whether the last live check found this domain’s delegation in place.
When the last check ran.
When the delegation last passed.
Why the last check failed — or, with ok true, a CAA policy on the
domain that prevents Let’s Encrypt from issuing.
How often NSIN re-checks the record on its own.
The canonical (first) accepted nameserver set.
Every accepted nameserver set. The delegation must name every
NSIN nameserver node, through any set’s hostname for it, and
nothing else; see GET /domains/ns-sets.
The nameservers currently observed in the parent zone.
Your role on a domain. owner is implicit for the domain’s creator and
for global admins; the other three are grantable via sharing.
How often the background checker re-checks the delegation.
Whose wallet this domain’s charges come out of. Always present — it falls back to the owner — so a client can name the payer without a second request. Only the owner can change it, in the panel — API keys cannot.
object
Who made the nomination. Absent when the owner pays.
True when no nomination is in force and the domain owner pays. The owner being named explicitly is stored as no nomination, so this never disagrees with ownership.
Example
{ "name": "example.com", "status": "pending", "dns_mode": "managed", "cache_cap_mb": 128, "hsts_max_age_sec": 0, "min_tls_version": "1.2", "origin_protocol": "http1", "bot_cache_kinds": [ "googlebot" ], "gateway_quota_reason": "requests", "uptime_host_match_type": "", "verification": { "type": "TXT" }, "ssl_delegation": { "type": "CNAME" }, "my_role": "owner", "my_permissions": [ "domain.view" ]}Malformed body or an invalid value — dns_mode not
managed/external, cache_l2_max_gb below 1,
cache_l2_ttl_days outside 1–7, cache_cap_mb not one of the
tiers, an HSTS step that skips a rung or a hsts_preload without
its prerequisites, min_tls_version or origin_protocol not one
of the listed values, a bot_cache_* window outside 300–86400 s
(or fresh longer than max age), an unknown or empty
bot_cache_kinds, or a path exclude that does not start with /,
is longer than 256 characters, or is one of more than 50.
The single error shape used by every endpoint.
object
Human-readable description of what went wrong.
Examples
{ "error": "hsts_max_age_sec can only be raised one step at a time: next step is 3600 seconds. HSTS cannot be undone once browsers have seen it, so raise it only after the site has run without trouble at the current value"}Missing, malformed, revoked or expired API key. (A valid key whose
account has been deactivated gets 403 account is inactive instead.)
The single error shape used by every endpoint.
object
Human-readable description of what went wrong.
Examples
{ "error": "invalid API key"}The domain has no active plan and the update turns
markdown_for_agents or the bot cache on. Plain-text body.
Example
This domain does not have an active plan.Read-only key or insufficient role (JSON); a cache value above the
plan’s ceiling (JSON, with max_cap_mb, max_disk_gb or
max_ttl_days and upgrade_url); or the plan lacks the bot cache
feature (plain-text body).
object
Human-readable description of what went wrong.
The largest cache_cap_mb the plan allows.
The largest cache_l2_max_gb the plan allows.
The largest cache_l2_ttl_days the plan allows.
Where in the panel to upgrade the plan.
Examples
{ "error": "cache_cap_mb exceeds your plan limit", "max_cap_mb": 512, "upgrade_url": "/plans"}Example
This feature is not enabled on this domain's plan. Upgrade the plan for this domain to use it.No such domain, or it is not visible to this account. Domains you cannot access are reported as not found rather than forbidden.
The single error shape used by every endpoint.
object
Human-readable description of what went wrong.
Example
{ "error": "read-only API key"}The domain is banned, so its dns_mode cannot be changed.
The single error shape used by every endpoint.
object
Human-readable description of what went wrong.
Example
{ "error": "read-only API key"}The key exceeded its request budget (300 requests per minute by default).
The single error shape used by every endpoint.
object
Human-readable description of what went wrong.
Examples
{ "error": "rate limit exceeded"}