---
title: "Results viewer payload"
method: POST
path: "/check/viewer"
tags: ["Results"]
---

# Results viewer payload

`POST /check/viewer`

## Request

- Base URL: `https://codequiry.com/api/v1`
- URL: `https://codequiry.com/api/v1/check/viewer`
- Auth: API key in header `apikey`

Everything the dashboard's results page loads for one submission, in one call: the submission's files (the first one with content inline, the rest fetched through /check/viewer/file), its peer and AI matches, its web sources collapsed to one entry per source, and a rail of every submission in the check carrying the Group, Web and AI scores the dashboard prints beside each name. Built by the same loader as the dashboard, so the two never disagree. Omit submission_id for the highest-scoring submission. Results that are paywalled on the account answer 402 with `paywalled: true`.

## Request body

- object
  - `check_id` integer, required
  - `submission_id` integer: Which submission to load. Omit for the highest-scoring one.

## Response `200`

Viewer payload

- ViewerResults
  - `success` boolean
  - `check` object
    - `id` integer
    - `name` string
    - `status_id` integer
    - `status` string
    - `test_type` integer
    - `language_id` integer
    - `ai_run` boolean
    - `created_at` string, nullable
    - `updated_at` string, nullable
  - `submission` object: The submission being viewed.
    - `id` integer
    - `assignment_id` integer
    - `filename` string
    - `total_result` number
    - `result1` number
    - `result2` number
    - `updated_at` string, nullable
  - `rail` ViewerRailEntry[]
    - `id` integer
    - `filename` string
    - `status_id` integer
    - `status` string
    - `group_score` number
    - `web_score` number
    - `web_score_derived` boolean: true when the engine left no overall web score and the strongest single source is shown instead.
    - `total_result` number
    - `ai_score` number, nullable
    - `ai_max` number, nullable
    - `ai_files` integer
    - `matches_local` integer
    - `matches_web` integer
    - `file_size` integer
    - `created_at` string, nullable
    - `updated_at` string, nullable
  - `submissions` object[]: Minimal sibling list as the dashboard loads it; `rail` carries the scores.
    - `id` integer
    - `filename` string
    - `total_result` number
    - `updated_at` string, nullable
  - `files` ViewerFileEntry[]
    - `id` integer
    - `submission_id` integer
    - `filedir` string
    - `size_bytes` integer
    - `total_lines` integer
    - `content` string: Only the first file carries content (and only under 256KB); fetch the others with /check/viewer/file.
  - `matches` ViewerMatch[]: Peer and AI matches for the viewed submission.
    - `id` integer
    - `submission_id` integer
    - `match_type` integer: 1 peer, 2 database, 3 StackOverflow, 4 GitHub, 5 open web, 6 library, 10 AI block.
    - `similarity` number
    - `matched_similarity` number
    - `file` string
    - `file_matched` string, nullable
    - `submission_id_matched` integer, nullable
    - `line_start` integer
    - `line_end` integer
    - `line_matched_start` integer
    - `line_matched_end` integer
    - `tokens` integer
    - `location` string, nullable
    - `source` string, nullable
    - `flags` string[]: AI-detection flags the engine attached to the block, if any.
    - `is_peer` boolean
    - `is_web` boolean
    - `is_ai` boolean
    - `is_legacy_web` boolean: Web entries only: the id belongs to the legacy web table; pass legacy=true to /check/viewer/counterpart.
    - `has_content` boolean: Web entries only: whether the source's text is stored, which decides whether a side-by-side can be opened.
    - `web_lines` integer: Web entries only: matched lines the engine reported for the whole source.
    - `web_longest` integer: Web entries only: the longest unbroken run of matched lines.
  - `web_files` ViewerMatch[]: Web sources for the viewed submission, one entry per source.
    - `id` integer
    - `submission_id` integer
    - `match_type` integer: 1 peer, 2 database, 3 StackOverflow, 4 GitHub, 5 open web, 6 library, 10 AI block.
    - `similarity` number
    - `matched_similarity` number
    - `file` string
    - `file_matched` string, nullable
    - `submission_id_matched` integer, nullable
    - `line_start` integer
    - `line_end` integer
    - `line_matched_start` integer
    - `line_matched_end` integer
    - `tokens` integer
    - `location` string, nullable
    - `source` string, nullable
    - `flags` string[]: AI-detection flags the engine attached to the block, if any.
    - `is_peer` boolean
    - `is_web` boolean
    - `is_ai` boolean
    - `is_legacy_web` boolean: Web entries only: the id belongs to the legacy web table; pass legacy=true to /check/viewer/counterpart.
    - `has_content` boolean: Web entries only: whether the source's text is stored, which decides whether a side-by-side can be opened.
    - `web_lines` integer: Web entries only: matched lines the engine reported for the whole source.
    - `web_longest` integer: Web entries only: the longest unbroken run of matched lines.
  - `ai_files` object[]: Per-file AI verdicts for the viewed submission.
    - `id` integer
    - `file_path` string
    - `ai_probability` number
    - `human_probability` number
    - `classification` string, nullable
    - `confidence` number, nullable
    - `summary` string, nullable
  - `stats` object
    - `avg` number
    - `max` number
    - `min` number
  - `avg` number
  - `max` number
  - `min` number
  - `dashboard_url` string
  - `meta` object
    - `execution_time_ms` number
    - `cached` boolean
    - `optimized` boolean

## Other responses

- `401`: Missing or invalid API key. The API key is checked before any endpoint logic runs, so this is returned for every operation.
- `402`: Payment required. Either the account is suspended for an unpaid invoice (every endpoint answers this until it is paid), or results are paywalled on this account until it upgrades (the viewer endpoints only). `paywalled` tells the two apart; the request was not performed.
- `404`: Resource not found or not owned by this account.
- `422`: Request validation failed.
- `429`: Rate limit exceeded: more than 60 requests in one minute from this IP. Retry after the number of seconds in the Retry-After header. Successful responses carry X-RateLimit-Limit and X-RateLimit-Remaining too, so you can pace a client without waiting to be refused.

---

[API](https://skmtc.dev/codequiry/apis/codequiry-api.md) · [All operations](https://skmtc.dev/codequiry/apis/codequiry-api/llms.txt) · [OpenAPI document](https://skmtc.dev/codequiry/apis/codequiry-api/revisions/6297e91d9665?raw)
