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

# Web domains

> The dual-track domain system: independent email and app verification, three registrar kinds, and the readiness gates email sits on.

> [!NOTE]
>
> **Available now.** Domains ship with Identity, gated by the [policy](https://vetta.sh/docs/concepts/policies.md) layer — domain purchase is approval-gated by default.

A **domain** is the foundation an identity's [email](https://vetta.sh/docs/identity/email.md) sits on, and the anchor for serving apps over HTTP. Naive Managed Agents models a domain with **two independent verification tracks** that must not be conflated:

> [card] Email track
>
> Governs whether the domain can send and receive mail. Exposed as `status` (overall) plus `dns_status` (mail DNS).

> [card] App / HTTP track
>
> Governs whether the domain can serve an app over HTTP. Exposed as `app_connect_status`, entirely separate from the email track.

> [!WARNING]
>
> A domain can be fully verified for email (`status: active`, `dns_status: provisioned`) while its app track is still `pending` — and vice-versa. Always check the specific track for the capability you need.

## Verification tracks and their states

| Capability | Required track state |
| - | - |
| Create an inbox on the domain | `status: active` |
| **Send** mail | `dns_status: provisioned` |
| **Receive** mail | domain verified for inbound at the email layer (MX in place) |
| Serve an app over HTTP | `app_connect_status: connected` |

## System domains: auto-provisioning at signup

Every organization gets a working `system` domain automatically. Provisioning is **fire-and-forget** — it runs in the background at signup and self-heals, so a usable domain is ready without any action from you.

**1. Create at the email layer**

Managed Agents creates the domain at the email layer with sending **and** receiving enabled.

**2. Write DNS into the shared apex zone**

The required SPF/DKIM/MX/DMARC records are written directly into Managed Agents' shared apex zone — no manual step, because Managed Agents controls the zone.

**3. Trigger verification and poll briefly**

Verification is triggered immediately and polled for a short window. When it clears, the domain row is usable.

**4. Background healing**

A background sweep periodically re-verifies any domain still `pending`, so transient DNS propagation delays resolve themselves.

```bash CLI theme={"system"}
vetta identity domain list
# NAME                          KIND     STATUS   DNS_STATUS    APP_CONNECT
# acme.<vetta-apex>             system   active   provisioned   pending
```

> [!NOTE]
>
> Because system domains are list-only, the resulting `{org-slug}.<vetta-apex>` subdomain is the fastest way to get an agent sending and receiving mail — no registrar steps at all.

## BYOD: connect and verify your own domain

Connecting an `external` domain is a two-call flow. `connect` returns the DNS records to add **at your registrar**; `verify` checks them and advances both tracks.

**1. Connect the domain**

Managed Agents returns a set of DNS records to add at your registrar. The exact set is returned **dynamically** — typically a `TXT` for SPF, `TXT`/`CNAME` for DKIM, `MX` for inbound, sometimes a `CNAME`, plus a `_dmarc` `TXT`.

```bash CLI theme={"system"}
vetta identity domain connect --domain acme-mail.com
```

```jsonc theme={"system"}
// records to add at YOUR registrar (illustrative — the real set is returned to you)
[
  { "type": "TXT",   "host": "@",              "value": "v=spf1 include:... ~all" },
  { "type": "CNAME", "host": "s1._domainkey",  "value": "s1.dkim...." },
  { "type": "MX",    "host": "@",              "value": "10 inbound....", "priority": 10 },
  { "type": "TXT",   "host": "_dmarc",         "value": "v=DMARC1; p=none; ..." }
]
```

**2. Add the records at your registrar**

Add every returned record exactly. Propagation can take a few minutes to a few hours depending on your registrar.

**3. Verify**

```bash CLI theme={"system"}
vetta identity domain verify --domain acme-mail.com
```

Verification advances the two tracks independently:
\
• Company/email track: `pending_dns` → `active`
\
• DNS track: `pending_verification` → `provisioned`

```typescript TypeScript theme={"system"}
const domain = await vetta.domains.create({
  name: "acme-mail.com",
  kind: "external",
});
// domain.records -> the DNS records to add at your registrar

await vetta.domains.verify(domain.id);
```

```bash cURL theme={"system"}
curl https://api.vetta.sh/v1/domains \
  -H "Authorization: Bearer $VETTA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "acme-mail.com", "kind": "external" }'

curl https://api.vetta.sh/v1/domains/$DOMAIN_ID/verify \
  -H "Authorization: Bearer $VETTA_API_KEY" -X POST
```

## Buy with Naive credits

Quote first, then authorize a maximum price. The purchase debits the organization's Naive balance;
no customer card is accepted or sent to the registrar. Automatic renewal is disabled.

```bash CLI theme={"system"}
vetta identity domain quote --domain founderframehq.com
vetta identity domain purchase --domain founderframehq.com --max-price-micro-usd 12000000
```

```typescript TypeScript theme={"system"}
const quote = await vetta.domains.quote("founderframehq.com");
if (quote.available && quote.registration_price_micro_usd !== null) {
  await vetta.domains.purchase({
    name: quote.name,
    max_price_micro_usd: quote.registration_price_micro_usd,
  });
}
```

The server checks the live price again immediately before purchase. Premium domains and price
increases above the authorized ceiling are refused. A pending registrar workflow is safely
retryable with the same idempotency key and cannot debit twice.

> [!NOTE]
>
> A domain is an **organization** object, not an identity one — two personas routinely send from the
> same domain, and the system domain belongs to the organization (ADR-0119). Earlier drafts of this
> page nested these calls under `/v1/identities/{id}/domains`; that spelling is not served. An
> identity reaches a domain through the inboxes provisioned on it.

## The email readiness gate

The three email-track requirements combine into a single practical rule: **a domain must be verified before an inbox can send.**

| Action | Gate |
| - | - |
| Create an inbox | `status: active` |
| Send from the inbox | `dns_status: provisioned` |
| Receive at the inbox | verified for inbound at the email layer |

> [!WARNING]
>
> A send attempted before the domain finishes verifying is not a hard failure — it returns a **retryable** `job_not_ready`. The [durable runtime](https://vetta.sh/docs/concepts/runtime.md) can retry it once verification completes rather than dropping the message.

## Protected DNS records

Some records are managed by Managed Agents to keep deliverability and inbound routing intact. **The agent cannot edit them:**

* `_dmarc`
* `_domainkey` and `*._domainkey` (DKIM)
* inbound `MX` and their associated `TXT`

On a `system` domain the entire zone is **list-only** — any edit attempt returns `403`. On `external`/`purchased` domains you may manage your other records, but the protected set above is still off-limits to the agent.

```bash CLI theme={"system"}
vetta identity domain records list --domain acme-mail.com   # always allowed
vetta identity domain records set  --domain acme.<vetta-apex> ...   # 403 on system domains
```

## Configuration reference

### Verification track fields

**status** `string`

Email-track lifecycle for the domain as a whole. `pending_dns` → `active`. Creating an inbox requires `active`.

**dns\_status** `string`

Email DNS (SPF/DKIM) provisioning state. `pending_verification` → `provisioned`. **Sending** requires `provisioned`.

**app\_connect\_status** `string`

App/HTTP track state, independent of the two email fields above. Follows its own `pending` → `connected` lifecycle.

### Registrar kinds

A domain's `kind` records where it lives and who owns it:

**system** `kind`

Auto-provisioned subdomain under Managed Agents' shared apex — e.g. `{org-slug}.<vetta-apex>`. Created for you at signup. **List-only**: DNS records are managed by Managed Agents and cannot be edited (editing returns `403`).

**external** `kind`

Bring-your-own-domain (BYOD). You own the domain at your registrar; Managed Agents returns the DNS records to add, then verifies them.

**purchased** `kind`

Bought through Managed Agents. Managed Agents owns registration and manages the zone on your behalf. Purchase is [approval-gated](https://vetta.sh/docs/identity/policies.md) by default.

> [card] [Next: email](https://vetta.sh/docs/identity/email.md)
>
> Provision inboxes on a verified domain and send mail.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.