
# Get an email sender domain

`GET /v1/email-sender-domains/{sender_domain_id}` · permission `email-sender-domains:read` · all plans

Returns a sender domain: its status, the results of the last DNS check and the DNS records to publish. The `ETag` header carries the version; send it as `If-Match` when you [delete](delete.md) the domain.

## Request

| Field | Type | Required | Description |
|---|---|---|---|
| `sender_domain_id` | string | yes | Sender domain ID (`sdom_…`). |

No request body.

## Response

`200 OK` with the sender domain and `ETag` set to its version.

| Field | Type | Description |
|---|---|---|
| `id` | string | Sender domain ID (`sdom_…`). |
| `domain` | string | The domain as an IDNA 2008 A-label, lowercase, without a trailing dot. |
| `status` | string | `pending_dns` (waiting for the DNS records), `verified` (ready to send), `degraded` (the records have been failing for 72 hours; the environment fell back to platform sending) or `disabled` (disabled by the platform). |
| `active_selector` | string | DKIM selector used for signing: `akp1` or `akp2`. |
| `dkim_status` | string or null | Last check of the two DKIM CNAMEs (the worse of the two): `ok`, `missing`, `wrong_target` or `lookup_failed`; null before the first check. |
| `return_path_status` | string or null | Last check of the return-path CNAME, same codes; null before the first check. |
| `dmarc_alignment` | string or null | DMARC result of the last check: `aligned`, `not_aligned`, `no_record`, `invalid_record` or `lookup_failed`. DMARC is not required. |
| `last_checked_at` | string or null | Time of the last check. |
| `failing_since` | string or null | First failed check of a `verified` domain; when it reaches 72 hours the domain becomes `degraded`. |
| `degraded_since` | string or null | When the domain became `degraded`. |
| `records` | array | DNS records to publish: `type` (`CNAME` or `TXT`), `name`, `value` and `required`. The two DKIM CNAMEs and the return-path CNAME are required; when the last check found no `_dmarc` record a DMARC suggestion (`v=DMARC1; p=none`) is added with `required: false`. |
| `version` | integer | Domain version, the same as the `ETag`; it increases on every write, checks included. |
| `created_at` | string | Creation time. |
| `updated_at` | string | Time of the last change. |

```json
{
  "id": "sdom_01k7r9m3q5t8v2w4x6y8z0a2b4",
  "domain": "mail.example.com",
  "status": "pending_dns",
  "active_selector": "akp1",
  "dkim_status": null,
  "return_path_status": null,
  "dmarc_alignment": null,
  "last_checked_at": null,
  "failing_since": null,
  "degraded_since": null,
  "records": [
    {
      "type": "CNAME",
      "name": "akp1._domainkey.mail.example.com",
      "value": "akp1.sdom_01k7r9m3q5t8v2w4x6y8z0a2b4.dkim.eu.keenauth.app",
      "required": true
    },
    {
      "type": "CNAME",
      "name": "akp2._domainkey.mail.example.com",
      "value": "akp2.sdom_01k7r9m3q5t8v2w4x6y8z0a2b4.dkim.eu.keenauth.app",
      "required": true
    },
    {
      "type": "CNAME",
      "name": "rp.mail.example.com",
      "value": "rp.eu.mail.keenauth.app",
      "required": true
    }
  ],
  "version": 1,
  "created_at": "2026-10-19T09:00:00Z",
  "updated_at": "2026-10-19T09:00:00Z"
}
```

## Errors

| HTTP | code | When |
|---|---|---|
| 404 | `not_found` | The sender domain does not exist, belongs to another environment or the ID is malformed. |
| 401 | `unauthenticated` | The credential is missing, invalid or revoked. |
| 403 | `insufficient_permissions` | The credential lacks the required permission. |
| 429 | `rate_limited` | The rate limit was exceeded; retry after the `Retry-After` period. |
| 503 | `service_unavailable` | A dependency is temporarily unavailable; retry after the `Retry-After` period. |

## Example

```bash
curl https://api.eu.keenauth.com/v1/email-sender-domains/sdom_01k7r9m3q5t8v2w4x6y8z0a2b4 \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY"
```

CLI: `keenauth email-sender-domains get sdom_01k7r9m3q5t8v2w4x6y8z0a2b4`
