# Ask for a sending domain review again

Source: https://kirora.io/docs/api/reference/requestSendingDomainReview

`POST /v1/sending-domains/{id}/review`

Requires an API key with the `domains:write` scope. [About keys and scopes](https://kirora.io/docs/api/reference/authentication)

Works with integration, agent and partner keys.

Safe to retry: a repeat sets the same values again. [About idempotency](https://kirora.io/docs/api/reference/idempotency)

A person at Kirora reviews each sending domain before it can send, against the workspace's sending profile (`website`, `mailKind`, `contactOptIn` in workspace settings); it is asked for on its own once the domain is proven yours and the profile is filled in. Call this to ask again after a decline, once you have changed what its `review.declineReason` names. Refused with `CONFLICT` when the domain is already approved or not yet proven yours, and `VALIDATION_ERROR` while the sending profile is incomplete.

## Path parameters

- `id` (string, required, uuid) — The sending domain's id.

## Header parameters

- `Kirora-Workspace` (string, optional, pattern `^[A-Za-z0-9._:-]{1,128}$`) — Partner keys only: the child workspace to act in, by the external id the partner gave it. Without it, a partner key acts in its own workspace. Any other key that sends it is refused with 403, and an unknown workspace is 404.
- `Idempotency-Key` (string, optional, 8–255 characters) — Makes a retry safe: a repeat with the same key and body within 24 hours gets the first response again, with `Idempotency-Replay: true`. The same key with another request is 409 `IDEMPOTENCY_KEY_REUSED`; while the first is still running, 409 `IDEMPOTENCY_KEY_IN_USE`; after an `unsafe` first request failed or never returned, 409 `IDEMPOTENCY_KEY_OUTCOME_UNKNOWN`. Use a new key, such as a UUID, for each new request.

## Returns

Returns `200 OK` with a `SendingDomain` in `data`. It can also return `409 Conflict`; see the statuses below. Otherwise returns an error; [Errors](https://kirora.io/docs/api/reference/errors) lists every code and which to retry.

- `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)

Statuses:

- `200 OK`: The domain, its review now `in_review`.
- `409 Conflict`: The request conflicts with current state — a duplicate unique value, or a resource whose status does not allow this operation.

Headers on `200 OK`:

- `Idempotency-Replay` (string, optional, one of `true`) — `true` when this is the stored response to an earlier request with the same key.

## Example

```bash
curl -X POST https://api.kirora.io/v1/sending-domains/018f2a4e-6b1c-7d3e-9f40-37386ae05a6b/review \
  -H "Authorization: Bearer $KIRORA_API_KEY"
```

Response `200`:

```json
{
  "data": {
    "id": "018f2a4e-6b1c-7d3e-9f40-37386ae05a6b",
    "domain": "domain_example",
    "status": "pending",
    "failureReason": "failureReason_example",
    "lastCheckedAt": "2030-03-14T09:30:00Z",
    "dnsRecords": [
      {
        "purpose": "ownership",
        "type": "CNAME",
        "name": "name_example",
        "host": "host_example",
        "value": "value_example",
        "matches": true,
        "reason": "reason_example"
      }
    ],
    "checks": {
      "ownership": "pending",
      "dkim": "pending",
      "mailFrom": "pending",
      "dmarc": {
        "status": "valid",
        "policy": "none",
        "policyDomain": "policyDomain_example",
        "inherited": true
      },
      "bimi": {
        "status": "present",
        "logoUrl": "logoUrl_example",
        "certificateUrl": "certificateUrl_example"
      }
    },
    "review": {
      "status": "not_requested",
      "declineReason": "declineReason_example"
    },
    "createdAt": "2030-03-14T09:30:00Z",
    "updatedAt": "2030-03-14T09:30:00Z"
  }
}
```
