Docs

Run tests: judge code against test cases

POST /api/run-tests/ runs one program against a list of tests, each in a fresh sandbox, and returns a verdict for each test, an overall verdict and a score from 0 to 100. Hidden tests come back with only their verdict, and each test counts as one run.

POST https://api.onlinecompiler.io/api/run-tests/

Run one program against a list of tests and get a verdict for each, an overall verdict and a score, in one request. It authenticates like the sync endpoint and always waits for the result. Each test runs in its own fresh sandbox, and each test counts as one run against your monthly allowance and your per-minute and pending limits. Each test takes one of your account's pending slots when the request arrives and frees it when that test finishes, so on Free one 8-test request starts out using all of them, and your other runs (the widget's included) wait or get 429 until its tests start finishing.

FieldTypeRequiredDescription
compilerstringYesA compiler id, as on the other endpoints.
codestringYesSource code (max 100KB). Compiled in every test, or once per request for C, C++ and Java when there are more tests than run at once.
testsarrayYesThe tests to run, 1 up to your plan's limit (table below).
tests[].inputstringNoStandard input for this test (max 100KB). Empty if left out.
tests[].expected_outputstringYesWhat the program should print (max 64KB). Stderr is never compared.
tests[].hiddenbooleanNofalse if left out. A hidden test returns only its verdict.
tests[].weightnumberNoAbove 0; 1 if left out. Counts only for weighted scoring.
time_limitnumberNoSeconds each test may run, above 0 and up to 30; 2 if left out. Java, Groovy and F# get a start-up allowance on top (see below).
checkerstringNoHow output is compared: trim (the default), exact, tokens or float.
tolerancenumberNoFor the float checker: 0 to 1; 1e-6 if left out.
scoringstringNoall_or_nothing (the default), percent or weighted.
stop_on_failurebooleanNoStop starting tests after the first one that is not accepted. true with all_or_nothing, false otherwise.

Limits for one request

PlanTests per requestRun at onceMost tests at the default time_limit
Free828
Starter20320
Pro40330
Business80330

The last column is for a language with the default round overhead of 3 seconds and no start-up allowance, such as Python or C++. Languages that compile slowly fit fewer tests (see below).

  • The number of tests is capped by your plan's pending limit. Tests run in the order you list them, at most as many at once as the table shows, and never more than your plan's runs at once.
  • One request has a 60-second budget. Tests run in rounds (tests divided by tests at once, rounded up), and a round takes up to time_limit + start-up allowance + the language's round overhead for compiling and starting. All the rounds must fit in 60 seconds, and the last must be able to start within 45. A request over budget gets 400 with the largest time_limit that would fit.
  • The round overhead is 3 seconds, except for languages that compile slowly: Crystal (13 s), Kotlin (6 s), Nim (5.5 s), Zig (4.5 s), Scala (4 s), C# (4 s) and Visual Basic (4 s). Each test compiles the program again, so these fit fewer tests; at the default time_limit, a Crystal request holds at most 12 tests on Pro.
  • C, C++ and Java compile once per request when there are more tests than run at once: one sandbox compiles the program, without any test input, then each test runs the build in its own fresh sandbox. If a C or C++ compile fails, the first test gets the verdict and counts as one run, and the rest are skipped; a Java program that fails to compile runs as before, compiling in every test. A request whose tests all run at once compiles in every test, which is faster for so few tests.
  • No test starts after 45 seconds from the request's arrival. Tests that never started are skipped, are not counted as runs and leave no history. When the cut-off skipped tests and none failed, the overall verdict is incomplete. The budget leaves time for every round, so this usually means tests waited for a sandbox, held by other users or by your account's other runs: retry the request. A retry runs, and counts, every test again.
  • A compilation error stops the remaining tests, because they would fail the same way. With stop_on_failure, the first test that is not accepted does too.
  • Inputs and expected outputs together may hold at most 1 MB.
  • A bad request answers 400 with {"error": "..."} and starts nothing. Account limits and a busy host answer 429, and nothing runs.

Verdicts

Each test gets one verdict, decided in the order of this table (accepted and wrong_answer last). The last column is the Judge0 status id it maps to.

VerdictWhenJudge0 id
internal_errorWe could not run the test.13
compilation_errorCompiling failed (languages with a compile step; a syntax error in an interpreted language is a runtime_error).6
time_limit_exceededExit code 124, or the run took longer than the time limit plus any start-up allowance.5
memory_limit_exceededKilled at the 512 MB memory limit (exit code 137). Judge0 has no memory status, so it reports 12.12
output_limit_exceededSignal 25, or stdout was cut at 64KB.8
runtime_errorAny other non-zero exit code or signal.7 to 12
wrong_answerExit code 0 and the checker rejects the output.4
acceptedExit code 0 and the checker accepts the output.3
skippedThe test never started: the program failed to compile, or failed with stop_on_failure, or the start cut-off came first. Test entries only; it counts as not accepted.none
incompleteOverall verdict only: the start cut-off skipped tests and none failed, usually because the host or your account's other runs kept the sandboxes busy. Retry the request.none

Checkers and scoring

checkerCompares
trimStrips trailing whitespace from every line and trailing blank lines, then compares exactly. The default; it is what Judge0 does.
exactThe two outputs are identical, byte for byte.
tokensSplits both on whitespace and compares the lists, so spacing and line breaks do not matter.
floatAs tokens, but two numbers match when they differ by at most tolerance times the larger of 1 and the expected value. Anything that is not a finite number must match as text.
scoringscore
all_or_nothing100 when every test is accepted, otherwise 0.
percent100 times accepted tests over all tests.
weighted100 times the weights of accepted tests over all weights.

Response (200)

FieldDescription
verdictThe overall verdict: accepted when every test is, otherwise the verdict of the first test (in your order) that failed. incomplete when tests were skipped only by the 45-second start cut-off, usually because the host or your account's other runs kept the sandboxes busy; retry the request.
scoreFrom 0 to 100, rounded to 2 decimals. Skipped tests count as not accepted.
passed, totalTests accepted, and tests sent.
time_limitThe time limit used, in seconds, without the start-up allowance.
compile_errorThe compiler output (first 4096 characters) when the code failed to compile and at least one test is visible; null otherwise. A request that compiles in every test takes it from the first visible test that failed to compile, so there it is also null when only hidden tests did.
testsOne entry per test, in the order sent. Each has verdict and hidden. A visible test that ran also has time, memory, exit_code, signal, output, error and truncated.
Response
{
  "verdict": "runtime_error",
  "score": 33.33,
  "passed": 1,
  "total": 2,
  "time_limit": 2,
  "compile_error": null,
  "tests": [
    {"verdict": "accepted", "hidden": false, "time": "0.0213", "memory": "9000",
     "exit_code": 0, "signal": null, "output": "3
", "error": "", "truncated": false},
    {"verdict": "runtime_error", "hidden": true}
  ]
}

Inputs and expected outputs are not sent back. output and error are cut to the first 4096 characters, and truncated is true when either was cut. time and memory are strings, as on the sync endpoint. The response above is for the examples below: the hidden test puts the two numbers on separate lines, which the program does not read, so it ends in a runtime_error and the score is 1 of 3 weight points.

Hidden tests return only their verdict. A hidden test, and a skipped one, comes back as {"verdict": ..., "hidden": ...} and nothing else: no output, error, exit code, time or memory. Compiler output from a compile that saw a hidden test's input never appears in compile_error; a request that compiles once compiles without any test input, so a failed compile's output appears in compile_error whenever a test is visible. A program can encode a hidden input in anything it controls, so a student's code cannot read a hidden test back through your results.

Start-up allowance for Java, Groovy and F#

These three compile as they start, inside the timed run, so even a hello-world uses part of a small time_limit. They get extra seconds on top of the limit: Java (1 s), Groovy (1.5 s) and F# (2.5 s). The run is stopped at time_limit plus the allowance, and a test is time_limit_exceeded only past that. time is still reported as measured, start-up included, and the response's time_limit is the one you asked for. The allowance applies wherever a time limit is honoured: here, the native time_limit on the run endpoints, and the Judge0 and Piston layers. In run-tests requests that compile once, Java compiles before the timed run, so its time is lower there; the allowance still applies everywhere for now. We will remove it once compiling always happens before the timed run.

Examples

Terminal
curl -X POST https://api.onlinecompiler.io/api/run-tests/ \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "compiler": "python-3.14",
    "code": "a, b = map(int, input().split())\nprint(a + b)",
    "tests": [
      {"input": "1 2\n", "expected_output": "3\n"},
      {"input": "5\n7\n", "expected_output": "12\n", "hidden": true, "weight": 2}
    ],
    "scoring": "weighted"
  }'
JavaScript
const res = await fetch('https://api.onlinecompiler.io/api/run-tests/', {
  method: 'POST',
  headers: { Authorization: 'YOUR_API_KEY', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    compiler: 'python-3.14',
    code: 'a, b = map(int, input().split())\nprint(a + b)',
    tests: [
      { input: '1 2\n', expected_output: '3\n' },
      { input: '5\n7\n', expected_output: '12\n', hidden: true, weight: 2 }
    ],
    scoring: 'weighted'
  })
});
const result = await res.json();
console.log(result.verdict, result.score, result.passed + '/' + result.total);

Questions

Does each test count as a run?
Yes. A request with 10 tests uses 10 runs of your monthly allowance and 10 of your per-minute and pending limits. Tests that never started, such as those skipped after a compile error, are not counted.
How many tests can one request hold?
Up to your plan's pending limit: 8 on Free, 20 on Starter, 40 on Pro, 80 on Business. They must also fit the request's 60-second budget, so a long time_limit or a slow-compiling language fits fewer; the table above shows the most at the default time limit.
Can students see the hidden tests?
No. A hidden test returns only its verdict: no output, error, time or memory. compile_error is filled in only when at least one test is visible.
How is the output compared?
trim, the default, strips trailing whitespace from each line and trailing blank lines, then compares exactly. exact compares byte for byte, tokens ignores all spacing and line breaks, and float accepts numbers within a tolerance.