Domains API

Add and verify LinkTrail link domains over the REST API: subdomains, custom domains with their DNS records, the verify checks, and the association files.

Note

Every endpoint on this page needs Authorization: Bearer <accessToken> and X-Workspace-Id: <id> — see Authentication. Paths are relative to https://backend.linktrail.io/v1.

MethodPathWhat it does
GET/domainsList domains (paginated; filter with ?type=)
POST/domainsAdd a subdomain or custom domain
GET/domains/:domainIdLoad one domain
PATCH/domains/:domainIdChoose which apps the domain serves
DELETE/domains/:domainIdRemove (archive) a domain
POST/domains/:domainId/verifyRe-run the DNS and TLS checks
GET/domains/:domainId/well-knownPreview the AASA and assetlinks this host serves

Reading needs any role; writing needs developer, admin or owner. The setup walkthrough is in Domains & Association Files.

The domain object

DomainJSON
{ "id": 1, "host": "acme.linktrail.io", "type": "Subdomain", "status": "active", "tls": true,
  "aasa": true, "assetlinks": true, "verified": true, "apps": 2, "associatedAppIds": [1, 2],
  "links": 3, "dns": [] }
  • status is the host's provisioning state: pending_dns → pending_tls → active. Subdomains are active as soon as they are created. A custom domain's short links redirect only once it is active.
  • aasa, assetlinks and verified say whether the workspace has apps this host can serve association files for. They are unrelated to status.
  • links is how many short links would stop redirecting if the domain were removed.

Add a custom domain

POST /v1/domains — requestJSON
{ "host": "links.acme.com", "type": "Custom" }
201 responseJSON
{ "id": 12, "host": "links.acme.com", "type": "Custom", "status": "pending_dns", "tls": false,
  "dns": [
    { "type": "CNAME", "name": "links.acme.com", "value": "custom.linktrail.io" },
    { "type": "TXT", "name": "_linktrail.links.acme.com", "value": "linktrail-verify=<token>" }
  ] }

type is Subdomain or Custom. Custom domains need the Growth or Scale plan; without it, or past the plan's custom-domain count, the call answers 402. A host already used by another workspace answers 400.

Verify

POST /domains/:domainId/verify checks the CNAME, then the TXT record, then TLS, and returns the domain with a checks breakdown (null for subdomains). Poll it while status starts with pending_. TLS is not checked until both DNS records pass.

POST /v1/domains/12/verify → 200JSON
{ "id": 12, "status": "pending_tls", "tls": false,
  "checks": {
    "cname": { "ok": true, "state": "ok" },
    "txt":   { "ok": true, "state": "ok" },
    "tls":   { "ok": false, "state": "pending",
               "message": "Certificate is being issued — this usually takes a few minutes." }
  } }

Each check's state is ok, missing, conflict or pending. On a failure it also carries expected, found, conflicting (for a conflict) and a message that names the fix — for example an A record that has to go before the CNAME can work.

Apps and removal

  • PATCH /domains/:domainId with { "associatedAppIds": [1, 2] } limits the association files to those apps. Empty or omitted, the domain serves every app in the workspace.
  • DELETE answers 204 and archives the domain: its short links stop redirecting and it serves no association files, but the links stay in place. Adding the same host again from the same workspace restores the domain and its links. A subdomain comes back active; a custom domain comes back pending_dns and must be verified again (its verification token is kept) before its links redirect.