# Quickstart

From a new key to a live TXT record in five calls. The examples are Dynadot style, the simplest to read; every [API style](https://maildns.io/docs.md#api-styles) has the same calls in its own shape, and the same key works in all of them. They use the host `advisor.example.com`: use one of yours, and replace `KEY` (and `SECRET` where a style needs one) with yours.

## Before you start

- You have a MailDNS key. For Spaceship-style calls you also have its secret.
- If your key is locked to IP addresses, run these from one of them. From anywhere else the key reads as `invalid key`.
- Any HTTP client works. The examples use `curl`; the [Google Workspace recipe](https://maildns.io/docs/google-workspace.md) has the same flow in Python.

## 1. Check the key

```bash
curl 'https://api.maildns.io/api3.json?key=KEY&command=account_info'
```

```json
{
  "AccountInfoResponse": {
    "ResponseCode": 0,
    "Status": "success",
    "AccountInfo": {"Username": "acme-inboxes", "Hosts": "3"}
  }
}
```

`Username` is the name your key was issued under; `Hosts` is how many hosts it reaches. If you get `{"Response": {"ResponseCode": "-1", "Error": "invalid key"}}`, check the key and the IP address you are calling from.

## 2. List your hosts

```bash
curl 'https://api.maildns.io/api3.json?key=KEY&command=list_domain'
```

```json
{
  "ListDomainInfoResponse": {
    "ResponseCode": 0,
    "Status": "success",
    "MainDomains": [
      {
        "Name": "advisor.example.com",
        "RootDomain": "example.com",
        "Expiration": "1798761600000",
        "Registration": "1735689600000",
        "NameServerSettings": {"Type": "Dynadot DNS"},
        "Status": "active"
      }
    ]
  }
}
```

One entry per host. `Name` is the host; `RootDomain` is the registered domain it lives in.

## 3. Read a host's records

```bash
curl 'https://api.maildns.io/api3.json?key=KEY&command=get_dns&domain=advisor.example.com'
```

```json
{
  "GetDnsResponse": {
    "ResponseCode": 0,
    "Status": "success",
    "GetDns": {
      "NameServerSettings": {
        "Type": "Dynadot DNS",
        "MainDomains": [],
        "SubDomains": [],
        "TTL": "3600"
      }
    }
  }
}
```

A new host has no records yet. `MainDomains` are records at the host; `SubDomains` are records under it.

## 4. Add a TXT record

Writes go as a form-encoded `POST`, so long values and your key stay out of the URL. `--data-urlencode` encodes each value for you.

```bash
curl https://api.maildns.io/api3.json \
  --data-urlencode key=KEY \
  --data-urlencode command=set_dns2 \
  --data-urlencode domain=advisor.example.com \
  --data-urlencode add_dns_to_current_setting=1 \
  --data-urlencode main_record_type0=txt \
  --data-urlencode main_record0=google-site-verification=3J9tq0iV8pTt1yW5zKc2mE7aR4bN6hD0sF1gL8xQ
```

```json
{"SetDnsResponse": {"ResponseCode": 0, "Status": "success"}}
```

> **Always send `add_dns_to_current_setting=1`** unless you mean to replace every record on the host. Without it, `set_dns2` replaces the host's records with exactly the ones in the call. See [replace calls](https://maildns.io/docs/hosts.md#replace-calls-work-per-host).

## 5. Wait until it is live

The write returned once the record was saved at the authoritative nameservers. Before you ask Google to verify, check that every one of them serves it:

```bash
curl https://api.maildns.io/api3.json \
  --data-urlencode key=KEY \
  --data-urlencode command=dns_status \
  --data-urlencode domain=advisor.example.com \
  --data-urlencode subdomain=@ \
  --data-urlencode record_type=txt \
  --data-urlencode value=google-site-verification=3J9tq0iV8pTt1yW5zKc2mE7aR4bN6hD0sF1gL8xQ
```

```json
{
  "DnsStatusResponse": {
    "ResponseCode": 0,
    "Status": "success",
    "Records": [
      {
        "Name": "advisor.example.com",
        "RecordType": "TXT",
        "Value": "google-site-verification=3J9tq0iV8pTt1yW5zKc2mE7aR4bN6hD0sF1gL8xQ",
        "Live": "yes",
        "Servers": {"ns1.example.net": "yes", "ns2.example.net": "yes"}
      }
    ]
  }
}
```

`Live` is `yes` once every nameserver answers with the record. Until then, ask again every 15 seconds or so. Usually it is `yes` on the first or second try. More in [Checking propagation](https://maildns.io/docs/propagation.md).

## The same five calls, Spaceship style

```bash
# 1 + 2. Your hosts (a wrong key or secret is HTTP 401)
curl 'https://api.maildns.io/api/v1/domains?take=100' \
  -H 'X-API-Key: KEY' -H 'X-API-Secret: SECRET'

# 3. A host's records
curl 'https://api.maildns.io/api/v1/dns/records/advisor.example.com?take=500' \
  -H 'X-API-Key: KEY' -H 'X-API-Secret: SECRET'

# 4. Add a TXT record (HTTP 204, no body)
curl -X PUT https://api.maildns.io/api/v1/dns/records/advisor.example.com \
  -H 'X-API-Key: KEY' -H 'X-API-Secret: SECRET' -H 'Content-Type: application/json' \
  -d '{"force": false, "items": [{"type": "TXT", "name": "@", "ttl": 3600,
       "value": "google-site-verification=3J9tq0iV8pTt1yW5zKc2mE7aR4bN6hD0sF1gL8xQ"}]}'

# 5. Is it live?
curl -G https://api.maildns.io/api/v1/dns/status/advisor.example.com \
  -H 'X-API-Key: KEY' -H 'X-API-Secret: SECRET' \
  --data-urlencode name=@ --data-urlencode type=TXT \
  --data-urlencode value=google-site-verification=3J9tq0iV8pTt1yW5zKc2mE7aR4bN6hD0sF1gL8xQ
```

## In the other styles

The add call from step 4, for each style. Full examples are on each style's page.

| Style | Add a record |
|---|---|
| [Cloudflare](https://maildns.io/docs/cloudflare.md#create-a-record) | `POST /client/v4/zones/{zone_id}/dns_records` with `{"type": "TXT", "name": "@", "content": "..."}` |
| [GoDaddy](https://maildns.io/docs/godaddy.md#add-records) | `PATCH /v1/domains/advisor.example.com/records` with `[{"type": "TXT", "name": "@", "data": "..."}]` |
| [Porkbun](https://maildns.io/docs/porkbun.md#create-a-record) | `POST /api/json/v3/dns/create/advisor.example.com` with `{"apikey": "KEY", "secretapikey": "SECRET", "name": "", "type": "TXT", "content": "..."}` |
| [Namecheap](https://maildns.io/docs/namecheap.md#write-records) | `namecheap.domains.dns.setHosts` with `SLD=advisor.example`, `TLD=com`, `HostName1=@`, `RecordType1=TXT`, `Address1=...` (replaces: send the host's other records too) |

## Next

- [Hosts](https://maildns.io/docs/hosts.md): addressing a host as its own domain or as root domain plus subhost.
- [Keys and limits](https://maildns.io/docs/keys.md): rate limits, IP locks and record limits.
- [Google Workspace on a subdomain](https://maildns.io/docs/google-workspace.md): verification, MX, SPF, DKIM and DMARC end to end.
