Judge0 migration guide

Migrating from Judge0 to OnlineCompiler.io

If your judge, course or assessment platform calls Judge0, hosted, on RapidAPI or on your own servers, you can move it by changing the base URL and the key. OnlineCompiler.io answers Judge0's submission, batch, language and status endpoints in Judge0's own shapes. Here's what carries over, what doesn't, and how the language ids map.

By the OnlineCompiler.io team. Updated . We make OnlineCompiler.io, so we're one of the options here. Every competitor figure links to the vendor's own page, and we say where our API falls short.

Change the base URL and the key

before.js
// Judge0 CE on RapidAPI (or your own Judge0 server)
const JUDGE0_URL = "https://judge0-ce.p.rapidapi.com";
const headers = {
  "x-rapidapi-key": process.env.RAPIDAPI_KEY,
  "x-rapidapi-host": "judge0-ce.p.rapidapi.com",
  "Content-Type": "application/json",
};
after.js
// OnlineCompiler.io
const JUDGE0_URL = "https://api.onlinecompiler.io/api/judge0";
const headers = {
  "X-Auth-Token": process.env.ONLINECOMPILER_API_KEY,
  "Content-Type": "application/json",
};

Send your OnlineCompiler.io API key in X-Auth-Token, the header self-hosted Judge0 uses, or in Authorization. Requests, tokens, polling, batches, base64_encoded, fields and callbacks keep working:

judge.js
// The rest of your Judge0 code stays as it is: submit, then poll by token.
const b64 = (s) => Buffer.from(s).toString("base64");
const submit = await fetch(`${JUDGE0_URL}/submissions?base64_encoded=true`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    language_id: 71, // runs on Python 3.14
    source_code: b64("print(int(input()) * 2)"),
    stdin: b64("21"),
    expected_output: b64("42"),
    cpu_time_limit: 2,
  }),
});
const { token } = await submit.json();

let result;
do {
  await new Promise((resolve) => setTimeout(resolve, 500));
  result = await (await fetch(`${JUDGE0_URL}/submissions/${token}?base64_encoded=true`, { headers })).json();
} while (result.status.id <= 2);

console.log(result.status.description); // "Accepted"
wait.js
// Or skip the polling: wait=true answers with the finished submission.
const res = await fetch(`${JUDGE0_URL}/submissions?wait=true`, {
  method: "POST",
  headers,
  body: JSON.stringify({ language_id: 71, source_code: "print(int(input()) * 2)", stdin: "21" }),
});
const { status, stdout, time, memory } = await res.json();

wait=true is switched off on ce.judge0.com, so Judge0 code always polls. Here it works, which saves a round trip per submission. The API docs list every endpoint.

What's different

  • Current versions. Old ids run on today's version: 71 (Python 3.8) runs on Python 3.14, 62 (Java 13) on Java 25 and 51 (C# on Mono) on .NET 9. Code written for an old version usually runs unchanged, but check for APIs the language has since removed.
  • Fixed limits. Every run gets 30 seconds, 512 MB and 2 CPUs. cpu_time_limit and wall_time_limit decide Time Limit Exceeded by comparing the run's time; memory_limit and the other limits are accepted and ignored.
  • time is wall-clock seconds of the run command, not CPU time. For Java, F# and TypeScript it includes compiling, which they do as they start.
  • Compilation Error (6) comes with compile_output for C, C++, C#, Go, Rust and Haskell, which compile before the run. Java, F# and TypeScript compile as they run, so their compile errors are Runtime Error (NZEC), with the message in stderr.
  • One source file. additional_files (and so multi-file programs, language 89), compiler_options, command_line_arguments and enable_network answer 422.
  • Batches hold up to 20 submissions and no more than your account's pending limit (8 on Free). A batch is admitted whole or not at all, so a 429 means none of it was queued.
  • Output is kept up to 64 KB per stream; when it's cut, message says so.
  • 12 languages against Judge0 CE's 71. Check the language table first.
  • Not there: listing and deleting submissions, /config_info, /about and /workers. compile_cmd and run_cmd are null in /languages/{id}; the docs list our commands.

How each status is decided

Judge0 statusWhen OnlineCompiler.io returns it
1 In QueueUntil the run finishes. 2 Processing is never returned.
3 Accepted / 4 Wrong AnswerExit code 0; with expected_output, compared ignoring trailing whitespace on each line and at the end
5 Time Limit ExceededStopped at 30 seconds, or time over your cpu_time_limit or wall_time_limit
6 Compilation ErrorCompiling failed, in C, C++, C#, Go, Rust or Haskell
7 SIGSEGV, 9 SIGFPE, 10 SIGABRTThe program was killed by signal 11, 8 or 6
8 SIGXFSZThe program printed more than 8 MB
11 NZECAny other non-zero exit code
12 OtherAny other signal, such as 9 when the program used more than 512 MB
13 Internal ErrorThe run failed on our side; message says why

Judge0 has no Memory Limit Exceeded status, and neither does this API: a program killed at the memory limit gets 12 with exit_signal 9. Account limits and busy servers answer HTTP 429 as {"error": "..."}; retry those with backoff.

Callbacks

Send callback_url as you do now. When the run finishes, the submission's default fields are sent to it with a PUT, base64-encoded, as Judge0 does. Delivery is attempted up to 4 times, 10 seconds apart. Callback URLs must be public HTTP(S) addresses of up to 200 characters, and they can't be combined with wait=true, where the result is in the response.

Coming from Judge0 on RapidAPI

Swap https://judge0-ce.p.rapidapi.com for https://api.onlinecompiler.io/api/judge0, and the x-rapidapi-key and x-rapidapi-host headers for X-Auth-Token. Judge0 CE on RapidAPI has no free plan and starts at $44.99 a month for 2,000 submissions a day, and Judge0's own hosted plans start at €27 a month for the same daily quota. OnlineCompiler.io is free up to 100,000 runs a month and counts by month, not by day, so a deadline spike doesn't hit a daily cap.

Language ids

/languages lists the newest id for each language. The older ids run too, on the same current version, and /languages/all lists them as archived.

Judge0 language_idJudge0 versionOlder idsRuns on
113Python (3.14.0)109, 100, 92, 71Python 3.14 (python-3.14)
103C (GCC 14.1.0)50, 49, 48C GCC 15 (gcc-15)
105C++ (GCC 14.1.0)54, 53, 52C++ G++ 15 (g++-15)
91Java (JDK 17.0.6)62Java OpenJDK 25 (openjdk-25)
51C# (Mono 6.6.0.161)C# .NET SDK 9 (dotnet-csharp-9)
87F# (.NET Core SDK 3.1.202)F# .NET SDK 9 (dotnet-fsharp-9)
107Go (1.23.5)106, 95, 60Go 1.26 (go-1.26)
108Rust (1.85.0)73Rust 1.93 (rust-1.93)
98PHP (8.3.11)68PHP 8.5 (php-8.5)
72Ruby (2.7.0)Ruby 4.0 (ruby-4.0)
61Haskell (GHC 8.8.1)Haskell GHC 9.12 (haskell-9.12)
101TypeScript (5.6.2)94, 74TypeScript Deno (typescript-deno)
102JavaScript (Node.js 22.08.0)97, 93, 63TypeScript Deno (typescript-deno)

JavaScript runs on Deno, as TypeScript does, so Node-only APIs such as require() may not work. For how Judge0 compares with other hosted APIs, see Judge0 alternatives.

Moving to the native API instead

If you'd rather drop the Judge0 shapes, POST /api/run-code-sync/ takes a compiler id, code and input as plain JSON and returns the output in the response. The fields map like this:

Judge0Native API
language_idcompiler, such as python-3.14 (table above)
source_code, stdincode, input, as UTF-8 strings, up to 100 KB each
expected_outputNot accepted; compare output yourself
callback_urlSet once on your API key; use POST /api/run-code/
stdoutoutput (truncated is true when cut)
stderr, compile_outputerror, both in one field
exit_code, exit_signalexit_code, signal
statusstatus is "success" or "error"; work out the rest from exit_code and signal
time, wall_time, memorytime, total (seconds, as strings) and memory (KB, as a string)

See the API docs for the rest of the native API.

Frequently asked questions

Is OnlineCompiler.io compatible with the Judge0 API?

Yes, for what most integrations use: submissions with tokens or wait=true, batches, base64_encoded, fields, expected_output, callbacks, languages and statuses, at https://api.onlinecompiler.io/api/judge0. Send your key in X-Auth-Token or Authorization. Per-run limits other than time, compiler options, command-line arguments and multi-file programs are not supported.

Does OnlineCompiler.io compare expected_output like Judge0?

Yes. It ignores trailing whitespace on each line and at the end, as Judge0 does, and answers Accepted (3) or Wrong Answer (4).

How do I set a 1 or 2 second time limit?

Send cpu_time_limit or wall_time_limit as you do now. Programs still run for up to 30 seconds, and a submission whose time is over your limit gets Time Limit Exceeded (5). time is wall-clock seconds for the run command, so give Java, F# and TypeScript a little more room: they compile as they start.

Does it support Judge0 batch submissions?

Yes: POST /submissions/batch and GET /submissions/batch?tokens=. A batch holds up to 20 submissions and no more than your account's pending limit (8 on Free), and it is admitted whole or not at all.

How much cheaper is it than Judge0 on RapidAPI?

Judge0 CE on RapidAPI has no free plan and starts at $44.99 a month for 2,000 submissions a day. OnlineCompiler.io is free up to 100,000 runs a month, commercial use included, and Pro is $49 a month for 1,000,000.