Skip to content

Deterministic Generation

The StudyPlug API generates content on demand. Without determinism, every request produces different problems — useful for variety, but problematic when you need:

  • Caching — Identical requests should return cached responses without regenerating content.
  • Testing — Automated tests need predictable output to assert against.
  • Sharing — A teacher shares a worksheet link. Every viewer must see the same problems.
  • Debugging — Reproduce an exact set of items to investigate a reported issue.
  • Answer keys — The problems on page 1 must match the answers on page 2.

Seeds solve all of these. Pass a seed parameter, and the API guarantees the same input produces the same output, every time.

Include an integer seed in your generation request:

Terminal window
curl -X POST https://api.studyplug.org/api/v1/generate \
-H "Content-Type: application/json" \
-d '{
"skill": "add-within-20",
"grade": "grade-1",
"count": 5,
"seed": 42
}'

The response includes the seed in meta for traceability:

{
"data": {
"items": [ ... ],
"answerKey": [ ... ],
"metadata": {
"skill": "add-within-20",
"grade": 1,
"totalGenerated": 5
}
},
"meta": {
"requestId": "req_x7k9m2",
"generatedAt": "2026-02-23T14:30:00Z",
"seed": 42,
"apiVersion": "v1",
"cacheHit": false,
"generationTimeMs": 18
}
}

Call the same endpoint with the same seed, skill, grade, and count tomorrow, next month, or next year — you get the same five problems with the same numbers, same wording, and same answer key.

Same seed + same parameters = same output. Specifically, all of the following must match:

ParameterEffect on Output
seedThe random number generator seed.
skill / skillsWhich skill(s) to generate for.
gradeThe target grade level.
countHow many items to generate.
difficultyThe difficulty filter.
formatThe requested content type format.

Changing any of these parameters — even with the same seed — may produce different output.

When you omit seed, the API generates a random seed automatically. The response still includes the seed in meta.seed, so you can replay the exact same generation later:

Terminal window
# First request -- no seed, get random output
POST /api/v1/generate
{ "skill": "multiply-within-100", "grade": "grade-3", "count": 10 }
# Response meta: { "seed": 8837291, ... }
# Replay the exact same output
POST /api/v1/generate
{ "skill": "multiply-within-100", "grade": "grade-3", "count": 10, "seed": 8837291 }

This is especially useful for “save and replay” workflows. Generate content freely, then persist the seed from the response to recreate it on demand.

Encode the seed in your URL so every visitor sees the same worksheet:

https://yourapp.com/worksheet/add-within-20?seed=42

Your backend calls the API with that seed and renders the result. The URL is shareable and bookmarkable.

Pin seeds in your test suite for predictable assertions:

const { data } = await client.generate({
skill: "add-within-10",
grade: "kindergarten",
count: 3,
seed: 12345,
});
expect(data.items).toHaveLength(3);
expect(data.items[0].content.operand1).toBe(4);
expect(data.items[0].content.operand2).toBe(3);

Use different seeds to produce distinct variants of the same worksheet:

const seeds = [100, 200, 300];
const variants = await Promise.all(
seeds.map((seed) =>
client.generate({ skill: "subtract-within-100", grade: "grade-2", count: 10, seed })
)
);
// Three different worksheets, all for the same skill and grade

When you provide a seed, the API can serve cached responses. The meta.cacheHit field tells you whether the response was generated fresh or served from cache:

{
"meta": {
"cacheHit": true,
"generationTimeMs": 1
}
}

Seeded requests with matching parameters hit the cache automatically. No additional headers or configuration required.