# Sending domains

Source: https://kirora.io/docs/api/reference/sending-domains

A sending domain is a domain your email is sent from, with the DNS records that prove you own it. Nothing sends email from an address until its domain is verified here, and a domain can be verified in only one workspace, so use a subdomain for staging.

## Endpoints

- [List sending domains](https://kirora.io/docs/api/reference/listSendingDomains): `GET /v1/sending-domains`
- [Add a sending domain](https://kirora.io/docs/api/reference/createSendingDomain): `POST /v1/sending-domains`
- [Retrieve a sending domain](https://kirora.io/docs/api/reference/getSendingDomain): `GET /v1/sending-domains/{id}`
- [Delete a sending domain](https://kirora.io/docs/api/reference/deleteSendingDomain): `DELETE /v1/sending-domains/{id}`
- [Check a sending domain](https://kirora.io/docs/api/reference/checkSendingDomain): `POST /v1/sending-domains/{id}/check`
- [Retrieve a sending domain's usage](https://kirora.io/docs/api/reference/getSendingDomainUsage): `GET /v1/sending-domains/{id}/usage`
- [Ask for a sending domain review again](https://kirora.io/docs/api/reference/requestSendingDomainReview): `POST /v1/sending-domains/{id}/review`

## The SendingDomain object

```json
{
  "id": "0192f3f0-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
  "domain": "mail.acme-shop.com",
  "status": "pending",
  "failureReason": null,
  "lastCheckedAt": "2026-10-01T09:45:00.000Z",
  "dnsRecords": [
    {
      "purpose": "ownership",
      "type": "TXT",
      "name": "kirora1._domainkey.mail.acme-shop.com",
      "host": "kirora1._domainkey.mail",
      "value": "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7v3k2x",
      "matches": false,
      "reason": "No TXT record found at kirora1._domainkey.mail.acme-shop.com"
    },
    {
      "purpose": "mailFrom",
      "type": "MX",
      "name": "bounce.mail.acme-shop.com",
      "host": "bounce.mail",
      "value": "10 feedback-smtp.eu-central-1.amazonses.com",
      "matches": false,
      "reason": "No MX record found at bounce.mail.acme-shop.com"
    },
    {
      "purpose": "mailFrom",
      "type": "TXT",
      "name": "bounce.mail.acme-shop.com",
      "host": "bounce.mail",
      "value": "v=spf1 include:amazonses.com ~all",
      "matches": false,
      "reason": "No TXT record found at bounce.mail.acme-shop.com"
    }
  ],
  "checks": {
    "ownership": "pending",
    "dkim": "pending",
    "mailFrom": "pending",
    "dmarc": null,
    "bimi": null
  },
  "review": {
    "status": "not_requested",
    "declineReason": null
  },
  "createdAt": "2026-10-01T09:30:00.000Z",
  "updatedAt": "2026-10-01T09:45:00.000Z"
}
```

- `id` (string, required, uuid)
- `domain` (string, required)
- `status` (string, required, one of `pending`, `awaiting_review`, `verified`, `verification_lost`, `failed`, `quarantined`) — Whether the domain can send: `pending` until its DNS records are all found; `awaiting_review`, you own it but a person at Kirora has not cleared it to send yet, and it is set up the moment they do (`review` says more); `verified`, it can send; `verification_lost`, it was verified but a record has since gone missing, and nothing sends from it until the record is back; `failed`, see `failureReason`; `quarantined`, the domain is already set up by another account, so nothing sends from it until Kirora support reviews it.
- `failureReason` (string | null, required) — Why verification failed, when it has.
- `lastCheckedAt` (string | null, required, date-time) — When DNS was last checked.
- `dnsRecords` (SendingDomainDnsRecord[], required) — The records to publish at your DNS host, the ownership record first.
  - `purpose` (string, required, one of `ownership`, `dkim`, `mailFrom`) — `ownership`: proves you control the domain, and holds the key that signs its mail; `dkim`: another signing key record; `mailFrom`: the `bounce.` subdomain that receives bounces and aligns SPF.
  - `type` (string, required, one of `CNAME`, `TXT`, `MX`)
  - `name` (string, required) — The full hostname to publish the record at.
  - `host` (string, required) — The name without the registered domain, which most DNS hosts ask for, since they add the domain themselves: `sel._domainkey` for `sel._domainkey.example.com`, `@` for the domain itself.
  - `value` (string, required) — What the record must contain.
  - `matches` (boolean, required) — Whether the last check found the record as given.
  - `reason` (string | null, required) — Why it does not match, such as what DNS holds there; null when it does.
- `checks` (object, required) — Each check's state, for showing progress; `status` is what decides.
  - `ownership` (string, required, one of `pending`, `verified`) — Whether proof that you control the domain has been found in DNS.
  - `dkim` (string, required, one of `pending`, `verified`, `failed`) — The DKIM signing records.
  - `mailFrom` (string, required, one of `pending`, `verified`, `failed`) — The `bounce.` (MAIL FROM) records.
  - `dmarc` (object | null, required) — The DMARC record covering the domain, which marketing email needs; null before the first check.
    - `status` (string, required, one of `valid`, `missing`, `invalid`, `unknown`) — Whether a usable DMARC record was found.
    - `policy` (string | null, required, one of `none`, `quarantine`, `reject`) — The policy the DMARC record sets.
    - `policyDomain` (string | null, required) — The domain the DMARC record was found on.
    - `inherited` (boolean, required) — True when the record is the parent domain's, not the domain's own.
  - `bimi` (object | null, required) — BIMI, for the brand's logo beside its email: guidance, never a requirement. Mailboxes show it only with DMARC at `quarantine` or `reject`. Null until a check reads it.
    - `status` (string, required, one of `present`, `missing`, `unknown`) — Whether `default._bimi.<domain>` holds a BIMI record.
    - `logoUrl` (string | null, required) — Its logo (`l=`): an SVG Tiny PS file over HTTPS.
    - `certificateUrl` (string | null, required) — Its mark certificate (`a=`, a VMC or CMC), which Gmail and Apple Mail need before showing the logo; Yahoo can show it without one.
- `review` (object, required) — Its sending review (`SENDING_REVIEW_REQUIRED`).
  - `status` (string, required, one of `not_requested`, `in_review`, `approved`, `declined`) — Whether a person at Kirora has cleared the domain to send; until then it has no provider identity (`status` is `awaiting_review` once you own it), and nothing sends from it, not even a test. `not_requested`: proven yours, waiting for the workspace's sending profile (website, what it sends, how contacts agreed), which asks for review once filled in. `in_review`: waiting for a person, usually within a day. A subdomain of an approved domain is approved when proven.
  - `declineReason` (string | null, required) — Why it was declined; null unless `declined`.
- `createdAt` (string, required, date-time)
- `updatedAt` (string, required, date-time)
