Build a round-robin schedule from participant names
Four teams such as Falcons, Owls, Ravens and Hawks get 3 rounds and 6 matches, with everyone meeting everyone exactly once. Paste your participant list to get numbered rounds, every pairing and one bye per round when the count is odd. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Participants
- Falcons, Owls, Ravens, Hawks
- Participant count
- 4
- Round count
- 3
- Match count
- 6
Turn a list of teams, players, clubs, or other participant names into a complete single round-robin schedule. The generator uses the standard circle method, which fixes one position and rotates the others between rounds so that every participant meets every other participant exactly once. Even-sized lists fill every slot in every round. Odd-sized lists receive one automatic bye per round, distributed so each participant rests once. The result includes numbered rounds, explicit matchups, any bye assignment, and summary counts. Processing is local, deterministic, and repeatable: the same ordered list always produces the same schedule, without network calls, random seeds, or changing external data.
Prepare a clean participant list
Start with at least two participant names in the order you want the initial circle to use. A participant can be a team, player, classroom group, game club, sales representative, or any other distinct competitor. Names are trimmed before scheduling, so harmless spaces around a name do not affect the result.
Every name must still be a non-empty string, and names must be unique after trimming. Unique labels matter because the output must make each pairing unambiguous; two entries both called Tigers would otherwise be impossible to distinguish in later rounds. If necessary, add a division, city, number, or initials before submitting the list.
The capability accepts as many as one thousand participants, although a full round-robin grows quickly because every possible pair must appear. Two participants create one match in one round, while ten participants create forty-five matches across nine rounds. The submitted order affects the arrangement of matches among rounds but never the set or total number of matchups.
Inputs with fewer than two entries, blank names, repeated names, non-string entries, or more than the supported maximum return an invalid input error rather than a partial schedule.
Understand the circle-method result
The circle method creates a balanced single round-robin without searching, guessing, or shuffling. For an even number of participants, it holds one position fixed and rotates all remaining positions after each round. Participants opposite each other in the circle are paired, producing one match per participant in every round.
An even list of n participants therefore takes n minus one rounds, with n divided by two matches in each round. For an odd list, the algorithm adds an internal empty position so the circle becomes even. Whoever is paired with that empty position receives the bye, which is reported on the round rather than emitted as a fake match.
An odd list of n participants consequently takes n rounds, contains n minus one divided by two real matches per round, and gives every participant exactly one bye. Each round has a one-based round number and a matches array whose records contain participant1 and participant2. Odd schedules also include a bye field.
Across the entire response, every unordered pair appears exactly once, nobody appears in two matches in the same round, and the match count equals n multiplied by n minus one divided by two.
Share and adjust your match schedule
Use the generated rounds as the structural foundation for a competition calendar. You can attach dates, venues, tables, referees, streams, or court numbers afterward according to your operational constraints. The circle method solves the pairing problem, but it deliberately does not choose real dates or account for venue availability, travel distance, holidays, rest requirements, home-field balance, or broadcast preferences.
Those decisions belong in a later planning stage because they depend on information beyond participant names. If a competition requires home-and-away legs, generate the single round-robin first and create a return leg by reversing each matchup in a downstream process; this capability itself guarantees only one meeting per pair. For a web form, send the participant strings as an array and display each numbered round in its own section.
Odd competitions should display the bye clearly so organizers do not mistake the resting participant for missing data.
What you can do with it
Classroom and club rotations
Pair groups across balanced rounds for debates, practice games, peer reviews, or other repeated head-to-head activities.
FAQ
What happens when there is an odd number of participants?
The generator assigns one bye in every round. Each participant receives exactly one bye over the complete schedule.
Does every participant play every other participant?
Yes. This is a single round-robin, so every unordered pair appears exactly once in the generated matches.
Can two participants have the same name?
No. Names must be unique after surrounding whitespace is removed so every matchup remains unambiguous.
Does the generator assign dates or venues?
No. It creates rounds, matchups, and byes only. Add calendar dates, venues, and operational constraints afterward.
How many rounds and matches will my tournament have?
With an even number of participants, there is one round fewer than participants and half as many matches per round. Four teams play six matches over three rounds; ten play forty-five matches over nine rounds.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/game/round-robin-schedule \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"participants":["Falcons","Owls","Ravens","Hawks"]}'const res = await fetch("https://api.kit.forhosting.com/game/round-robin-schedule", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"participants": [
"Falcons",
"Owls",
"Ravens",
"Hawks"
]
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/game/round-robin-schedule",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"participants": [
"Falcons",
"Owls",
"Ravens",
"Hawks"
]
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/game/round-robin-schedule", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"participants":["Falcons","Owls","Ravens","Hawks"]}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"participants":["Falcons","Owls","Ravens","Hawks"]}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/game/round-robin-schedule", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"participants": [
"Falcons",
"Owls",
"Ravens",
"Hawks"
]
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "game.round_robin_schedule",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
Understand the circle-method result
The response preserves the normalized participant list and reports participant_count, round_count, match_count, and a rounds array. These invariants make the JSON straightforward to audit or transform.
Publish, customize, and integrate the fixtures
For an API workflow, store the summary counts for validation and iterate through rounds and matches when creating event records. Successful API requests use the published base price of $0.002 per item, while the pure browser execution can provide an immediate planning preview. Because the implementation uses no time, randomness, network access, or external model, repeating an identical input produces identical JSON.
Integration use cases
Community league fixtures
Generate every matchup once for a local sports league, then assign fields, dates, and referees to the numbered rounds.
Esports group scheduling
Build a reproducible group-stage fixture list in which every player or team meets every other entrant exactly once.
Technical questions
How much does an API request cost?
A successful API request costs $0.002 per item. The deterministic calculation requires no external service or network call.