{
  "schemaVersion": 1,
  "slug": "margin-of-error-calculator",
  "category": "statistics",
  "kind": "implementation",
  "independentValidation": false,
  "implementationHash": "62f80b51388d7ea2c2dbfa7bd69422c6dedc93d6c93627a997d2f328a862c026",
  "provenance": "Generated from the calculation contract used by the published page. Publication is not external validation.",
  "sourceFiles": [
    "data/calculators/margin-of-error-calculator.json",
    "src/engine.js"
  ],
  "runtimeSource": "/sources/engine.txt",
  "runtimeHash": "5c888d8898afbdee36267bb9977829e1e2ac568f6677c8ee87469c139864645c",
  "scope": "The compute function records implemented equations, constants, lookup tables and custom rules. Inputs record defaults and allowed values; outputs record precision and units. Defaults are examples, not recommendations. General background references are not evidence for this specific algorithm.",
  "publishedFormula": {
    "formula": "ME = z × √(p(1 − p) ÷ n × (N − n) ÷ (N − 1)) × 100",
    "vars": [
      [
        "ME",
        "margin of error, percentage points"
      ],
      [
        "z",
        "critical z-value"
      ],
      [
        "p",
        "sample proportion, 0–1"
      ],
      [
        "n",
        "sample size"
      ],
      [
        "N",
        "population size"
      ]
    ],
    "note": "Normal approximation for a simple random sample with finite population correction when N is known. The interval bounds are clipped to 0–100%; design and non-sampling errors are excluded."
  },
  "externalEvidence": {
    "reviewedAt": "2026-10-12",
    "sources": [
      {
        "name": "NIST — Confidence intervals and sampling assumptions",
        "url": "https://www.itl.nist.gov/div898/handbook/prc/section2/prc241.htm"
      }
    ],
    "referenceRole": "context",
    "implementationHash": "62f80b51388d7ea2c2dbfa7bd69422c6dedc93d6c93627a997d2f328a862c026",
    "basis": "ME = z × √(p(1 − p) ÷ n × (N − n) ÷ (N − 1)) × 100",
    "limitations": "The references provide context and limitations. They do not validate this page’s illustrative multipliers, lookup values or predictions."
  },
  "contract": {
    "compute": "const Z={80:1.2816,90:1.6449,95:1.96,99:2.5758},n=sampleSize,p=proportion/100,N=Number(population),z=Z[Number(confidence)];if(!Number.isInteger(n)||n<2||!Number.isFinite(p)||p<0||p>1||!Number.isInteger(N)||N<0||N===1||!z||(N>=2&&n>N))return{marginOfError:null,lower:null,upper:null,standardError:null,criticalValue:null,__error:'inputError'};let se=Math.sqrt(p*(1-p)/n);if(N>=2)se=Math.sqrt(p*(1-p)/n*Math.max(0,(N-n)/(N-1)));const me=z*se*100;return{marginOfError:me,lower:Math.max(0,proportion-me),upper:Math.min(100,proportion+me),standardError:se*100,criticalValue:z};",
    "inputs": [
      {
        "name": "sampleSize",
        "type": "number",
        "default": 500,
        "min": 2,
        "max": 10000000,
        "step": 1
      },
      {
        "name": "proportion",
        "type": "number",
        "default": 50,
        "min": 0,
        "max": 100,
        "step": 1,
        "slider": true
      },
      {
        "name": "confidence",
        "type": "select",
        "default": 95,
        "options": [
          {
            "value": 80
          },
          {
            "value": 90
          },
          {
            "value": 95
          },
          {
            "value": 99
          }
        ]
      },
      {
        "name": "population",
        "type": "number",
        "default": 0,
        "min": 0,
        "max": 2000000000,
        "step": 1
      }
    ],
    "outputs": [
      {
        "name": "marginOfError",
        "precision": 2,
        "unit": "pp"
      },
      {
        "name": "lower",
        "precision": 2,
        "unit": "%"
      },
      {
        "name": "upper",
        "precision": 2,
        "unit": "%"
      },
      {
        "name": "standardError",
        "precision": 3,
        "unit": "pp"
      },
      {
        "name": "criticalValue",
        "precision": 4,
        "unit": ""
      }
    ],
    "interpret": null
  }
}
