Send your own report
This page shows how to make a product you run send its own daily counts to NoticeOS, so they are shown beside its traffic and revenue.
Most of the data NoticeOS has about a site comes from data sources you connect on Integrations, such as Google Analytics. A report adds counts that only your product's own servers have: sign-ups, saved items, rows in its database. Once a day your product either sends it to the installation or returns it when the installation requests it, and NoticeOS shows those counts on the site's page and raises an alert when one moves unusually. Most sites do not need one; add it when the numbers that matter to you are not collected by any outside service.
Before you begin
- The site added in NoticeOS. Its id is its domain as added in the product.
- The site's token. Each site has one secret shared with the installation. It authenticates a push, and NoticeOS sends it when it fetches the report. The installation holds the map of site id to token in its secrets file,
workers/ingest/.dev.secrets.json, underASSET_TOKENS. Whoever runs the installation sets it; it is one of the four bootstrap secrets that are never entered in the product. Your product stores its own copy and requires it on its metrics endpoint.
What belongs in a report
A report contains only what your product's own servers can count: requests at a route, rows in its database, objects in storage. Client-side analytics such as GA4 are not part of it. NoticeOS collects those centrally and joins them to the site by its id; a product never queries an analytics provider about itself.
Each metric is one name with three numbers: how many in the last 24 hours, the average per day over the last 7 days, and the all-time total. A stock figure, such as how many items a catalogue holds, can be included in metrics for the totals row, but leave it out of capabilities so an unchanged catalogue is not counted as a day with no activity.
The shape
{
"asset": "example.com",
"generatedAt": "2026-10-10T02:00:00.000Z",
"capabilities": ["signups", "plansSaved"],
"metrics": {
"signups": { "last24h": 10, "avg7d": 9.4, "total": 4210 },
"plansSaved": { "last24h": 0, "avg7d": 6.5, "total": 1900 },
"catalogItems": { "last24h": 0, "avg7d": 0, "total": 2402 }
},
"negativeByPage": [{ "page": "/calculator", "count": 3 }],
"flags": [
{ "severity": "info", "kind": "milestone", "metric": "signups", "msg": "4000 signups" }
]
}assetis the site's id, which is its domain as added in the product. It must match the token presented.generatedAtis a date-time with a time-zone offset.capabilitieslists the metric names that count as activity.metricsmaps each name tolast24h(whole number),avg7d(number) andtotal(whole number), none negative.negativeByPageandflagsare optional. A flag has aseverityofinfo,warnorerrorand akindofanomaly,opportunityormilestone; a milestone is alwaysinfo.
Push the report each night
- In your product, build the report in the shape each night.
- Send it to the installation's ingest at
POST /api/pulse, with the headerAuthorization: Bearer <token>.
Have NoticeOS fetch it instead
- On the site's Settings tab, open Data collection.
- Set Metrics endpoint to the address where your product serves its metrics.
- Under Response format, select Nightly report envelope when the address returns the report shape, or Prometheus metrics page when it exposes a metrics page that NoticeOS maps into it.
- Check that Nightly fetch shows Enabled, not Paused.
The same panel shows Report endpoint and Auth source for push, Schedule, and Last report once one has arrived. The nightly fetch runs at 02:30 UTC; change it on Settings > Data collection under Nightly reports.
Push by hand once
In a terminal, with the report saved as
report.json, run:shcurl -sS -X POST https://<your-installation>/api/pulse \ -H 'authorization: Bearer <token>' \ -H 'content-type: application/json' \ -d @report.json
Verify
- The ingest returns
201with{ "ok": true }when the report is stored. - The site's Data sources tab has a Daily metrics table: Metric, Latest report · 24h with its date, Prior reports · avg / day, and History · daily counts as a small chart. Before the first report it shows Nothing yet — metrics appear with this site's first nightly report. Missing days are counted and shown, never drawn as zero.
- The site's Overview can show a totals row from
total, once you add the cards on the site's Settings tab under Card totals. - Alerts fire on a metric only after four matching prior weekdays exist, so NoticeOS raises no alerts on a new metric for at least 28 days. A metric averaging 4.6 or more a day is tested one day at a time and a quieter one over several days, up to 14; a count is flagged when it is improbable against that baseline. Thresholds are in Settings > Alert rules.
If it didn't work
- The ingest returns
401: the token or the site id does not match.assetmust equal the site's domain as added, and the token must be the one inASSET_TOKENSfor that site. - The ingest returns
422with a list of issues: the shape is wrong. A rejected report stores nothing. Fix the listed fields and send it again. - The report stops arriving: the product raises an alert when a nightly fetch fails, and marks the site's report stale on the Data sources tab. See Troubleshooting.
The contract is in doc 02, Signal contract. Onboarding a site, including counting without a database: doc 09, Onboarding a site. The four bootstrap secrets: doc 06, Operations & self-observability.