---
title: "Import a zone file or add records to the managed zone"
method: POST
path: "/connections/{id}/managed-dns/records"
tags: ["Managed DNS"]
---

# Import a zone file or add records to the managed zone

`POST /connections/{id}/managed-dns/records`

## Request

- Base URL: `https://api.customdomain.ai/v1`
- URL: `https://api.customdomain.ai/v1/connections/{id}/managed-dns/records`
- Auth: one of:
  - HTTP bearer
  - HTTP bearer

Send exactly one of `zone_file` (a BIND zone file, at most 256 KB) or `records` (at most 500). Records from a zone file are `imported`: for every name and type the file defines, they replace what discovery found. Listed records are `manual` and are added alongside what is there. Records CustomDomain™ needs for the connection always win: an imported record that collides with one is skipped with a note, and a listed one is refused with 409. Zone file lines that can't be hosted (SOA, the zone's own NS set, unsupported types, names outside the zone) are skipped, each with a warning naming its line. A zone holds at most 500 records.

Once the zone is `active`, only an API key or an app-scoped widget token may change it; an end user's connect-scoped token may change the zone only during setup.

## Path parameters

- `id` string, required

## Request body

- ManagedDNSRecordsRequest: Exactly one of zone_file or records.
  - `zone_file` string: A BIND zone file (RFC 1035 master format).
  - `records` ManagedDNSRecordInput[]
    - `type` 'A' | 'AAAA' | 'CNAME' | 'MX' | 'TXT' | 'SRV' | 'CAA' | 'NS', required
    - `name` string, required: Relative to the zone ("@", "www", "_dmarc") or fully qualified inside it.
    - `value` string, required: Same forms as ManagedDNSRecord.value.
    - `ttl` integer: Seconds; default 3600, clamped to 60 to 604800.
    - `priority` integer, nullable: MX preference (default 10) or SRV priority (default 0).

## Response `200`

The zone after the change.

- ManagedDNSView
  - `zone` string, required: The hosted zone: the registrable domain.
  - `status` 'awaiting_delegation' | 'active' | 'failed', required: `awaiting_delegation`: the zone holds the records; set the nameservers below at the registrar. `active`: every nameserver the registry lists is ours. `failed`: the switch never happened within 14 days, or the nameservers moved away again (the first warning says which); a failed zone keeps being checked and turns active once the delegation appears.
  - `nameservers` string[], required: The nameservers to set at the registrar.
  - `observed_nameservers` string[], required: The nameservers the registry listed at the last check.
  - `registrar` object, nullable, required: The domain's registrar from RDAP, or null when unknown.
    - `name` string, required
    - `url` string, required: The registrar's website, or an empty string.
  - `records` ManagedDNSRecord[], required
    - `id` string, required: Stable id derived from the record content.
    - `type` 'A' | 'AAAA' | 'CNAME' | 'MX' | 'TXT' | 'SRV' | 'CAA' | 'NS', required
    - `name` string, required: Fully qualified owner name, lower case ("acme.com" is the apex, "*.acme.com" a wildcard).
    - `value` string, required: A/AAAA: the address. CNAME/NS/MX: the target host ("." for a null MX). TXT: the text. SRV: "<weight> <port> <target>". CAA: `<flags> <tag> "<value>"`.
    - `ttl` integer, required: Seconds.
    - `priority` integer, nullable, required: MX preference or SRV priority; null for other types.
    - `source` 'discovered' | 'imported' | 'customdomain' | 'manual', required: Where the record came from. `customdomain` records are the ones CustomDomain™ needs for connected domains; they win every conflict and can't be removed here.
  - `warnings` string[], required: Plain-language notes for the user (a partial delegation, records a zone file import skipped, records replaced).
  - `checked_at` string, date-time, required: When the delegation was last checked.
  - `activated_at` string, date-time, nullable, required

## Other responses

- `400`: Error envelope: {code, title, details}.
- `401`: Error envelope: {code, title, details}.
- `403`: Error envelope: {code, title, details}.
- `404`: Error envelope: {code, title, details}.
- `409`: Error envelope: {code, title, details}.
- `413`: Error envelope: {code, title, details}.
- `422`: `invalid_zone_file` (nothing in the file can be hosted) or `too_many_records` (the zone would pass 500 records).
- `503`: Error envelope: {code, title, details}.

---

[API](https://skmtc.dev/customdomain/apis/customdomain-control-plane-api.md) · [All operations](https://skmtc.dev/customdomain/apis/customdomain-control-plane-api/llms.txt) · [OpenAPI document](https://skmtc.dev/customdomain/apis/customdomain-control-plane-api/revisions/34d89cb7a7cd?raw)
