Skip to content
You're reading the dev preview docs. Some features here aren't in the released app yet. Released docs

Learning Studio / agents

Use the HTTP agent API

Read courses, apply operations, and inspect history through authenticated requests.

Use the HTTP API to read courses, propose changes, and inspect saved versions. Start with discovery so your integration uses the available endpoints and schemas.

Use your app origin plus /api/public/agent, and send a user access token with every request. Send GET to the base path to inspect discovery.

Method Path after the base Purpose
GET / POST /courses List / create a course
GET /courses/:id Read content and version
POST /courses/:id/ops Validate or apply operations
GET / POST /courses/:id/versions List versions / save a checkpoint
GET /courses/:id/versions/:versionId Read a saved version
POST /courses/:id/files Upload multipart field file
GET / POST /courses/:id/comments Read threads / add feedback or update a thread
GET /courses/:id/alignment Read objective alignment
POST /courses/:id/ai/:action Request an AI suggestion

AI actions include edit, rewrite, distractors, blueprint, design, and build; their inputs differ. Check the schema for the action you need; an edit instruction is not a valid body for every action. MCP exposes the same rewrite, wrong-answer, design, comment, assessment-plan and alignment-CSV work as its own tools. Level suggestions, rubric drafts and the decision log are MCP tools as well.

GET /courses/:id/alignment returns version, blueprint, alignment, strength, assessmentBlueprint, and timeEstimates. The strength array has one entry per objective × scored-question link. Each entry includes objectiveId, questionId, blockId, sectionId, and strength (aligned, below_level, kind_too_weak, or unclassified). When a framework drove the result, the entry also includes frameworkId, objectiveLevelId, and questionLevelId; when the question type limited rigor, ceilingLevelId. An author acceptance adds overrideReason and the link counts as aligned. To accept a question, send block.update with the question’s rigorOverride: { reason } (1–200 characters); leave it out to remove the acceptance.

assessmentBlueprint summarizes scored questions linked to at least one objective: frameworkId, levels, totalPoints, unlinkedPoints, unlinkedQuestions, objectives (each with objectiveId, points, percent, questionCount, optional targetPercent, optional difference), levelTotals, cells, and deviations (each with id blueprint_weight_deviation, objectiveId, actualPercent, targetPercent, difference). Practice questions and scored questions with no objective link are excluded from totalPoints.

Add ?format=csv to get the alignment as CSV instead: one row per objective × linked element, with columns objective_code, objective_text, objective_revision, objective_status, element_kind, element_id, page_title, tier, strength, level and points (UTF-8 with a byte order mark, RFC 4180 quoting). The JSON response also includes timeEstimates (courseMinutes, estimatedPages, totalPages, perObjective); set a page’s estimate with section.update and estimatedMinutes (1–600, or null to clear).

Set or clear targets with course.settings.update and assessmentTargets: an array of { objectiveId, weightPercent } entries (each 0–100; the sum must be at most 100), or null or [] to clear all targets.

Replace the ID and base version with values from a fresh course read. Send this JSON to POST /courses/:id/ops:

{
"baseVersion": 1,
"idempotencyKey": "example-title-update-001",
"dryRun": true,
"label": "Clarify course title",
"ops": [
{ "op": "course.settings.update", "patch": { "title": "Designing meaningful learning" } }
]
}

A dry run validates without saving. To commit after review, submit with dryRun: false and the still-current version. See operations and recovery for conflicts and retries.

POST /courses to create a course. For a blank course, send idempotencyKey (8–100 characters), optional title (1–200 characters), and optional language (up to 16 characters; default en). A new blank course returns 201; a replay with the same key returns 200.

To generate initial content with AI, also supply ai: { mode, text }. Use mode prompt for a short brief or mode document for source text. Text is limited to 60,000 characters; document mode requires at least 200 characters, and prompt mode requires at least 20. The AI creates the course and commits the draft as one version. The AI creation branch currently does not replay the supplied idempotency key, so if the response is interrupted, check the course list before retrying to avoid creating a second draft.

List versions with GET /courses/:id/versions; use its before cursor for older entries. POST the same path with { "label": "Before restructuring" } to save a checkpoint. GET /courses/:id/versions/:versionId returns content for a saved version. Check each operation’s retry behavior; the /ops replay guarantee doesn’t apply to every endpoint.

After a successful response, open Studio home to find the course. The fixture image below illustrates where courses appear; it is not a capture of an HTTP request or proof of API creation.

Illustrative Projects view with a sample course. Use this list to find a course after a successful API creation response. Full-resolution PNG
Action Required fields Optional fields
edit baseVersion ≥1, instruction (3–2,000) scopeBlockId, scopeSectionId (up to 100 each)
rewrite text (1–8,000), instruction (3–1,000) context (up to 8,000; default empty)
distractors prompt (1–500), correct (1–6 strings up to 300), count (1–5) None
blueprint baseVersion ≥1, brief (10–20,000) length (short, medium, long; default medium)
design baseVersion ≥1, brief (10–20,000), approach (academic or performance) audience (customers or employees)
build baseVersion ≥1 None

For edit, supply a scopeSectionId for a content page or a scopeBlockId on that page. Although both fields are optional in the request schema, the current runtime requires at least one: requests without a page scope, or targeting a cover/chapter, return 422. If both are supplied they must identify the same page. An edit suggestion is limited to that page; it is not a whole-course rewrite.

The HTTP blueprint brief limit differs from MCP’s 4,000-character limit. A design brief is 10–20,000 characters on both. Edit, blueprint, design, and build return operations as suggestions; apply them separately through /ops. design returns course.settings.update (objectives) and course.design.update (the Backward Design plan), plus model, rationale, sources, promptVersion, and eventId. Nothing is saved. audience applies only when approach is performance; omit it to use the course audience, or customers when the course has none. Academic ignores audience. Rewrite returns text, and distractors returns options. A stale AI base version can return 409; provider failures can return 502.

Upload files to /courses/:id/files using multipart form field file, with the user bearer token. The current upload limit is 200 MB; an oversized request returns 413. The HTTP upload route remains course-scoped; the account Files library and its version controls are UI workflows, not additional public agent endpoints. Use its returned resource/storage path in the appropriate content operation; do not store a temporary signed URL as a permanent media reference.

GET /courses/:id/comments?status=open or status=resolved filters threads. POST accepts these alternative bodies:

{ "sectionId": "page-1", "blockId": "intro-1", "body": "Could this include a worked example?" }
{ "threadId": "<thread ID from the response>", "body": "The example is now included." }
{ "threadId": "<thread ID from the response>", "status": "resolved" }

Comment access follows owner/reviewer permissions. Comment bodies are limited to 4,000 characters. Comment creation does not take an idempotency key, so inspect existing threads before retrying an uncertain creation response.

Last updated · Kite v0.25.6

Same update, your timezone

Pacific · Nov 6
Central · Nov 6
Eastern · Nov 6

Made with love by the team at EdStratum Labs AI