Creating an assignment
Submitting
A student submits withsubmissions.create():
Documentation Index
Fetch the complete documentation index at: /llms.txt
Use this file to discover all available pages before exploring further.
Gradable artefacts: rubrics, due dates, AI grading, human-in-the-loop.
Assignment "Essay: explain Lorentz invariance"
├─ Submission (student A) → grade 8.5 (AI), 9.0 (human override)
├─ Submission (student B) → grade 6.5 (AI)
└─ Submission (student C) → grade 0 (not submitted yet)
await hk.assignments.create({
lesson_id: "lsn_123",
type: "essay",
title: "Explain Lorentz invariance in your own words",
due_at: "2026-06-01T23:59:00Z",
rubric: {
criteria: [
{ name: "clarity", weight: 0.4 },
{ name: "physics accuracy", weight: 0.4 },
{ name: "use of sources", weight: 0.2 },
],
scale: { min: 0, max: 10 },
},
});
$hk->assignments->create([
'lesson_id' => 'lsn_123',
'type' => 'essay',
'title' => 'Explain Lorentz invariance in your own words',
'due_at' => '2026-06-01T23:59:00Z',
'rubric' => [
'criteria' => [
['name' => 'clarity', 'weight' => 0.4],
['name' => 'physics accuracy', 'weight' => 0.4],
['name' => 'use of sources', 'weight' => 0.2],
],
'scale' => ['min' => 0, 'max' => 10],
],
]);
await hk.assignments.configure(assignmentId, {
ai_evaluator: { enabled: true, model: "claude-sonnet-4-6" },
human_review: "required" | "optional" | "off",
});
$hk->assignments->configure($assignmentId, [
'ai_evaluator' => ['enabled' => true, 'model' => 'claude-sonnet-4-6'],
'human_review' => 'required', // 'required' | 'optional' | 'off'
]);
submissions.create():
await hk.submissions.create({
assignment_id: "asg_123",
student_id: "usr_123",
content: { text: "Lorentz invariance means that the laws of physics ..." },
});
$hk->submissions->create([
'assignment_id' => 'asg_123',
'student_id' => 'usr_123',
'content' => ['text' => 'Lorentz invariance means that the laws of physics ...'],
]);
await hk.submissions.gradeWithAi(submissionId);
const sub = await hk.submissions.retrieve(submissionId);
// sub.grade_ai → 8.5
// sub.grading_rationale → markdown explanation, criterion-by-criterion
$hk->submissions->gradeWithAi($submissionId);
$sub = $hk->submissions->retrieve($submissionId);
// $sub->grade_ai → 8.5
// $sub->grading_rationale → markdown explanation, criterion-by-criterion
await hk.submissions.update(submissionId, {
grade_manual: 9.0,
grader_comments: "Strong on conceptual clarity; missed the bit on simultaneity.",
});
$hk->submissions->update($submissionId, [
'grade_manual' => 9.0,
'grader_comments' => 'Strong on conceptual clarity; missed the bit on simultaneity.',
]);
await hk.submissions.bulk({
assignment_id: "asg_123",
rows: classSubmissions.map(s => ({
submission_id: s.id,
grade_manual: s.draftScore,
grader_comments: s.feedback,
})),
});
$hk->submissions->bulk([
'assignment_id' => 'asg_123',
'rows' => array_map(fn ($s) => [
'submission_id' => $s->id,
'grade_manual' => $s->draftScore,
'grader_comments' => $s->feedback,
], $classSubmissions),
]);
// 1. AI grades all of them
for (const sub of submissions) {
await hk.submissions.gradeWithAi(sub.id);
}
// 2. Show teacher the AI grade + rationale; teacher confirms or edits
// in your UI
// 3. Save with a manual grade (optional) and mark reviewed
await hk.submissions.update(submissionId, {
grade_manual: teacherDecision.score,
grader_comments: teacherDecision.notes,
human_review_status: "reviewed",
});
// 1. AI grades all of them
foreach ($submissions as $sub) {
$hk->submissions->gradeWithAi($sub->id);
}
// 2. Show teacher the AI grade + rationale; teacher confirms or edits
// in your UI
// 3. Save with a manual grade (optional) and mark reviewed
$hk->submissions->update($submissionId, [
'grade_manual' => $teacherDecision->score,
'grader_comments' => $teacherDecision->notes,
'human_review_status' => 'reviewed',
]);
Submission includestype Submission = {
id: string;
assignment_id: string;
student_id: string;
content: SubmissionContent;
files: File[];
grade_ai: number | null;
grade_manual: number | null;
grading_rationale: string | null; // markdown, AI-generated
grader_comments: string | null; // markdown, human-written
human_review_status: "pending" | "reviewed" | "off";
ai_status: "pending" | "ready" | "error";
evaluated_at: string | null; // ISO 8601
uploaded_at: string; // ISO 8601
};