> ## Documentation Index
> Fetch the complete documentation index at: https://docs.chartcastr.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Snapshots & delivery

> How Chartcastr renders monthly briefing PDFs, the once-per-calendar-month throttle, and destination delivery.

A **snapshot** is a frozen, multi-page PDF render of your briefing at a point in time, plus the act of delivering it to your destination. Snapshots are throttled to **once per calendar month** per briefing.

## When snapshots run

| Trigger                  | Source                                                                                          | Throttle? |
| ------------------------ | ----------------------------------------------------------------------------------------------- | --------- |
| Scheduled                | The monthly cron, fired by the briefing's connection at the day-of-month + time you configured. | Yes.      |
| Manual ("Send Snapshot") | The button in the composer or list page.                                                        | Yes.      |
| Manual override          | Org admins only — bypasses the monthly throttle for support / failed-delivery retries.          | No.       |

If a scheduled or manual run hits the throttle, the orchestrator writes a `BriefingContent` with `status = UNCHANGED` and `runWarnings = [{ code: 'THROTTLED_MONTHLY' }]`, then exits without calling the AI or rendering a PDF.

<Note>"Calendar month" is computed in your **organisation's timezone**, not UTC. A briefing scheduled for the 1st of the month will fire on your local 1st, and `lastSnapshotAt` is compared against the start of that local month.</Note>

## Schedule shape

The briefing settings page exposes a structured form, not a cron textarea:

* **Day of month**: 1–28 (avoids the 29/30/31 edge cases).
* **Hour**: 0–23, in your org timezone.
* **Minute**: 0–59.

The server materialises this to a cron expression internally — the UI never sees one.

## What's in the PDF

The PDF is rendered server-side with `@react-pdf/renderer` (Bun-compatible, no headless browser). Layout:

| Page                      | Contents                                                                                                                                              |
| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| **1 — Cover**             | Briefing name, period label (e.g. "April 2026"), generated timestamp, organisation name, description, brand mark.                                     |
| **2 — Big Picture**       | The overall review — `aiSummaryLong` body + highlight bullets. Placed up-front.                                                                       |
| **3+ — Per-row sections** | For each row: title, item grid (chart image + name + short summary, 2 per row), then the cross-analysis commentary + highlights.                      |
| **Last — Appendix**       | Per-item full long summaries (anything that didn't fit above), and a data-freshness table showing each item's `latest.generatedAt` vs. fresh / stale. |

The PDF is uploaded to R2 and linked from `BriefingContent.pdfUrl` so it can be re-downloaded from the snapshot history page even after delivery.

## Delivery

Briefings are delivered to your configured [destination](/integrations/destinations). The cover message includes the briefing name, period label, the overall short summary, and a link to view the snapshot online. The PDF is attached to the message wherever the destination supports attachments; if the file is too large for the destination, Chartcastr falls back to a download link instead.

The deliverable is consistent across destinations — only the wrapping format differs.

## Snapshot history

Every run — successful, throttled, failed — writes a `BriefingContent` row. The `/admin/briefings/[id]/snapshots` page lists them, ordered newest-first. By default the list filters to `status = SUCCESS` and `pdfUrl IS NOT NULL`; toggle to show all.

Each row records:

* Completion date, status, trigger type (Scheduled / Manual)
* Token usage breakdown (titles + rows + overall)
* PDF download link
* A view of the frozen `briefingSnapshot` so the snapshot detail page can re-render the briefing exactly as it was delivered, even if you've since changed the live composition.

## Failure modes

| Code                          | Cause                                                              | What it means                                                                                                        |
| ----------------------------- | ------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------- |
| `THROTTLED_MONTHLY`           | A run for the same briefing already completed this calendar month. | Run exits early. No AI, no PDF. Use the admin override to bypass.                                                    |
| `BRIEFING_COMMIT_IN_PROGRESS` | A save is already in flight.                                       | Wait for the in-flight run to finish.                                                                                |
| `PLAN_UPGRADE_REQUIRED`       | The org's plan dropped below paid.                                 | Read access still works; mutations and new snapshots are blocked. Existing scheduled connections move to `DEGRADED`. |

A run is `SUCCESS` when at least one row produced commentary AND the overall summary call succeeded. A row that failed individually is recorded with `aiError` set and surfaces on the snapshot detail page as a per-row "retry" affordance — it does not block the rest of the briefing from being delivered.
