API
The tools on this site run one statistics core. This API is that same core, callable from your own programs: send JSON, get the answer back as JSON. It is not a second implementation — the website tools, this API, and the MCP server all call the identical functions, so their answers cannot drift apart.
No account, no key, no tracking. A request is computed and forgotten: nothing is stored, logged or measured, and there are no cookies. Browsers may call it from any page (CORS is open). The base URL is https://solvedwithstats.com; this is version v1 — the list of endpoints is itself readable at GET /api/v1.
Every call is a POST with a JSON body. A good call returns { "ok": true, "endpoint": …, "result": { … } }. A bad one returns { "ok": false, "error": … } with HTTP 400 and a message naming the field at fault — try it and read what it says. Any one list of numbers may hold at most 10,000 values. Where a result is genuinely unbounded (a one-sided interval has no far end), that field comes back as null.
The endpoints
POST /api/v1/descriptive
Summarise a dataset: centre, spread, quartiles, outliers, skewness — and a plain-language ruling on which centre to report.
POST /api/v1/descriptive
{ "data": [10, 15, 20, 30, 50, 70] }
→ mean 32.5, median 25, sample SD 23.18, and the guidance:
"Report the median (25)" — the mean is pulled up by the large values.
POST /api/v1/confidence-interval
A confidence interval for a mean — from raw data, or from n, mean and sd — or for a proportion, from x successes out of n (Wilson score interval by default; "method": "normal" for the textbook Wald interval).
POST /api/v1/confidence-interval
{ "data": [10000001, 10000003, 10000005] }
→ 95% interval [9999998.03, 10000007.97] around the mean 10000003.
{ "x": 10, "n": 100 }
→ 95% Wilson interval [0.0552, 0.1741] around the proportion 0.10.
POST /api/v1/welch-t-test
Welch’s two-sample t-test, which does not assume the two groups share a variance. Each group goes in as raw data or as a summary (n, mean, sd); alt may be "two-sided" (default), "greater" or "less".
POST /api/v1/welch-t-test
{ "a": { "n": 10, "mean": 5.0, "sd": 2.0 },
"b": { "n": 12, "mean": 3.5, "sd": 2.5 } }
→ t = 1.563 on 19.98 degrees of freedom, p = 0.1337,
difference 1.5 with 95% interval [-0.502, 3.502], Cohen's d = 0.655.
POST /api/v1/sample-size
How many subjects a study needs, planned before the data exists. "kind" is "mean" (detect a difference of delta with spread sd), "mean-margin" (estimate a mean within ±margin), "proportion" (p1 against p2, or against a known p0 with "groups": 1), or "proportion-margin" (estimate a proportion within ±margin). Leave kind out and it is inferred from the fields you send. Calculations are the normal (z) approximation, as in the Sample Size & Power tool — exact for large samples, a subject or two optimistic for very small ones.
POST /api/v1/sample-size
{ "kind": "mean", "delta": 5, "sd": 12, "groups": 2 }
→ 91 subjects per group (180 total) for 80% power at alpha 0.05.
{ "kind": "proportion-margin", "margin": 0.03 }
→ n = 1068 — the canonical survey number for ±3 points at 95%.
POST /api/v1/power
The other direction: given a finished or planned design, what could it detect? Default answer is the test’s power; with "solve": "mde" it is the smallest effect the design can detect at the target power (default 0.8).
POST /api/v1/power
{ "kind": "mean", "n": 64, "delta": 1, "sd": 2, "groups": 2 }
→ power 0.807 — a study of 64 per group catches a 1-unit
difference (at SD 2) about four times in five.
{ "kind": "mean", "n": 100, "sd": 10, "groups": 2, "solve": "mde" }
→ smallest detectable difference 3.96 units at 80% power.
POST /api/v1/correlation
The Pearson correlation of x and y. Add a third list z and you also get the partial correlation holding z fixed, the within-band correlations, and a plain-language verdict on whether the association survives the control.
POST /api/v1/correlation
{ "x": [1, 2, 3, 4, 5], "y": [2, 4, 5, 4, 5], "z": [5, 3, 4, 2, 1] }
→ raw r = 0.775; with z held fixed, r = 0.582.
POST /api/v1/regression
Least-squares fit of y on x: slope, intercept, R², fitted values and residuals. Add "degree": 2 (or higher, to 12) for a polynomial fit instead — its coefficients come back in raw-x ascending order, the convention numpy’s polyfit output is reversed into.
POST /api/v1/regression
{ "x": [1, 2, 3, 4, 5, 6, 7, 8],
"y": [2.1, 3.9, 6.2, 7.8, 10.3, 11.9, 14.2, 15.8] }
→ slope 1.988, intercept 0.079, R² 0.9984.
With "degree": 2, coefficients [-0.046, 2.063, -0.0083].
POST /api/v1/p-value
A one-sample t-test: from data, or from n / mean / sd, against mu0 (default 0). Or, if the test is already done, send a finished t with its df and get its p-value. alt works as in the t-test endpoint.
POST /api/v1/p-value
{ "t": 3.0, "df": 10 }
→ p = 0.01334 (two-sided).
{ "data": [12.1, 11.3, 12.8, 11.9, 12.4, 11.6, 12.2, 12.0], "mu0": 12 }
→ t = 0.229 on 7 degrees of freedom, p = 0.825.
POST /api/v1/sampling-distribution
The sampling distribution of a mean, simulated: pick a population shape (normal, skewed, uniform, bimodal), a sample size n, how many samples (reps), and a seed. The simulation is seeded, so the same request always returns the same answer — and the theory it should match (the population mean, and the standard error σ/√n) comes back beside the simulated values.
POST /api/v1/sampling-distribution
{ "shape": "normal", "n": 25, "reps": 2000, "seed": 42 }
→ mean of the 2000 sample means 99.933, SD of them 2.974,
against theory: mean 100, standard error 3 — plus a 24-bin histogram.
POST /api/v1/bias-variance
The bias–variance split, computed: a true curve (shape wave, curve, plateau or peak) is buried under noise of size noiseSd, polynomials of increasing degree are fitted to repeated seeded samples, and the expected error at each degree comes back decomposed into bias², variance and the irreducible noise — with the best degree marked.
POST /api/v1/bias-variance
{ "shape": "curve", "noiseSd": 1, "seed": 7 }
→ degree 1: bias² 0.0054, variance 0.0836, expected error 1.0890
degree 10: bias² 0.0068, variance 0.4493, expected error 1.4561
— the flexibility tax, priced: variance grows five-fold.
For agents: the MCP server
If your program is an AI agent, the same core is also a remote MCP server (Model Context Protocol, streamable HTTP, stateless). Point an MCP client at https://solvedwithstats.com/mcp — no account, no key — and it can call ten tools: descriptive_stats, confidence_interval, welch_t_test, sample_size, power, correlation, regression, p_value, sampling_distribution and bias_variance. Each tool takes the same fields as the API endpoint above it and returns the same numbers, computed by the identical functions — an agent’s answer and this page’s answer cannot drift apart. Nothing an agent sends is stored, logged or tracked, exactly as with the API.
For a generic MCP client that reads a JSON configuration, the connection is one entry:
{
"mcpServers": {
"solvedwithstats": {
"url": "https://solvedwithstats.com/mcp"
}
}
}
Clients that connect over HTTP directly just POST JSON-RPC messages to that URL (initialize, then tools/list, then tools/call). The two simulators are seeded, so an agent that cites a seed can be checked: the same seed always returns the same result.
Terms of use
The API is free to call for ordinary use. It is the same proprietary core as the rest of the site (© 2351485 ALBERTA INC.) — calling it is welcome; republishing its source is not. If you build something on it that matters, pin your expectations to v1: fields within a version do not change meaning, and anything breaking arrives as a new version, never as a silent change.