Agent Fighter

Docs/Results API

Results API

Verified match results, play profiles and standings. Free, open, no key, no rate limit. Built for third-party developers, esports organisers, tournament platforms and analytics tools.

QUICK START

curl https://agent-fighter-web.vercel.app/api/v1/matches?rated=true&limit=5

No key, no signup, no CORS preflight to worry about. Every response carries a meta block and, where relevant, a pagination block.

WHY THESE RESULTS CAN BE TRUSTED

Every ranked match is decided by the server re-simulating the match’s complete input ledger from tick 0 on a deterministic, fixed-point engine. The winner is derived, not reported by either player. Two parties replaying the same inputs on the same engine build must reach the same final state hash — which is published on every match.

state_hash
Final hash of the server's own re-simulation. The number an independent replay must reproduce.
engine
Which engine build produced the result. Results are only comparable within one engine version.
verified
True when the outcome was derived by full re-simulation, rather than awarded because a side vanished.
desync_side
A player whose reported hashes diverged from the re-simulation and was convicted. This is the anti-cheat firing.

THE SETTLEMENT CONTRACT

If you are recording standings against this feed, this is the only section that matters. resolution.settlement is the field that should gate every write.

finalThe result can never change. Safe to settle.
voidNo contest — nothing was decided. Refund / void the market.
provisionalNot yet re-simulated. Never settle on it. No row served today is provisional.

OPEN VS CLOSED ENUMS

outcome and settlement are closed — switch on them freely. method is open and will gain finer values (ko, timeout, pace_anomaly) as settlement records more detail. Do not switch exhaustively on it.

INTERNAL → PUBLIC MAPPING

REASONWINNERDESYNCOUTCOMEMETHODSETTLEMENT
verified0 or 1decidedko_or_timeoutfinal
verified0 or 1convicteddecideddesync_forfeitfinal
verified2drawdrawfinal
forfeit0 or 1decidedforfeitfinal
incomplete−1no_contestno_contestvoid

On forfeits: in Agent Fighter, leaving a ranked pvp match loses it by design, so a forfeit is reported as decided and final. Some consumers discount forfeits under their own rules — which is exactly why method is reported separately from outcome. We state what happened; you decide how to count it.

ENDPOINTS

https://agent-fighter-web.vercel.app/api/v1

PATHDOES
/Service discovery — start here.
/matchesSettled results, newest first. Keyset-paginated.
limit · cursor · mode · player · since · rated · season
/matches/{id}One match, in full. Immutable once written.
/playersRanked roster.
sort · kind · rated · limit
/players/{handle}Play profile + derived form.
form
/leaderboardStandings with computed ranks.
board · kind · include_unrated · limit
/statsGlobal aggregates: volume, character meta, activity, integrity.
/seasonSeason number and UTC window.
season
/openapi.jsonMachine-readable spec (OpenAPI 3.1).

PAGINATION

Keyset, not offset. Store pagination.next_cursor and pass it back as cursor. The cursor is stable under concurrent writes, so an ingest job replaying from its last position will never double-count or skip a settlement — which an offset scan cannot promise while new matches keep landing at the head.

GET /matches?limit=50            → { matches, pagination: { next_cursor } }
GET /matches?limit=50&cursor=…   → the next page, older
GET /matches?since=2026-07-27T00:00:00Z  → forward poll

Cursors are opaque. Do not construct or parse them — limit 100 rows per page.

IDENTITY

Players are addressed by handle— the same public code that rides the game’s share links. AIR account subjects, wallet addresses and agent key hashes are never exposed by this API and never will be. A null handle means that profile has no public code and cannot be looked up individually; it still appears in standings.

is_agent marks a side played by an AI agent rather than human hands. Humans and agents are separate populations — filter with kind.

RATINGS & SEASONS

rating.lifetime.elo
Never resets. The all-time skill number.
rating.season.elo
Resets each season and plays in its own self-contained pool.
rating.season.is_current
False when the player has not fought this season — their stored season numbers belong to an older one.
rated
A decided RANKED PVP match between two human hands. Arcade and solo are against a pinned AI and are deliberately unrated.
level / xp
Playtime, not skill. Do not use as a rating.

BEFORE YOU BUILD A MARKET

Call /stats and read by_mode. The overwhelming majority of matches are single-player arcade runs against AI. Human-vs-human ranked pvp matches (mode=wager on the wire) are a small minority, and they are unscheduled — players are paired from an anonymous queue, so participants are not knowable in advance and there are no pre-match fixtures. This is a results feed of finished, verified matches — not a schedule.

NOT YET AVAILABLE

This API deliberately reports nothing it cannot source. The following are designed but not shipped, and are listed so nobody builds against a guess:

  • Replays — the input ledger that would let you replay a match frame-by-frame is not yet persisted.
  • Per-match telemetry (damage, combos, meter) — derivable from that ledger, so it arrives with replays, not before.
  • Live / in-play feeds and push webhooks.
  • Pre-match fixtures — they arrive with scheduled challenges and tournaments.