Hosted
Send numbers to hosted ZeroWidth
A script or an AI agent can send a team's numbers, such as daily revenue or signups, with a team token. Sending the same numbers again is safe.
ZeroWidth checks each decision against the numbers it was meant to move. A script, or an AI agent running a script, can send those numbers with a team token.
Before you start, an admin defines each metric in the console. Sending a number for a metric that isn't defined is refused, and ZeroWidth never makes the metric for you. Metrics
Make a team token
Only an admin can make a token.
Open Sources and choose "Make a token and the prompt".
Copy the token or the prompt now. The token is shown once.
A team token can send numbers for its own team and can't do anything else. Keep the token in an environment variable, never in code or in a chat. Sources lists each token with when it was last used. An admin can end a token at any time, and it stops working at once.
Send numbers
Send a POST to /api/<team>/readings with the token in the Authorization header and the numbers as JSON.
{
"readings": [
{ "metric": "revenue", "date": "2026-11-01", "value": 1234.5 },
{ "metric": "signups", "date": "2026-11-01", "value": 41 }
]
}Each reading has these fields:
| Field | What to send |
|---|---|
metric | The id of a metric your team has defined. Required. |
value | The number. Required. |
date | The day the number is for, such as 2026-11-01. |
at | A full time with a time zone, such as 2026-11-01T09:00:00Z. Use at in place of date. |
labels | Names and values that say which part of the metric the number is for, such as {"country": "DE", "plan": "pro"}. Optional. |
key | Optional. Tells two numbers for the same metric on the same day apart. |
Send date or at, never both. A date is a whole day, and at is a moment in time. An at with no time zone is refused.
Labels
Labels work on any metric. Send Acme's revenue for Germany on the Pro plan like this:
{ "metric": "revenue", "date": "2026-11-01", "value": 310, "labels": { "country": "DE", "plan": "pro" } }A reading can have up to 10 labels. Each label name is up to 80 characters, and each value is up to 200 characters, as text. For one metric, send either one number a day or the parts that add up to it, not both.
Limits and resending
One request can hold up to 10,000 readings. For more, send several requests.
A request is all or nothing. If any reading is wrong, none are kept, and the reply says which readings were wrong.
Sending the same reading again is safe. Nothing is counted twice. Sending a different value for the same metric, day and labels corrects the earlier number.
The reply says how many numbers were new or corrected and how many ZeroWidth already had:
{ "added": 2, "unchanged": 0 }A curl example
curl -X POST https://<your-zerowidth-address>/api/acme/readings \
-H "Authorization: Bearer $ZEROWIDTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"readings":[{"metric":"revenue","date":"2026-11-01","value":1234.5}]}'A prompt for your agent
Paste this into Claude Code, Codex, Cursor or another AI tool that can run code. Sources makes the same prompt with your team's metrics filled in.
Send Acme's numbers to ZeroWidth. Metrics to fill: revenue, signups.
Post to https://<your-zerowidth-address>/api/acme/readings with the header
"Authorization: Bearer $ZEROWIDTH_TOKEN" and a JSON body like
{"readings":[{"metric":"revenue","date":"2026-11-01","value":1234.5}]}.
1. Find where each number lives in our tools and ask me if you can't tell.
2. Write a small job that sends yesterday's number for each metric every day.
Read the token from the ZEROWIDTH_TOKEN environment variable, never from code.
3. Send the daily numbers back as far as each source goes, in batches of a few hundred.
4. Run the job once and tell me how many numbers were added and how many were already there.Error replies
| Reply | What it means |
|---|---|
| 400 | A reading is wrong, or the body isn't JSON. The reply lists up to 50 wrong readings by place in the list, such as "#3 no metric is called visits". None were kept. Fix them and send again. |
| 401 | The token isn't live for this team. It may be ended, mistyped, or from another team. Make a new token. |
| 403 | A team token can only send numbers to its own team's readings address. |
| 413 | The request is too big: more than 10,000 readings, or more than 8 MB. Send fewer at a time. |
| 415 | Send the body as JSON, with the header Content-Type: application/json. |
Connect a tool directly instead
If the numbers live in one of these tools, connect it on Sources and ZeroWidth fetches them every day, with nothing for you to run:
Stripe
PostHog
Shopify
HubSpot
Zendesk
Intercom
Mixpanel
Amplitude
Use a token instead when the numbers come from your own database or a spreadsheet, from a tool not on this list, or when you want numbers split by country or plan with labels. PostHog also sends signups split by country and by device, as the metrics "Signups by country" and "Signups by device". The other connected tools send one number a day.