# Recurring Client Reporting SOP — [Company name]

Template status: [Draft / In review / Approved] · Applies from: [date]

## Purpose

Produce the recurring client report on the same day, from the same data window,
with the same metric definitions every period, so that a number the client saw
last month still means the same thing this month and any change in it is a real
change in performance rather than a change in how it was calculated.

## Scope

The [monthly] performance report for clients on [retainer / managed service],
from data cut-off to delivery and archive.

Out of scope: ad-hoc analysis requests, quarterly business reviews
([QBR SOP]), and invoicing, which reads from the same data but has its own
sign-off.

## Owner

Accountable: [Account Manager].
Supporting: [Analyst] for the data pull, [Delivery Lead] for the internal
review, [Account Director] for external sign-off.

## Trigger

Scheduled: [working day 2] of each month at [09:00] for the previous calendar
month.

Out-of-cycle trigger: a client contract that specifies a different window runs
on its own schedule and is listed in [reporting calendar], never handled by
memory.

## Inputs

| Input | System of record | Required |
| --- | --- | --- |
| Metric definitions and formulas, versioned | [Metric dictionary] | Yes |
| Period data from each source platform | [Named platforms] | Yes |
| Prior period report as published | [Report archive] | Yes |
| Spend and budget for the period | [Finance system] | Yes |
| Commentary notes logged during the period | [Account notes] | Yes |
| Client-specific reporting requirements | [Client file] | Yes |

## Prerequisites

- The metric dictionary is current and every metric in the report template maps
  to a definition in it. A metric with no definition does not go in the report.
- All source platforms have finished their own attribution or restatement window
  for the period. Pulling before a platform settles is the most common cause of
  a number changing after delivery.
- Last period's report is archived exactly as sent, including the commentary.
- The recipient list on the client file was confirmed within the last [90] days.

## Steps

1. **Freeze the data window** and record it explicitly: start timestamp, end
   timestamp, timezone. Every figure in the report comes from this window and
   nothing else.
2. **Confirm each source has settled.** → Decision **D1**. If a platform is
   still restating, either wait within the SLA or publish with a stated
   provisional marker; do not publish a settled-looking number from unsettled
   data.
3. **Pull the raw data per source** into the working file without editing.
   Record row counts and the pull timestamp per source.
4. **Apply the metric definitions** from the dictionary version in force for
   this period, and stamp that version onto the report. This is what lets you
   answer "why is this different from last month" a year later.
5. **Reconcile against the prior period.** Compare every headline metric to the
   published prior figure. → Decision **D2** for anything that has moved beyond
   the variance threshold.
6. **Check for data gaps and outliers** before writing anything: zero-value days
   in a normally active series, a single day carrying an implausible share of
   the period, a metric that is exactly flat. Each of these is a data question
   before it is a performance story.
7. **Compare against budget and target** for the period, and against the same
   period last year where [12] months of comparable data exists under the same
   definitions.
8. **Write the commentary.** Every headline variance beyond the D2 threshold
   gets a sentence naming the cause or explicitly saying the cause is not yet
   known. "Not yet known" is an acceptable answer; silence is not.
9. **Decide whether a prior period must be restated.** → Decision **D3** and
   approval **A2**. A restatement is always disclosed in the report, never
   applied quietly.
10. **Internal review.** [Delivery Lead] checks the numbers against the sources
    and the commentary against the notes. The reviewer is never the person who
    pulled the data.
11. **External sign-off and delivery.** → Approval **A1**. Send to the confirmed
    recipient list only.
12. **Archive** the delivered file, the working file, the source extracts, the
    dictionary version and the sign-off, all under the period key.

## Decisions

| ID | Decision | Criteria | Default |
| --- | --- | --- | --- |
| D1 | Source has settled | Platform's stated attribution window has closed **and** yesterday's pull matches today's for the same window | Not settled → wait or mark provisional |
| D2 | Variance needs commentary | Absolute change ≥ [x%] period-on-period **or** ≥ [amount] **or** crosses a target boundary | Comment |
| D3 | Restate a prior period | Prior figure was wrong by more than [x%] **and** the client made or could reasonably have made a decision on it | Disclose without restating |
| D4 | Hold delivery | A headline metric cannot be produced, or a restatement is unresolved, or the client contact list is unconfirmed | Deliver on time with a stated gap |
| D5 | Provisional marker | Any source not settled at cut-off | Mark the affected metrics provisional and state the settle date |

## Exceptions

- **E1 — Source platform unavailable at cut-off.** Record the outage, deliver
  with the metric marked unavailable and a stated re-issue date. Never estimate
  a platform figure and present it in the same format as measured ones.
- **E2 — Metric definition changed mid-period.** Report both the old and the new
  basis for the first period after the change, then the new basis alone. Note
  the change in the report and bump the dictionary version.
- **E3 — Client changed reporting contacts.** Do not send until the new
  recipient list is confirmed in writing by a known contact. A report is client
  data; a wrong recipient is a disclosure.
- **E4 — Numbers contradict what the client was told during the period.** Raise
  internally before delivery. The report is not the place a client first learns
  that a mid-period update was wrong.
- **E5 — Period contains a one-off event** (an outage, a campaign pause, a
  pricing change). Isolate it in the commentary and state whether the headline
  figures include it. Do not remove it silently.
- **E6 — Data window overlaps a client's own restatement.** Use the client's
  published figures for shared metrics and note the source, rather than
  publishing a competing version of their own numbers.

## Approvals

| ID | What is approved | Who approves | Why it stays with a person |
| --- | --- | --- | --- |
| A1 | Delivery to the client | [Account Director] | Once a report leaves the building it cannot be unsent |
| A2 | Restatement of a previously published figure | [Account Director] with [Delivery Lead] | It changes something the client already acted on |
| A3 | Adding or changing a metric definition | [Delivery Lead] | Definitions are the contract behind the numbers |
| A4 | Sending to a recipient not on the confirmed list | [Account Director] | Disclosure of client data |

## Output

- A delivered report stamped with the data window, the dictionary version and
  the preparer and reviewer.
- Commentary covering every variance above the D2 threshold.
- An archived bundle: delivered file, working file, source extracts, sign-off.
- A log of provisional metrics with their settle dates and re-issue status.

## SLA / KPI

- Delivered by working day [5]: target [100%].
- Reports requiring a post-delivery correction: target under [2%] per quarter.
- Metrics delivered without a dictionary version stamp: target zero.
- Median time from data cut-off to internal review: [x] hours, tracked to see
  where the cycle actually goes.

## Audit record

Retain for [36] months per period and client: the frozen window definition,
source extracts with pull timestamps and row counts, the metric dictionary
version, the working file, the delivered file exactly as sent, the recipient
list, the A1 sign-off, and any A2 restatement with its disclosure text.

> Simulated example data
>
> Client [Harbour Retail], period [2026-06-01 → 2026-06-30 Europe/Berlin], cut
> off [2026-07-02 09:00]. Source [Platform A] settled; source [Platform B]
> still in a [72]-hour attribution window → D5 provisional marker applied to
> [attributed conversions]. Headline [qualified enquiries] moved from [412] to
> [351], a [-14.8%] change, above the D2 threshold of [10%], so commentary
> names the [two-week campaign pause] logged on [2026-06-09]. Dictionary
> version [2026-Q2.1].

## Revision log

| Version | Date | Author | Change |
| --- | --- | --- | --- |
| v1.0 | 2026-07-24 | [Your name] | initial draft |
