---
title: "Add domain"
method: POST
path: "/api/v1/me/domains"
tags: ["Domains"]
---

# Add domain

`POST /api/v1/me/domains`

## Request

- Base URL: `https://api.proof.holdings`
- URL: `https://api.proof.holdings/api/v1/me/domains`
- Auth: API key in cookie `auth_token`

Add a new domain for verification. Supports auto-DNS, manual DNS, HTTP file, and email verification methods.

## Request body

- AddDomainRequest: Request body for adding a domain
  - `domain` string, required: Domain name to add
  - `profile_id` string: Associate domain with a profile for email config
  - `for_email_sending` boolean: Whether domain is for email sending
  - `verification_method` 'auto_dns' | 'manual_dns' | 'http_file' | 'email'

## Response `201`

Domain added

- Domain: Domain record
  - `id` string, required: MongoDB ObjectId
  - `domain` string, required
  - `status` 'pending' | 'verified' | 'failed', required: Domain verification status
  - `verification_method` string
  - `provider` string
  - `email_sending_enabled` boolean
  - `profile_id` string: MongoDB ObjectId
  - `created_at` string, date-time, required
  - `updated_at` string, date-time, required
  - `verified_at` string, date-time
  - `proof_id` string, nullable: Public handle of the control proof backing this domain (`ph_ctl_<32 hex>`), resolved through the domain's mirroring asset — the same source `GET /me/assets` reads, so the two surfaces cannot disagree. Null when the domain has no proof, or when its proof predates the registry.
  - `proof_status` 'active' | 'revoked' | 'expired' | 'suspended' | 'null', nullable: Registry status of that proof. A domain row can read `verified` while its proof is `revoked` — the row records that control was once shown, the proof records whether it still stands — so a client showing domain control must render THIS. Null means no registry record, which is NOT a revocation.
  - `proof_revoked_reason` string, nullable: Reason the registry recorded, present only while `proof_status` is `revoked`.
  - `proof_expires_at` string, date-time, nullable: When that proof expires — the signed token's own `exp`. `proof_status` stays `active` after this instant (nothing rewrites it), so a client must compare against the clock to tell a live proof from an expired one. Proofs inside 30 days of expiry are renewed automatically while control can still be confirmed. Carried even when `proof_id` is null (a proof that predates the registry still has a signed expiry); null when the domain has no proof, or its proof never stored one.

## Other responses

- `400`: Validation error

---

[API](https://skmtc.dev/proof/apis/proof-holdings-api.md) · [All operations](https://skmtc.dev/proof/apis/proof-holdings-api/llms.txt) · [OpenAPI document](https://skmtc.dev/proof/apis/proof-holdings-api/revisions/b15f506de696?raw)
