Elo Rating Update Calculator
A 1400 player who beats a 1600 player with a K-factor of 32 gains about 24 points, and the opponent loses the same amount. Enter both ratings, the result and your league's K-factor to see the expected scores and new ratings. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
This Elo rating update calculator turns one match result into new ratings for both players. Enter each player's current Elo rating, identify whether Player A won, drew, or lost, and provide the positive K-factor used by your league or game. The result includes each competitor's expected score, actual score, signed rating change, and updated rating. It is useful for checking leaderboard code, explaining an adjustment to players, or applying consistent updates in a tournament workflow without relying on a spreadsheet.
Enter ratings and describe the result clearly
Start with the two ratings immediately before the match. Player A and Player B are labels for this calculation, not permanent roles, so either competitor can occupy either position. Finally, enter the K-factor defined by your rating policy.
It must be greater than zero. A larger value makes ratings respond more strongly to each match, while a smaller value makes them steadier. The calculator deliberately does not select a K-factor because organizations often vary it by experience, age, event type, rating band, or number of games played.
Use the value your system already prescribes, and retain that value with the match record if you need to audit the update later. Ratings themselves may be any finite numbers, allowing the tool to work with differently centered Elo pools.
Understand expected score and rating change
Elo first converts the rating difference into an expected score. This calculator uses the standard logistic expression with a 400-point scale: Player A's expectation is one divided by one plus ten raised to the difference between Player B and Player A, divided by 400. Player B receives the complementary expectation, so the two expectations sum to one.
The actual score is then compared with that expectation. Multiplying the difference by the K-factor produces the rating change. A favored player who wins normally gains only a little because that outcome was already expected; an underdog who wins gains much more.
A draw can raise the lower-rated player's rating and lower the higher-rated player's rating. The two signed changes are opposites, keeping the combined rating total constant before display rounding. Output includes old rating, expected score, actual score, rating change, and new rating for each player.
Apply updates consistently in a rating workflow
For a single match, store the returned new ratings as the starting ratings for the competitors' next match. For a sequence of matches, order matters: calculate the first result, update the relevant records, and only then calculate the next result using those latest ratings. Do not calculate a whole round from stale ratings unless your competition rules explicitly say that updates are batched.
Keep the original ratings, result, and K-factor alongside the returned adjustment rather than saving only the final number; those inputs explain exactly why a rating moved. This capability implements the common two-player Elo formula, not specialized variants involving margin of victory, team composition, rating floors, provisional bonuses, inactivity decay, or federation-specific integer rounding. If your rules include those features, treat this result as the base calculation and apply only documented policy adjustments in a separate, testable step.
What you can do with it
Update a tournament leaderboard
Apply a documented K-factor after each recorded result and save both players' new ratings for the next round.
Verify rating software
Compare an application's expected scores and rating changes with deterministic reference output during automated tests.
Explain an upset adjustment
Show why an underdog gained more points by exposing the expected score, actual score, and signed change.
FAQ
Which Elo formula does this use?
It uses the standard two-player logistic expectation with a 400-point rating scale, followed by new rating = old rating + K × (actual score − expected score).
How do I represent a draw?
Set result to draw. Both players receive an actual score of 0.5, and the lower-rated player may gain rating while the higher-rated player loses the same amount.
Can the K-factor be zero or negative?
No. The K-factor must be a finite number greater than zero; zero or negative values return an invalid-input error.
Are updated ratings rounded to whole numbers?
No. Calculated fields are returned to as many as six decimal places. Apply whole-number rounding separately only if your competition rules require it.
Does the order of matches matter?
Yes. Calculate the first result, store the new ratings, and only then calculate the next match from those latest ratings. Working out a whole round from older ratings is only right when your competition rules batch the updates.
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/elo-rating-update \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"player_a_rating":1600,"player_b_rating":1400,"result":"player_a_win","k_factor":32}'const res = await fetch("https://api.kit.forhosting.com/game/elo-rating-update", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"player_a_rating": 1600,
"player_b_rating": 1400,
"result": "player_a_win",
"k_factor": 32
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/game/elo-rating-update",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"player_a_rating": 1600,
"player_b_rating": 1400,
"result": "player_a_win",
"k_factor": 32
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/game/elo-rating-update", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"player_a_rating":1600,"player_b_rating":1400,"result":"player_a_win","k_factor":32}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"player_a_rating":1600,"player_b_rating":1400,"result":"player_a_win","k_factor":32}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/game/elo-rating-update", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"player_a_rating": 1600,
"player_b_rating": 1400,
"result": "player_a_win",
"k_factor": 32
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "game.elo_rating_update",
"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
Enter ratings and describe the result clearly
Then choose the result from Player A's perspective: player_a_win means Player A scored 1 and Player B scored 0, draw gives each player 0.5, and player_b_win reverses the win scores. This explicit viewpoint prevents a common integration mistake in which a winner flag is paired with the wrong rating.
Apply updates consistently in a rating workflow
The endpoint is deterministic, so the same four inputs always yield the same JSON output.
Technical questions
What does one request cost?
One API request costs $0.002. The calculation is also available through the browser runner using the same deterministic solver.