Skip to content

Examples

Ready-to-use examples for common SDK use cases. Each example is self-contained and can be dropped into any TypeScript project.

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++;
}

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 questions
data.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 key
console.log("\n--- Answer Key ---");
data.answerKey.forEach((entry, i) => {
console.log(`${i + 1}. ${entry.answer}`);
});

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 skill
const 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`);
}

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`);

Find skills aligned to a CCSS standard and generate content for them.

import { StudyPlug } from "studyplug";
const sp = new StudyPlug();
// Look up a standard
const { 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 standard
const { data: content } = await sp.generate({
standard: "3.OA.C.7",
count: 10,
});
console.log(`\nGenerated ${content.items.length} problems for ${standard.code}`);

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 content
const 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 match
const match = JSON.stringify(run1.data.items) === JSON.stringify(run2.data.items);
console.log(`Deterministic: ${match}`); // true
console.log(`Seed used: ${run1.meta.seed}`); // 12345
// Single item is also deterministic
const 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