---
title: "Send Site Summary"
method: POST
path: "/site-summaries/{summary_id}/send"
tags: ["site summaries"]
---

# Send Site Summary

`POST /site-summaries/{summary_id}/send`

## Request

- Base URL: `https://api.verdun.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.verdun.ai/site-summaries/{summary_id}/send`
- Auth: HTTP bearer

Send this summary now — `test` to the caller, `resend` to the contacts.

THREE REFUSALS BEFORE ANY MAIL:

* 503 when `SITE_SUMMARY_EMAILS_ENABLED` is not exactly `true`. That
  INCLUDES `mode: test`: the flag means "this deployment may put mail in
  somebody's inbox", and an operator's own inbox is somebody's.
* 429 when this summary has already spent its five test/resend sends in the
  last hour. Counted in the DATABASE, because two ECS tasks would give a
  per-process counter double the budget.
* 404 for a summary outside the caller's scope, from the resolving query.

The response is the audit row, so the drawer can render the outcome per
recipient without a second call.

## Path parameters

- `summary_id` string, uuid, required

## Request body

- SendSiteSummaryRequest
  - `mode` 'test' | 'resend', required: 'test' sends only to the calling operator's own e-mail (audited with contact_id: null); 'resend' sends to every site contact with a usable address and no opt-out.

## Response `200`

Successful Response

- SiteSummarySendItem
  - `id` string, required: Send-attempt UUID.
  - `triggered_by` string, required: 'schedule' (the digest loop), 'test' or 'resend' (an owner/site-manager action). Only the latter two consume the hourly budget.
  - `sent_at` string, date-time, required: When the attempt was made (UTC).
  - `status` string, required: 'pending' (reserved, outcome not yet known) | 'sent' | 'partial' | 'failed' | 'skipped_quiet' | 'skipped_no_recipients' | 'skipped_disabled'.
  - `recipients` object[], required: Per-recipient outcome: {contact_id, email, status, error}. contact_id is null for a test send, whose recipient is the caller's own address. An account manager sees {contact_id, email, status} only, and only for entries that have a contact_id.
  - `ses_message_ids` string[], required: SES message ids, one per accepted recipient, for tracing a delivery with the provider. Always empty for an account manager.
  - `error` string, nullable: Failure detail for the attempt as a whole; null on success and on every skip. An account manager sees a flat 'delivery failed' instead of the provider text.

## Other responses

- `422`: Validation Error

---

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