Enable email routing
const url = 'https://api.nsin.ir/domains/example.com/email-routing/enable';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"remove_existing_mx":true,"merge_spf":true}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.nsin.ir/domains/example.com/email-routing/enable \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "remove_existing_mx": true, "merge_spf": true }'Publishes the MX, SPF and DKIM records and turns routing on. Any MX
records the domain already has must be removed (they would route mail
elsewhere) — send remove_existing_mx: true to agree, otherwise the
call answers 409 with conflict: mx and the rows. An existing SPF
record is merged rather than duplicated (merge_spf: true); two SPF
records answer 409 with conflict: spf_multiple. The removed MX rows
are kept so a later disable can put them back.
Refused while no mail host is ready (503, code: hosts_not_ready),
on external DNS (409, conflict: external_dns) and on a plan
without the feature (403). Idempotent: an enabled domain answers
200 unchanged. Requires domain.settings.
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
Section titled “Request Body ”object
Agree to remove the domain’s existing MX records (they are snapshotted for disable).
Agree to merge our include term into the domain’s existing SPF record.
Example generated
{ "remove_existing_mx": true, "merge_spf": true}Responses
Section titled “ Responses ”Routing enabled; the status.
object
At least one mail host has checked in recently. Enable is refused while false.
The managed records are not editable.
object
object
object
Relative to the domain; @ is the apex.
extra is a foreign MX or a second SPF seen publicly.
The managed record’s id, when the row is ours.
Only while unconfigured — what enable would have to remove or merge.
object
object
object
Enable removed MX records that disable can restore.
object
Every message except discarded bounces.
object
Always present. Before Email Routing is enabled the selector and name are already known (they come from platform settings) and txt is empty, because the key is generated at enable time.
object
The TXT name relative to the domain.
object
object
Example
{ "status": "unconfigured", "catch_all": { "action": "forward" }, "dns": { "records": [ { "type": "MX", "state": "ok" } ] }}Missing, malformed, revoked or expired API key — or the owning account is inactive.
The single error shape used by every endpoint.
object
Human-readable description of what went wrong.
Examples
{ "error": "invalid API key"}The key is read-only, your role lacks the permission, the domain has no
active plan (402-class message with upgrade_url), the plan does not
include Email Routing, or the plan’s max_email_rules is reached —
the body then carries max_rules and upgrade_url.
object
Human-readable description of what went wrong.
Examples
{ "error": "You have reached the maximum number of email addresses for this domain's plan. Upgrade the plan for this domain to add more.", "max_rules": 50, "upgrade_url": "/plans"}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"}Something in the zone has to change first. conflict says what:
mx (existing MX records, listed under records — re-send with
remove_existing_mx: true), spf (an existing SPF record, with the
merged preview — re-send with merge_spf: true), spf_multiple
(two SPF records; keep one), external_dns (the domain does not use
NSIN DNS) or domain_status (the domain is disabled).
object
Human-readable description of what went wrong.
What conflicts (mx, spf, spf_multiple, external_dns, domain_status, not_enabled, local_part, destination).
For mx / spf_multiple — the rows in the way.
object
For spf — the existing SPF row.
For spf — its current value.
For spf — what it becomes with our include merged in.
For destination — the existing row.
object
When the last verification mail went out.
Seconds until another verification mail may be sent; 0 when allowed now.
Rules and catch-alls pointing at it.
The receiving server’s last refusal, when forwards to it are bouncing.
Examples
{ "error": "this domain already has MX records; enabling email routing replaces them", "conflict": "mx", "records": [ { "id": 12, "name": "@", "content": "mail.example.ir.", "priority": 10 } ]}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"}The nameservers could not be updated; nothing was changed. Retry in a moment.
The single error shape used by every endpoint.
object
Human-readable description of what went wrong.
Example
{ "error": "read-only API key"}No mail host has checked in recently (code: hosts_not_ready), or
the platform is missing its key-encryption key (code: kek_unset).
object
Human-readable description of what went wrong.
Machine-readable reason (hosts_not_ready, kek_unset, loop, no_mx, unverified).
The offending body field, when one applies.
Example
{ "error": "read-only API key"}