---
title: "Add a domain"
method: POST
path: "/domains"
tags: ["Domains"]
---

# Add a domain

`POST /domains`

## Request

- Base URL: `https://api.oveyon.com/v1`
- URL: `https://api.oveyon.com/v1/domains`
- Auth: HTTP bearer

Returns the DNS records to publish (SPF, DKIM, DMARC). On the Free plan the domain goes through reputation screening; refusal = 403 domain_not_allowed_free, without a reason (on purpose).

## Request body

- object
  - `domain` string, required

## Response `201`

Created, with the records

- Domain
  - `id` integer
  - `domain` string
  - `records` object[]
    - `type` string
    - `name` string
    - `value` string
    - `purpose` string
    - `optional` boolean: true = not needed to send (e.g. the tracking CNAME).
  - `verification` object
    - `spf` boolean
    - `dkim` boolean
    - `dmarc` boolean
    - `inconclusive` string[]

## Other responses

- `400`: bad_domain
- `401`: Missing or invalid API key.
- `403`: domain_not_allowed_free — a free-mail domain (gmail.com…) cannot be registered; or any of the common 403s (key_disabled, account_suspended…).
- `409`: domain_exists (already yours) or domain_taken (belongs to another account).
- `413`: payload_too_large — the request body exceeds this route's limit (`limit`, in bytes: 25 MB unless the operation says otherwise). The key is validated before the body is read: without a valid key the answer is 401/403 and the body is not read. Do not retry the same body.
- `415`: unsupported_media_type — send the body as `application/json` (form and plain-text bodies are not accepted).
- `422`: domain_limit_reached — the plan's domain cap is reached (Free: 1). Remove a domain you no longer use, or contact support to raise the limit.
- `429`: Per-key limit (`rate_limited`, 600 requests/min by default per API key — or per MCP OAuth connection —, from any IP), per-IP limit for requests WITHOUT a valid credential (`rate_limited`, 600/min by default), too many unknown or malformed credentials from your address (`too_many_auth_failures`, 20/min by default, counted per IPv4 address or per IPv6 /48; a missing `Authorization`, an expired OAuth token or a disabled key do not count, and anything without the shape of one of our keys counts without being checked; from an address over that limit a valid key still gets through within 120 credential checks/min, and above them every credential not validated in the last 5 minutes gets this 429 until the minute turns) — all checked before the route, on every operation —, account quota (`quota_exceeded` with `window`, `used`, `limit`), warmup cap (`warmup_cap_reached`) or saturation (`queue_full`). Honor `Retry-After` with exponential backoff and jitter.
- `500`: internal_error — an unexpected failure on our side. The detail stays in our logs, never in the body. Retry reads; retry a write only when it is idempotent or carries an idempotency key.
- `503`: ip_rules_unavailable — the IP ranges bound to your key could not be checked right now (caution, not a denial). Retry after `Retry-After` (30 s).

---

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