dist enum required Which distribution to draw from. Each one reads its own parameters; anything belonging to another distribution is echoed back with a warning and ignored.
Seeded draws from normal, log-normal, exponential, Poisson, binomial, Pareto and Zipf distributions, with empirical and theoretical statistics.
Generated test data for fixtures and development
Each record is one independent draw: value, the theoretical CDF at that value in percentile (null for the discrete distributions), the sampler branch in method, and index so that repeated discrete draws stay distinct records.
| Parameter | Type | Default & allowed | Description |
|---|---|---|---|
dist
required
| enum | allowed: uniform | normal | lognormal | exponential | poisson | binomial | pareto | zipf example: normal | Which distribution to draw from. Each one reads its own parameters; anything belonging to another distribution is echoed back with a warning and ignored. |
min | float | allowed: -1000000000 – 1000000000 example: 0 | dist=uniform: lower bound, inclusive. Defaults to 0. Must be ≤ max, and min=max is allowed (with a warning) — every draw is then that exact value. Rounded draws are clamped up to the smallest value with `precision` decimals that is still ≥ min. |
max | float | allowed: -1000000000 – 1000000000 example: 10 | dist=uniform: upper bound. Defaults to 1. Draws are rounded to `precision` and clamped down to the largest value with that many decimals that is still ≤ max, so a value can land exactly on the bound but never past it. |
mean | float | allowed: -1000000000 – 1000000000 example: 100 | Location. dist=normal: the mean itself. dist=lognormal: the mean of the underlying normal, so exp(mean) is the MEDIAN of the draw, not its mean. Defaults to 0. |
stddev | float | allowed: ≤ 1000000000 example: 15 | Scale for dist=normal and dist=lognormal; must be > 0 (zero or negative is a 400). For lognormal it is the standard deviation of the underlying normal. Defaults to 1. |
rate | float | allowed: ≤ 1000000000 example: 0.5 | dist=exponential: the rate λ; must be > 0. The theoretical mean is 1/rate. Defaults to 1. |
lambda | float | allowed: ≤ 1000000000 example: 4 | dist=poisson: the mean number of events per interval; must be > 0. Required — Poisson has no canonical default. At or below 30 the sampler is Knuth's exact method, above it a normal approximation. |
trials | int | allowed: 1 – 10000 example: 20 | dist=binomial: the number of Bernoulli trials n (1–10000). Required. At or below 30 the sampler sums real trials, above it uses a normal approximation. |
probability | float | example: 0.3 | dist=binomial: the success probability p of one trial, between 0 and 1 inclusive (anything outside is a 400). Required. |
alpha | float | allowed: ≤ 1000 example: 1.5 | Shape; must be > 0. dist=pareto: the tail index — required, and log5/log4 ≈ 1.161 is the classic 80/20 shape. dist=zipf: the rank exponent, defaulting to 1 (Zipf's law). |
xmin | float | allowed: ≤ 1000000000 example: 1 | dist=pareto: the scale — the smallest value the distribution can take; must be > 0. Defaults to 1. No draw is ever returned below it: after rounding, a value is clamped up to the smallest number with `precision` decimals that is still ≥ xmin. |
support | int | allowed: 1 – 100000 example: 1000 | dist=zipf: the number of ranks N (1–100000). Required. Draws are whole ranks 1..N with P(k) ∝ k^−alpha. |
precision | int | allowed: 0 – 10 example: 2 | Decimal places for the continuous distributions (uniform, normal, lognormal, exponential, pareto). Defaults to 4. Rounding happens last and is clamped back inside the support; a grid too coarse for the distribution's interquartile range is warned about, and one that leaves no valid uniform value is a 400. Ignored — with a warning — by Poisson, binomial and Zipf, whose draws are whole numbers. |
dist enum required Which distribution to draw from. Each one reads its own parameters; anything belonging to another distribution is echoed back with a warning and ignored.
min float dist=uniform: lower bound, inclusive. Defaults to 0. Must be ≤ max, and min=max is allowed (with a warning) — every draw is then that exact value. Rounded draws are clamped up to the smallest value with `precision` decimals that is still ≥ min.
max float dist=uniform: upper bound. Defaults to 1. Draws are rounded to `precision` and clamped down to the largest value with that many decimals that is still ≤ max, so a value can land exactly on the bound but never past it.
mean float Location. dist=normal: the mean itself. dist=lognormal: the mean of the underlying normal, so exp(mean) is the MEDIAN of the draw, not its mean. Defaults to 0.
stddev float Scale for dist=normal and dist=lognormal; must be > 0 (zero or negative is a 400). For lognormal it is the standard deviation of the underlying normal. Defaults to 1.
rate float dist=exponential: the rate λ; must be > 0. The theoretical mean is 1/rate. Defaults to 1.
lambda float dist=poisson: the mean number of events per interval; must be > 0. Required — Poisson has no canonical default. At or below 30 the sampler is Knuth's exact method, above it a normal approximation.
trials int dist=binomial: the number of Bernoulli trials n (1–10000). Required. At or below 30 the sampler sums real trials, above it uses a normal approximation.
probability float dist=binomial: the success probability p of one trial, between 0 and 1 inclusive (anything outside is a 400). Required.
alpha float Shape; must be > 0. dist=pareto: the tail index — required, and log5/log4 ≈ 1.161 is the classic 80/20 shape. dist=zipf: the rank exponent, defaulting to 1 (Zipf's law).
xmin float dist=pareto: the scale — the smallest value the distribution can take; must be > 0. Defaults to 1. No draw is ever returned below it: after rounding, a value is clamped up to the smallest number with `precision` decimals that is still ≥ xmin.
support int dist=zipf: the number of ranks N (1–100000). Required. Draws are whole ranks 1..N with P(k) ∝ k^−alpha.
precision int Decimal places for the continuous distributions (uniform, normal, lognormal, exponential, pareto). Defaults to 4. Rounding happens last and is clamped back inside the support; a grid too coarse for the distribution's interquartile range is warned about, and one that leaves no valid uniform value is a 400. Ignored — with a warning — by Poisson, binomial and Zipf, whose draws are whole numbers.
| Parameter | Type | Default & allowed | Description |
|---|---|---|---|
count | int | default: 10 allowed: 1 – 100 example: 3 | How many records to generate (1–100). |
seed | int | example: 42 | Deterministic output: the same seed always returns the same records. Omit for random (the used seed is echoed in meta.seed). |
fields | list | example: index,value | Return only these fields (comma-separated). Mutually exclusive with 'exclude'. |
exclude | list | example: method | Return all fields except these (comma-separated). |
format | enum | default: json allowed: json | ndjson | csv example: csv | Response format: json envelope, ndjson (one record per line) or csv. |
pretty | boolean | default: false example: true | Pretty-print the JSON response. |
unwrap | boolean | default: false example: true | Drop the envelope: return the raw array/object without data/meta wrapper. |
count int How many records to generate (1–100).
seed int Deterministic output: the same seed always returns the same records. Omit for random (the used seed is echoed in meta.seed).
fields list Return only these fields (comma-separated). Mutually exclusive with 'exclude'.
exclude list Return all fields except these (comma-separated).
format enum Response format: json envelope, ndjson (one record per line) or csv.
pretty boolean Pretty-print the JSON response.
unwrap boolean Drop the envelope: return the raw array/object without data/meta wrapper.
| Field | Type | Description | Example |
|---|---|---|---|
index | integer | 0-based record position. It exists so repeated discrete draws remain distinct records without any jitter being added to `value`. | 0 |
value | number | The draw. A decimal rounded to `precision` for uniform, normal, lognormal, exponential and pareto; a whole number for poisson, binomial and zipf. | 106.9337 |
percentile nullable | float | Theoretical CDF evaluated at the returned `value`, 0–1, rounded to 6 decimals. Null for poisson, binomial and zipf, whose CDF is a step function. | 0.678048 |
method | string | The sampler branch actually used: inverse-cdf, box-muller, knuth, bernoulli-sum or normal-approximation. | box-muller |
index integer 0-based record position. It exists so repeated discrete draws remain distinct records without any jitter being added to `value`.
example: 0
value number The draw. A decimal rounded to `precision` for uniform, normal, lognormal, exponential and pareto; a whole number for poisson, binomial and zipf.
example: 106.9337
percentile float nullable Theoretical CDF evaluated at the returned `value`, 0–1, rounded to 6 decimals. Null for poisson, binomial and zipf, whose CDF is a step function.
example: 0.678048
method string The sampler branch actually used: inverse-cdf, box-muller, knuth, bernoulli-sum or normal-approximation.
example: box-muller
/api/distributions?dist=normal {
"data": [
{
"index": 0,
"value": -0.503,
"percentile": 0.307482,
"method": "box-muller"
},
{
"index": 1,
"value": 0.2839,
"percentile": 0.611756,
"method": "box-muller"
},
{
"index": 2,
"value": 1.4461,
"percentile": 0.925925,
"method": "box-muller"
},
{
"index": 3,
"value": -0.4989,
"percentile": 0.308925,
"method": "box-muller"
},
{
"index": 4,
"value": -0.412,
"percentile": 0.34017,
"method": "box-muller"
},
{
"index": 5,
"value": -0.1553,
"percentile": 0.438292,
"method": "box-muller"
},
{
"index": 6,
…
"generatedAt": "2026-07-29T08:13:22.000Z"
}
} /api/distributions?dist=uniform&min=0&max=100&precision=2&count=10&seed=4 {
"data": [
{
"index": 0,
"value": 42.77,
"percentile": 0.4277,
"method": "inverse-cdf"
},
{
"index": 1,
"value": 73.35,
"percentile": 0.7335,
"method": "inverse-cdf"
},
{
"index": 2,
"value": 17.12,
"percentile": 0.1712,
"method": "inverse-cdf"
},
{
"index": 3,
"value": 49.08,
"percentile": 0.4908,
"method": "inverse-cdf"
},
{
"index": 4,
"value": 89.08,
"percentile": 0.8908,
"method": "inverse-cdf"
},
{
"index": 5,
"value": 15.59,
"percentile": 0.1559,
"method": "inverse-cdf"
},
{
"index": 6,
…
"generatedAt": "2026-07-29T08:13:22.000Z"
}
} /api/distributions?dist=normal&mean=100&stddev=15&count=20&seed=42 {
"data": [
{
"index": 0,
"value": 92.4545,
"percentile": 0.30747,
"method": "box-muller"
},
{
"index": 1,
"value": 104.2583,
"percentile": 0.611751,
"method": "box-muller"
},
{
"index": 2,
"value": 121.6914,
"percentile": 0.925924,
"method": "box-muller"
},
{
"index": 3,
"value": 92.5158,
"percentile": 0.308908,
"method": "box-muller"
},
{
"index": 4,
"value": 93.8202,
"percentile": 0.340175,
"method": "box-muller"
},
{
"index": 5,
"value": 97.6712,
"percentile": 0.438311,
"method": "box-muller"
},
{
"index": 6,
…
"generatedAt": "2026-07-29T08:13:22.000Z"
}
} /api/distributions?dist=lognormal&mean=4.6&stddev=0.55&precision=1&count=20&seed=7 {
"data": [
{
"index": 0,
"value": 164.3,
"percentile": 0.819161,
"method": "box-muller"
},
{
"index": 1,
"value": 55,
"percentile": 0.140612,
"method": "box-muller"
},
{
"index": 2,
"value": 105.3,
"percentile": 0.541136,
"method": "box-muller"
},
{
"index": 3,
"value": 71.7,
"percentile": 0.275764,
"method": "box-muller"
},
{
"index": 4,
"value": 76.6,
"percentile": 0.317294,
"method": "box-muller"
},
{
"index": 5,
"value": 142.1,
"percentile": 0.741585,
"method": "box-muller"
},
{
"index": 6,
…
"generatedAt": "2026-07-29T08:13:22.000Z"
}
} /api/distributions?dist=poisson&lambda=4&count=20&seed=1 {
"data": [
{
"index": 0,
"value": 3,
"percentile": null,
"method": "knuth"
},
{
"index": 1,
"value": 2,
"percentile": null,
"method": "knuth"
},
{
"index": 2,
"value": 3,
"percentile": null,
"method": "knuth"
},
{
"index": 3,
"value": 3,
"percentile": null,
"method": "knuth"
},
{
"index": 4,
"value": 2,
"percentile": null,
"method": "knuth"
},
{
"index": 5,
"value": 5,
"percentile": null,
"method": "knuth"
},
{
"index": 6,
…
"generatedAt": "2026-07-29T08:13:22.000Z"
}
} /api/distributions?dist=binomial&trials=200&probability=0.12&count=10&seed=3 {
"data": [
{
"index": 0,
"value": 25,
"percentile": null,
"method": "normal-approximation"
},
{
"index": 1,
"value": 37,
"percentile": null,
"method": "normal-approximation"
},
{
"index": 2,
"value": 24,
"percentile": null,
"method": "normal-approximation"
},
{
"index": 3,
"value": 25,
"percentile": null,
"method": "normal-approximation"
},
{
"index": 4,
"value": 18,
"percentile": null,
"method": "normal-approximation"
},
{
"index": 5,
"value": 25,
"percentile": null,
"method": "normal-approximation"
},
{
"index": 6,
…
"generatedAt": "2026-07-29T08:13:22.000Z"
}
} /api/distributions?dist=pareto&alpha=1.161&xmin=1024&precision=0&count=10&seed=5 {
"data": [
{
"index": 0,
"value": 1730,
"percentile": 0.456015,
"method": "inverse-cdf"
},
{
"index": 1,
"value": 1650,
"percentile": 0.425276,
"method": "inverse-cdf"
},
{
"index": 2,
"value": 5421,
"percentile": 0.855558,
"method": "inverse-cdf"
},
{
"index": 3,
"value": 1079,
"percentile": 0.058933,
"method": "inverse-cdf"
},
{
"index": 4,
"value": 1580,
"percentile": 0.39561,
"method": "inverse-cdf"
},
{
"index": 5,
"value": 10173,
"percentile": 0.930448,
"method": "inverse-cdf"
},
{
"index": 6,
…
"generatedAt": "2026-07-29T08:13:22.000Z"
}
} /api/distributions?dist=zipf&support=1000&count=15&seed=9 {
"data": [
{
"index": 0,
"value": 6,
"percentile": null,
"method": "inverse-cdf"
},
{
"index": 1,
"value": 10,
"percentile": null,
"method": "inverse-cdf"
},
{
"index": 2,
"value": 13,
"percentile": null,
"method": "inverse-cdf"
},
{
"index": 3,
"value": 2,
"percentile": null,
"method": "inverse-cdf"
},
{
"index": 4,
"value": 193,
"percentile": null,
"method": "inverse-cdf"
},
{
"index": 5,
"value": 33,
"percentile": null,
"method": "inverse-cdf"
},
{
"index": 6,
…
"generatedAt": "2026-07-29T08:13:22.000Z"
}
} /api/distributions?dist=exponential&rate=0.5&fields=value&format=ndjson&count=25 {"value":1.2993}
{"value":0.0807}
{"value":3.8896}
{"value":0.3353}
{"value":3.5879}
{"value":0.0335}
{"value":0.1736}
{"value":3.5873}
{"value":1.2138}
{"value":6.7377}
{"value":8.597}
{"value":0.3965}
{"value":0.1631}
{"value":1.5526}
{"value":2.7816}
{"value":3.3317}
{"value":0.5679}
{"value":1.8913}
{"value":1.261}
{"value":1.3326}
{"value":3.1711}
{"value":0.017}
{"value":0.0658}
{"value":2.3421}
{"value":1.756}
Draws size values from the chosen distribution and reports the sample's mean, variance, standard deviation, extremes and quantiles alongside the closed-form moments. Moments that do not exist are null with an explanation in theoretical.note.
| Parameter | Type | Default & allowed | Description |
|---|---|---|---|
dist
required
| enum | allowed: uniform | normal | lognormal | exponential | poisson | binomial | pareto | zipf example: normal | Which distribution to draw from. Each one reads its own parameters; anything belonging to another distribution is echoed back with a warning and ignored. |
size | int | default: 1000 allowed: 1 – 10000 example: 5000 | How many values to draw before computing the statistics (1–10000). Larger samples sit closer to the theoretical moments on average — the remaining gap is sampling error. |
seed | int | default: 0 example: 42 | Determinism anchor for the sample. Any integer is accepted and reduced modulo 2³² exactly as the root route's `seed` is, so the sample is exactly the records the root route returns for that seed — `seed=-1` and `seed=4294967295` are the same sample on both routes. |
min | float | allowed: -1000000000 – 1000000000 example: 0 | dist=uniform: lower bound, inclusive. Defaults to 0. Must be ≤ max, and min=max is allowed (with a warning) — every draw is then that exact value. Rounded draws are clamped up to the smallest value with `precision` decimals that is still ≥ min. |
max | float | allowed: -1000000000 – 1000000000 example: 10 | dist=uniform: upper bound. Defaults to 1. Draws are rounded to `precision` and clamped down to the largest value with that many decimals that is still ≤ max, so a value can land exactly on the bound but never past it. |
mean | float | allowed: -1000000000 – 1000000000 example: 100 | Location. dist=normal: the mean itself. dist=lognormal: the mean of the underlying normal, so exp(mean) is the MEDIAN of the draw, not its mean. Defaults to 0. |
stddev | float | allowed: ≤ 1000000000 example: 15 | Scale for dist=normal and dist=lognormal; must be > 0 (zero or negative is a 400). For lognormal it is the standard deviation of the underlying normal. Defaults to 1. |
rate | float | allowed: ≤ 1000000000 example: 0.5 | dist=exponential: the rate λ; must be > 0. The theoretical mean is 1/rate. Defaults to 1. |
lambda | float | allowed: ≤ 1000000000 example: 4 | dist=poisson: the mean number of events per interval; must be > 0. Required — Poisson has no canonical default. At or below 30 the sampler is Knuth's exact method, above it a normal approximation. |
trials | int | allowed: 1 – 10000 example: 20 | dist=binomial: the number of Bernoulli trials n (1–10000). Required. At or below 30 the sampler sums real trials, above it uses a normal approximation. |
probability | float | example: 0.3 | dist=binomial: the success probability p of one trial, between 0 and 1 inclusive (anything outside is a 400). Required. |
alpha | float | allowed: ≤ 1000 example: 1.5 | Shape; must be > 0. dist=pareto: the tail index — required, and log5/log4 ≈ 1.161 is the classic 80/20 shape. dist=zipf: the rank exponent, defaulting to 1 (Zipf's law). |
xmin | float | allowed: ≤ 1000000000 example: 1 | dist=pareto: the scale — the smallest value the distribution can take; must be > 0. Defaults to 1. No draw is ever returned below it: after rounding, a value is clamped up to the smallest number with `precision` decimals that is still ≥ xmin. |
support | int | allowed: 1 – 100000 example: 1000 | dist=zipf: the number of ranks N (1–100000). Required. Draws are whole ranks 1..N with P(k) ∝ k^−alpha. |
precision | int | allowed: 0 – 10 example: 2 | Decimal places for the continuous distributions (uniform, normal, lognormal, exponential, pareto). Defaults to 4. Rounding happens last and is clamped back inside the support; a grid too coarse for the distribution's interquartile range is warned about, and one that leaves no valid uniform value is a 400. Ignored — with a warning — by Poisson, binomial and Zipf, whose draws are whole numbers. |
dist enum required Which distribution to draw from. Each one reads its own parameters; anything belonging to another distribution is echoed back with a warning and ignored.
size int How many values to draw before computing the statistics (1–10000). Larger samples sit closer to the theoretical moments on average — the remaining gap is sampling error.
seed int Determinism anchor for the sample. Any integer is accepted and reduced modulo 2³² exactly as the root route's `seed` is, so the sample is exactly the records the root route returns for that seed — `seed=-1` and `seed=4294967295` are the same sample on both routes.
min float dist=uniform: lower bound, inclusive. Defaults to 0. Must be ≤ max, and min=max is allowed (with a warning) — every draw is then that exact value. Rounded draws are clamped up to the smallest value with `precision` decimals that is still ≥ min.
max float dist=uniform: upper bound. Defaults to 1. Draws are rounded to `precision` and clamped down to the largest value with that many decimals that is still ≤ max, so a value can land exactly on the bound but never past it.
mean float Location. dist=normal: the mean itself. dist=lognormal: the mean of the underlying normal, so exp(mean) is the MEDIAN of the draw, not its mean. Defaults to 0.
stddev float Scale for dist=normal and dist=lognormal; must be > 0 (zero or negative is a 400). For lognormal it is the standard deviation of the underlying normal. Defaults to 1.
rate float dist=exponential: the rate λ; must be > 0. The theoretical mean is 1/rate. Defaults to 1.
lambda float dist=poisson: the mean number of events per interval; must be > 0. Required — Poisson has no canonical default. At or below 30 the sampler is Knuth's exact method, above it a normal approximation.
trials int dist=binomial: the number of Bernoulli trials n (1–10000). Required. At or below 30 the sampler sums real trials, above it uses a normal approximation.
probability float dist=binomial: the success probability p of one trial, between 0 and 1 inclusive (anything outside is a 400). Required.
alpha float Shape; must be > 0. dist=pareto: the tail index — required, and log5/log4 ≈ 1.161 is the classic 80/20 shape. dist=zipf: the rank exponent, defaulting to 1 (Zipf's law).
xmin float dist=pareto: the scale — the smallest value the distribution can take; must be > 0. Defaults to 1. No draw is ever returned below it: after rounding, a value is clamped up to the smallest number with `precision` decimals that is still ≥ xmin.
support int dist=zipf: the number of ranks N (1–100000). Required. Draws are whole ranks 1..N with P(k) ∝ k^−alpha.
precision int Decimal places for the continuous distributions (uniform, normal, lognormal, exponential, pareto). Defaults to 4. Rounding happens last and is clamped back inside the support; a grid too coarse for the distribution's interquartile range is warned about, and one that leaves no valid uniform value is a 400. Ignored — with a warning — by Poisson, binomial and Zipf, whose draws are whole numbers.
| Parameter | Type | Default & allowed | Description |
|---|---|---|---|
fields | list | example: dist,size | Return only these fields (comma-separated). Mutually exclusive with 'exclude'. |
exclude | list | example: seed | Return all fields except these (comma-separated). |
pretty | boolean | default: false example: true | Pretty-print the JSON response. |
unwrap | boolean | default: false example: true | Drop the envelope: return the raw array/object without data/meta wrapper. |
fields list Return only these fields (comma-separated). Mutually exclusive with 'exclude'.
exclude list Return all fields except these (comma-separated).
pretty boolean Pretty-print the JSON response.
unwrap boolean Drop the envelope: return the raw array/object without data/meta wrapper.
| Field | Type | Description | Example |
|---|---|---|---|
dist | string | The distribution that was sampled. | normal |
size | integer | Number of values drawn. | 1000 |
parameters | object | The resolved distribution parameters that were used, defaults included (plus `precision` for the continuous distributions). | {"mean":100,"stddev":15,"precision":4} |
empirical | object | Statistics of the drawn sample: `mean`, population `variance`, `stddev`, `min`, `max`, `median`, `p25`, `p75`, `p95`. Quantiles are nearest-rank, so each is an actual draw. | {"mean":99.9571,"variance":220.5983,"stddev":14.8525,"min":52.7431,"max":148.9902,"median":99.9128,"p25":89.7712,"p75":110.0264,"p95":124.3187} |
theoretical | object | Closed-form `mean` and `variance` of the distribution itself. Either is null when the moment does not exist, or cannot be represented as a double, and `note` then explains which. | {"mean":100,"variance":225,"note":null} |
method | string | The sampler branch used for every value in the sample. | box-muller |
seed | integer | The seed the sample was drawn from. | 42 |
dist string The distribution that was sampled.
example: normal
size integer Number of values drawn.
example: 1000
parameters object The resolved distribution parameters that were used, defaults included (plus `precision` for the continuous distributions).
example: {"mean":100,"stddev":15,"precision":4}
empirical object Statistics of the drawn sample: `mean`, population `variance`, `stddev`, `min`, `max`, `median`, `p25`, `p75`, `p95`. Quantiles are nearest-rank, so each is an actual draw.
example: {"mean":99.9571,"variance":220.5983,"stddev":14.8525,"min":52.7431,"max":148.9902,"median":99.9128,"p25":89.7712,"p75":110.0264,"p95":124.3187}
theoretical object Closed-form `mean` and `variance` of the distribution itself. Either is null when the moment does not exist, or cannot be represented as a double, and `note` then explains which.
example: {"mean":100,"variance":225,"note":null}
method string The sampler branch used for every value in the sample.
example: box-muller
seed integer The seed the sample was drawn from.
example: 42
/api/distributions/summary?dist=normal&mean=100&stddev=15 {
"data": {
"dist": "normal",
"size": 1000,
"parameters": {
"mean": 100,
"stddev": 15,
"precision": 4
},
"empirical": {
"mean": 99.523127,
"variance": 210.609656,
"stddev": 14.512397,
"min": 50.4711,
"max": 146.4477,
"median": 100.0259,
"p25": 89.9118,
"p75": 109.1211,
"p95": 122.3621
},
"theoretical": {
"mean": 100,
"variance": 225,
"note": null
},
"method": "box-muller",
"seed": 0
},
"meta": {
"endpoint": "distributions",
"route": "/summary",
"params": {
"dist": "normal",
"size": 1000,
"seed": 0,
"mean": 100,
"stddev": 15,
"precision": 4
},
"generatedAt": "2026-07-29T08:13:22.000Z"
}
} /api/distributions/summary?dist=poisson&lambda=4&size=5000&seed=42 {
"data": {
"dist": "poisson",
"size": 5000,
"parameters": {
"lambda": 4
},
"empirical": {
"mean": 3.9702,
"variance": 3.813312,
"stddev": 1.95277,
"min": 0,
"max": 12,
"median": 4,
"p25": 3,
"p75": 5,
"p95": 7
},
"theoretical": {
"mean": 4,
"variance": 4,
"note": null
},
"method": "knuth",
"seed": 42
},
"meta": {
"endpoint": "distributions",
"route": "/summary",
"params": {
"dist": "poisson",
"size": 5000,
"seed": 42,
"lambda": 4
},
"generatedAt": "2026-07-29T08:13:22.000Z"
}
} /api/distributions/summary?dist=pareto&alpha=0.8&size=2000 {
"data": {
"dist": "pareto",
"size": 2000,
"parameters": {
"alpha": 0.8,
"xmin": 1,
"precision": 4
},
"empirical": {
"mean": 21.284961,
"variance": 32352.089235,
"stddev": 179.866865,
"min": 1.0003,
"max": 4103.8254,
"median": 2.4197,
"p25": 1.4569,
"p75": 5.5733,
"p95": 37.1668
},
"theoretical": {
"mean": null,
"variance": null,
"note": "A Pareto distribution has an infinite mean for alpha ≤ 1 and an infinite variance for alpha ≤ 2, so both are reported as null instead of a number the distribution does not have."
},
"method": "inverse-cdf",
"seed": 0
},
"meta": {
"endpoint": "distributions",
"route": "/summary",
"params": {
"dist": "pareto",
"size": 2000,
"seed": 0,
"alpha": 0.8,
"xmin": 1,
"precision": 4
},
"generatedAt": "2026-07-29T08:13:22.000Z"
}
} /api/distributions/summary?dist=exponential&rate=0.25&size=10000&seed=7 {
"data": {
"dist": "exponential",
"size": 10000,
"parameters": {
"rate": 0.25,
"precision": 4
},
"empirical": {
"mean": 3.979804,
"variance": 15.903349,
"stddev": 3.9879,
"min": 0.0002,
"max": 36.5569,
"median": 2.7852,
"p25": 1.1515,
"p75": 5.4894,
"p95": 11.7879
},
"theoretical": {
"mean": 4,
"variance": 16,
"note": null
},
"method": "inverse-cdf",
"seed": 7
},
"meta": {
"endpoint": "distributions",
"route": "/summary",
"params": {
"dist": "exponential",
"size": 10000,
"seed": 7,
"rate": 0.25,
"precision": 4
},
"generatedAt": "2026-07-29T08:13:22.000Z"
}
} /api/distributions/summary?dist=zipf&support=500&alpha=1.2&size=5000&seed=3 {
"data": {
"dist": "zipf",
"size": 5000,
"parameters": {
"alpha": 1.2,
"support": 500
},
"empirical": {
"mean": 43.9554,
"variance": 7800.444211,
"stddev": 88.320123,
"min": 1,
"max": 500,
"median": 6,
"p25": 2,
"p75": 36,
"p95": 259
},
"theoretical": {
"mean": 43.321384,
"variance": 7799.173693,
"note": null
},
"method": "inverse-cdf",
"seed": 3
},
"meta": {
"endpoint": "distributions",
"route": "/summary",
"params": {
"dist": "zipf",
"size": 5000,
"seed": 3,
"alpha": 1.2,
"support": 500
},
"generatedAt": "2026-07-29T08:13:22.000Z"
}
} Draws seeded pseudo-random numbers from eight named distributions, so fixtures, load-test inputs and charts have a realistic shape instead of the flat noise a uniform generator gives you. Every response names the exact sampler branch it used in method, and /summary puts a sample's empirical statistics next to the closed-form theoretical ones.
Parameters per distribution. A parameter with a canonical textbook default is optional; the rest must be supplied, and omitting one is a 400 naming both the parameter and the distribution. Every resolved value — defaults included — is echoed in meta.params.
dist |
parameters | defaults | returned draw |
|---|---|---|---|
uniform |
min, max |
0, 1 | decimal in [min, max] |
normal |
mean, stddev |
0, 1 | decimal of either sign |
lognormal |
mean, stddev |
0, 1 | decimal ≥ 0 — the draw itself is positive, but rounding can bring a tiny one down to 0 |
exponential |
rate |
1 | decimal ≥ 0 |
poisson |
lambda |
required | whole number ≥ 0 |
binomial |
trials, probability |
both required | whole number in [0, trials] |
pareto |
alpha, xmin |
alpha required, xmin 1 | decimal ≥ xmin |
zipf |
alpha, support |
alpha 1, support required | whole rank in [1, support] |
Every continuous draw is rounded to precision last, so that column describes the value you actually receive, not just the mathematics behind it. See Rounding below.
The algorithms, all standard and all named.
min + u·(max − min). method: "inverse-cdf".mean + stddev·√(−2·ln u₁)·cos(2π u₂). The transform produces two independent deviates; this endpoint always keeps the cosine one and discards the sine, so a record depends only on its own seed stream and never on the record before it. Because the uniform stream has 2⁻³² resolution the deviate is truncated at |z| ≈ 6.6604 — a tail worth about 3 in 100 billion draws, and the reason no draw can come back as Infinity. method: "box-muller".exp() of that same normal deviate, which is why exp(mean) is the median of the draw and exp(mean + stddev²/2) its mean. method: "box-muller".−ln(1 − u)/rate. u = 0 maps to exactly 0, the left end of the support, and the generator's 2⁻³² resolution caps one draw at ln(2³²)/rate ≈ 22.18/rate — there is no code path that can return Infinity. Draws smaller than half a rounding step also come back as 0, which is inside the support. method: "inverse-cdf".e^−λ), which is exact, for lambda ≤ 30. Above 30 the sampler switches to a rounded normal approximation round(λ + √λ·z) floored at 0 and reports method: "normal-approximation" instead of "knuth". 30 is both the conventional point where that approximation becomes good and the point where Knuth's ~λ+1 draws per value get expensive.trials ≤ 30, the same cost cutoff: an exact sum at trials=10000 and size=10000 would be 100 million draws in one request. Above 30 the sampler switches to a rounded normal approximation round(np + √(np(1−p))·z) clamped to [0, n] and reports method: "normal-approximation" instead of "bernoulli-sum". If that approximation runs while n·p or n·(1−p) is below 10 — the textbook validity rule — the response adds a warning saying so, because that is where the approximated shape stops being trustworthy.xmin/(1 − u)^(1/alpha). alpha = log 5 / log 4 ≈ 1.161 is the classic 80/20 shape. method: "inverse-cdf".P(k) = k^−alpha / H(N, alpha) over ranks 1..support, from a cumulative table built once per request (not once per record) and searched in O(log N) per draw. method: "inverse-cdf".Rounding: precision is applied last, and never at the cost of the support. The five continuous distributions round their draw to precision decimals (default 4) as the final step, so the rounding grid — a step of 10^−precision — is part of the answer, not cosmetic:
ceil(min) / floor(max) for uniform, ceil(xmin) for pareto. A pareto draw is therefore never returned below xmin, and a value never carries more decimals than you asked for. A normal is unbounded and needs no clamp; lognormal and exponential are bounded below by 0, which sits on every grid — which is why a very small lognormal draw can legitimately be returned as 0 even though the distribution itself is strictly positive.precision=0 on a uniform over [0.3, 0.7], rate=1e9 at the default precision — the values stop being a usable sample of that shape. The response says so in meta.warnings, naming the step and the interquartile range. Nothing is silently flattened.?dist=uniform&min=0.3&max=0.7&precision=0 has no value with zero decimals anywhere inside its bounds, so it is refused rather than answered with something outside them.Why every record has an index. A generated list has to return count distinct records, and discrete draws repeat by nature — ten Poisson draws at lambda=2 will contain duplicates, as they should. index (the 0-based record position) makes the records distinct without touching the numbers: no jitter is ever added to value, because that would quietly corrupt the very distribution you asked for. If you only want the numbers, project it away with ?fields=value.
percentile is the theoretical CDF evaluated at the value that was actually returned — the rounded one, so you can recompute it yourself — clamped to [0, 1] and rounded to 6 decimals. The normal and log-normal CDFs use the erf approximation published as Abramowitz & Stegun formula 7.1.26, whose maximum absolute error is 1.5e-7; six decimals is as far as that is worth reporting. Poisson, binomial and Zipf return percentile: null: their CDF is a step function, so "the percentile of this draw" is not well defined.
/summary draws size values (default 1000) and reports them as statistics. Because record i uses exactly the seed derivation the root route uses, the sample is the first size records the root route returns for the same seed and parameters. empirical.variance is the population variance (divided by size, not size − 1); median, p25, p75 and p95 use the nearest-rank method — the ⌈p·size⌉-th smallest draw — so each is a real value from the sample, not an interpolation. Unlike the root route, /summary defaults to seed=0 rather than a random seed, so it is reproducible out of the box.
Honest limits.
size and it shrinks.precision rounds the returned values but not the theoretical moments, which are the closed forms of the unrounded distribution. At a sensible precision the difference is far below sampling error; at a coarse one the warning above tells you the two are no longer describing the same thing.null with an explanation in theoretical.note — a Pareto with alpha ≤ 1 has an infinite mean, and with alpha ≤ 2 an infinite variance. The same happens to a moment that exists but is too large for a double (a log-normal with a very large stddev), and note says which of the two it was. Never a fabricated number.rate, a tiny Pareto alpha, an enormous log-normal mean) are refused with a 400 that shows the computed bound, so no response ever contains Infinity or an unexplained null.Call /api/distributions?dist=normal&mean=100&stddev=15. Each draw comes from a Box–Muller transform of the seeded stream, and every record reports the theoretical CDF at its own value in percentile.
Eight: uniform, normal, lognormal, exponential, Poisson, binomial, Pareto and Zipf. Every record names the exact sampler branch used in its method field.
For lambda up to 30 it uses Knuth's product method, which is exact. Above 30 it switches to a rounded normal approximation and says so with method: "normal-approximation" — the switch is never hidden.
precision (default 4) rounds every continuous draw, so a distribution narrower than that grid collapses onto a few points. The response warns whenever fewer than four grid steps fit in the interquartile range — raise precision and the shape comes back.
/api/distributions/summary returns a sample's empirical mean, variance, min, max, median and p25/p75/p95 next to the theoretical moments. For the same seed and parameters its sample is exactly what the root route returns.
No. They come from a deterministic seeded mulberry32 stream — reproducible by design and not cryptographically secure. Use them for fixtures and load-test shapes only.
Random integers or floats in any range — control decimal precision, draw guaranteed-unique values, and pin a seed for reproducible sequences.
Weighted random picks from your own options, unbiased list shuffles and tunable coin flips — every decision reproducible with a seed.
Roll dice in standard NdS+M notation (2d6+3, d20, 4d8-2) — get each die result, the modifier and the total, with seedable, reproducible rolls.
Generate compact mock metric series and standalone points with exact intervals, bounded values, coherent trends and deterministic timestamps.
Sparkline SVGs straight from a URL — plot 2–100 numbers as a line, area or bar chart with custom size, color and smoothing. No chart library needed.