> For the complete documentation index, see [llms.txt](https://docs.doma.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.doma.xyz/agentic-commerce/agentroot/zone-file-reference.md).

# Zone File Reference

The `.well-known/agentroot.json` zone file is the canonical declaration of what AI capabilities a domain offers. This page documents the full schema, the inline-TXT alternative, and the validation rules a publisher must respect.

## Top-level structure

```json
{
  "domain": "string",
  "records": [ /* array of records */ ],
  "subdomains": [ "optional", "list", "of", "subdomains" ]
}
```

| Field        | Type      | Required | Notes                                                                                                                |
| ------------ | --------- | -------- | -------------------------------------------------------------------------------------------------------------------- |
| `domain`     | string    | yes      | Apex domain. Must exactly match the host serving the file.                                                           |
| `records`    | array     | yes      | List of capability records (see types below).                                                                        |
| `subdomains` | string\[] | no       | Discovery hint: subdomains that publish their own `_agentroot` records. Each subdomain's DNS is the source of truth. |

Additional top-level fields (e.g. `version`, `contact`) are preserved but not part of the protocol.

## TXT record format

Independent of the zone file. Set this DNS record at `_agentroot.<domain>`:

```
v=ar1 zone=https://<domain>/.well-known/agentroot.json
```

Field descriptions:

* `v=ar1`: protocol version, always literal `ar1` for V1.
* `zone=<url>`: absolute HTTPS URL to the zone file. Must be reachable without authentication.

## Common base fields

Every record (regardless of `type`) shares the same required base, plus a set of optional metadata fields any consumer can read.

### Required base

| Field         | Type   | Notes                                                            |
| ------------- | ------ | ---------------------------------------------------------------- |
| `type`        | string | `agent`, `mcp`, `skill`, `a2a`, `payment`, or any custom string. |
| `id`          | string | Unique within the zone. Lowercase alphanumeric + hyphens.        |
| `name`        | string | Human-readable display name.                                     |
| `description` | string | One or two sentences describing what it does.                    |

### Optional base

These are **labels**, not protocol definitions. `"auth": "api-key"` means "you'll need an API key" (it does not define the auth flow). Link to your docs for details.

| Field      | Type      | Description                                                              |
| ---------- | --------- | ------------------------------------------------------------------------ |
| `auth`     | string    | Auth hint: `"none"`, `"api-key"`, `"bearer"`, `"oauth2"`.                |
| `pricing`  | string    | Pricing hint: `"free"`, `"freemium"`, `"paid"`.                          |
| `payments` | string\[] | Payment protocols accepted, e.g. `["mpp", "x402", "stripe-acp", "ap2"]`. |
| `docs`     | string    | URL to documentation.                                                    |
| `source`   | string    | URL to source code.                                                      |
| `category` | string    | Semantic category, e.g. `"devtools"`, `"data"`, `"finance"`.             |

## Record types

### `skill` record

Declares a `SKILL.md` collection (instructions for AI agents).

```json
{
  "type": "skill",
  "id": "coding-helpers",
  "name": "Coding Helpers",
  "description": "Skills for linting, testing, and deployment workflows.",
  "index": "https://examplecorp.com/.agents/skills/index.json"
}
```

| Field      | Type  | Required     | Notes                                                    |
| ---------- | ----- | ------------ | -------------------------------------------------------- |
| `skill_md` | URL   | one of these | Absolute URL to a single `SKILL.md`.                     |
| `index`    | URL   | one of these | Absolute URL to an `index.json` listing multiple skills. |
| `skills`   | array | one of these | Inline list of skill objects (alternative to fetching).  |

Exactly one of `skill_md`, `index`, or `skills` must be present.

**`index.json` format** (when using `index`):

```json
{
  "schema": "agent-skills/1.0",
  "domain": "examplecorp.com",
  "skills": [
    {
      "id": "lint-fix",
      "name": "Lint Fixer",
      "description": "Auto-fix common linting issues.",
      "skill_md": "https://examplecorp.com/.agents/skills/lint-fix/SKILL.md"
    }
  ]
}
```

### `mcp` record

Declares a Model Context Protocol server.

```json
{
  "type": "mcp",
  "id": "examplecorp-tools",
  "name": "ExampleCorp Tools",
  "description": "Database query and visualization tools.",
  "endpoint": "https://api.examplecorp.com/mcp",
  "transport": "streamable-http",
  "tools": [
    { "name": "search_catalog", "description": "Search the product catalog." }
  ]
}
```

| Field       | Type   | Required              | Notes                                                                                  |
| ----------- | ------ | --------------------- | -------------------------------------------------------------------------------------- |
| `endpoint`  | URL    | for remote transports | URL of the MCP server. Required when `transport` is `sse` or `streamable-http`.        |
| `transport` | string | yes                   | One of `stdio`, `sse`, `streamable-http`.                                              |
| `install`   | object | for stdio             | When `transport` is `stdio`: `{ "package": "@pkg/name", "command": "npx @pkg/name" }`. |
| `tools`     | array  | no                    | List of tool definitions exposed by the server.                                        |

Each entry in `tools` is an object with at minimum:

| Sub-field     | Type   | Required | Notes                                                    |
| ------------- | ------ | -------- | -------------------------------------------------------- |
| `name`        | string | yes      | Tool identifier; unique within the `tools` array.        |
| `description` | string | yes      | One-line summary, shown to agents during tool selection. |

Additional MCP tool fields (input schema, output schema) follow the [MCP specification](https://modelcontextprotocol.io/specification).

### `agent` record

Declares an AI agent endpoint.

```json
{
  "type": "agent",
  "id": "support-agent",
  "name": "ExampleCorp Support",
  "description": "Answers questions about ExampleCorp integration.",
  "endpoint": "https://api.examplecorp.com/agent",
  "protocol": "a2a",
  "capabilities": ["customer-support", "order-status"]
}
```

| Field          | Type      | Required | Notes                                                                         |
| -------------- | --------- | -------- | ----------------------------------------------------------------------------- |
| `endpoint`     | URL       | yes      | URL to reach the agent.                                                       |
| `protocol`     | string    | no       | `"a2a"` (default), `"rest"`, `"graphql"`, `"websocket"`, or any custom value. |
| `capabilities` | string\[] | no       | Free-form capability tags.                                                    |
| `card`         | URL       | no       | URL to a full agent-card JSON.                                                |

### `a2a` record

Declares an Agent-to-Agent communication endpoint.

```json
{
  "type": "a2a",
  "id": "examplecorp-a2a",
  "name": "ExampleCorp A2A",
  "description": "Negotiate and execute deals with other agents.",
  "endpoint": "https://api.examplecorp.com/a2a",
  "capabilities": ["negotiate", "quote", "execute"]
}
```

| Field          | Type      | Required | Notes                      |
| -------------- | --------- | -------- | -------------------------- |
| `endpoint`     | URL       | yes      | URL of the A2A endpoint.   |
| `capabilities` | string\[] | yes      | Free-form capability tags. |

### `payment` record

Declares a payment endpoint that agents can call to settle (e.g. for paying gated APIs).

```json
{
  "type": "payment",
  "id": "doma-mpp-payment",
  "name": "Doma MPP Payment",
  "description": "Settle MPP payments for tokenized domain registration.",
  "endpoint": "https://mpp.doma.xyz",
  "api_spec": "https://mpp.doma.xyz/openapi.json",
  "protocols": ["mpp"],
  "methods": ["tempo"],
  "assets": ["USDC"]
}
```

| Field       | Type      | Required | Notes                                          |
| ----------- | --------- | -------- | ---------------------------------------------- |
| `endpoint`  | URL       | yes      | URL of the payment endpoint.                   |
| `api_spec`  | URL       | no       | OpenAPI document describing the endpoint.      |
| `protocols` | string\[] | yes      | Payment protocols, e.g. `["mpp"]`, `["x402"]`. |
| `methods`   | string\[] | yes      | Settlement methods (chain or rail names).      |
| `assets`    | string\[] | yes      | Accepted assets, e.g. `["USDC", "ETH"]`.       |

### Custom types

Any string is a valid `type` value. The five above are conventions; the protocol does not gate publishers to a closed set. A consumer that doesn't understand a custom type ignores the record.

## Worked example: full zone

A fictional `examplecorp.com` publishing one of each built-in record type:

```json
{
  "domain": "examplecorp.com",
  "records": [
    {
      "type": "skill",
      "id": "coding-helpers",
      "name": "Coding Helpers",
      "description": "Skills for linting, testing, and deployment workflows.",
      "index": "https://examplecorp.com/.agents/skills/index.json"
    },
    {
      "type": "mcp",
      "id": "examplecorp-tools",
      "name": "ExampleCorp Tools",
      "description": "Database query and visualization tools.",
      "endpoint": "https://api.examplecorp.com/mcp",
      "transport": "streamable-http",
      "auth": "api-key",
      "pricing": "freemium",
      "tools": [
        { "name": "search_catalog", "description": "Search the product catalog." }
      ]
    },
    {
      "type": "agent",
      "id": "support-agent",
      "name": "ExampleCorp Support",
      "description": "Answers questions about ExampleCorp integration.",
      "endpoint": "https://api.examplecorp.com/agent",
      "protocol": "a2a",
      "capabilities": ["customer-support", "order-status"]
    },
    {
      "type": "a2a",
      "id": "examplecorp-a2a",
      "name": "ExampleCorp A2A",
      "description": "Negotiate and execute deals with other agents.",
      "endpoint": "https://api.examplecorp.com/a2a",
      "capabilities": ["negotiate", "quote", "execute"]
    }
  ],
  "subdomains": ["api.examplecorp.com"]
}
```

## Inline mode

For domains with one or two capabilities, the record can live entirely in the DNS TXT value: no zone file, no web hosting required. Tokenized domains use this pattern (one skill record + one payment record on a single `_agentroot` name).

### Format

```
_agentroot.<domain>  IN  TXT  "v=ar1 type=<type> name=<name> [field=value ...]"
```

| Field  | Required | Description                              |
| ------ | -------- | ---------------------------------------- |
| `v`    | yes      | Always `ar1`.                            |
| `type` | yes      | Record type.                             |
| `name` | yes      | Display name (use `\` to escape spaces). |

All other fields from the record schema are passed as `key=value` pairs.

### Examples

```dns
; Inline agent
_agentroot.example.com  IN TXT "v=ar1 type=agent name=My\ Bot endpoint=https://example.com/agent protocol=a2a"

; Inline MCP server
_agentroot.example.com  IN TXT "v=ar1 type=mcp name=DB\ Tools endpoint=https://example.com/mcp transport=sse"

; Inline skill collection
_agentroot.example.com  IN TXT "v=ar1 type=skill name=Helpers index=https://example.com/.agents/skills/index.json"

; Inline payment (tokenized-domain pattern)
_agentroot.example.com  IN TXT "v=ar1 type=payment id=doma-mpp-payment endpoint=https://mpp.doma.xyz api_spec=https://mpp.doma.xyz/openapi.json protocols=mpp methods=tempo assets=USDC"
```

### Parsing rules

1. Fields are space-separated `key=value` pairs.
2. Spaces within values are escaped with `\` (backslash-space).
3. Array fields (`capabilities`, `payments`, `protocols`, `methods`, `assets`, `caps`) are comma-separated: `protocols=mpp,x402`. AgentRoot normalizes these to arrays in the stored record.
4. A single TXT string must be ≤ 255 bytes. If a record's content exceeds 255 bytes, drop verbose fields like `name` or `description`. Richer metadata is available via `api_spec`, `zone=`, or `skill_md` endpoints.

### Multi-record discovery

A single `_agentroot` name can carry several TXT records of different types. The resolver applies this rule:

1. Fetch all `v=ar1` TXT records at `_agentroot.<domain>`.
2. **If any record is `zone=<url>`**: the zone file is authoritative. Index every record from the JSON; ignore sibling inline TXTs on the same name.
3. **Otherwise**: iterate every remaining `v=ar1` record, parse each, dedupe by `id`, and index each as a separate record.

```dns
; Tokenized domain with skill + payment inline
_agentroot.alice.xyz  IN TXT "v=ar1 skill=https://doma.xyz/.well-known/skills/secondary-sales/SKILL.md"
_agentroot.alice.xyz  IN TXT "v=ar1 type=payment id=doma-mpp-payment endpoint=https://mpp.doma.xyz protocols=mpp methods=tempo assets=USDC"
```

`dig +short TXT _agentroot.alice.xyz` returns two distinct strings; AgentRoot stores both as separate records (one skill, one payment).

## Validation and hosting rules

* All URLs in the zone file must be absolute and HTTPS (`http://` is rejected by resolvers).
* `id` slugs must be URL-safe (`[a-z0-9-]+`) and unique within `records[]`.
* `domain` must exactly match the host serving the file. Mismatches cause the zone to be rejected.
* For `skill` records, exactly one of `skill_md`, `index`, or `skills` must be present.
* For `mcp` records, `transport` must be one of `stdio`, `sse`, `streamable-http`.
* The zone file must be served with `Content-Type: application/json`.
* The zone file must be ≤ **1 MB**.
* Each inline TXT string must be ≤ **255 bytes**. Use multiple separate TXT records for multiple capabilities (not one record split across strings).

{% hint style="info" %}
Use `npx agent-root validate <path-to-zone.json>` to check a zone file locally before publishing.
{% endhint %}

## What's next

* [Publish Your Own](/agentic-commerce/agentroot/publish-your-own.md): three steps to put your domain on the agentic web.
* [Discover & Use Skills](/agentic-commerce/agentroot/discover-and-use.md): how agents consume the records you publish.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.doma.xyz/agentic-commerce/agentroot/zone-file-reference.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
