# Watch your own data quality

**The job:** know when Signal has stopped seeing your site, before you build a
decision on a number that has quietly become wrong.

**Who this is for:** everyone. This is the workflow that protects every other
workflow on this site.

---

## The failure that matters

The dangerous failure is not an outage. An outage is loud. The dangerous
failure is *silence that looks like data*: the pixel stops firing, or the order
sync breaks, and every endpoint keeps returning 200 with numbers that are
smaller than reality. Dashboards look fine. Conclusions quietly rot.

## The cheapest possible check

```python
a = requests.get(f"{BASE}/attribution", params={"days": 7}, headers=H).json()

if not a["has_data"]:
    alert("Signal attribution has no data for the last 7 days")

if a["totals"]["visitors"] < expected_floor:
    alert(f"visitors={a['totals']['visitors']}, expected at least {expected_floor}")

if a["totals"]["identify_rate"] < 0.2:
    alert(f"identify_rate has fallen to {a['totals']['identify_rate']:.0%}")
```

`expected_floor` should come from your own history, not a guess — the median of
the last eight weeks is a reasonable start. A fixed threshold is wrong within a
quarter.

## Asking the system about itself

The assistant can answer the health questions directly, which is often faster
than assembling them:

```bash
curl -s https://app.signal.geysera.com/agent-api/signal/copilot/ask \
  -H "Authorization: Bearer $SIGNAL_COPILOT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"question": "Is my workspace set up properly, and have we stopped identifying visitors?"}'
```

`workspace_setup` returns store connection, onboarding progress, pixel status,
identification health and plan usage in one call, and it distinguishes "nothing
happened" from "we are not collecting" — which is exactly the distinction this
workflow exists to make.

## What to check, and how often

| Check | Cadence | What a failure means |
|---|---|---|
| `has_data` on a 7-day window | daily | nothing is being collected |
| visitors vs your 8-week median | daily | the pixel is partially broken |
| `identify_rate` vs its own history | daily | identification is degraded |
| `median_hours_to_identify` | weekly | the pipeline is lagging |
| revenue question returns a number | daily | order sync has stopped |

The last one is the one people miss. Ask *"what was revenue in the last 7
days?"*: a workspace whose store connection has silently expired answers zero,
confidently, and everything downstream inherits it.

## Make the alert clearable

Before adding any check here, decide what makes it stop. An alert that fires
forever is one people mute, and a muted alert is worse than none — it is a
check you believe you have.

## What will go wrong

**A quiet weekend fires everything.** Compare like with like: this Monday
against previous Mondays, not against Friday.

**Your own traffic.** Staff and monitoring hit the site too. A floor set from
history already includes them; a floor set by intuition usually does not.

**Crawlers.** Unflagged bot traffic has inflated visitor counts before — by a
lot. If a number moves and nothing else did, check that the visitors are
people before you act on it.

---

Next: [notice an account going quiet](./notice-an-account-going-quiet.md) ·
[the pipeline that reported success while doing nothing](../case-studies/the-pipeline-that-reported-success-while-doing-nothing.md)
