Draft. Not legal advice. Written by the developer who wrote the service, not by a lawyer. It is accurate about what the code does — every statement below was checked against
src/andschema.sql— but it has not been reviewed for legal sufficiency in any jurisdiction. Have a qualified lawyer review this before it is published or relied on.Placeholders in
[SQUARE BRACKETS]must be filled in before publication.
Version 0.1 · draft of 25 August 2026 · applies to batchwatch.dev, www.batchwatch.dev and api.batchwatch.dev.
1. Who we are
batchwatch is operated by Stenager Consulting ApS, CVR 44456923, Stenagervaenget 45, 7100 Vejle, Denmark. Contact: hello@batchwatch.dev.
Referred to below as "we", "us", "batchwatch". "You" means the person or organisation using the service.
2. What the service is
batchwatch measures how long jobs actually take on large-language-model batch APIs — the /v1/batches endpoints at OpenAI, Anthropic, Google and similar — and publishes the distribution of those waits.
Two things follow from that, and they are the most important terms here:
- We publish measurements, not predictions. Every answer describes what comparable jobs did in the past. It is not a forecast for your job, and the API says so in every response (
"not": "a prediction for your job"). - We answer from thin data on purpose, and we label it. With no measurements at all we return the provider's own published window with
basis: "sla_prior"andconfidence.level: "none". With few measurements the confidence interval widens by itself and the response says how thin the basis is. You are expected to readn,confidence,basisandfreshnessbefore acting on a number.
3. No accounts
There are no user accounts. We do not ask for an email address, we do not issue passwords, and there is nothing to log in to.
What exists instead is an API key — a bearer token you can create with a single unauthenticated request:
curl -X POST https://batchwatch.dev/v1/keys -d '{"label":"my pipeline"}'
The token is shown once. We store only a SHA-256 hash of it, so we cannot recover or resend it. If you lose it, create a new one.
The optional label is your own note, so you can tell your keys apart. It is never shown to anyone else. Do not put personal data in it — see PRIVACY.md.
Key creation is limited to 5 keys per IP address per day. That is a noise limit against a runaway loop, not a security control, and it is stated as such in the code. A key does not by itself carry weight in the published statistics, which is why we do not gate it behind an email we would not verify.
DELETE /v1/keys/current revokes the key you authenticate with. There is no route to revoke somebody else's key, because without accounts there is no way to decide who would be entitled to.
4. Access tiers
| Tier | How you get it | Delay on figures | Read quota |
|---|---|---|---|
| Anonymous | no key | 15 minutes | 20 free trial calls |
| Free | a key, not currently contributing | 15 minutes | 20 free trial calls |
| Contributor | 5 completed measurements in the last 7 days | 5 minutes | 10,000 calls / 7 days |
| Paid | assigned by us | live, no delay | 1,000,000 calls / 7 days |
These numbers are configuration, not commitments. They are read from environment variables at request time and can be changed without a deployment. The pricing model is not decided. See §9 on how we will handle changes.
Contributor status is derived from your data, not from a flag on your key: a call counts if it has status = 'completed', a server end timestamp, and started within the last 7 days. You cannot mark yourself a contributor. "Paid" is the one thing we assign.
Which routes are open to everyone
Open, subject only to the delay for your tier:
- the dashboard at
/ GET /v1/wait— what the queue is doingGET /v1/curve— the empirical distributionGET /v1/coverage— what we can answerGET /v1/probe— the state of our own measurement jobsGET /health
/v1/curve is deliberately open because the model picker on the front page calls it on every click; gating it would spend a visitor's free calls just for browsing.
The dashboard is free for everyone, with no account. We do not intend to change that.
Which routes need contribution or a trial call
GET /v1/should-i-batch, GET /v1/estimate-batchtime, GET /v1/conditions and GET /v1/distribution.
Submitting measurements
POST /v1/calls followed by PATCH /v1/calls/{id} is open to everyone, with or without a key. We put no obstacle in the way of contributing, because without contributions there is no dataset.
POST /v1/calls/complete — the bulk history import — requires a key. That path takes your own timestamps, so nothing can be verified against our clock. See ACCEPTABLE-USE.md §3 for why.
5. The free trial
Twenty calls to the gated routes, with no key, no account and no card.
- The counter is per identity. With a key, it follows the key. Without one, it is counted against a salted hash of your IP address — never the address itself. If the operator has not configured the salt, keyless callers get no trial at all rather than a stored hash that only pretends to be anonymous.
- Calls that error do not count. We serve first and count afterwards, and only on a
200. The twenty are for finding out whether the answer is worth having, not how the query string is spelled. - Contributors never spend theirs. The counter is touched only when contribution alone would not have let the call through. If you contribute and then lapse, your twenty are still there.
- It is not a security boundary and is not built as one. Anyone can change IP address. Deliberately doing so to evade the contribution requirement is nevertheless a breach of ACCEPTABLE-USE.md.
6. Quotas
Contributor and paid quotas run on a rolling seven-day window kept in daily buckets, not a calendar week. The window moves with you, so usage frees up gradually rather than resetting at a fixed moment.
Exceeding the quota returns 429 with the limit, your usage and the window in the body. It does not affect your ability to submit measurements — ingest is never quota-limited.
7. Your measurements: what you keep and what we get
This is stated up front rather than buried, because the data comes from infrastructure you may not personally own and you should be able to justify sending it to whoever does.
You keep:
- Ownership of your raw submissions.
- The right to obtain a copy of everything you sent. There is no export endpoint today; write to hello@batchwatch.dev from the key you want exported and we will produce it manually.
- The right to stop at any time, with no effect on data you already received.
- The right to request deletion of what you sent. Read PRIVACY.md §7 before relying on this — what we can and cannot delete is set out there in detail, including the case we cannot honour (anonymous submissions we cannot attribute to you).
We get:
- A perpetual, worldwide, royalty-free licence to use your measurements in aggregate, including commercially — to compute and publish percentiles, distributions and verdicts, and to sell access to them.
- The right to publish aggregate statistics openly and to charge for access.
We never get:
- The right to publish, sell or expose an individual submission, or anything traceable to you.
8. What we do not receive
The client library reads timing and token counts off your batch job and nothing else. It never touches the payload. We do not receive, hash or sample your prompts, your completions, your system prompts, your tool definitions, or your provider API keys. The full field list is in PRIVACY.md §2, checked against the database schema.
The client library is open source. Reading the ~90 lines that do the sending is the point of publishing them.
9. These terms will change
Saying otherwise before there is a business would be a promise made at the moment of least information, and we would rather not make one we might have to break.
What we do commit to:
- 30 days' notice before any change that reduces what contributors get.
- We will not retroactively bill for data you have already read.
Notice will be given on the dashboard and in this repository. Continuing to use the service after a change takes effect means you accept it. If you do not accept it, stop using the service; that has no effect on data you have already received.
10. No warranty
The service is provided "as is", without warranty of any kind, express or implied, including merchantability, fitness for a particular purpose and non-infringement.
Specifically and without limiting the above:
- The measurements are crowdsourced. They may be thin, stale, unevenly distributed across models, or wrong.
- Our own defences against fabricated measurements are real but not complete, and their known limits are published in ACCEPTABLE-USE.md §4 rather than hidden.
- A verdict of
run_batchis not a guarantee that your job will finish in time. Queue behaviour is the provider's, not ours, and it changes. - The coverage of providers is uneven. At the time of writing, only OpenAI has been measured by our own prober; the Anthropic and Google submit paths were written from the documented API shape and have never run against the real endpoint. The README states which is which, and it is kept current.
You remain responsible for your own deadlines. Do not build a system whose failure mode is "batchwatch said it would be fast".
11. Limitation of liability
To the maximum extent permitted by law, we are not liable for indirect, incidental, special, consequential or punitive damages, or for lost profits, lost revenue, lost data or business interruption, arising out of or in connection with the service — including any decision to use a batch API rather than a synchronous one, or the reverse.
For paid plans, our total aggregate liability is limited to the amount you paid us in the 12 months preceding the event giving rise to the claim. For free use, it is limited to [AMOUNT — e.g. DKK 1,000].
Nothing here excludes liability that cannot lawfully be excluded, including liability for death or personal injury caused by negligence, for fraud, or under mandatory Danish consumer law where it applies.
12. Acceptable use
Use of the service is subject to ACCEPTABLE-USE.md. The most important rule there is that every measurement you submit must be one you actually observed.
13. Suspension and termination
We may revoke a key, exclude a key's history from the published aggregate, or block access, if the acceptable use rules are breached. Where we can, we will say why.
Revoking a key stops it authenticating. Measurements already submitted under it remain in the dataset by default — they were true when they were taken, and a record that can be deleted backwards is not a record. This default is separate from a data-protection erasure request, which is handled under PRIVACY.md §7.
You may stop using the service at any time. DELETE /v1/keys/current revokes your key.
14. Governing law and venue
These terms are governed by Danish law, excluding its conflict-of-law rules. Disputes go to the courts of [VENUE — e.g. Retten i Kolding], unless mandatory consumer-protection rules give you the right to sue elsewhere.
15. Contact
hello@batchwatch.dev for anything, including the export and deletion requests described above.
Reviewer's checklist
Before this is published, a lawyer needs to resolve at least:
- The legal entity, CVR number, address, contact address, liability cap and venue placeholders.
- Whether the licence in §7 is drafted broadly enough to cover selling access to the aggregate, and narrowly enough to match the promise never to expose an individual submission.
- Whether B2C consumer rules apply at all, given the audience is developers acting for their employers — and what changes if they do.
- Whether the
endpointandlabelfree-text fields need an express contractual warranty from the submitter that they contain no personal data (see PRIVACY.md §2 and DATA-PROCESSING.md §2). - The conflict flagged in PRIVACY.md §7 between §13 above ("measurements stay") and the front page's "the right to delete everything you sent". These must say the same thing before launch.