Resources
Content API Changelog

Content API Changelog

Dated list of additions, changes, and deprecations in the TutorFlow Content API.

On this page

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[].creditAmount is always 0. See Pricing.
  • Key scopes, classroom allowlists, and expiry. New keys can be limited to content:read, content:write, content:generate, and webhooks: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}/rotate accepts gracePeriodHours (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 rateLimitPerMinute is one budget per 60-second window across every route. Responses carry X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset, and a 429 carries Retry-After and error.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, and video.render.failed.
  • Webhook signatures and delivery. A timestamped X-Content-Integration-Signature-V2 header and an X-Content-Integration-Event-Id header; the legacy signature is still sent. Up to 9 attempts over about 23 hours. 307 and 308 redirects are followed; 301, 302, and 303 are not. Webhook URLs must be https on 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:manage key.
  • Webhook secret rotation with a grace period. rotate-secret accepts gracePeriodHours (0 to 168). During the grace period the V2 header carries one v1= 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 answer 202, with Idempotency-Key support and a GET .../run status route. Streaming is unchanged. See Generation.
  • Video rendering. POST .../videos/{videoId}/render, a render status route with a signed videoUrl, 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 videoKey and metadata.remotionLambda, scene ttsAudioKey and videoClipKey, slide contentKey, course authorId, chatSession, and settings, module authorId, and learner contact details in course stats are no longer returned. See Response fields.
  • Deletes. Every resource delete returns 200 with { "id", "deleted": true, "success": true }. Video delete used to return 204 with no body.
  • Lists. Resource lists return { "data", "meta" }.
  • Course read. A course that does not exist returns 404 instead of 200 with null.
  • Expansion scope. Creating an expansion job needs content:generate.
  • Errors. A render already in progress returns 409 content_video_render_in_progress instead 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.

  • items and totalCount on module, course, slide, test, game, and simulation lists. Read data and meta.itemCount.
  • total on the video list. Read meta.itemCount.
  • success on delete responses. Read deleted.

Was this page helpful?