Skip to the page

REST API

Domains

Domains: 6 endpoints of the REST API.

GET/domains

List domains

The domains of this environment: its platform host first, then custom domains in the order they were added, each with status, verification times and the last check.

Secret key scope (any of): domains:write

Parameters

FieldTypeDescription
limit (query)integer

Items per page (1–100).

cursor (query)string

next_cursor of the previous page; omit for the first page. A cursor only works with the sort order it was issued for.

type (query)"shared" | "custom"

Only shared or only custom domains.

Responses

200 A page of domains.

FieldTypeDescription
datarequiredobject[]
data[].idrequiredstring
data[].environmentrequired"test" | "live"
data[].hostnamerequiredstring

Normalized (lowercase, punycode) hostname.

data[].typerequired"shared" | "custom"

shared is the project host on the platform domain; custom is your own.

data[].statusrequired"pending_dns" | "verifying" | "issuing_ssl" | "active" | "dns_misconfigured" | "ssl_failed" | "suspended"

pending_dns (added, never checked), verifying (checked, ownership not proven yet), issuing_ssl (DNS is right, certificate pending), active (serves links), dns_misconfigured and ssl_failed (fix and re-verify), suspended (contact support).

data[].dns_recordsrequiredobject[] | null

The records to create for a custom domain (a CNAME to the edge host, or an A/AAAA record to its addresses, plus the ownership TXT); null for shared domains.

data[].verified_atrequiredstring (date-time) | null

When ownership was first proven; null until then.

data[].last_checked_atrequiredstring (date-time) | null
data[].failed_check_countrequiredinteger

Consecutive failed checks.

data[].failing_sincerequiredstring (date-time) | null
data[].cert_expires_atrequiredstring (date-time) | null
data[].suspended_atrequiredstring (date-time) | null
data[].created_atrequiredstring (date-time)
data[].updated_atrequiredstring (date-time)
next_cursorrequiredstring | null

Pass as cursor to get the next page; null on the last page.

custom_domains_enabledboolean

Whether this deployment lets projects add custom domains. When false, adding one is a 403 feature_disabled, so clients can hide the action up front.

Example

Bash
POST/domains

Add a custom domain

Claims a domain or subdomain you own for this environment, e.g. go.acme.com. The response carries dns_records: a CNAME to the edge host and a TXT record with your verification token. Create them, then call verify.

A domain another project already holds is a 409 domain_taken, unless that claim never proved ownership and is older than 7 days. Not available unless the deployment enables custom domains (403 feature_disabled).

Secret key scope (any of): domains:write

Request body

FieldTypeDescription
hostnamerequiredstring

The domain or subdomain to serve links on, e.g. go.acme.com. Normalized (lowercase, punycode); no scheme, path or port. Apex domains need a DNS provider with CNAME flattening (ALIAS/ANAME).

Responses

201 The pending domain.

FieldTypeDescription
idrequiredstring
environmentrequired"test" | "live"
hostnamerequiredstring

Normalized (lowercase, punycode) hostname.

typerequired"shared" | "custom"

shared is the project host on the platform domain; custom is your own.

statusrequired"pending_dns" | "verifying" | "issuing_ssl" | "active" | "dns_misconfigured" | "ssl_failed" | "suspended"

pending_dns (added, never checked), verifying (checked, ownership not proven yet), issuing_ssl (DNS is right, certificate pending), active (serves links), dns_misconfigured and ssl_failed (fix and re-verify), suspended (contact support).

dns_recordsrequiredobject[] | null

The records to create for a custom domain (a CNAME to the edge host, or an A/AAAA record to its addresses, plus the ownership TXT); null for shared domains.

verified_atrequiredstring (date-time) | null

When ownership was first proven; null until then.

last_checked_atrequiredstring (date-time) | null
failed_check_countrequiredinteger

Consecutive failed checks.

failing_sincerequiredstring (date-time) | null
cert_expires_atrequiredstring (date-time) | null
suspended_atrequiredstring (date-time) | null
created_atrequiredstring (date-time)
updated_atrequiredstring (date-time)

Example

Bash
GET/domains/{domain}

Get a domain

Secret key scope (any of): domains:write

Parameters

FieldTypeDescription
domain (path)requiredstring

The ID of the domain.

Responses

200 The domain.

FieldTypeDescription
idrequiredstring
environmentrequired"test" | "live"
hostnamerequiredstring

Normalized (lowercase, punycode) hostname.

typerequired"shared" | "custom"

shared is the project host on the platform domain; custom is your own.

statusrequired"pending_dns" | "verifying" | "issuing_ssl" | "active" | "dns_misconfigured" | "ssl_failed" | "suspended"

pending_dns (added, never checked), verifying (checked, ownership not proven yet), issuing_ssl (DNS is right, certificate pending), active (serves links), dns_misconfigured and ssl_failed (fix and re-verify), suspended (contact support).

dns_recordsrequiredobject[] | null

The records to create for a custom domain (a CNAME to the edge host, or an A/AAAA record to its addresses, plus the ownership TXT); null for shared domains.

verified_atrequiredstring (date-time) | null

When ownership was first proven; null until then.

last_checked_atrequiredstring (date-time) | null
failed_check_countrequiredinteger

Consecutive failed checks.

failing_sincerequiredstring (date-time) | null
cert_expires_atrequiredstring (date-time) | null
suspended_atrequiredstring (date-time) | null
created_atrequiredstring (date-time)
updated_atrequiredstring (date-time)

Example

Bash
DELETE/domains/{domain}

Remove a custom domain

Removes a custom domain. Its links stop resolving at once and stay disabled while the domain can still be restored (30 days). The platform host of an environment cannot be removed (409).

Secret key scope (any of): domains:write

Parameters

FieldTypeDescription
domain (path)requiredstring

The ID of the domain.

Responses

204 The domain is removed.

Example

Bash
GET/domains/{domain}/diagnostics

Diagnose a domain

Expected against found DNS records and, for each configured app, whether the host serves a correct apple-app-site-association (Team ID and bundle ID) and assetlinks.json (package name and signing fingerprints). The files are fetched over HTTPS from the host with the same rules Apple and Google apply (no redirects, status 200, JSON).

Secret key scope (any of): domains:write

Parameters

FieldTypeDescription
domain (path)requiredstring

The ID of the domain.

Responses

200 The diagnostics.

FieldTypeDescription
domain_idrequiredstring
hostnamerequiredstring
typerequired"shared" | "custom"
statusrequired"pending_dns" | "verifying" | "issuing_ssl" | "active" | "dns_misconfigured" | "ssl_failed" | "suspended"
checked_atrequiredstring (date-time)
dnsrequiredobject[]

Empty for shared domains: their DNS is ours.

dns[].purposerequired"routing" | "ownership"
dns[].typerequired"CNAME" | "TXT"
dns[].namerequiredstring
dns[].expectedrequiredstring[]

What the record should hold. Routing accepts either the CNAME target or an address that belongs to it.

dns[].foundrequiredstring[]

What DNS answers right now.

dns[].statusrequired"ok" | "missing" | "mismatch" | "lookup_failed"
dns[].viarequired"cname" | "address" | null

For routing: how the host reaches the edge (a CNAME chain or a shared address).

dns[].detailrequiredstring | null

A hint when the record is not right.

iosrequiredobject
ios.platformrequired"ios" | "android"
ios.urlrequiredstring
ios.sourcerequired"fetched" | "generated" | "skipped"

fetched over HTTPS from the host; generated from the shared generators (platform hosts without a public HTTPS endpoint, i.e. local development); skipped when the app is not configured or the host cannot serve yet.

ios.configuredrequiredboolean

The environment has this platform configured.

ios.http_statusrequiredinteger | null
ios.content_typerequiredstring | null
ios.valid_jsonrequiredboolean | null
ios.expectedrequiredobject
ios.expected.identifiersrequiredstring[]

iOS: app IDs (TEAMID.bundle.id). Android: package names.

ios.expected.fingerprintsrequiredstring[]

Android SHA-256 signing fingerprints; empty for iOS.

ios.foundrequiredobject
ios.found.identifiersrequiredstring[]

iOS: app IDs (TEAMID.bundle.id). Android: package names.

ios.found.fingerprintsrequiredstring[]

Android SHA-256 signing fingerprints; empty for iOS.

ios.matchesrequiredboolean | null

True when the served file names this app; null when nothing was compared.

ios.problemsrequiredobject[]
ios.problems[].coderequired"not_configured" | "unreachable" | "blocked_address" | "not_found" | "redirected" | "unexpected_status" | "wrong_content_type" | "too_large" | "invalid_json" | "wrong_structure" | "identifier_missing" | "fingerprint_missing"
ios.problems[].messagerequiredstring
androidrequiredobject
android.platformrequired"ios" | "android"
android.urlrequiredstring
android.sourcerequired"fetched" | "generated" | "skipped"

fetched over HTTPS from the host; generated from the shared generators (platform hosts without a public HTTPS endpoint, i.e. local development); skipped when the app is not configured or the host cannot serve yet.

android.configuredrequiredboolean

The environment has this platform configured.

android.http_statusrequiredinteger | null
android.content_typerequiredstring | null
android.valid_jsonrequiredboolean | null
android.expectedrequiredobject
android.expected.identifiersrequiredstring[]

iOS: app IDs (TEAMID.bundle.id). Android: package names.

android.expected.fingerprintsrequiredstring[]

Android SHA-256 signing fingerprints; empty for iOS.

android.foundrequiredobject
android.found.identifiersrequiredstring[]

iOS: app IDs (TEAMID.bundle.id). Android: package names.

android.found.fingerprintsrequiredstring[]

Android SHA-256 signing fingerprints; empty for iOS.

android.matchesrequiredboolean | null

True when the served file names this app; null when nothing was compared.

android.problemsrequiredobject[]
android.problems[].coderequired"not_configured" | "unreachable" | "blocked_address" | "not_found" | "redirected" | "unexpected_status" | "wrong_content_type" | "too_large" | "invalid_json" | "wrong_structure" | "identifier_missing" | "fingerprint_missing"
android.problems[].messagerequiredstring

Example

Bash
POST/domains/{domain}/verify

Re-verify a domain

Checks the domain now: the ownership TXT record, the CNAME (or address) to the edge and, while the certificate is pending, HTTPS. The status moves accordingly: verifying, dns_misconfigured, issuing_ssl, active or ssl_failed. A lookup that fails (DNS temporarily unavailable) changes nothing (inconclusive). A domain can be checked once every 30 seconds (429 with Retry-After). Shared platform hosts are always active.

Secret key scope (any of): domains:write

Parameters

FieldTypeDescription
domain (path)requiredstring

The ID of the domain.

Responses

200 The domain after the check, and what the check found.

FieldTypeDescription
domainrequiredobject
domain.idrequiredstring
domain.environmentrequired"test" | "live"
domain.hostnamerequiredstring

Normalized (lowercase, punycode) hostname.

domain.typerequired"shared" | "custom"

shared is the project host on the platform domain; custom is your own.

domain.statusrequired"pending_dns" | "verifying" | "issuing_ssl" | "active" | "dns_misconfigured" | "ssl_failed" | "suspended"

pending_dns (added, never checked), verifying (checked, ownership not proven yet), issuing_ssl (DNS is right, certificate pending), active (serves links), dns_misconfigured and ssl_failed (fix and re-verify), suspended (contact support).

domain.dns_recordsrequiredobject[] | null

The records to create for a custom domain (a CNAME to the edge host, or an A/AAAA record to its addresses, plus the ownership TXT); null for shared domains.

domain.verified_atrequiredstring (date-time) | null

When ownership was first proven; null until then.

domain.last_checked_atrequiredstring (date-time) | null
domain.failed_check_countrequiredinteger

Consecutive failed checks.

domain.failing_sincerequiredstring (date-time) | null
domain.cert_expires_atrequiredstring (date-time) | null
domain.suspended_atrequiredstring (date-time) | null
domain.created_atrequiredstring (date-time)
domain.updated_atrequiredstring (date-time)
checkrequiredobject
check.outcomerequired"passed" | "pending" | "failed" | "inconclusive" | "not_applicable"

passed (active), pending (DNS is right, the certificate is being issued), failed (see the probes), inconclusive (a DNS lookup failed; nothing changed, retry), not_applicable (shared domains need no checks).

check.ownershiprequired"ok" | "fail" | "unknown" | "not_checked"

The TXT record holds the token.

check.routingrequired"ok" | "fail" | "unknown" | "not_checked"

The CNAME or the addresses point at the edge.

check.certificaterequired"ok" | "fail" | "unknown" | "not_checked"

HTTPS answers with a valid certificate; only probed while issuing it.

check.checked_atrequiredstring (date-time)

Example

Bash