# List domains — GET /v1/projects/{slug}/domains

URL: https://docs.hanzo.ai/docs/openapi/project/get-projects-by-slug-domains

> Returns every custom hostname this site holds: the live ones, plus any pending claim with the DNS records it still owes.

`GET /v1/projects/{slug}/domains`

> [Project →](https://docs.hanzo.ai/docs/openapi/project) · [All API references →](https://docs.hanzo.ai/docs/openapi) · [Get started →](https://docs.hanzo.ai/docs/guides)

|               |                                                   |
| ------------- | ------------------------------------------------- |
| **Address**   | `https://api.hanzo.ai/v1/projects/{slug}/domains` |
| **Method**    | `GET`                                             |
| **Operation** | `get_projects_by_slug_domains`                    |
| **Auth**      | `Authorization: Bearer $HANZO_API_KEY`            |

Returns every custom hostname this site holds: the live ones, plus
any pending claim with the DNS records it still owes.

`domains` is the routing answer — the hosts that are verified right now —
while `claims` is the full panel, one row per host, each saying whether it is
live or pending and, if pending, exactly what to publish.

Scope: a validated principal is required (401 without one) and the site is
resolved within that principal's org, so another tenant's slug is a 404.

## Request

1 field.

| Field  | In   | Type   | Required | Description                                   |
| ------ | ---- | ------ | -------- | --------------------------------------------- |
| `slug` | path | string | yes      | Slug is the project to act on, from the path. |

## Response

| Status    | Body                    | Meaning |
| --------- | ----------------------- | ------- |
| `200`     | project.projectsDomains | ok      |
| `default` | problem-details         | refused |

`200` body — 14 fields.

| Field                      | In   | Type                      | Always | Description                                                                                                                               |
| -------------------------- | ---- | ------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `claims`                   | body | project.projectsDomain\[] | —      | Claims is one row per host — live, or pending with the DNS records it still owes.                                                         |
| `claims[].createdAt`       | body | integer (int64)           | —      | CreatedAt is when the host was claimed, as Unix seconds — not when it went live.                                                          |
| `claims[].detail`          | body | string                    | —      | Detail is what is holding the claim up, in words a person can act on.                                                                     |
| `claims[].host`            | body | string                    | —      | Host is the custom hostname claimed for this site.                                                                                        |
| `claims[].records`         | body | project.Record\[]         | —      | Records are EXACTLY the DNS records to publish to prove ownership and route the host.                                                     |
| `claims[].records[].name`  | body | string                    | —      | the record name the customer creates                                                                                                      |
| `claims[].records[].type`  | body | string                    | —      | TXT \| CNAME                                                                                                                              |
| `claims[].records[].value` | body | string                    | —      | the record value                                                                                                                          |
| `claims[].status`          | body | string                    | —      | Status is `live` when the edge answers for this host now, `pending` while the claim is waiting on DNS proof of ownership.                 |
| `claims[].url`             | body | string                    | —      | URL is where the host will serve once it is live — present on a pending claim too, so a console can show the destination before it works. |
| `claims[].verified`        | body | boolean                   | —      | Verified is the same fact as a boolean, for a caller that only needs the yes or no.                                                       |
| `domains`                  | body | string\[]                 | —      | Domains are the hostnames that are VERIFIED and routing right now.                                                                        |
| `org`                      | body | string                    | —      | Org is the organisation that owns the site.                                                                                               |
| `slug`                     | body | string                    | —      | Slug is the site the panel belongs to.                                                                                                    |

Failure carries the platform error shape — see [Errors](https://docs.hanzo.ai/docs/errors).

## Examples

**CLI**

```bash
hanzo projects domains list <slug>
```

**SDK**

**.ts**

```ts
import { Configuration, ProjectApi } from 'hanzoai';

const api = new ProjectApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.getProjectsBySlugDomains({ slug: 'slug' });
```

**.py**

```python
from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import ProjectApi

client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = ProjectApi(client).get_projects_by_slug_domains(slug='slug')
```

**.go**

```go
cfg := hanzoai.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := hanzoai.NewAPIClient(cfg)

resp, _, err := client.ProjectAPI.GetProjectsBySlugDomains(context.Background()).Execute()
if err != nil {
	return err
}
```

**.rs**

```rust
use hanzo_client::apis::{configuration::Configuration, project_api};

let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();

let result = project_api::get_projects_by_slug_domains(&cfg, Default::default()).await?;
```

**.java**

```java
import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.ProjectApi;

ApiClient client = new ApiClient();
client.setBearerToken(System.getenv("HANZO_API_KEY"));

var result = new ProjectApi(client).getProjectsBySlugDomains();
```

The method above is the one at the current release of the document. `hanzoai@8.5.914` (npm) and `hanzoai@8.5.914` (PyPI) were generated from an earlier release, where this operation carried a different id, so it spells the method differently — regenerating the clients is what makes the two agree. [SDKs →](https://docs.hanzo.ai/docs/sdks)

**HTTP**

```bash
curl https://api.hanzo.ai/v1/projects/<slug>/domains \
  -H "Authorization: Bearer $HANZO_API_KEY"
```

**MCP**

Tool `project`, op `get_projects_by_slug_domains` — POST the JSON-RPC envelope to `https://api.hanzo.ai/v1/mcp`.

```bash
curl -X POST https://api.hanzo.ai/v1/mcp \
  -H "Authorization: Bearer $HANZO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
       "jsonrpc": "2.0",
       "id": 1,
       "method": "tools/call",
       "params": {
         "name": "project",
         "arguments": {
           "op": "get_projects_by_slug_domains",
           "input": {
             "slug": "<slug>"
           }
         }
       }
     }'
```

---

[Project API](https://docs.hanzo.ai/docs/openapi/project) · [All Hanzo APIs](https://docs.hanzo.ai/docs/openapi) · [Interactive reference](https://docs.hanzo.ai/docs/openapi/reference)
