Results Viewer
Build plagiarism detection into your apps. Check code against 20+ billion sources.
Results Viewer
Three endpoints that together render a results screen: the payload the Codequiry dashboard's own results page loads for one submission, the text of any of that submission's files, and the other side of any match. Codequiry Desktop's built-in viewer is built on exactly these, so a client built on them shows what the dashboard shows.
The viewer payload
One call returns everything needed to draw a submission: its files (the first one with its text inline, the rest as metadata), its peer and AI matches with line ranges on both sides, its web sources collapsed to one entry per source, per-file AI verdicts, and a rail of every submission in the check carrying the Group, Web and AI scores the dashboard prints beside each name. Omit submission_id to start on the highest-scoring submission.
402 with "paywalled": true and an upgrade_url; other endpoints are unaffected.
| Parameter | Type | Required | Description |
|---|---|---|---|
check_id |
Integer | Required | ID of the check |
submission_id |
Integer | Optional | Which submission to load. Omit for the highest-scoring one. |
Request Example
curl -X POST 'https://codequiry.com/api/v1/check/viewer' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'apikey: YOUR_API_KEY_HERE ' \
-d '{"check_id": 12345, "submission_id": 90271}'
Response
{
"success": true,
"check": { "id": 12345, "name": "Assignment 4", "status_id": 4, "status": "Completed", "test_type": 1, "language_id": 13, "ai_run": true },
"submission": { "id": 90271, "assignment_id": 12345, "filename": "Nowak_Alice_A4", "total_result": "0.00", "result1": "75.00", "result2": "89.00" },
"rail": [
{ "id": 90271, "filename": "Nowak_Alice_A4", "status_id": 4, "status": "Completed", "group_score": 75, "web_score": 89, "web_score_derived": false, "ai_score": 64.3, "ai_max": 91.2, "ai_files": 1, "matches_local": 3, "matches_web": 12 },
{ "id": 90272, "filename": "carter_ben_assignment4", "status_id": 4, "status": "Completed", "group_score": 82, "web_score": 89, "web_score_derived": false, "ai_score": 12.0, "ai_max": 12.0, "ai_files": 1, "matches_local": 3, "matches_web": 13 }
],
"files": [
{ "id": 785285, "submission_id": 90271, "filedir": "nowak_alice_a4/BankAccount.java", "size_bytes": 2310, "total_lines": 96, "content": "package banking;\n..." }
],
"matches": [
{ "id": 1849201, "match_type": 1, "similarity": 82, "matched_similarity": 75, "file": "nowak_alice_a4/BankAccount.java", "file_matched": "carter_ben_assignment4/BankAccount.java", "submission_id_matched": 90272, "line_start": 12, "line_end": 58, "line_matched_start": 10, "line_matched_end": 56, "tokens": 47, "is_peer": true, "is_web": false, "is_ai": false }
],
"web_files": [
{ "id": 1849230, "match_type": 4, "similarity": 89, "file": "nowak_alice_a4/BankAccount.java", "file_matched": "gh/3f9a...java", "location": "GitHub: octocat/bank-account", "source": "https://github.com/octocat/bank-account/blob/main/BankAccount.java", "line_start": 1, "line_end": 40, "is_web": true, "is_legacy_web": false, "has_content": true, "web_lines": 33, "web_longest": 12 }
],
"ai_files": [
{ "id": 5120, "file_path": "nowak_alice_a4/BankAccount.java", "ai_probability": 91.2, "human_probability": 8.8, "classification": "AI-generated", "confidence": 0.93, "summary": "Uniform structure and comment density typical of generated code." }
],
"stats": { "avg": 31.6, "max": 82, "min": 0 },
"dashboard_url": "https://dashboard.codequiry.com/course/57963/assignment/12345/result-drillerv2"
}
Reading the payload
- Group is
result1(similarity to the other submissions in the check). Web isresult2; where the engine recorded no overall web score but did store sources, the strongest single source is shown andweb_score_derivedis true. AI is the mean AI probability over the submission's files. matchesholds peer (match_type1) and AI (10) entries;web_filesholds the external sources (2 database, 3 Stack Overflow, 4 GitHub, 5 web, 6 library), one entry per source.has_contentsays whether a source's text is stored, which decides whether a side-by-side can be opened.- Only the first file carries
content, and only when it is under 256 KB. Fetch the rest with/check/viewer/file.
One submission file
The stored text of one of the submission's own files, by the filedir from the viewer payload. Resolved the way the dashboard resolves it: the engine's cache under every spelling of the path, then the submission's stored archive. Line numbers in the matches map directly onto this text.
| Parameter | Type | Required | Description |
|---|---|---|---|
check_id | Integer | Required | ID of the check |
submission_id | Integer | Required | ID of the submission the file belongs to |
file_path | String | Required | The file's filedir from the viewer payload |
Request Example
curl -X POST 'https://codequiry.com/api/v1/check/viewer/file' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'apikey: YOUR_API_KEY_HERE ' \
-d '{"check_id": 12345, "submission_id": 90271, "file_path": "nowak_alice_a4/Main.java"}'
Response
{
"success": true,
"content": "package banking;\n\npublic class Main {\n ...\n}\n",
"filedir": "nowak_alice_a4/Main.java"
}
The other side of a match
The code a match was found against: the peer submission's file for a peer match, or the cached copy of the external source for a web match, with the line ranges on both sides so you can draw the comparison. AI entries have no counterpart. A web entry flagged is_legacy_web carries an id from a different table; send legacy: true for those.
source URL instead.
| Parameter | Type | Required | Description |
|---|---|---|---|
check_id | Integer | Required | ID of the check |
submission_id | Integer | Required | ID of the submission the match belongs to |
match_id | Integer | Required | The id of an entry in matches or web_files |
legacy | Boolean | Optional | true when the entry's is_legacy_web is true |
Request Example
curl -X POST 'https://codequiry.com/api/v1/check/viewer/counterpart' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'apikey: YOUR_API_KEY_HERE ' \
-d '{"check_id": 12345, "submission_id": 90271, "match_id": 1849201}'
Response
{
"success": true,
"file": {
"content": "package banking;\n\npublic class BankAccount {\n ...\n}\n",
"filedir": "carter_ben_assignment4/BankAccount.java"
},
"match": {
"line_start": 12,
"line_end": 58,
"line_matched_start": 10,
"line_matched_end": 56,
"similarity": 82
}
}
Drawing a comparison
Load the viewer payload, pick a match, fetch its counterpart, and highlight line_start..line_end on the submission's file beside line_matched_start..line_matched_end on the counterpart.
const headers = { apikey: API_KEY, 'Content-Type': 'application/json', Accept: 'application/json' };
const post = (path, body) => fetch('https://codequiry.com/api/v1' + path, { method: 'POST', headers, body: JSON.stringify(body) }).then(r => r.json());
const view = await post('/check/viewer', { check_id: 12345 });
const match = view.matches.find(m => m.is_peer) || view.web_files.find(w => w.has_content);
const other = await post('/check/viewer/counterpart', {
check_id: 12345, submission_id: view.submission.id, match_id: match.id, legacy: !!match.is_legacy_web
});
const left = view.files.find(f => f.filedir === match.file);
const leftText = left.content || (await post('/check/viewer/file', { check_id: 12345, submission_id: view.submission.id, file_path: match.file })).content;
console.log('left lines', match.line_start, '-', match.line_end, 'of', match.file);
console.log('right lines', other.match.line_matched_start, '-', other.match.line_matched_end, 'of', other.file.filedir);