D&D dice roller
Type 2d6+3 with seed 42 and you get faces 1 and 5 plus the modifier 3, for a total of 9, every time. Each die is listed, so the whole table can check a damage or attack roll later. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Notation
- 2d6+3
- Seed
- 42
- Total
- 9
- Normalized
- 2d6+3
- Dice
- 1, 5
- Dice sum
- 6
A D&D dice roller turns a published notation string such as 2d6+3, 1d20+5, or 4d6 into one concrete total and the individual die values that produced it.
What a D&D notation roll actually returns
Standard tabletop notation writes a pool of dice as N d S, optionally followed by plus or minus constants and further dice terms: 2d6+3 is two six-sided dice plus three, 1d20+5 is a twenty-sided attack roll plus a modifier, and 4d6 is four six-sided dice with no constant. Each die is an independent discrete uniform random variable on the integers from one through the number of sides; the rolled total is the signed sum of those faces plus every constant in the expression.
A dnd dice roller therefore does not answer the probability of a sum, nor the theoretical minimum and maximum of an NdS phrase. It materializes one concrete outcome so you can resolve damage, an attack, a saving throw with a bonus, or a classroom trial of several dice at once. Determinism is part of the product promise.
Faces are returned in left-to-right expression order, the modifier is the net constant, and total is their signed combination. Fairness is hard-coded: every face of a given die is equally likely under the remainder map. Keep-highest, drop-lowest, exploding dice, and multiply operators are rejected because they are not the published 2d6+3 contract this landing ranks for.
When the notation string is malformed the task fails instead of inventing faces, because a broken expression is not a D&D roll that anyone can grade.
Where a D&D dice roller earns its keep
Tabletop groups and virtual tabletops use a dnd dice roller so every player can see the same 2d6+3 damage or 1d20+5 attack that the published seed implies, without passing a physical pair of cubes around the table or trusting a client that could have been edited. Adventure authors publish notation in stat blocks; this landing evaluates those strings instead of forcing the reader to split count, sides, and modifier by hand.
Contest organizers and charity raffles that decide a prize from 2d10+4 need an auditable toss: given the published seed and notation, any later reviewer can recompute the exact faces and total. Developers call the same contract from scripts to seed unit-test vectors, to drive Monte Carlo worksheets that must match a printed key, or to satisfy programming-challenge statements that demand a full NdS roll rather than a single d20 face.
What you can do with it
Damage and attack expressions at the table
Publish a session seed so every player and the dungeon master recompute the same 2d6+3 damage or 1d20+5 attack without passing physical dice.
Adventure stat blocks and published modules
Evaluate the NdS strings printed in monster stat blocks and one-shots so readers see faces and a total instead of splitting count, sides, and modifier by hand.
FAQ
How do I roll 2d6+3 with this D&D dice roller?
Send notation as a string such as 2d6+3 and seed as a non-negative integer. The same pair always produces the same roll.
What dice notation is supported?
Standard NdS terms and plus or minus constants: 2d6+3, 1d20+5, 4d6, d20, d%, and mixed forms such as 1d20+1d4-1. Keep-highest, drop-lowest, exploding dice, and multiply operators are rejected.
What happens if the notation string is malformed?
Trailing operators, missing dice terms, unsupported keep or explode flags, empty strings, and expressions that exceed the dice or sides limits are rejected and are not billed.
Why does a D&D dice roller need a seed?
The seed makes the faces and total reproducible. Two machines, two graders, or a later audit reconstruct the same 2d6+3 roll. Seed zero is valid and is not treated as missing.
Can I roll 4d6 and drop the lowest die?
Not as part of the expression: keep-highest, drop-lowest, exploding dice and multiplication are rejected. You can still roll 4d6 and set the lowest face aside yourself, because every die value is listed in the result.
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/stat/dnd-dice-roller \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"notation":"2d6+3","seed":42}'const res = await fetch("https://api.kit.forhosting.com/stat/dnd-dice-roller", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"notation": "2d6+3",
"seed": 42
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/stat/dnd-dice-roller",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"notation": "2d6+3",
"seed": 42
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/stat/dnd-dice-roller", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"notation":"2d6+3","seed":42}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"notation":"2d6+3","seed":42}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/stat/dnd-dice-roller", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"notation": "2d6+3",
"seed": 42
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "stat.dnd_dice_roller",
"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.
Limits
max_dice | 100 |
max_sides | 1000 |
max_notation_len | 200 |
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
A malformed notation string fails with invalid_input instead of inventing a roll.
What a D&D notation roll actually returns
This endpoint tokenizes the notation string, initializes a mulberry32 generator from the non-negative integer seed you send, and for each die takes one unsigned thirty-two-bit word that maps onto the closed integer range from 1 to S inclusive. Identical notation and seed always produce identical JSON because the path never consults the wall clock or the host random source.
Input contract, response shape, and error behaviour
Zero is a valid seed and is not treated as missing. Example: notation 2d6+3 with a published seed always produces the same two faces and the same total, because the generator and the remainder map are fixed. Failed validation does not consume balance. Expressions longer than two hundred characters, more than one hundred dice, or a die with more than one thousand sides are rejected so an isolate cannot be exhausted by a hostile string. POST a JSON body with two fields. notation is the required dice expression; aliases expression, dice, formula, expr, input, and text are accepted when clients reuse older form names. Spaces around plus and minus are allowed. seed is a required non-negative integer; aliases rng_seed and value are accepted. The seed may arrive as a JSON number or as a numeric string of digits; empty strings, booleans, objects, fractions, negatives, and values outside the safe integer range fail with invalid_input naming the field. Those failures are not billed. On success the body echoes notation and seed, returns normalized as the canonical spaced-stripped form with implicit counts written as one, returns total as the integer result, returns dice as the array of individual faces in expression order, returns dice_sum as the signed sum of those faces, returns modifier as the net constant, and documents dice_count, min_total, and max_total so a renderer can label the primary value without extra constants. Pair the response with your own character sheet if you need advantage, disadvantage, or keep-highest; this endpoint only rolls standard NdS plus constants. Keep seeds documented next to the session log, pin goldens for the seeds you ship, and treat invalid_input as a data-quality signal rather than retrying a malformed string.
Where a D&D dice roller earns its keep
Exam-prep generators and probability classrooms need a deterministic oracle that marks a broken expression as invalid_input instead of silently returning an empty total a buggy grader might treat as success. Keep requests to one notation string and one seed per call, pin the integer total and the face list in tests, and you get reproducible D&D rolls for homework, LMS plugins, and edge workers without standing up a custom random service of your own.
Integration use cases
Deterministic automation and test fixtures
Generate a stable notation roll in unit tests and worksheets so continuous integration and printed answer keys never drift between machines.
Technical questions
What does the D&D dice roller cost?
The browser tool is free. API requests use prepaid KIT balance at $0.002 per successful call; invalid input is not billed.