# DNS & nameservers ## Hosted vs. external DNS A domain's DNS lives wherever its **nameservers** point: - **Our nameservers** (`ns1.ingram.tech` / `ns2.ingram.tech` — the default at registration): the domain gets a hosted zone you manage here, via the API, the dashboard's DNS tab, or the assistant. - **External nameservers** (e.g. Cloudflare): DNS is managed at that provider. Zone endpoints answer `409 no_hosted_zone`, and the dashboard's DNS tab shows where the delegation points instead. Transfers keep independent DNS and move DNS run by the losing registrar here, records included. See [Keeping DNS working](/docs/transfers#keeping-dns-working). Switch delegation any time from the domain's **Nameservers tab** in the dashboard, or by asking the [assistant](/docs/agents) ("switch example.com to your nameservers"). Nameserver changes are free. A REST endpoint for delegation changes is on the roadmap; today the API manages records, not delegation. ## Managing records Record types: `A`, `AAAA`, `CNAME`, `MX`, `TXT`, `NS`, `CAA`, `SRV`. Changes propagate from our nameservers in ~30 seconds (subject to record TTLs downstream). ```bash # List curl -s https://domains.ingram.tech/api/v1/domains/example.com/zone \ -H "authorization: Bearer $INGRAM_TOKEN" # Create curl -s -X POST https://domains.ingram.tech/api/v1/domains/example.com/zone \ -H "authorization: Bearer $INGRAM_TOKEN" -H 'content-type: application/json' \ -H 'idempotency-key: 7e2f1c9a-dns-1' \ -d '{"subdomain": "app", "type": "A", "value": "203.0.113.10", "ttl": 3600}' # Delete — a record is identified by its subdomain + type + value triple curl -s -X DELETE 'https://domains.ingram.tech/api/v1/domains/example.com/zone?subdomain=app&type=A&value=203.0.113.10' \ -H "authorization: Bearer $INGRAM_TOKEN" -H 'idempotency-key: 7e2f1c9a-dns-2' ``` ### Importing a zone file Most DNS providers can export a zone as a BIND file. Import one to bring over a whole zone, or to fill in records a transfer couldn't discover: ```bash curl -s -X POST https://domains.ingram.tech/api/v1/domains/example.com/zone/import \ -H "authorization: Bearer $INGRAM_TOKEN" -H 'content-type: application/json' \ -H 'idempotency-key: 7e2f1c9a-dns-import-1' \ --data-binary @<(jq -Rs '{zone_file: .}' example.com.zone) ``` The import only adds records. Records already in the zone are left alone, and a record that would conflict with one (a CNAME next to other records) comes back in `skipped` with the reason. Set `"replace": true` to let the file win for A/AAAA/MX/CNAME records at the names it sets. SOA, the root NS records and DNSSEC records are ignored, because the zone's host provides its own. Types we don't host are counted in `notImportable`. If the domain's DNS is elsewhere, add `"move_here": true` to switch it to Ingram DNS and load the file into the new zone. Without it, the call answers `409 no_hosted_zone`. The dashboard's DNS tab has the same action (**Import zone file**), with a preview of what will and won't be imported. The CLI has `domains dns import example.com example.com.zone`. There is no record id: updates are delete + create of the identifying triple (the dashboard's edit form does exactly this). `MX` and `SRV` records take a `priority`; `SRV` additionally understands service/protocol/weight/port fields. ## DNSSEC Toggle per domain — `PATCH /api/v1/domains/{name}/settings` with `{"dnssec": true}`, or the domain's Security tab. Signing is handled on our nameservers; DNSSEC on an externally-delegated domain is managed at the external provider instead.