nsindocs Search the docs⌘K
  1. Docs
  2. API reference
  3. DNS Records

Commit a reviewed import session

posthttps://api.nsin.ir/domains/{domain}/records/import-sessions/{sessionId}/commit

Auth: Authorization: Bearer nsin_… or X-Api-Key: nsin_… — see API keys.

Writes the reviewed set into the domain's records and into DNS. Requires records.edit, and the session must be ready.

  • mode: "selected" with records — commits exactly what you post. This is the reviewed path: send back the rows you kept, with the proxied flags you chose.
  • mode: "all", an empty records, or no body at all — commits the session's own preselected rows with the proxy defaults it staged (the proxied flag of each row — on for website rows).

An existing record with the same name and type is overwritten; for the types that hold several values per name (MX, NS, SRV, CAA, TLSA, SSHFP, URI) only one with the same value is, and a new value is added next to the others. Per-row problems come back in failed and never abort the batch.

The session is claimed before anything is written, so a second click loses the race and gets 409 rather than importing twice. A whole-import failure — the plan's record limit — releases the session back to ready, so you can upgrade and commit the same staged rows again.

Path parameters

  • domainstringrequiredpath

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

  • sessionIdintegerrequiredpath

    Numeric id of the record import session. Sessions are resolved within the domain, so an id from another domain reads as not found.

Request body

Content type: application/json

  • modestring

    selected commits records exactly as posted. all — or an empty records — commits the rows the session preselected, with the proxy defaults it staged.

    One of: "all" "selected"
    Default: "all"
  • recordsarray of ImportRecordItem

    The reviewed set. Rows may be dropped, and proxied may be switched on per row, but a row must still be one the plan and the address rules accept.

    Item fields
    • namestringrequired
    • typestringrequired
      One of: "A" "AAAA" "CNAME" "ANAME" "NS" "TXT" "MX" "SRV" "PTR" "CAA" "TLSA" "SSHFP" "URI"
    • destinationstringrequired

      The record's value.

    • ttlinteger

      TTL in seconds; missing or 0 becomes 120.

    • mx_priorityinteger

      MX priority. MX only.

    • proxiedboolean

      Proxy the new record. Ignored for a record that already exists (it keeps its setting) and for types that cannot be proxied.

Responses

200Import outcome, plus the domain's full record list afterwards.

Content type: application/json

  • createdinteger
  • overwritteninteger

    Existing records replaced by a staged row of the same name and type.

  • failedarray of object

    Per-row failures. They never abort the batch — everything else was still written.

    Item fields
    • namestring
    • typestring
    • errorstring
  • recordsarray of Record

    The domain's full record list after the commit.

    Item fields
    • idinteger
    • namestring

      Record name relative to the domain. @ is the apex.

    • original_namestring

      The fully-qualified name, with trailing dot.

    • typestring
      One of: "A" "AAAA" "CNAME" "ANAME" "NS" "TXT" "MX" "SRV" "PTR" "CAA" "TLSA" "SSHFP" "URI"
    • destinationstring

      The record's value. For a proxied record this is the origin the edge connects to, and the published DNS answer is the NSIN proxy IP instead — see dns_content.

    • dns_contentstring

      What is actually published in DNS. Equals the proxy IP for proxied records.

    • ttlinteger

      TTL in seconds.

    • proxiedboolean

      Route this hostname through the NSIN edge. Only A, AAAA, CNAME and ANAME may be proxied.

    • captchaboolean

      Challenge visitors before passing them to the origin.

    • editableboolean

      False for records NSIN manages on your behalf.

    • managed_bystring

      The platform feature that owns this record, or empty for a record you created. email_routing marks the MX, SPF and DKIM rows Email Routing publishes; they are removed by disabling routing, never through the record endpoints (which refuse them while locked).

    • user_idinteger
    • domain_idinteger
    • schemestring

      Protocol the edge uses to reach the origin of a proxied record.

      • Https — TLS to port (443 when the port is unset or out of range).
      • Http — plain HTTP to port (80 when unset or out of range).
      • Auto — HTTPS on 443 first, falling back to plain HTTP. The port is always 443.
      • Default — accepted on input, and so are an empty or unrecognised value, but stored as Auto with port 443: a record never reads back as Default.
      One of: "Http" "Https" "Auto" "Default"
    • portinteger

      Origin port for proxied records: 443 for Auto, otherwise as set (default 443 for Https, 80 for Http).

    • host_headerstring

      Overrides the Host header (and SNI) sent to the origin.

    • host_header_modestring

      Which name a proxied CNAME/ANAME sends to its origin as the Host header (and SNI) when host_header is empty: empty — the record's own hostname (the default); target — the hostname it points at.

      One of: "" "target"
    • gateway_preset_idinteger | null

      The gateway this record was created for, or null for a record you made. A gateway record is not editable here; rename or remove it through the gateway endpoints.

    • gateway_allowed_hostsstring

      Gateway records only: a JSON array, as a string, of the other hostnames the gateway's service links to. The edge serves them under /_nsin/<host>/ on the gateway hostname.

    • gateway_rewrite_urlsboolean

      Gateway records only — whether the edge rewrites URLs in responses to go through the gateway.

    • monitorboolean

      Include this record in uptime monitoring.

    • timeoutinteger

      How long an edge node waits for the origin to start responding before returning 504, in seconds. Default 60, maximum 1800 (30 minutes). Only applies to proxied records.

      Default: 60
    • mx_priorityinteger

      Only meaningful for MX.

    • commentstring

      Free-form note.

    • created_atstring (date-time)
    • updated_atstring (date-time)
    • deleted_atstring | null (date-time)

      Always null — deleted records are never returned.

    • edge_statusstring

      External-DNS domains, proxied records only. Whether the name resolves to NSIN's edge, as last checked: ok — every address it resolves to is ours; miss — it resolves elsewhere, only partly to us, or not at all; error — the first lookup failed and nothing is known yet. Absent until the first check, and always absent on a managed-DNS domain.

      One of: "ok" "miss" "error"
    • edge_viastring

      How an ok record reaches NSIN: through the CNAME target (cname), by publishing our address directly (a), or proxy — DNS points at another CDN or proxy, but that service forwards to NSIN and the edge is serving the host (judged from the last 24h of request logs). A CNAME keeps working when our addresses change; an A record does not.

      One of: "cname" "a" "proxy"
    • edge_detailstring

      What the name actually resolves to, for display.

    • edge_checked_atstring (date-time)
json
{
  "created": 0,
  "overwritten": 0,
  "failed": [
    {
      "name": "string",
      "type": "string",
      "error": "string"
    }
  ],
  "records": [
    {
      "id": 0,
      "name": "www",
      "original_name": "www.example.com.",
      "type": "A",
      "destination": "string",
      "dns_content": "string",
      "ttl": 0,
      "proxied": true,
      "captcha": true,
      "editable": true,
      "managed_by": "string",
      "user_id": 0,
      "domain_id": 0,
      "scheme": "Http",
      "port": 0,
      "host_header": "string",
      "host_header_mode": "",
      "gateway_preset_id": 0,
      "gateway_allowed_hosts": "string",
      "gateway_rewrite_urls": true,
      "monitor": true,
      "timeout": 60,
      "mx_priority": 0,
      "comment": "string",
      "created_at": "2026-01-01T00:00:00Z",
      "updated_at": "2026-01-01T00:00:00Z",
      "deleted_at": "2026-01-01T00:00:00Z",
      "edge_status": "ok",
      "edge_via": "cname",
      "edge_detail": "string",
      "edge_checked_at": "2026-01-01T00:00:00Z"
    }
  ]
}
400Nothing to commit — mode: "selected" with no usable rows, or a session whose every row was unsupported.

Content type: application/json

  • errorstringrequired

    Human-readable description of what went wrong.

json
{
  "error": "no records to import"
}
401Missing, malformed, revoked or expired API key. (A valid key whose account has been deactivated gets 403 account is inactive instead.)

Content type: application/json

  • errorstringrequired

    Human-readable description of what went wrong.

json
{
  "error": "invalid API key"
}
402The domain has no active plan, so records cannot be created.

Content type: application/json

  • errorstringrequired

    Human-readable description of what went wrong.

json
{
  "error": "read-only API key"
}
403Read-only key, insufficient role, or the import would exceed the plan's record limit. The session stays ready and can be committed again after an upgrade.

Content type: application/json

  • errorstringrequired

    Human-readable description of what went wrong.

json
{
  "error": "read-only API key"
}
404No such domain or import session, the session belongs to another domain, or the domain is not visible to this account.

Content type: application/json

  • errorstringrequired

    Human-readable description of what went wrong.

json
{
  "error": "import session not found"
}
409The domain is disabled, the session is not ready, or somebody else — a second click, or the auto-commit — already claimed it. The body carries the session's current status.

Content type: application/json

  • errorstringrequired

    Human-readable description of what went wrong.

  • statusstring

    The session's status as it stands now, so a loser of the claim race can tell "already committed" from "discarded".

json
{
  "error": "string",
  "status": "string"
}
429The key exceeded its request budget (300 requests per minute by default).

Content type: application/json

  • errorstringrequired

    Human-readable description of what went wrong.

json
{
  "error": "rate limit exceeded"
}

Example request

bash
curl -X POST "https://api.nsin.ir/domains/example.com/records/import-sessions/0/commit" \
  -H "Authorization: Bearer $NSIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "mode": "all",
  "records": [
    {
      "name": "string",
      "type": "A",
      "destination": "string",
      "ttl": 0,
      "mx_priority": 0,
      "proxied": true
    }
  ]
}'
esc