Examples
Ready-to-use examples for common SDK use cases. Each example is self-contained and can be dropped into any TypeScript project.
List Skills for a Grade
Section titled “List Skills for a Grade”Fetch all math skills available for Grade 3, with pagination.
import { StudyPlug } from "studyplug";
const sp = new StudyPlug();
let page = 1;let hasMore = true;
while (hasMore) { const { data, pagination } = await sp.skills.list({ grade: "grade-3", subject: "math", page, pageSize: 50, });
for (const skill of data.skills) { console.log(`${skill.slug} — ${skill.name} (${skill.topic.name})`); }
hasMore = pagination?.hasNext ?? false; page++;}Generate a Quiz
Section titled “Generate a Quiz”Build a 10-question quiz from a single skill, print questions and answers.
import { StudyPlug } from "studyplug";
const sp = new StudyPlug();
const { data } = await sp.generate({ skill: "multiply-by-6", grade: "grade-3", count: 10,});
// Print questionsdata.items.forEach((item, i) => { if (item.content.type === "arithmetic") { const b = item.content; console.log(`${i + 1}. ${b.operand1} ${b.operator} ${b.operand2} = ?`); } else if (item.content.type === "multiple-choice") { const b = item.content; console.log(`${i + 1}. ${b.stem}`); b.choices.forEach((c, j) => console.log(` ${"ABCD"[j]}. ${c.text}`)); }});
// Print answer keyconsole.log("\n--- Answer Key ---");data.answerKey.forEach((entry, i) => { console.log(`${i + 1}. ${entry.answer}`);});Generate a Worksheet Batch
Section titled “Generate a Worksheet Batch”Generate content for multiple skills in a single call.
import { StudyPlug } from "studyplug";
const sp = new StudyPlug();
const { data, meta } = await sp.generate({ skills: [ "add-within-20", "subtract-within-20", "compare-two-digit", ], grade: "grade-1", count: 15,});
console.log(`Generated ${data.items.length} items in ${meta.generationTimeMs}ms`);console.log(`Cache hit: ${meta.cacheHit}`);
// Group items by skillconst grouped = new Map<string, typeof data.items>();for (const item of data.items) { const key = item.skill ?? "unknown"; if (!grouped.has(key)) grouped.set(key, []); grouped.get(key)!.push(item);}
for (const [skill, items] of grouped) { console.log(`\n${skill}: ${items.length} items`);}Handle Rate Limits with Retry
Section titled “Handle Rate Limits with Retry”Wrap SDK calls with a retry loop that respects the retryAfter value.
import { StudyPlug, isRateLimitError, isStudyPlugError } from "studyplug";
const sp = new StudyPlug();
async function generateWithRetry( skill: string, count: number, maxAttempts = 3,) { for (let attempt = 1; attempt <= maxAttempts; attempt++) { try { return await sp.generate({ skill, count }); } catch (err) { if (isRateLimitError(err) && attempt < maxAttempts) { console.log(`Rate limited. Waiting ${err.retryAfter}s (attempt ${attempt}/${maxAttempts})`); await new Promise((r) => setTimeout(r, err.retryAfter * 1000)); continue; } throw err; } }}
const result = await generateWithRetry("add-within-10", 20);console.log(`Got ${result!.data.items.length} items`);Search by Standard
Section titled “Search by Standard”Find skills aligned to a CCSS standard and generate content for them.
import { StudyPlug } from "studyplug";
const sp = new StudyPlug();
// Look up a standardconst { data } = await sp.standards.get("3.OA.C.7");const standard = data.standard;
console.log(`${standard.code}: ${standard.description}`);console.log(`Mapped to ${standard.skills.length} skills:`);
for (const skill of standard.skills) { console.log(` - ${skill.name} (${skill.grade.name})`);}
// Generate content aligned to this standardconst { data: content } = await sp.generate({ standard: "3.OA.C.7", count: 10,});
console.log(`\nGenerated ${content.items.length} problems for ${standard.code}`);Deterministic Generation
Section titled “Deterministic Generation”Use seeds to produce identical content across runs. Useful for caching, snapshot tests, and reproducible worksheets.
import { StudyPlug } from "studyplug";
const sp = new StudyPlug();const SEED = 12345;
// These two calls return identical contentconst run1 = await sp.generate({ skill: "add-within-10", count: 5, seed: SEED });const run2 = await sp.generate({ skill: "add-within-10", count: 5, seed: SEED });
// Verify they matchconst match = JSON.stringify(run1.data.items) === JSON.stringify(run2.data.items);console.log(`Deterministic: ${match}`); // trueconsole.log(`Seed used: ${run1.meta.seed}`); // 12345
// Single item is also deterministicconst s1 = await sp.generate.single({ skill: "add-within-10", seed: SEED });const s2 = await sp.generate.single({ skill: "add-within-10", seed: SEED });console.log(`Single match: ${s1.data.item.id === s2.data.item.id}`); // true