Code execution
Run untrusted code in a sandbox via CodeEdit — synchronous, no LLM required.
CodeEdit compiles and runs a small set of files in an isolated sandbox and returns the result on the same HTTP response. There is no job id and nothing to poll: if you need an agent, or a run that outlives one request, use the agent runtime or Harbor instead.
Discover the languages
Language ids come from the platform catalog, not from a fixed list in this page —
ask the running deployment rather than guessing, because an id that is not in the
catalog is rejected with 400 unknown catalog entry:
curl -sS -H "Authorization: Bearer $SANDBOX_TOKEN" \
"$SANDBOX_GATEWAY_URL/sandbox/codeedit/v1/languages"Each entry carries the id to send, the entrypoint_file the runner executes,
and the compile and run commands, so you can see exactly what will happen to your
code. At the time of writing dev serves python3.12 and cpp20.
The examples below authenticate with a team token, which is what a consumer holds.
Against a local stack substitute -H "X-Api-Key: dev-local-key"; see
authentication for which credential is which.
Run
files is an object keyed by path, not a list, and one of those paths must be the
language's entrypoint_file (main.py for python3.12, main.cpp for cpp20).
Send as many files as you need alongside it:
export SANDBOX_GATEWAY_URL="${SANDBOX_GATEWAY_URL:-http://localhost:8780}"
curl -sS -H "Authorization: Bearer $SANDBOX_TOKEN" -H "Content-Type: application/json" \
-d '{"language":"python3.12","files":{"main.py":"print(2+2)"}}' \
"$SANDBOX_GATEWAY_URL/sandbox/codeedit/v1/executions"{"status":"ok","exit_code":0,"stdout":"4","stderr":"","duration_ms":5427,"truncated":false}status classifies the outcome, so you do not have to infer it from exit_code:
status | Meaning |
|---|---|
ok | Compiled and exited zero |
compile_error | Never ran; look at stderr |
runtime_error | Ran and exited non-zero, with the code in exit_code |
tle | Exceeded wall_time_ms |
oom | Exceeded memory_mb |
output_limit | Produced more than output_bytes |
sandbox_error | The platform failed, not your code — retryable |
Only sandbox_error means the platform is at fault. The rest are verdicts about
your program and will not change if you retry them. truncated is true when output
was cut at the output_bytes limit, which can accompany any status.
Limits
Every request runs under limits, whether or not you send any. Override them per
request with limits. Values outside the accepted range are rejected with 422,
so the bounds are part of the contract:
| Field | Default | Range | Meaning |
|---|---|---|---|
wall_time_ms | 5000 | 100–30000 | Run time budget |
memory_mb | 256 | 32–1024 | Sandbox memory ceiling |
pids | 64 | 4–512 | Max processes, so a fork bomb cannot take the node |
output_bytes | 1048576 | 1024–2097152 | stdout and stderr are truncated past this |
filesystem_mb | 64 | 4–512 | Writable scratch space |
-d '{"language":"python3.12","files":{"main.py":"..."},"limits":{"wall_time_ms":20000,"memory_mb":1024}}'stdin is a string on the request if your program reads input.
wall_time_ms is not yet a tight bound. The sandbox deadline is currently the
sum of your limit and a fixed 30-second allowance for scheduling and image pull, so
a program that never exits runs for roughly 30 seconds longer than the limit you
set. Because that exceeds the load balancer's own 30-second timeout, a program that
overruns a short limit surfaces as 502 rather than tle. Do not rely on a small
wall_time_ms to bound cost, or to produce a tle verdict, until this is
tightened.
Latency, and the cold start
A warm deployment answers a trivial program in roughly 6 seconds end to end. Most of that is sandbox setup rather than your code — CodeEdit runs each execution in a fresh gVisor-isolated pod, which is what makes it safe to hand it untrusted input, and it is not free.
Budget for the cold case separately. When no sandbox-capable node is warm the
cluster must add one first, which takes tens of seconds and can exceed the load
balancer's 30-second timeout — so the request surfaces as a 502 even though the
platform is healthy and the sandbox was starting normally. This is most likely on
the first request after an idle period. Treat a 502 on this route as retryable:
retry once, and the second attempt lands on the node the first one caused to be
created.
If you are dispatching many executions, expect the first to be slow and the rest not to be, and do not put a synchronous execution on a path where a user is waiting on a hard deadline.
Errors
| Status | Meaning |
|---|---|
400 | unknown catalog entry — the language id is not in this deployment's catalog |
401 | Missing or invalid credential |
422 | Request shape is wrong — most often files sent as a list instead of an object |
429 | Your project is at its concurrency limit; retry after a moment |
502 | Usually a cold start exceeding the proxy timeout — see above, retry once |
Reference: CodeEdit API. See also errors and limits.