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

# Organization domain API

> Manage DNS ownership claims and agent domain affiliations

These endpoints require an organization admin's API key. The Inkbox Console also
supports these operations for organization admins. Agent-scoped credentials cannot
read claim tokens or change affiliations.

Base URL: `https://inkbox.ai/api/v1`.

## Claim endpoints

| Method | Path | Result |
| - | - | - |
| `POST` | `/organization-domains` | Create a TXT challenge, or return the current claim for this organization and exact domain. |
| `GET` | `/organization-domains` | List this organization's claims. Accepts `limit` (1–100, default 50) and `cursor`. |
| `GET` | `/organization-domains/{claim_id}` | Read state, TXT instructions, and recovery information. |
| `POST` | `/organization-domains/{claim_id}/verify` | Recheck the TXT proof. |
| `DELETE` | `/organization-domains/{claim_id}` | Release the claim and remove its affiliations. Returns 204. |

Create request:

```json theme={null}
{"domain": "example.com"}
```

Creation returns 201 for a new challenge and 200 for the existing current claim.
A pending challenge expires after seven days. Recreating it after expiry issues a
new challenge. Repeated creation does not extend the deadline or change an active
token. Verification returns 200 with the resulting state, which may still be
`pending` when the record is absent, DNS is inconclusive, or another claim reserves
the domain.

The default organization limit is 10 domains, including pending claims and
verified, grace, or expired reservations. Released claims and expired pending
challenges do not count. At the limit, creating a new claim returns 429 with
`detail.error: "organization_domain_quota_exceeded"` and `detail.limit`.
Release an unused domain before adding another. Returning an existing current
claim, verifying it, and attaching it to agents remain available at the limit.

Claim response fields:

| Field | Type | Meaning |
| - | - | - |
| `id` | string | Claim resource ID. |
| `domain` | string | Normalized exact domain. |
| `state` | string | `pending`, `verified`, `grace`, `expired`, `pending_expired`, or `released`. |
| `dns_record` | object | `type: "TXT"`, `name`, and exact `value`. |
| `created_at` | timestamp | Claim creation time. |
| `verified_at` | timestamp or null | First verification time. |
| `last_checked_at` | timestamp or null | Last applied DNS observation. |
| `last_success_at` | timestamp or null | Last positive DNS observation. A competing pending claim can have a positive observation without owning the domain. |
| `valid_until` | timestamp or null | Assertion deadline; validity also requires an unreleased active reservation. |
| `pending_expires_at` | timestamp or null | Pending challenge deadline. |
| `next_check_at` | timestamp or null | Next scheduled check. |
| `last_check_result` | string or null | `present`, `absent`, or `inconclusive`. |
| `ownership_conflict` | boolean | Another claim reserves the domain. No other organization's details are exposed. |
| `recovery_action` | string or null | `verify`, `enroll`, or null. |

List responses contain `items` and `next_cursor`. Pass `next_cursor` unchanged to
retrieve the next page. A null cursor marks the end.

## Identity affiliation endpoints

| Method | Path | Result |
| - | - | - |
| `GET` | `/identities/{agent_handle}/domain-affiliation` | Read the attached domain and current assertion. |
| `PUT` | `/identities/{agent_handle}/domain-affiliation` | Attach an owned verified domain. |
| `DELETE` | `/identities/{agent_handle}/domain-affiliation` | Remove the selection. Returns 204. |

PUT requires a claim ID:

```json theme={null}
{
  "domain_claim_id": "OrganizationDomainClaim_YOUR_ID"
}
```

The claim and the active, claimed identity must belong to the authenticated
organization. Attaching a claim requires valid proof. The domain follows the
agent's visibility; there is no separate publication setting. You can detach an
expired selection with DELETE.

GET and PUT return:

```json theme={null}
{
  "domain_claim_id": "OrganizationDomainClaim_YOUR_ID",
  "domain": "example.com",
  "affiliation": {
    "domain": "example.com",
    "verifier": "Inkbox",
    "last_success_at": "2026-09-10T12:00:00Z",
    "valid_until": "2026-09-11T12:00:00Z"
  }
}
```

An expired selection retains `domain_claim_id` and `domain`, but has
`affiliation: null`. With no selection, all three fields are null.

## Errors

| Status | Meaning |
| - | - |
| 400 | Invalid domain input. |
| 401 / 403 | Missing credentials or insufficient authority. |
| 404 | Claim or eligible identity not found in the authenticated organization. |
| 409 | Expired challenge, changed claim, or invalid attachment. Read current state before retrying. |
| 422 | Invalid request fields or pagination bounds. |
| 429 | Organization domain limit reached, or manual verification cooldown. Release an unused domain for `organization_domain_quota_exceeded`; observe `Retry-After` when supplied for cooldowns. |

See [verified domains](/docs/capabilities/verified-domains) for timing, ownership rules,
privacy behavior, and SDK examples. Email sending-domain endpoints remain separate.


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