# Verify domains — POST /v1/project/{slug}/domains/{host}/verify

URL: https://docs.hanzo.ai/docs/openapi/project/post-project-by-slug-domains-by-host-verify

> Checks the DNS challenge for a pending custom hostname and, when it passes, promotes the host so it begins routing at the edge.

`POST /v1/project/{slug}/domains/{host}/verify`

> [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/project/{slug}/domains/{host}/verify` |
| **Method**    | `POST`                                                         |
| **Operation** | `post_project_by_slug_domains_by_host_verify`                  |
| **Auth**      | `Authorization: Bearer $HANZO_API_KEY`                         |

Checks the DNS challenge for a pending custom hostname and, when
it passes, promotes the host so it begins routing at the edge.

It answers 200 either way, with the host's honest current state: verified once
the TXT record is found, still pending — with the records to publish and the
resolver's own explanation in `detail` — when it is not. A not-yet is not an
error: the check ran, DNS simply has not propagated, and the customer retries.
An already-verified host is returned unchanged without re-resolving. On a
successful promotion the edge cache-tag is flushed, since the host routes as
of that moment.

Scope: a validated principal is required (401 without one). Both the site and
the claim are resolved within that principal's org, so a host claimed by
another tenant is "not claimed by this site".

## Request

2 fields.

| Field  | In   | Type   | Required | Description                                                 |
| ------ | ---- | ------ | -------- | ----------------------------------------------------------- |
| `slug` | path | string | yes      | Slug is the project the host is attached to, from the path. |
| `host` | path | string | yes      | Host is the custom hostname, from the path.                 |

## Response

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

`200` body — 10 fields.

| Field             | In   | Type              | Always | Description                                                                                                                               |
| ----------------- | ---- | ----------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `createdAt`       | body | integer (int64)   | —      | CreatedAt is when the host was claimed, as Unix seconds — not when it went live.                                                          |
| `detail`          | body | string            | —      | Detail is what is holding the claim up, in words a person can act on.                                                                     |
| `host`            | body | string            | —      | Host is the custom hostname claimed for this site.                                                                                        |
| `records`         | body | project.Record\[] | —      | Records are EXACTLY the DNS records to publish to prove ownership and route the host.                                                     |
| `records[].name`  | body | string            | —      | the record name the customer creates                                                                                                      |
| `records[].type`  | body | string            | —      | TXT \| CNAME                                                                                                                              |
| `records[].value` | body | string            | —      | the record value                                                                                                                          |
| `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.                 |
| `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. |
| `verified`        | body | boolean           | —      | Verified is the same fact as a boolean, for a caller that only needs the yes or no.                                                       |

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

## Examples

**CLI**

```bash
hanzo project domains verify <slug> <host>
```

**SDK**

**.ts**

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

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

**.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).post_project_by_slug_domains_by_host_verify(slug='slug', host='host')
```

**.go**

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

resp, _, err := client.ProjectAPI.PostProjectBySlugDomainsByHostVerify(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::post_project_by_slug_domains_by_host_verify(&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).postProjectBySlugDomainsByHostVerify();
```

**HTTP**

```bash
curl -X POST https://api.hanzo.ai/v1/project/<slug>/domains/<host>/verify \
  -H "Authorization: Bearer $HANZO_API_KEY"
```

**MCP**

Tool `project`, op `post_project_by_slug_domains_by_host_verify` — 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": "post_project_by_slug_domains_by_host_verify",
           "input": {
             "slug": "<slug>",
             "host": "<host>"
           }
         }
       }
     }'
```

---

[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)
