Matches in other apps
zpe-stats
mount /analytics · base https://zpe.vc/analytics · v1.1.5 · 4 operations · 1 write · 0 need no account · stable
the registry's copy of this app's contract. No address: the app answers no document route, so apis/zpe-stats.json in the registry is the only published form of these bytes · sha256 fe317fef53dd
GET
/api/v1/data/runs/latest
The newest census run, and the stores it read
getLatestCensusRun
The run with the greatest `ran_at`, its totals, and one row per store. `limit` and `cursor` page the STORES inside that run, not the runs, because a census of the estate is larger than one answer: the first answer carries the run and the first `limit` stores, and `next` is the cursor for the rest of them.
Parameters
| name | in | required | type | notes |
|---|---|---|---|---|
cursor | query | no | string | The `next` value from a previous answer for the same run. It is a position in that run's stores and means nothing in another run. |
limit | query | no | integer | How many stores to return. Absent, the app answers its own default. |
Request body
None: this operation takes its arguments in the path and the query.
Responses
| status | meaning | body |
|---|---|---|
200 | The newest run, with its totals and the stores this page carries. `next` is the cursor for the following page of stores, and is `null` on the last one. | object |
400 | `limit` is not a number in range, or `cursor` is not a cursor this app wrote: nothing was read. | object |
401 | No credential, or one the app could not verify: the census is not public, so nothing was read. | object |
403 | A real credential that may not read this surface, or the door named no account for it. | object |
404 | No run is recorded yet, so there is no newest one: the census has not been posted to this deployment. | object |
500 | This app failed while answering, so nothing here describes the estate. The problem's `detail` says what it was doing. | object |
503 | `zpe-stats-db` could not be read, so the newest run could not be named. The problem's `detail` names the store that refused it. | object |
Example
The newest census run, and the stores it read, with a token from the door.
curl -X GET 'https://zpe.vc/analytics/api/v1/data/runs/latest?cursor=string&limit=50' \ -H 'Authorization: Bearer $ZPE_TOKEN'
{
"run": {
"run_id": "string",
"ran_at": "2026-10-31T09:00:00Z",
"instrument_version": "string",
"instrument_commit": "string",
"totals": {
"stores": 0,
"disagreements": 0,
"unclassified": 0
}
},
"stores": [
{
"name": "string",
"state": "read",
"error": "string",
"binders": [
{
"repo": "string",
"config": "string",
"binding": "string"
}
],
"declared": {
"statements": 0,
"source": "schema.sql",
"absent": [
"string"
]
},
"database_uuid": null,
"account_id": null,
"uuid_source": null,
"live": null,
"live_tables": null,
"tables": [
{
"name": "string",
"classification": "person",
"keys": [
"string"
],
"reason": "string",
"agreement": "agree"
}
]
}
],
"findings": null,
"next": null
}The example is generated from the schema in the contract: the shape is the document's, the values are placeholders.
GET
/api/v1/data/runs/{run_id}
One census run by its id, and the stores it read
getCensusRun
The run with that `run_id`, its totals, and one row per store — the SAME answer shape `/runs/latest` gives while that run is the newest. `/latest` moves as soon as a newer run is posted, so this is the only address a run keeps once it stops being the newest: a reader comparing tonight's declarations with the previous run's reads the previous run here instead of keeping a copy of it. `limit` and `cursor` page the STORES inside this run, exactly as they do on `/latest`, and a cursor carries the run it belongs to: a cursor from another run is a `400`, because it would otherwise be a position in a list this answer does not contain. An id this deployment does not hold is a `404` problem document naming the id it asked for.
Parameters
| name | in | required | type | notes |
|---|---|---|---|---|
run_id | path | yes | string | The run's own id: the hash the instrument computed over what it measured, which is also the id `/runs` lists and the one the POST answered. It is the primary key, so the id a caller holds is the id this route answers. |
cursor | query | no | string | The `next` value from a previous answer for the SAME run. It is a position in that run's stores and means nothing in another run. |
limit | query | no | integer | How many stores to return. Absent, the app answers its own default. |
Request body
None: this operation takes its arguments in the path and the query.
Responses
| status | meaning | body |
|---|---|---|
200 | The run, with its totals and the stores this page carries. The shape is `/runs/latest`'s, for the run that was asked for rather than the newest one. `next` is the cursor for the following page of stores, and is `null` on the last one. | object |
400 | `limit` is not a number in range, `cursor` is not a cursor this app wrote, or the cursor belongs to a different run: nothing was read. | object |
401 | No credential, or one the app could not verify: the census is not public, so nothing was read. | object |
403 | A real credential that may not read this surface, or the door named no account for it. | object |
404 | No run with that `run_id` is recorded in `zpe-stats-db`: the id is not one this deployment holds, or the run has been pruned by the store's retention. The problem's `detail` names the id it asked for. | object |
500 | This app failed while answering, so nothing here describes the estate. The problem's `detail` says what it was doing. | object |
503 | `zpe-stats-db` could not be read, so the run's stores could not be named. The problem's `detail` names the store that refused it. | object |
Example
One census run by its id, and the stores it read, with a token from the door.
curl -X GET 'https://zpe.vc/analytics/api/v1/data/runs/string?cursor=string&limit=50' \ -H 'Authorization: Bearer $ZPE_TOKEN'
{
"run": {
"run_id": "string",
"ran_at": "2026-10-31T09:00:00Z",
"instrument_version": "string",
"instrument_commit": "string",
"totals": {
"stores": 0,
"disagreements": 0,
"unclassified": 0
}
},
"stores": [
{
"name": "string",
"state": "read",
"error": "string",
"binders": [
{
"repo": "string",
"config": "string",
"binding": "string"
}
],
"declared": {
"statements": 0,
"source": "schema.sql",
"absent": [
"string"
]
},
"database_uuid": null,
"account_id": null,
"uuid_source": null,
"live": null,
"live_tables": null,
"tables": [
{
"name": "string",
"classification": "person",
"keys": [
"string"
],
"reason": "string",
"agreement": "agree"
}
]
}
],
"findings": null,
"next": null
}The example is generated from the schema in the contract: the shape is the document's, the values are placeholders.
GET
/api/v1/data/runs
The census history, newest run first
listCensusRuns
One row per run, newest first, with each run's totals and no stores: the history is what answers whether the census is current, and `/runs/latest` is what answers what it found. `limit` and `cursor` page the runs, and `next` is the cursor for the following page.
Parameters
| name | in | required | type | notes |
|---|---|---|---|---|
cursor | query | no | string | The `next` value from a previous answer: a position in the run history, newest first. |
limit | query | no | integer | How many runs to return. Absent, the app answers its own default. |
Request body
None: this operation takes its arguments in the path and the query.
Responses
| status | meaning | body |
|---|---|---|
200 | The runs this page carries, newest first, and the cursor for the next page. `next` is `null` on the last page, and the app answers an empty `runs` list when no run has been recorded. | object |
400 | `limit` is not a number in range, or `cursor` is not a cursor this app wrote: nothing was read. | object |
401 | No credential, or one the app could not verify: the history is not public, so nothing was read. | object |
403 | A real credential that may not read this surface, or the door named no account for it. | object |
500 | This app failed while answering, so the history is not an answer about the estate. The problem's `detail` says what it was doing. | object |
503 | `zpe-stats-db` could not be read, so the history could not be listed. The problem's `detail` names the store that refused it. | object |
Example
The census history, newest run first, with a token from the door.
curl -X GET 'https://zpe.vc/analytics/api/v1/data/runs?cursor=string&limit=20' \ -H 'Authorization: Bearer $ZPE_TOKEN'
{
"runs": [
{
"run_id": "string",
"ran_at": "2026-10-31T09:00:00Z",
"instrument_version": "string",
"instrument_commit": "string",
"totals": {
"stores": 0,
"disagreements": 0,
"unclassified": 0
}
}
],
"next": null
}The example is generated from the schema in the contract: the shape is the document's, the values are placeholders.
POST
/api/v1/data/runs
Record a census run the instrument measured
postCensusRun
The instrument posts one run per measurement: the run's own `run_id`, when it ran, which instrument version and commit read the estate, and one row per store. A run is KEYED by `run_id`, which is the hash of what was measured, so the same run posted twice answers `200` with the row the first call wrote and makes no second row. A store the instrument could not read is posted as a row whose `state` is `error`, with the reason in `error`; that is a fact about the store, not a refusal of this call.
Parameters
No parameters.
Request body application/json · required
| field | type | required | notes |
|---|---|---|---|
run_id | string | yes | The run's identity: the sha256 of what the instrument measured. Two runs that measured the same estate have the same `run_id`, which is why a retry is not a second row. |
ran_at | string (date-time) | yes | When the instrument finished the walk, as UTC. |
instrument_version | string | yes | The instrument's own version, so a run can be read against the rules it measured with. |
instrument_commit | string | yes | The commit the instrument ran from. |
totals | object | no | What the walk counted, as the instrument posts it: all eight counts. `configs` is the wrangler configs it opened, `stores` the databases they name, and `scratch_only` the stores only a scratch or development config binds; `tables` is how many tables the run saw, `live_tables` how many of them were in a database rather than a declaration, `findings` how many stores the walk could not settle, and `disagreements` and `unclassified` are the two numbers a reader acts on. This object is the POST body's. A recorded run answers `CensusRunTotals`, the three counts the service stores. |
stores | array of object | yes | One row per database the walk found. |
disagreements | array of object | no | Every table whose declaration and live shape disagree, named rather than counted: the instrument's own summary, and the reason a person reads this body. Accepted, and used for `totals.disagreements` only when `totals` is missing. The names are not stored, so the run this service answers does not echo them; each store row already carries them. |
findings | array of object | no | Every store the walk could not settle, named rather than counted. This is where a store the account has no database for appears: `kind` says which failure and `detail` carries the sentence the account answered. The service KEEPS these (1.1.3), so `/runs/latest` answers them whole; omitting the key is not the same as posting `[]`, because an instrument that did not look must not read as one that looked and found nothing. |
Responses
| status | meaning | body |
|---|---|---|
200 | The run was already recorded: `run_id` matched a row, so this answers that row and writes no second one. The body is the run the first call stored, not the one in this request. | object |
201 | The run was new and is now recorded, with one row per store it carried. | object |
400 | The body is not a census run: `run_id`, `ran_at`, `instrument_version`, `instrument_commit`, or a store row is missing or malformed. The problem's `detail` names the store whose row it was, so the instrument that posted it knows which read to look at. | object |
401 | No service token, or one that is not live: nothing was read and nothing was written. | object |
403 | A real credential that may not write the census: a person's session and an account key may read it, and only the service token records a run. | object |
500 | This app failed while answering, and whether the run was recorded is NOT answered by this response. The problem's `detail` says what it was doing, so a caller can post the same `run_id` again and be told. | object |
503 | `zpe-stats-db` could not be reached, so nothing was written and this run is not recorded. The problem's `detail` names the store that refused the write. | object |
Example
Record a census run the instrument measured, with a token from the door.
curl -X POST 'https://zpe.vc/analytics/api/v1/data/runs' \
-H 'Authorization: Bearer $ZPE_TOKEN' \
-H 'content-type: application/json' \
-d '{
"run_id": "string",
"ran_at": "2026-10-31T09:00:00Z",
"instrument_version": "string",
"instrument_commit": "string",
"totals": {
"configs": 0,
"stores": 0,
"scratch_only": 0,
"tables": 0,
"live_tables": 0,
"findings": 0,
"disagreements": 0,
"unclassified": 0
},
"stores": [
{
"name": "string",
"state": "read",
"error": "string",
"binders": [
{
"repo": "string",
"config": "string",
"binding": "string"
}
],
"declared": {
"statements": 0,
"source": "schema.sql",
"absent": [
"string"
]
},
"database_uuid": null,
"account_id": null,
"uuid_source": null,
"live": null,
"live_tables": null,
"tables": [
{
"name": "string",
"classification": "person",
"keys": [
"string"
],
"reason": "string",
"agreement": "agree"
}
]
}
],
"disagreements": [
{
"store": "string",
"table": "string",
"kind": "declared-absent",
"detail": "string"
}
],
"findings": [
{
"store": "string",
"kind": "string",
"detail": "string"
}
]
}'{
"run_id": "string",
"ran_at": "2026-10-31T09:00:00Z",
"instrument_version": "string",
"instrument_commit": "string",
"totals": {
"stores": 0,
"disagreements": 0,
"unclassified": 0
}
}The example is generated from the schema in the contract: the shape is the document's, the values are placeholders.