Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.hawkings.education/llms.txt

Use this file to discover all available pages before exploring further.

This guide covers the most common high-stakes flow: a student submits an essay, the AI grades it, a teacher reviews, the gradebook updates.

1. Configure the assignment

const assignment = await hk.assignments.create({
  lesson_id: "lsn_123",
  type: "essay",
  title: "Explain mass-energy equivalence",
  rubric: {
    criteria: [
      { name: "clarity",  weight: 0.4 },
      { name: "accuracy", weight: 0.4 },
      { name: "sources",  weight: 0.2 },
    ],
    scale: { min: 0, max: 10 },
  },
});

await hk.assignments.configure(assignment.id, {
  ai_evaluator: { enabled: true, model: "claude-sonnet-4-6" },
  human_review: "required",   // student doesn't see grade until reviewed
  feedback: { tone: "encouraging", verbosity: "normal" },
});

2. Receive a submission

The student app sends the response:
const submission = await hk.submissions.create({
  assignment_id: assignment.id,
  student_id: "usr_student_42",
  content: { text: studentEssay },
});
If the assignment accepts files:
await hk.submissions.create({
  assignment_id: assignment.id,
  student_id: "usr_student_42",
  content: { text: "" },
  files: [{ name: "essay.pdf", body: fileBlob, content_type: "application/pdf" }],
});

3. Trigger AI grading

await hk.submissions.gradeWithAi(submission.id);
This is async. Subscribe to the submission.graded webhook for production, or poll for prototypes:
const graded = await hk.poll(
  () => hk.submissions.retrieve(submission.id),
  { until: s => s.ai_status === "ready" || s.ai_status === "error" },
);

4. Show the teacher

console.log(graded.grade_ai);             // 8.5
console.log(graded.grading_rationale);    // markdown breakdown
console.log(graded.grading_breakdown);    // [{criterion, score, max}, ...]
Render grading_rationale as markdown next to the student’s text. The teacher gets context, not a black box.

5. Teacher confirms or overrides

await hk.submissions.update(submission.id, {
  grade_manual: 9.0,                                     // override
  grader_comments: "Great link to E=mc² in the closing.", // markdown
  human_review_status: "reviewed",
});
If the teacher accepts the AI’s grade verbatim:
await hk.submissions.update(submission.id, {
  grade_manual: graded.grade_ai,
  human_review_status: "reviewed",
});
Or, if you want to skip the override and trust the AI:
await hk.submissions.update(submission.id, { human_review_status: "reviewed" });
// `grade_manual` stays null; the gradebook reads from `grade_ai`.

6. Read the final grade

The SDK abstracts the precedence rule:
const sub = await hk.submissions.retrieve(submission.id);
console.log(sub.final_grade);   // grade_manual ?? grade_ai
final_grade is null while human_review_status === "pending" if the assignment requires human review. That’s what your student-facing UI should read.

At scale: grade a whole class

const subs = (await hk.submissions.list({ assignment_id: assignment.id })).data;

await Promise.all(
  subs.map(s => hk.submissions.gradeWithAi(s.id)),
);

await hk.poll(
  () => hk.submissions.list({ assignment_id: assignment.id }),
  { until: page => page.data.every(s => s.ai_status === "ready") },
);

// Now show the teacher a queue of submissions ranked by edge cases:
const needsReview = subs.filter(s => s.grading_breakdown.some(c => c.score / c.max < 0.5));

Tips

Pin the model. AI grades drift between model versions. If you need audit-grade reproducibility, pass model: "claude-sonnet-4-6" (or similar) in the assignment config.
Show the rubric to the student before they submit. A 30% increase in rubric-aligned answers is typical.
Never auto-publish AI grades on consequential assessments. The human_review: "required" flag exists for a reason. Use it.