batchwatch

batchwatch › Acceptable Use Policy

Acceptable Use Policy

Version 0.1 · draft of 25 August 2026 · forms part of TERMS.md.

Draft. Not legal advice. Written by the developer who wrote the enforcement code, not by a lawyer. The rules below are deliberately written to match what the code actually does — no more. Where a rule is honour-based rather than enforced, it says so. Have a qualified lawyer review this before it is published.

Version 0.1 · draft of 25 August 2026 · forms part of TERMS.md.


1. The one rule

Every measurement you submit must be one you actually observed.

Everything else in this document follows from that. The only asset batchwatch has is that the numbers are true. A service that publishes crowdsourced percentiles has exactly one way to fail permanently, and this is it.

2. Prohibited

You must not:

  1. Submit a measurement of a job that did not happen. No synthetic rows, no test data left pointed at production, no "representative" figures, no timings copied from somewhere else.
  2. Misreport what did happen. Do not submit timestamps that are not the real start and end of the job. Do not relabel the model, the provider, the mode (batch vs sync) or the token counts.
  3. Submit measurements you did not take. Do not forward another party's timings as your own; each key is meant to be one source.
  4. Run multiple keys in order to gain influence over the published figures. One organisation, one voice. Creating additional keys to get additional votes is the specific attack this service is built against, and it is prohibited whether or not it currently succeeds.
  5. Deliberately evade the free-trial counter by changing IP address, cycling keys, or otherwise resetting the count in order to keep using the gated routes without contributing. The trial is explicitly not a security boundary; going around it anyway is a breach of this policy.
  6. Exceed the key-creation limit by rotating addresses. The limit of 5 keys per IP per day is hygiene against a runaway loop, not a wall. Do not treat it as a challenge; one key per service is plenty, and keys are not per-machine.
  7. Attack the availability or integrity of the service — flooding ingest, attempting to drive a model's confidence to very_low to make it useless to others, exploiting a vulnerability rather than reporting it.
  8. Scrape the API in order to reconstruct and redistribute the aggregate dataset. Reading the data for your own use, including commercially, is the point. Republishing it as a competing dataset is not licensed. See TERMS.md §7.
  9. Put personal data in the free-text fieldsmodel, endpoint and the key label. They are stored verbatim and not scrubbed. See PRIVACY.md §2.

3. What the code actually checks

This section exists so nobody is surprised in either direction — neither by a rule enforced more tightly than expected, nor by a defence that turns out not to exist.

The live path is checked against our clock

POST /v1/callsPATCH /v1/calls/{id} is open to everyone, with or without a key, because it is self-limiting:

The consequence is that faking an eight-hour wait on this path costs eight hours of real waiting. That is why it needs no key.

The import path is not, so it needs a key

POST /v1/calls/complete takes your timestamps, because it exists to import history. There is no physics left in it. It checks only that both timestamps are present, that the end is not before the start, that the provider and model are valid, and that a request carries at most 500 records.

It therefore requires an API key. This is not a formality: measured against a running worker before the route was closed, 2,000 fabricated eight-hour jobs took four anonymous requests and 287 ms, moved a model's p50 from 146 s to 28,800 s, and flipped the verdict. A key does not prevent that, but it makes it named, revocable and visible.

Percentiles are decided by contributors, not by volume

This is the defence that actually works, and it is worth stating precisely because the rule above ("one organisation, one voice") is the human version of it.

Separately, each source is capped at half of what all other sources contribute combined before the pooled figures are computed, sampled evenly in sorted order so the shape — and the tail — survives the cut.

Measured effect: a keyed attacker submitting 5,000 fabricated rows against three honest contributors moved p50 and p90 by zero seconds, and dropped confidence from high to very_low. The system says it is unsure rather than saying something wrong.

4. What these defences do not do

Published here rather than hidden, because a defence you overstate is worse than one you do not have.

  1. A patient attacker with several accounts can still reach a majority. Four accounts run for a week, producing plausible-looking data on separate days, can out-vote three honest contributors. There is a test in the repository that says so out loud. Quarantining outliers until a second established contributor corroborates them is the next step, and it is not built yet.
  2. Confidence intervals are computed on the pooled data on purpose, so an attacker can widen them upward. That makes us recommend synchronous calls, which costs money, not deadlines. It is the safe direction and it is deliberate.
  3. Denial of service on a model's usefulness is possible. Driving confidence to very_low for a model makes the answer useless without making it wrong. It is not free, but it is not prevented.
  4. size_effect compares the size band against a non-capped pool, so that particular flag can be flipped by volume. Known, recorded, not yet fixed.
  5. The free trial is not a security boundary and is not built as one. Anyone can change IP address. The data is aggregate percentiles, not secrets; what makes the product work is that sustained use requires contributing.
  6. There is no automated abuse detection. Nothing scans for suspicious submissions. Enforcement under §6 is a human noticing.

5. Our own measurements

Our prober submits real batch jobs to real queues on our own provider accounts and records them like any other measurement, marked source: 'probe'. They count in the statistics because they are real jobs in the real queue. /v1/coverage reports crowdsourced: false while our own jobs are all we have for a model — a dataset that is really one account has to say so.

Where the prober gives up on a job it records abandoned, never completed. We stopped looking; the job did not expire; the true wait is unknown and longer than what we saw. Only completed rows enter any percentile.

6. Enforcement

If we conclude this policy has been breached we may:

Note honestly: there is no admin route for any of this. Revocation, exclusion and deletion are manual database operations by the operator. There is no queue of reports, no automated scoring, and no appeal process beyond writing to hello@batchwatch.dev. Where we can say why we acted, we will.

7. Reporting