Submissions
A submission is a program sent in for a problem, together with everything the judge recorded while running it. It is created once and read from then on: the same object gains a status, then per-test results, then a verdict and a score.
Submissions live in the same atlas API as the problems they belong to, and like problems they are addressed against the space:
https://api.eolymp.com/spaces/<space-id>/submissions
Contest submissions use the same service with the contest as the base URL instead, so one code path serves both practice and competition. Reads need the atlas:submission:read scope, creating needs atlas:submission:write.
Creating a submission
CreateSubmission takes the problem, the runtime to compile with, and the source:
out = submissions.CreateSubmission(request=eolymp.atlas.CreateSubmissionInput(
problem_id=problem_id,
lang="cpp:20-gnu14", # a runtime id, not a language name
source=source,
))
print(out.submission_id)lang takes a runtime id such as cpp:20-gnu14 or python:3.13-python, not a language name. The ids a particular problem accepts come from ListRuntimes on the problem, a narrower set than the platform-wide list.
The call returns nothing but an id; evaluation happens afterwards, in the background. Two limits apply to code that submits in a loop: the request body caps at 5 MB, and submissions are rate limited per account to roughly one every six seconds with a burst of five. A space can add a per-IP limit on top of that through the atlas configuration.
Problems whose submission form asks for more than plain source — an uploaded answer file for an output-only problem, or code with attachments — take that input through values instead, following the form described on the problem.
Status and verdict
status and verdict are distinct fields, and the distinction governs how a submission is read.
status says how far evaluation has got, and describes the machinery rather than the program.
| Status | Meaning |
|---|---|
PENDING | queued, nothing has happened yet |
PROVISIONING, INITIALIZING | the environment and program are being set up |
TESTING | running against the tests |
COMPLETE | finished, and score is populated |
ERROR | the program failed — a compilation error, for instance; error and error_url carry the detail |
TIMEOUT | evaluation itself took too long, with too many tests timing out |
FAILURE | a system or problem-configuration fault, not the program's fault |
SKIPPED, BLOCKED | not evaluated, because an earlier test or a testset dependency failed |
verdict is the outcome of an evaluation that ran to completion, and it stays NO_VERDICT until there is one.
| Verdict | Meaning |
|---|---|
ACCEPTED | correct answer |
WRONG_ANSWER | incorrect answer |
TIME_LIMIT_EXCEEDED | ran past the wall-clock limit |
CPU_EXHAUSTED | ran past the CPU limit |
MEMORY_OVERFLOW | used too much memory |
RUNTIME_ERROR | finished with an error |
NO_VERDICT | not judged |
An unjudged submission therefore has a status and no verdict. Code that reads verdict without checking status first reads NO_VERDICT and draws the wrong conclusion.
Other submission fields
Beyond those two:
- Identity —
id,problem_id,submitted_at,judged_at, and asubmitterwhich is either auser_idor amember_iddepending on whether an Eolymp account or a space member sent it. - The program —
lang,source_url(the code is fetched from there; the inlinesourcefield is deprecated),valuesfor form-based submissions, and asignature. - Score —
scoreis what was earned,costis the maximum that was available,percentageis the ratio. - Resource usage —
time_usageandcpu_usagein milliseconds,memory_usagein bytes,resource_usageas a combined figure. Each is the maximum across the runs. version— a counter that only ever increases, which identifies the newer of two snapshots that arrive out of order.
Groups and runs
The per-test detail is two levels deep. A group is the result of one testset, and a run is one test inside it.
A group carries its own status and verdict, its score against the cost available, the scoring_mode and feedback_policy it was evaluated under, the testset dependencies it waited on, and its own resource-usage figures. Its runs hold the individual tests, each with a verdict, resource usage, score, and URLs for the input it was fed, the output it produced and the expected answer.
How much of this comes back is not controlled by the request. It is decided by the testset's feedback_policy and by the caller: a caller who may edit the problem sees every run, while a participant on an ICPC-feedback testset sees only the first test that failed. Source code and debug output are likewise omitted for callers not allowed to see them, so the same submission legitimately looks different to different callers.
On ListSubmissions, and when following a submission, groups and runs are opt-in through the extra field — request GROUPS or RUNS to receive them. DescribeSubmission does not take extra; it returns whatever the caller's permissions allow.
Following a submission
Judging can be followed in two ways.
Polling DescribeSubmission is the straightforward one: call it until status reaches a final value.
while True:
submission = submissions.DescribeSubmission(request=eolymp.atlas.DescribeSubmissionInput(
submission_id=submission_id,
)).submission
if submission.status in (eolymp.atlas.Submission.COMPLETE, eolymp.atlas.Submission.ERROR):
break
time.sleep(1)As an alternative to polling, the SDKs can follow a submission as it is evaluated and deliver each new state as it arrives, which is how a UI shows a verdict appearing live.
Finding submissions
ListSubmissions returns the space's submissions newest first, with filters on id, problem_id, user_id, member_id, submitted_at, runtime, status, verdict, score and percentage.
Two details affect how results are read. A caller without space-wide permission to read submissions gets only their own, and without an error, so an empty-looking result does not necessarily mean an empty space. For deep listings, feed the previous page's after cursor into the next request rather than walking offset; the cursor skips counting the total and stays fast.
Rejudging
RetestSubmission re-runs an existing submission — "rejudge" in the console. The result is recomputed in place: the id, the submission time and the position in listings all stay as they were. It returns as soon as evaluation is queued, and is followed the same way as a new submission.
Counting and charting
Three methods report aggregates directly, without listing every submission and counting it.
AggregateSubmissions reports a metric per group over a time range, with up to two grouping dimensions, and returns empty time buckets as zeroes rather than skipping them, which suits charting. Reading analytics takes its own permission, broader than being able to see the submissions.
ListProblemTop returns up to 25 submissions that scored a problem in full, most efficient first, ranked by resource usage with ties going to whoever solved it earlier. It backs "best solutions" boards. Partial and unfinished submissions never appear, and it can be neither filtered nor paged.
DescribeSubmissionUsage reports how much evaluation the space has consumed against what its subscription allows, over the subscription's current quota period — or the last 30 days when there is no subscription.
Updated 8 days ago
