Tournament Decklist API
If players register for your tournament on your own website or in your own tool, OpenRift can receive their decklists over an API. Judges then check the physical decks against the submitted lists on the tournament's Deck check tab, with full card images, and every player gets a personal link to view their own submitted deck. This article is for organizers and the developers wiring a registration system up.
How it fits together
- Create the tournament in OpenRift with deck submission enabled. The API can never create tournaments, it only fills existing ones with decklists.
- Create an API key for whoever hosts the tournament: you, or your organization.
- Push entries from your system, one at a time as registrations arrive or the whole field at once. Both work the same way.
- Judges check decks on the tournament's Deck check tab as usual.
- Players claim their deck through the claim link the API returns for each entry, typically forwarded in your confirmation email.
The tournament's Deck check tab shows this same guide pre-filled with the real tournament id, ready to copy into your integration.
API keys
Personal keys are managed under API keys on your profile. For a tournament hosted by an organization, keys live on the organization's page instead and can be managed by its owners and managers. A push must use a key that belongs to the tournament's host: a personal key cannot push into an organization's tournament, and the other way around.
A key looks like orpk_… and is shown once, right when it is created. Store it like a password: it lets its holder send decklists to every tournament of your account or organization. You can rename keys, see when each was last used, and revoke one at any time. A revoked key stops working immediately.
Pushing decklists
Send a POST to /api/v1/ingest/deck-check on this site, with your key in the Authorization header and a JSON body:
POST /api/v1/ingest/deck-check
Authorization: Bearer orpk_your-key-here
Content-Type: application/json
{
"tournamentId": "019eb565-3d55-7d21-8d86-e9b6939a2c2f",
"entries": [
{
"externalId": "1234",
"playerName": "A. Player",
"riotId": "Player#EUW",
"submittedAt": "2026-06-18T20:00:00Z",
"allowDeckPublishing": true,
"allowNameSharing": true,
"allowRiotIdSharing": true,
"withdrawn": false,
"cards": [
{ "name": "Darius, Trifarian", "quantity": 1, "section": "champion" },
{ "name": "Blazing Scorcher", "quantity": 3, "section": "main" }
]
}
]
}tournamentId— the tournament's id, copied from its Deck check tab.externalId— your own id for the player. Pushing the same id again updates that entry instead of creating a new one. Ids starting withopenrift:are reserved for decks players submit themselves and are rejected.playerName— shown to judges next to the entry.riotIdandsubmittedAtare optional and also shown to judges.allowDeckPublishing,allowNameSharing,allowRiotIdSharing— the player's consent to publish their deck, name, and Riot ID after the event. Sendfalsewhen a player declined; omit a flag to keep what is already stored (new entries default to allowed).withdrawn— settrueto withdraw a player. Pushing the entry again without the flag restores them.cards— one line per card with its English name as printed, the quantity, and the deck section.
Sections map onto OpenRift's deck zones: legend, champion, main, runes, battlefield, sideboard, and overflow. Common variants like deck, maindeck, side, and plurals work too; any other section rejects the whole push, so nothing is half-imported. Card names don't have to resolve, though: a misspelled or unknown name never blocks a push, the line is flagged and judges see the raw name exactly as you sent it.
What a push changes
Pushes are partial: only the entries you send are touched, and leaving a player out of a push never withdraws them. Withdrawing is always the explicit withdrawn flag. That makes pushes safe to repeat: re-sending an unchanged entry does nothing, so you can push on every registration event without bookkeeping.
When a re-pushed entry's card list actually changed, the stored deck is replaced. If a judge had already checked that deck, the check is reset and the judge sees exactly which cards were added, removed, or changed, so a stale check can never pass a changed deck. Your system stays the source of truth for the list: a push also replaces any edits the player made in OpenRift in the meantime.
The response and claim links
A successful push returns counts of what happened plus one result per entry, keyed by your own externalId:
{
"tournamentId": "019eb565-3d55-7d21-8d86-e9b6939a2c2f",
"entriesCreated": 1,
"entriesUpdated": 0,
"entriesUnchanged": 0,
"entriesWithdrawn": 0,
"checksInvalidated": 0,
"entries": [
{
"externalId": "1234",
"entryId": "019eb565-4a01-7c3b-9f12-c2d80f5a1e77",
"claimUrl": "https://…/tournaments/claim/8f3c2a…"
}
]
}entryId is the stable OpenRift id for the entry. claimUrl is a personal link for that player: put it in your confirmation email. A player who opens it signs in (or creates an account), confirms, and from then on sees their own submitted deck in OpenRift, and only their own. Nothing about the deck or the player is visible before the claim is confirmed, and OpenRift never needs the player's email address for this.
The link is stable: re-pushing the same entry returns the same URL, so it is safe to re-send in a follow-up email. If a link ever reaches the wrong person, a judge can unlink the entry, which also blocks it from being claimed again.
Limits and errors
A push carries at most 500 entries with up to 200 card lines each, the body is capped at 1 MB, and each key may push 60 times per minute (responses include standard RateLimit headers). Larger fields simply split across several pushes.
| Status | Meaning |
|---|---|
| 400 | The body is not valid JSON or doesn't match the payload shape. |
| 401 | The API key is missing, unknown, or revoked. |
| 404 | No tournament with that id belongs to the key's host, or the tournament has deck submission turned off. |
| 409 | The tournament is archived. Un-archive it before pushing. |
| 413 | The body is larger than 1 MB. |
| 422 | A card uses an unknown section, or an external id starts with the reserved “openrift:” prefix. Nothing from the push is imported. |
| 429 | More than 60 pushes in a minute with this key. Wait and retry. |
Failed pushes import nothing, so it is always safe to fix the problem and send the same push again.
Reference and support
The full request and response schemas are part of the OpenAPI specification, browsable in Swagger UI. Building an integration and something is missing or unclear? Let me know on Discord or GitHub and I'll do my best to help.