> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hopae.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Verify Custom Domain

> Re-check DNS and SSL and advance the custom domain status.

Re-checks your DNS records and SSL certificate status, advances the lifecycle when it can, and returns the updated `CustomDomainStateDto`. This is how you move a custom domain forward — **status only advances when you call verify.** See [Custom Domain](/guides/concepts/custom-domain) for the concept and lifecycle.

<Note>
  Reading with [Get Custom Domain](/api-reference/workspace/get-custom-domain) never advances the status. Verify is the only trigger — there is no background polling and no webhooks. **Poll this endpoint until the status is `active`.**
</Note>

## Request

This endpoint takes **no request body**.

<ParamField header="Authorization" type="string" required>
  `Bearer <API_KEY>` from Console > Developers > Workspace API Keys.
</ParamField>

<ParamField header="Idempotency-Key" type="string">
  Optional client-generated string (max 255 chars) to safely retry without duplicating work. Scoped per workspace. A key is valid for 24 hours. If the same key is replayed with an identical request, the original response is returned with an `Idempotency-Replayed: true` header. Reusing the same key with a different request returns `409 IDEMPOTENCY_KEY_CONFLICT`.
</ParamField>

### Path parameters

<ParamField path="client_id" type="string" required>
  Client identifier of the app.
</ParamField>

## Response

Returns the updated `CustomDomainStateDto`. `lastCheckedAt` is set to the time of this verify.

<ResponseField name="webDomain" type="string">
  The configured Web Frontend host.
</ResponseField>

<ResponseField name="oidcDomain" type="string">
  The configured OIDC Backend host.
</ResponseField>

<ResponseField name="status" type="string">
  Lifecycle status. One of `unconfigured`, `awaiting_dns`, `verifying`, `active`, `invalid`. Keep calling verify until it is `active`.
</ResponseField>

<ResponseField name="requiredAction" type="string">
  What you need to do next. One of `none`, `add_cname`, `waiting`, `verify`, `contact_support`, `retry`.
</ResponseField>

<ResponseField name="statusMessage" type="string">
  Human-readable explanation of the current status. Omitted when there is nothing to report.
</ResponseField>

<ResponseField name="dnsRecords" type="object[]">
  DNS records to add at your DNS provider. See [Get Custom Domain](/api-reference/workspace/get-custom-domain) for each record's fields.
</ResponseField>

<ResponseField name="lastCheckedAt" type="string">
  ISO 8601 timestamp of this verify.
</ResponseField>

<RequestExample>
  ```bash theme={null}
  curl -X POST \
    -H "Authorization: Bearer sk_workspace_test_..." \
    -H "Idempotency-Key: 5d42c2c4-f7a3-4c0b-8a6d-2d3c6d38b9c9" \
    "https://sandbox.api.hopae.com/connect/v1/apps/abc123/custom-domain/verify"
  ```
</RequestExample>

<ResponseExample>
  ```json theme={null}
  {
    "webDomain": "verify.example.com",
    "oidcDomain": "connect.example.com",
    "status": "active",
    "requiredAction": "none",
    "statusMessage": "Your custom domain is live.",
    "dnsRecords": [
      {
        "id": "web-cname",
        "type": "CNAME",
        "host": "verify.example.com",
        "name": "verify.example.com",
        "value": "cname.hopae-edge.com",
        "required": true,
        "description": "Routes your Web Frontend host to the Hopae edge."
      },
      {
        "id": "oidc-cname",
        "type": "CNAME",
        "host": "connect.example.com",
        "name": "connect.example.com",
        "value": "cname.hopae-edge.com",
        "required": true,
        "description": "Routes your OIDC Backend host to the Hopae edge."
      }
    ],
    "lastCheckedAt": "2026-06-18T01:20:05.000Z"
  }
  ```
</ResponseExample>
