Most API speed pages quote a number with no method behind it. Here is ours, split into the part we control and the part physics controls — and a one-line command so you never have to take our word for it.
Our test, measured 26 August 2026: Amsterdam origin, 20 server-processing samples, 25 cold-request samples and 11 warm-request samples.
/v1/health, 20 samples. Worst case 5.4ms.Odds are served from a single origin in Amsterdam. Our share of the response is small and steady; the variable is the distance between you and that origin, and whether your client reuses its connection. That is why we publish a formula instead of one headline number — a flat "sub-100ms everywhere" claim would only be true for clients close enough to make it true, and you would find that out in your first test anyway.
| Measurement | Result | What it is |
|---|---|---|
| Server processing | 1.3ms | Application time only, 20 samples |
| TCP connect | 2.3ms | Median, 25 samples |
| TLS handshake complete | 39ms | Median — the real cost of a cold start |
| Cold request (TTFB) | 41ms | Median, 25 samples — handshakes included |
| Warm request (TTFB) | 1.5ms | Reused connection, 11 samples |
Two things fall out of that table. First, on a connection that is already open we answer in about a millisecond and a half — there is almost nothing between your request and the odds. Second, the expensive part of a cold request is not our code, it is the TLS handshake, and you pay it once per connection rather than once per request. Add your own round trip to Amsterdam to both figures and you have your number; run the command below from wherever your bots actually live and you will have it in about five seconds.
The public demo key is literally key=demo. Time a real response:
curl -o /dev/null -s -w "total: %{time_starttransfer}s\n" \
"https://pinnwire.com/v1/health?key=demo"
That single request pays the handshakes. To see the warm number — what a well-written client actually experiences — send a few on one reused connection. Five is plenty, and stays well inside the demo allowance:
curl -o /dev/null -s -w "%{time_starttransfer}\n" \
$(printf '%s ' $(yes "https://pinnwire.com/kit/v1/markets?sport_id=1&key=demo" | head -5))
The first line includes the handshakes. The rest are warm, and they are the number to judge us on.
The demo key allows 10 requests per minute in total — that allowance is shared by everyone using it, not granted per person. Keep test runs to a handful and you leave room for the next person; loop it and you will hit a 429 with a Retry-After header partway through, which hands you numbers measuring our rate limiter rather than our speed.
For a real benchmark, take a free trial key from the homepage — 100 requests a day, no card — or run against a paid plan, where the ceiling is 10 to 30 requests per second.
This is the single biggest thing you control. A fresh connection pays a TCP handshake and a TLS handshake before a single byte of odds moves; an open one pays neither. Measured at the origin, that is the difference between 41ms and 1.5ms for the identical request — roughly thirtyfold. Any HTTP client with keep-alive enabled pays it once at startup. Further from Amsterdam the absolute numbers rise, but the gap only widens, because a cold start costs you several round trips instead of one.
REST provides current snapshots on demand. SSE pushes detected drop alerts, while the optional raw WebSocket streams live and prematch market updates. Each long-lived stream pays the handshake once at startup instead of on every REST poll.
Narrow the request and the response gets smaller and faster to parse: filter by sport_id, use since= for incremental polling, and prefer /kit/v1/prematch/lines over full fixture payloads when you only need the main lines.
Server processing was measured on the origin host against localhost:8080, 20 samples of /v1/health, reporting median and maximum — that isolates application time from every network effect. The connect, handshake, cold and warm figures were measured at the origin over its public HTTPS interface, 25 cold samples and 11 warm ones, reporting time_starttransfer (time to first byte). Because network distance is effectively zero there, these are a floor, not a promise: they are what remains when you subtract the internet, and we label them that way deliberately. Your own number is that floor plus your round trip, which is why the command above matters more than this table.
View PinnWire’s current service status and rolling 24-hour availability.