---
title: "List domains"
method: POST
path: "/v2/domains.listDomains"
tags: ["domains"]
---

# List domains

`POST /v2/domains.listDomains`

List the custom domains attached to an environment and their verification status.

Results are paginated and sorted by their id. When `hasMore` is true, send the
returned `cursor` to get the next page. An environment with no domains returns an
empty array, not a 404.

`status: verified` means the domain is verified. Unkey has configured routing and requested a
certificate. Each domain includes its full `dnsRecords`. Each record has a `verified` flag.
The flag shows which records Unkey has read back, so you can see which records are still
missing without a second call. Some providers hide a record from DNS lookups, for example a
proxied or flattened routing record. Such a record stays `false` while it serves traffic.

**Required Permissions**

Your root key must have one of the following permissions:
- `environment.*.read_domain` (to read domains in any environment)
- `environment.<environment_id>.read_domain` (to read domains in a specific environment)

## Request body

- V2DomainsListDomainsRequestBody
  - `project` string, required — Identifies a resource by either its unique ID or its slug. Accepts a prefixed ID (such as 'proj_' or 'app_') or a slug.
  - `app` string, required — Identifies a resource by either its unique ID or its slug. Accepts a prefixed ID (such as 'proj_' or 'app_') or a slug.
  - `environment` string, required — Identifies a resource by either its unique ID or its slug. Accepts a prefixed ID (such as 'proj_' or 'app_') or a slug.
  - `limit` integer — The maximum number of domains one response contains. A small limit makes the response smaller, but makes more requests necessary.
  - `cursor` string — The pagination cursor from the response that came before. Send it to get the next page when that response has `hasMore: true`.
  - `search` string — Free-form text to filter domains. Returns domains whose ID or name contains the search string. Matching is case-insensitive.

## Response `200`

Successfully retrieved the environment's domains.

- V2DomainsListDomainsResponseBody
  - `meta` Meta, required — Metadata object included in every API response. This provides context about the request and is essential for debugging, audit trails, and support inquiries. The `requestId` is particularly important when troubleshooting issues with the Unkey support team.
    - `requestId` string, required — A unique id for this request. Always include this ID when contacting support about a specific API request. This identifier allows Unkey's support team to trace the exact request through logs and diagnostic systems to provide faster assistance.
  - `data` Domain[], required — The domains attached to the environment, sorted by their id. The array is empty when the environment has no domains. This is not an error.
    - `id` string, required — Identifies a resource by either its unique ID or its slug. Accepts a prefixed ID (such as 'proj_' or 'app_') or a slug.
    - `domain` string, required — Fully qualified domain name attached to the environment.
    - `projectId` string, required — The project the domain's environment belongs to.
    - `appId` string, required — The app the domain's environment belongs to.
    - `environmentId` string, required — The environment this domain serves. Traffic to the domain reaches whatever is currently deployed to this environment.
    - `status` 'pending' | 'verifying' | 'verified' | 'failed', required — The verification status of the domain. - `pending`: the domain is created. No DNS check has completed yet. - `verifying`: Unkey checks the DNS records approximately each minute. - `verified`: the domain is verified. Unkey has configured routing and requested a certificate. - `failed`: the required DNS records did not appear within 24 hours. Fix the records, then retry verification.
    - `verificationError` string — Why the most recent verification attempt did not succeed, in plain language. Omitted while verification is progressing normally.
    - `dnsRecords` DnsRecord[], required — The DNS records this domain needs. Create each record at your DNS provider. Each record has a `verified` flag. The flag shows whether Unkey has read that record back, so it tells you which records are still missing.
      - `type` 'CNAME' | 'ALIAS' | 'TXT', required — Record type to create. `ALIAS` is not a real DNS record type: it means an apex-compatible alias, which providers expose as ALIAS, ANAME, or a flattened CNAME. Apex domains cannot hold a plain CNAME, so they receive `ALIAS` where a subdomain receives `CNAME`.
      - `name` string, required — Fully qualified name of the record, ready to use as-is. Some providers want a name relative to the zone instead. Drop the zone and its trailing dot: in zone `acme.com`, `api.acme.com` becomes `api` and `_unkey.api.acme.com` becomes `_unkey.api`. A name equal to the zone itself is usually entered as `@`.
      - `value` string, required — The value to set on the record, exactly as given, including any prefix. Do not trim or reformat it: verification compares the published record against this string. Use the lowest TTL your provider allows until the domain is verified. Verification polls DNS, so a long TTL keeps a stale value cached and can burn the verification window on a value you have already corrected. Raise it afterwards if you want.
      - `ttl` integer, required — Seconds a resolver may cache this record. Set it in your provider alongside the record's name and value.
      - `verified` boolean, required — Whether Unkey has read this record back with the expected value. Use it to see which records are still outstanding. False does not always mean the record is missing. A provider that does not expose the published value to a DNS lookup, such as a proxied or flattened routing record, leaves this false for as long as it serves traffic; such a domain verifies through its TXT record instead. Always false on a domain no check has run against yet.
      - `note` string — What this record is for and any provider-specific caveat that applies to it. Worth surfacing to whoever edits the DNS zone. Treat it as optional: it carries no data the record itself needs, so a future record type may omit it.
    - `createdAt` integer, required — Unix timestamp in milliseconds when the domain was created. The 24 hour verification window runs from here.
    - `updatedAt` integer — Unix timestamp in milliseconds of the last change to this domain. Omitted if it has never changed.
  - `pagination` Pagination, required — Pagination metadata for list endpoints. Provides information necessary to traverse through large result sets efficiently using cursor-based pagination.
    - `cursor` string — Opaque pagination token for retrieving the next page of results. Include this exact value in the cursor field of subsequent requests. Cursors are temporary and may expire after extended periods.
    - `hasMore` boolean, required — Indicates whether additional results exist beyond this page. When true, use the cursor to fetch the next page. When false, you have reached the end of the result set.

## Other responses

- `400` — Bad request
- `401` — Unauthorized
- `403` — Forbidden - The root key or its workspace is disabled. A root key that simply lacks `environment.*.read_domain` receives a 404 instead, so permissions cannot be used to discover which environments exist.
- `404` — Not Found - The environment does not exist in your workspace, or your root key may not read it.
- `429` — Too Many Requests
- `500` — Internal server error

---

[API](https://skmtc.net/unkeyed/apis/unkey-api.md) · [All operations](https://skmtc.net/unkeyed/apis/unkey-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/unkeyed/unkey-api/revisions/fa78aafac89c/schema)
