> ## Documentation Index
> Fetch the complete documentation index at: https://docs.teasy.link/api-v1/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom Domains

> Connecting a domain, verifying it, and what disconnecting costs.

Serving links from your own hostname takes two steps: register it with us, then prove it is yours
by adding the DNS records we hand back.

[`POST /v1/domains`](/api-v1/api-v1/api-reference/domains/connect-a-domain) returns the domain with
`dns_instructions`. Add those records at your DNS provider; verification happens on our side
afterwards.

```json theme={null}
{
  "id": "dom_c47b1f9e2a8d4e6fb35c0a71d8e94f22",
  "object": "domain",
  "hostname": "links.example.com",
  "status": "pending",
  "expires_at": "2026-08-17T10:00:00Z",
  "created_at": "2026-08-14T10:00:00Z",
  "dns_instructions": []
}
```

<Tip>
  Domain verification depends on DNS propagation time. To be updated you can poll `GET /v1/domains/{id}` to watch the status change.
</Tip>

## Statuses

| Status        | Meaning                                 |
| ------------- | --------------------------------------- |
| `pending`     | Waiting for the DNS records to appear   |
| `ssl_pending` | Records found, certificate being issued |
| `active`      | Serving traffic                         |
| `failed`      | Verification did not complete in time   |

Links start working once the domain is `active`. There is no way to trigger a re-check through
the API.

[`GET /v1/domains`](/api-v1/api-v1/api-reference/domains/list-domains) returns your own domains

## DNS instructions

```json theme={null}
"dns_instructions": [
  {
    "type": "CNAME",
    "name": "links",
    "value": "cname.teasy.link",
    "purpose": "traffic_routing"
  },
  {
    "type": "CNAME",
    "name": "_acme-challenge.links.example.com",
    "value": "links.example.com.xxxxxxxx.dcv.cloudflare.com",
    "purpose": "ssl_auto_renewal"
  },
  {
    "type": "TXT",
    "name": "_cf-custom-hostname.links.example.com",
    "value": "unique_string",
    "purpose": "ownership_verification"
  }
]
```

## Disconnecting

[`DELETE /v1/domains/{id}`](/api-v1/api-v1/api-reference/domains/disconnect-a-domain) has side effects and
asks for no confirmation:

* Links on the domain move to the system domain and are **switched off**.
* Colliding slugs will be changed.
* Previous addresses stop working either way.

```json theme={null}
{
  "id": "dom_c47b1f9e2a8d4e6fb35c0a71d8e94f22",
  "object": "domain",
  "deleted": true,
  "message": "Domain deleted. 12 links were moved to the system domain and deactivated.",
  "deactivated_links": 12
}
```

There is no update endpoint — the only thing that changes on a domain is its status. To change a
hostname, connect the new one and disconnect the old one.
