Every change to /v1/content/** that an integration can observe is listed here, newest first. How additive and breaking changes are handled, and when deprecated fields stop being sent, is described in Versioning and Deprecation.
2026-09-30
Existing integrations keep working. This release adds capabilities and deprecates four response keys.
Added
- Expansion jobs are free. Expansions create editable drafts without calling a model, so they no longer check or charge AI Credits (previously 3, 1, and 3 credits per output), and they no longer return
402.outputs[].creditAmountis always0. See Pricing. - Key scopes, classroom allowlists, and expiry. New keys can be limited to
content:read,content:write,content:generate, andwebhooks:manage, to a list of classrooms, and to an expiry time. Keys created earlier hold every scope. See Keys and Authentication. - Key rotation with a grace period.
POST .../api-keys/{keyId}/rotateacceptsgracePeriodHours(0 to 168) so the old key keeps working while a deployment switches over. - Settings page. Keys and webhooks can be created and managed in TutorFlow under Settings > Content API.
- Per-key rate limits with headers. Each key's
rateLimitPerMinuteis one budget per 60-second window across every route. Responses carryX-RateLimit-Limit,X-RateLimit-Remaining, andX-RateLimit-Reset, and a429carriesRetry-Afteranderror.retryAfterSeconds. See Limits. - Audit log and ownership. Every change made with a key is recorded with the key id. Resources a key creates are owned by the admin who created the key while they remain an active admin, otherwise by the longest-standing active admin.
- Webhook events.
resource.created,resource.updated,resource.deleted,game.brief.*,game.build.*,simulation.brief.*,simulation.build.*,video.render.completed, andvideo.render.failed. - Webhook signatures and delivery. A timestamped
X-Content-Integration-Signature-V2header and anX-Content-Integration-Event-Idheader; the legacy signature is still sent. Up to 9 attempts over about 23 hours.307and308redirects are followed;301,302, and303are not. Webhook URLs must behttpson a public address. - Webhook management. Endpoints can be updated, paused, tested, and inspected through a delivery log, and deliveries can be sent again, with an admin session or a
webhooks:managekey. - Webhook secret rotation with a grace period.
rotate-secretacceptsgracePeriodHours(0 to 168). During the grace period the V2 header carries onev1=signature per secret. See Rotate the signing secret. - Async generation. Game and simulation brief, build, and revise accept
Prefer: respond-async(or?async=true) and answer202, withIdempotency-Keysupport and aGET .../runstatus route. Streaming is unchanged. See Generation. - Video rendering.
POST .../videos/{videoId}/render, a render status route with a signedvideoUrl, and cancel. See Video Rendering. - Course chapters and lessons. Chapters and text lessons can be listed, added, edited, moved, reordered, and deleted.
- Idempotency. Records replay for 24 hours, and a request stuck in progress for 5 minutes can be taken over by a retry.
- OpenAPI 3.1 description at
https://tutorflow.io/resources/integrations/openapi.json. See API Reference.
Changed
- Response contracts. Every response is an explicit list of public fields. Authoring tokens, video
videoKeyandmetadata.remotionLambda, scenettsAudioKeyandvideoClipKey, slidecontentKey, courseauthorId,chatSession, andsettings, moduleauthorId, and learner contact details in course stats are no longer returned. See Response fields. - Deletes. Every resource delete returns
200with{ "id", "deleted": true, "success": true }. Video delete used to return204with no body. - Lists. Resource lists return
{ "data", "meta" }. - Course read. A course that does not exist returns
404instead of200withnull. - Expansion scope. Creating an expansion job needs
content:generate. - Errors. A render already in progress returns
409content_video_render_in_progressinstead of restarting and charging again. Unexpected server errors always carry the message "An unexpected error occurred". Failed renders report a fixed public message instead of engine output.
Deprecated
These keys are still sent. They stop being sent on the sunset date in Versioning and Deprecation.
itemsandtotalCounton module, course, slide, test, game, and simulation lists. Readdataandmeta.itemCount.totalon the video list. Readmeta.itemCount.successon delete responses. Readdeleted.