Platform
ScaiWave ScaiGrid ScaiCore ScaiBot ScaiDrive ScaiKey Models Tools & Services
Solutions
Organisations Developers Internet Service Providers Managed Service Providers AI-in-a-Box
Resources
Support Documentation Blog Downloads
Company
About Research Careers Investment Opportunities Contact
Log in

Import and Export

Move zones in and out of ScaiDNS using BIND zone files, JSON, or CSV. Useful for migrations, backups, and bulk edits.

Base path: /api/v1/domains/{domain_id}/import and /export Required permission: records:create for import, records:read for export

Export#

Get a zone as a BIND-format text file:

bash
1
2
curl https://scaidns.scailabs.ai/api/v1/domains/$DOMAIN_ID/export \
  -H "X-API-Key: $SCAIDNS_API_KEY"
python
1
2
3
4
5
resp = httpx.get(
    f"https://scaidns.scailabs.ai/api/v1/domains/{DOMAIN_ID}/export",
    headers={"X-API-Key": os.environ["SCAIDNS_API_KEY"]},
)
print(resp.json()["zone_file"])
typescript
1
2
3
4
5
6
const resp = await fetch(
  `https://scaidns.scailabs.ai/api/v1/domains/${domainId}/export`,
  { headers: { "X-API-Key": process.env.SCAIDNS_API_KEY! } }
);
const { zone_file } = await resp.json();
console.log(zone_file);

Response:

json
1
2
3
4
5
6
{
  "domain_id": "d_abc123",
  "domain_name": "example.com",
  "format": "bind",
  "zone_file": "$ORIGIN example.com.\n$TTL 3600\n@ SOA ns1.scaidns.scailabs.ai. hostmaster.example.com. (...)\n..."
}

Download as attachment#

For saving directly to a file:

bash
1
2
3
curl https://scaidns.scailabs.ai/api/v1/domains/$DOMAIN_ID/export/download \
  -H "X-API-Key: $SCAIDNS_API_KEY" \
  -o example.com.zone

Returns the zone file as plain text with Content-Disposition: attachment; filename="example.com.zone".

Import#

Import creates records from a zone file, JSON, or CSV input. Three ways to provide the data:

Import from pasted text#

bash
1
2
3
4
5
6
7
8
curl -X POST https://scaidns.scailabs.ai/api/v1/domains/$DOMAIN_ID/import/text \
  -H "X-API-Key: $SCAIDNS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "format": "bind",
    "mode": "merge",
    "content": "www IN A 192.0.2.10\nmail IN A 192.0.2.20"
  }'

Import from file upload#

bash
1
2
3
4
5
curl -X POST https://scaidns.scailabs.ai/api/v1/domains/$DOMAIN_ID/import \
  -H "X-API-Key: $SCAIDNS_API_KEY" \
  -F "file=@example.com.zone" \
  -F "format=bind" \
  -F "mode=merge"
python
1
2
3
4
5
6
7
8
with open("example.com.zone", "rb") as f:
    resp = httpx.post(
        f"https://scaidns.scailabs.ai/api/v1/domains/{DOMAIN_ID}/import",
        headers={"X-API-Key": os.environ["SCAIDNS_API_KEY"]},
        files={"file": f},
        data={"format": "bind", "mode": "merge"},
    )
print(resp.json())
typescript
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
const form = new FormData();
form.append("file", new Blob([zoneFileText]), "example.com.zone");
form.append("format", "bind");
form.append("mode", "merge");

const resp = await fetch(
  `https://scaidns.scailabs.ai/api/v1/domains/${domainId}/import`,
  {
    method: "POST",
    headers: { "X-API-Key": process.env.SCAIDNS_API_KEY! },
    body: form,
  },
);

Formats#

BIND#

Standard zone-file format. Parser handles $ORIGIN, $TTL, comments, and multi-line records:

zone
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
$ORIGIN example.com.
$TTL 3600
@    IN SOA ns1.scaidns.scailabs.ai. hostmaster.example.com. (
     2026042301 ; serial
     3600       ; refresh
     600        ; retry
     604800     ; expire
     600        ; minimum
     )
@    IN NS   ns1.scaidns.scailabs.ai.
@    IN NS   ns2.scaidns.scailabs.ai.
www  IN A    192.0.2.10
mail IN A    192.0.2.20
@    IN MX   10 mail.example.com.
@    IN TXT  "v=spf1 mx -all"

JSON#

Array of record objects:

json
1
2
3
4
5
[
  {"name": "www", "type": "A", "content": "192.0.2.10", "ttl": 300},
  {"name": "mail", "type": "A", "content": "192.0.2.20", "ttl": 300},
  {"name": "@", "type": "MX", "content": "10 mail.example.com.", "ttl": 3600}
]

CSV#

Header row required; columns are name,type,content,ttl,disabled:

csv
name,type,content,ttl,disabled
www,A,192.0.2.10,300,false
mail,A,192.0.2.20,300,false
@,MX,10 mail.example.com.,3600,false

Modes#

Mode Behavior
replace Delete all existing records, then import. Destructive — existing records not in the import are lost
merge Add new records; update existing ones where the (name, type, content) triple matches
skip_existing Add new records only; leave anything that already matches alone

Default is merge if unspecified. Use replace with care and only when you're sure the import is complete.

Preview before importing#

See what would happen without applying:

bash
1
2
3
4
5
6
7
8
curl -X POST https://scaidns.scailabs.ai/api/v1/domains/$DOMAIN_ID/import/preview \
  -H "X-API-Key: $SCAIDNS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "format": "bind",
    "mode": "merge",
    "content": "www IN A 192.0.2.10\ninvalid IN BADTYPE ..."
  }'

Response:

json
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{
  "records": [
    {"name": "www", "type": "A", "content": "192.0.2.10", "ttl": 3600, "action": "create"}
  ],
  "errors": [
    {"line": 2, "message": "Unknown record type: BADTYPE"}
  ],
  "valid_count": 1,
  "error_count": 1
}

Always preview before a replace — the preview shows exactly what will change.

Response#

After an actual import:

json
1
2
3
4
5
6
7
{
  "imported_count": 42,
  "conflict_count": 3,
  "errors": [
    {"line": 15, "message": "CNAME cannot coexist with A at apex"}
  ]
}
  • imported_count — records successfully created or updated.
  • conflict_count — records skipped because of existing conflicts (only in skip_existing mode).
  • errors — records that couldn't be imported with the reason.

Migration pattern#

Moving a zone from another provider:

  1. Export from the source using that provider's tool (usually produces a BIND file).
  2. Create the zone in ScaiDNS (POST /api/v1/domains/).
  3. Validate it (TXT challenge at the source provider).
  4. Preview the import to catch errors: POST /import/preview with mode: merge.
  5. Apply the import: POST /import/text or /import with mode: replace (after the zone's SOA and NS are excluded from the source file, usually automatic).
  6. Delegate NS at the registrar to the ScaiDNS nameservers.
  7. Wait for TTLs to expire at the old provider.
  8. If you want DNSSEC, enable it and publish DS records.

What's next#

Updated 2026-05-17 02:38:20 View source (.md) rev 1