Onboarding — Game Value, team board
Nine steps, each with a way to tell that it worked. Follow them in order and your values are scored. Skip one and everything still returns
201— and nothing is ever scored.
This is the page to read end to end before you write any code. The delivery contract is the reference you will keep open afterwards; the overview explains what is being measured and why.
This is not one submission
The Transfers benchmark is answer-once-and-wait: you fetch the open cases, submit one file, and are scored. You can hold the whole obligation in your head.
Team Value is a standing weekly obligation against a fixture list that moves. After every round you send one number per team per match, before a deadline that belongs to the round rather than to the match, and your score is rebuilt from the whole season each week. There is no single submission that finishes the job.
Two consequences worth knowing before you start:
- The gap between "my integration works" and "I am being scored" is real. A delivery can be accepted in full and still contribute nothing, because a value counts only toward fixtures kicking off after its deadline. That rule is what stops anyone pricing a match whose result they already know, and it is the single most common reason a correct-looking integration scores zero fixtures.
- From registering to a first score is weeks, not days. A fixture is scored only once both sides have enough delivered history behind them, at all three horizons. Your first rounds build that history and score nothing. This is by construction, not a fault in your setup.
Step 1 — Register
One identity for the whole Arena, whatever you enter.
POST /api/participants
{
"vendor_name": "Acme Analytics",
"leaderboard_name": "Acme values",
"short_description": "Possession value model",
"contact_email": "team@acme.example.com"
}
The response carries an API key beginning fa_. It is shown once and never again — store it
where your delivery job can read it. The contact address is where deadline reminders and delivery
problems are sent; it is never published.
Done when you hold a key starting
fa_and the confirmation email has arrived. The key is Arena-wide: the same one enters and delivers to every benchmark.
Step 2 — Enter the benchmark
Registering gives you an identity. Entering says which benchmark that identity is competing in.
POST /api/participants/entries Authorization: Bearer <your key>
{ "task_slug": "game_value_team" }
A 201 comes back with "participation_mode": "submission" — the Arena never calls you, so there
is no endpoint to expose and no service to keep running. Your job delivers to us.
Done when you have that 201.
Entering is not certifying. A real delivery now is refused with
403 Certify first. Step 4 is what enrolment actually means.
Step 3 — Integrate the identifiers
Everything you deliver is keyed on the Arena's identifiers. Map them to your own once, before you send anything.
GET /api/tasks/game-value-team/teams the registry: team_id -> club, country, competition
GET /api/tasks/game-value-team/fixtures the schedule: match_id, both team ids, kickoff, deadline
The team registry gives each team_id (FAT00066) a club name, country and competition. The
fixture list gives each match_id (fam_2627_premierleague_0042) its round, kick-off in
Europe/Paris, both team ids — with their names beside them for reading — its status, and the
deadline its round is due at.
Three things to build into your job now rather than later:
- Integrate on the ids, never the names. Club names are published so a row is readable; they are not accepted in a delivery. A name match is a guess, and a guess attaches a value to the wrong club silently.
- Re-read the fixture list every run. It is live: postponements, rescheduled kick-offs and
awarded results appear as they happen. Pass
?since=with the largestupdated_atyou hold to read only what changed. match_idis stable through any reschedule. A postponed match keeps its identifier and gets a new kick-off and its own deadline.
A ?competition= filter takes the exact published name — Premier League, LaLiga, Serie A,
Bundesliga, Ligue 1 — and anything else is refused with the valid names rather than answered
with an empty list.
Done when every club you cover resolves to a
team_idin your own database, and you can list the fixtures of the current round without consulting a name.
Step 4 — Certify
Certification is a dry run against one completed round, checked exactly as a real delivery would be and storing nothing.
POST /api/tasks/game-value-team/values?dry_run=true Authorization: Bearer <your key>
{
"task": "game_value_team",
"contract_version": "2026-09-game-value-team-v0",
"model_version": "my-model-1.4",
"values": [
{"match_id": "fam_2627_premierleague_0042", "team_id": "FAT0000042", "value": 1.83},
{"match_id": "fam_2627_premierleague_0042", "team_id": "FAT0000117", "value": 1.21}
]
}
To pass, the dry run must cover every match of one completed round in a competition, both sides of each, and nothing may be rejected.
lateis not a failure. Certification runs against a round whose deadline has passed, so its entries come back markedlate. That is expected and correct. The only outcome that prevents certification isrejected.
Certifying is also how you declare what you are entering. The competitions your dry run covered are the ones you will be scored on, and coverage within a competition is all or nothing — you cannot enter the half of a league you like. If you intend to cover all five, send one complete round per competition.
Done when the receipt says
"certified": true. That moment is your enrolment: you are scored from it, not from when you registered.
Dry runs count toward no limit, so run as many as you need until nothing is rejected.
Step 5 — Deliver, every round
The same call without dry_run. One number per team per match: what that team's performance was
worth, on your own scale.
POST /api/tasks/game-value-team/values Authorization: Bearer <your key>
- Nothing is normalised. The score depends only on the order your values put fixtures in, so there is no scale to match and no units to agree on.
- Both sides of a fixture must travel together. One side alone is refused: a fixture priced on one side has no net value for either team.
- Only played matches. A
statusofplayedorawardedcan be priced; a scheduled one cannot. - A delivery may carry any number of matches, from one round or several.
The response is your receipt: an outcome for every entry — accepted, replaced, unchanged,
late, or rejected with a reason — plus the Arena's receipt time and a payload_sha256 of the
body as received. Time is the Arena's; your own timestamps are not read.
You may store three deliveries per round. Dry runs are exempt.
Done when the receipt's outcomes are the ones you expected and its
payload_sha256matches the checksum of what you sent. Keep the receipt: it is what proves what you delivered and when.
Step 6 — Know your deadline
The deadline belongs to the round, not to the match, and every fixture carries it before it is played.
- A round's values are due at 23:59 Europe/Paris, a full day after the round's last match — Tuesday, for a weekend round.
- A postponed match is a round of its own and carries its own deadline.
- Values are replaceable until the deadline and freeze at it. Afterwards a first value still
lands, marked
late; a different value for something already delivered is refused asfrozen. - A value counts only toward fixtures kicking off after its deadline. This is what makes the benchmark a forecast rather than a description.
The reason for the day's delay is that match data is not final at the whistle. You are meant to correct a value during that window; that is what it is for.
Done when your job runs on a schedule that clears the deadline with room to spare — not on the final whistle, and not at 23:50.
Step 7 — Check what is still missing
GET /api/tasks/game-value-team/status Authorization: Bearer <your key>
due lists every open round with something outstanding: its competition, round, deadline, how many
values are expected, how many arrived, which (match_id, team_id) pairs are absent, and how many of
that round's three deliveries remain. missed_this_season counts values that were not there when a
deadline passed.
Reads are free and count toward no limit, so call it after every run. The Arena also emails a reminder before a deadline where something is still missing — but a job that checks its own work does not need to be chased.
Done when
dueis empty for the open round.
Step 8 — Be scored
The scoring run is every Saturday at 06:00 Europe/Paris, after the previous round's results are final. It rebuilds your score from the whole season and appends one immutable snapshot per week.
A fixture is scored for you only when:
- both sides were priced by you, before the deadline;
- both sides have enough delivered history behind them to build a signal at all three horizons.
The second condition is why your first rounds score nothing. Each round you deliver adds to the history the next fixtures are ordered from, and once both sides of a fixture have enough, it counts. Expect the first snapshot some weeks after your first delivery, not on the first Saturday.
Done when a snapshot exists for you. Until it does, you are enrolled and delivering correctly — there is simply nothing to compute yet.
Step 9 — Be published
Being scored and being named are separate. A person confirms who you are before your row appears on the public board.
Publication is resolved when the board is read, not captured into your snapshots, so confirming late reveals your whole trajectory at once. Being published slowly costs you nothing.
Done when your row is on the team board.
Your first month
What actually happens, week by week, if you certify today.
| When | What happens | What you should see |
|---|---|---|
| Day 0 | Register, enter, integrate, certify | "certified": true, and enrolment dated now |
| The first round after that | Your job delivers for every match played | A receipt with entries accepted |
| That Tuesday 23:59 | The round's values freeze | status shows nothing due |
| The first Saturday | Scoring runs | No snapshot yet — too little history |
| Weeks 2–3 | Deliver every round | status empty each week; still no snapshot |
| Around week 4 | Both sides of some fixtures now have enough history | Your first snapshot, and a skill score with an interval |
| After that | Weekly | One snapshot a week, and a trajectory |
Common refusals, and what each means
A whole delivery can be refused:
| Code | Means | Fix |
|---|---|---|
401 | No valid key | Send Authorization: Bearer <your key> |
403 | Not entered, or not certified | Step 2, then step 4 |
400 | Wrong task | It must be game_value_team |
409 | contract_version is not the one in force | The refusal names the version that is; see versioning |
422 | The body is not shaped like the contract | Check required fields and types |
Or individual entries can be rejected while the rest of the delivery lands:
| Reason | Means | Fix |
|---|---|---|
unknown match_id | No such fixture this season | Re-read /fixtures; do not construct identifiers |
team did not play in this match | The team is not one of the two sides | Check your id mapping — this is usually a name match gone wrong |
match not played | Priced before it was played | Deliver after the match, not before |
before enrolment | The match predates your certification | Not accepted: it could be priced knowing the result |
value is not a number | The value is not numeric | Send a number, not a string or null |
frozen | A different value after the deadline | The first value stands; corrections had to arrive before the deadline |
delivery limit reached for this round | A fourth stored delivery | Three per round; batch your corrections |
fixture described on one side only | Only one team priced | Send both sides together |
Joining mid-season
You may join at any point. Certify, and you are scored from that moment.
Values for matches that kicked off before you certified are refused as before enrolment. This
is not a penalty for arriving late — it is the same rule everyone is under. A value for a match
played weeks ago could be priced knowing every result since, and would not be a forecast.
The consequence is worth planning for: you build your delivered history from the day you certify, so the sooner you certify, the sooner the first fixture has enough behind it to be scored.
Before your first real delivery
- Your key is stored where the job reads it, and is not in source control
- Every club you cover maps to a
team_id, and nothing is matched by name - Your job re-reads
/fixtureseach run and handles a changed kick-off - You price only
playedandawardedmatches - Both sides of every fixture are in the same delivery
-
contract_versionis the one in force, and a409is treated as a change to act on - Your schedule clears the deadline by hours, not minutes
- You keep each receipt, with its
payload_sha256 - You call
/statusafter each run and alert on anything due - You have certified one complete round per competition you intend to cover
What to read next
- Delivery contract — the reference for every call above, with the deadline rules in full.
- Overview — what is measured, and why agreeing with the scoreline is not evidence.
- Reading a leaderboard — how to read a skill score and its interval.
- The team board — what a published participant looks like.