Developers
PongIQ ships a free, read-only public API and broadcast-ready overlay pages. No API key needed for now — please be nice: cache on your side where you can, poll no faster than the data changes, and expect rate limits to arrive later. Only published tournaments are exposed; drafts, emails and account data are never served.
API v1
Base URL is this site’s origin. Every response uses the envelope { "data": …, "meta": { "generatedAt": … } }, is cached for ~10 s (s-maxage=10, stale-while-revalidate=30) and 404s as JSON for unknown ids. The /v1 prefix is versioned — breaking changes will ship as /v2, never silently.
| Endpoint | Returns |
|---|---|
| GET /api/v1/events | Published events list |
| GET /api/v1/events/{slug} | One event + its categories |
| GET /api/v1/subevents/{id}/draw | Locked knockout bracket + results (null until published) |
| GET /api/v1/subevents/{id}/standings | Live group standings (ITTF 3.7.5, computed on read) |
| GET /api/v1/subevents/{id}/matches | Every match of a category with scores |
| GET /api/v1/matches/{id} | One match with live score + pre-match prediction |
| GET /api/v1/rankings | Public rating leaderboard |
Sample — GET /api/v1/events
{
"data": {
"events": [
{
"id": "c3c98379-0cc1-40cb-863f-8f56548918f7",
"slug": "uncle-cheng-friendly-king-of-pips-2-season-10",
"name": "Uncle Cheng Friendly King of Pips 2 - Season 10",
"venue": "V2TT",
"startDate": "2026-10-04",
"endDate": "2026-10-04",
"status": "published",
"description": "Open to all players. This is a single event. Only pips player can play this event. Requirement one of rubber must be pips. Or you can have 2 rubbers pips. Or one pips one smooth rubber.",
"posterUrl": null,
"categoryCount": 2
}
]
},
"meta": {
"generatedAt": "2026-10-02T00:44:24.350Z"
}
}Sample — GET /api/v1/rankings
{
"data": {
"rankings": [
{
"rank": 1,
"playerId": "45fb0b5d-c22e-4594-b800-052629f43361",
"displayName": "Uncle Cheng",
"rating": 999,
"matchCount": 18,
"association": "Uncle Cheng Table Tennis Group"
},
{
"rank": 2,
"playerId": "f9aa46e1-2043-4f6f-8177-bd76692d2824",
"displayName": "Weiming",
"rating": 912,
"matchCount": 3,
"association": "Taman Jurong Table Tennis Club"
},
{
"rank": 3,
"playerId": "1ac3dfde-0c3b-41de-806d-1276d760f60e",
"displayName": "Lee Choon khiang",
"rating": 908,
"matchCount": 2,
"association": null
}
]
},
"meta": {
"generatedAt": "2026-10-02T00:44:24.351Z"
}
}Sample — GET /api/v1/matches/{id}
{
"data": {
"match": {
"id": "aa1b2c3d-0000-4000-8000-000000000002",
"status": "in_progress",
"matchKind": "tournament",
"stage": "knockout",
"roundNo": 3,
"bracketPos": 0,
"stageLabel": "Final",
"homeName": "Ada Loop",
"awayName": "Bruno Net",
"homeId": "e-home",
"awayId": "e-away",
"winnerId": null,
"resultReasonCode": null,
"retirementAfterGame": null,
"gamesWon": {
"home": 1,
"away": 1
},
"currentGame": {
"home": 7,
"away": 5
},
"gameScores": [
{
"home": 11,
"away": 8
},
{
"home": 9,
"away": 11
}
],
"startedAt": "2026-09-05T03:00:00.000Z",
"completedAt": null,
"updatedAt": "2026-09-05T03:24:00.000Z"
},
"live": {
"started": true,
"gamesWon": {
"home": 1,
"away": 1
},
"currentGame": {
"home": 7,
"away": 5
},
"currentServer": "home",
"bestOf": 5
},
"prediction": {
"pHome": 0.64,
"ciLow": 0.55,
"ciHigh": 0.72,
"confidenceLabel": "medium",
"createdAt": "2026-09-05T02:00:00Z",
"outcome": null
}
},
"meta": {
"generatedAt": "2026-10-02T00:44:24.352Z"
}
}CORS
All /api/v1 responses carry Access-Control-Allow-Origin: *, so you can call them straight from a browser on any site — club pages, widgets, stream dashboards. There is no auth and no cookie involved, which is what makes the wildcard safe.
Honest predictions
Match payloads include the frozen pre-match prediction with its interval and confidence label. If you display the probability, display the confidence with it — and when the label is insufficient, show words, not a number.
OBS / stream overlays
Transparent scoreboard pages built for OBS, vMix and Streamlabs browser sources. They poll the live score once a second and never paint errors over your stream.
- In OBS: Sources → + → Browser.
- URL:
/overlay/match/{matchId}(the id from any match page URL,/m/{matchId}). Width/height: your canvas, e.g.1920×1080. - The page background is transparent — no chroma key. Position the source; the bar sits centred on the chosen edge.
| Param | Values | Meaning |
|---|---|---|
| pos | bottom (default) · top | Edge the scoreboard hugs |
| scale | 0.8–1.5 | Size multiplier (CSS transform) |
| debug | 1 | Checkerboard behind the bar for testing |
/overlay/subevent/{subeventId} is a compact category board (live matches + latest results) for a picture-in-picture corner — same params, same transparent ground.
Venue TV mode
Point a hall TV or projector at /t/uncle-cheng-friendly-king-of-pips-2-season-10/tv — full-screen, no interaction needed. It rotates every ~12 seconds between the live board, latest results, group standings and a “scan to follow” QR code. Pairs with the printable /t/{event-slug}/poster.
Questions or an integration that needs more? Ask via the organiser of your event — the API grows with real use cases.