# List DMARC reporting posture per domain

`GET /v1/domain-auth/domains`

- Authentication: required (Bearer token)
- Required scope: `api.domain_auth.view`

Returns each of the org's domains with its published DMARC policy,
reporting coverage and source counts.

`source_counts` carries two different groupings and they must not be
conflated. The five class counts partition `total` — what the traffic is
made of. `alerting` answers a separate question — how much of it needs a
human — and may overlap any of them; it is the field to read for "is
something wrong with this domain", not `unknown`. `awaiting_decision`
and `open_finding` partition `alerting` exactly, and only the first can
be reduced by a decision.

`traffic` is `null` when the window holds no report data. Null is not
zero: a domain nobody has reported on has no pass rate, and rendering 0%
would report total failure where there is only silence.

## Query parameters

- `limit` (integer, optional) — Page size (1–200). Default 50.

## Example request

```bash
curl 'https://api.sendops.dev/v1/domain-auth/domains' \
  -H "Authorization: Bearer $SENDOPS_API_KEY"
```

## Responses

### 200 — List of domains with their reporting posture

Content type: `application/json`

```json
{
  "data": [
    {
      "domain": "acme.com",
      "dmarc_record": "string",
      "policy": "no_record",
      "report_address": "string",
      "has_reports": true,
      "has_tls_reports": true,
      "first_report_at": "2026-05-17T20:00:00Z",
      "last_report_at": "2026-05-17T20:00:00Z",
      "report_count": 0,
      "source_counts": {
        "total": 0,
        "sendops": 0,
        "sendops_relayed": 0,
        "sendops_unaligned": 0,
        "known": 0,
        "unknown": 0,
        "alerting": 0,
        "awaiting_decision": 0,
        "open_finding": 0
      },
      "traffic": {
        "volume": 0,
        "pass_volume": 0,
        "pass_rate": 0,
        "adjusted_pass_rate": 0,
        "authenticable_volume": 0,
        "campaign_excluded": true,
        "last_received_at": "2026-05-17T20:00:00Z"
      },
      "dispersion": {
        "sources": 0,
        "volume": 0,
        "largest_source_volume": 0,
        "distributed_spoofing": true,
        "window_days": 0,
        "assessed_at": "2026-05-17T20:00:00Z"
      }
    }
  ],
  "pagination": {
    "has_more": true,
    "next_cursor": "string"
  }
}
```

### 401 — Missing, malformed, or unknown API key

Content type: `application/problem+json`

```json
{
  "type": "https://example.com",
  "title": "string",
  "status": 0,
  "detail": "string",
  "code": "invalid_key",
  "request_id": "string",
  "retry_after": 0,
  "retention_days": 0,
  "scope": "string",
  "resource": "string",
  "errors": [
    {
      "field": "string",
      "reason": "string"
    }
  ],
  "attribute_id": "00000000-0000-0000-0000-000000000000",
  "content_hash": "string",
  "differs": [
    "string"
  ]
}
```

### 403 — Key lacks the required scope or plan limit violated

Content type: `application/problem+json`

```json
{
  "type": "https://example.com",
  "title": "string",
  "status": 0,
  "detail": "string",
  "code": "invalid_key",
  "request_id": "string",
  "retry_after": 0,
  "retention_days": 0,
  "scope": "string",
  "resource": "string",
  "errors": [
    {
      "field": "string",
      "reason": "string"
    }
  ],
  "attribute_id": "00000000-0000-0000-0000-000000000000",
  "content_hash": "string",
  "differs": [
    "string"
  ]
}
```

### 422 — Query parameter or path value failed validation

Content type: `application/problem+json`

```json
{
  "type": "https://example.com",
  "title": "string",
  "status": 0,
  "detail": "string",
  "code": "invalid_key",
  "request_id": "string",
  "retry_after": 0,
  "retention_days": 0,
  "scope": "string",
  "resource": "string",
  "errors": [
    {
      "field": "string",
      "reason": "string"
    }
  ],
  "attribute_id": "00000000-0000-0000-0000-000000000000",
  "content_hash": "string",
  "differs": [
    "string"
  ]
}
```

### 429 — Per-org rate limit exceeded

Content type: `application/problem+json`

```json
{
  "type": "https://example.com",
  "title": "string",
  "status": 0,
  "detail": "string",
  "code": "invalid_key",
  "request_id": "string",
  "retry_after": 0,
  "retention_days": 0,
  "scope": "string",
  "resource": "string",
  "errors": [
    {
      "field": "string",
      "reason": "string"
    }
  ],
  "attribute_id": "00000000-0000-0000-0000-000000000000",
  "content_hash": "string",
  "differs": [
    "string"
  ]
}
```

### 500 — Unexpected server-side failure. The `code` is `internal_error`. The
`request_id` field can be quoted to SendOps support to investigate.

Content type: `application/problem+json`

```json
{
  "type": "https://example.com",
  "title": "string",
  "status": 0,
  "detail": "string",
  "code": "invalid_key",
  "request_id": "string",
  "retry_after": 0,
  "retention_days": 0,
  "scope": "string",
  "resource": "string",
  "errors": [
    {
      "field": "string",
      "reason": "string"
    }
  ],
  "attribute_id": "00000000-0000-0000-0000-000000000000",
  "content_hash": "string",
  "differs": [
    "string"
  ]
}
```
