Resources
Content API FAQ

Content API FAQ

Short answers to common questions about Content API keys, credits, source JSON, idempotency, webhooks, and generation.

On this page

Where do I get a key?

In TutorFlow, under Settings > Content API, as an organization admin. To automate it, see Create a key with the API.

Why is the key shown only once?

TutorFlow stores only a hash of it. If you lose it, rotate the key or create a new one.

Can I use one key for test and production?

Use separate keys. Each has its own rate limit and can be rotated or revoked without touching the other.

Which credits does the Content API use?

The organization's AI Credits, the balance shown in TutorFlow Billing. Never Agent Platform credits. Prices are in Pricing, and GET /v1/content/credits returns the balance.

Why does /v1/platform/agent/account show a different balance?

/v1/platform/** is the separate Agent Platform, with its own balance. Content API integrations use GET /v1/content/credits.

How large can a request be?

100 KB of JSON per request. Other limits, including list page sizes and field lengths, are in Limits.

How much source JSON should one expansion job carry?

One level. A job expands exactly one level, the first one with lessons. Send one job per level. See Source JSON Format.

What happens if I retry with the same idempotency key?

The same key and body return the first response for 24 hours, with the header Idempotent-Replayed: true, and a different body returns 409. This holds for expansion jobs too, so change the key when your source changes. Keys are scoped to your API key, so another integration in your organization cannot collide with yours. See Idempotency.

Why is the video output not an mp4?

Expansion and POST /videos create an editable video plan so a person can review it. Render it with POST /videos/{videoId}/render; see Video Rendering.

Why does building a game return text/event-stream?

Streaming is the default, for interfaces where a person watches progress. For server-to-server code, send Prefer: respond-async and wait for the webhook. See Generation.

Can I download a built game or simulation?

Yes. GET /games/{gameId} and GET /simulations/{simulationId} return the built page as one HTML document in content. Lists leave it out.

How do I find what changed since my last sync?

List with updatedSince set to the start of your previous sync, and subscribe to resource.* webhooks for changes made through the API, including deletions. See Syncing changes.

Should I poll or use webhooks?

Poll while you build and test the integration. Use webhooks in production, especially for builds and renders that take minutes.

Can TutorFlow write a test, module, course, or slide deck for me?

Yes. POST .../tests/generate, .../modules/generate, .../courses/generate, and .../slides/generate start a run that writes it from a topic, at the editor's price. See Generate Tests, Modules, Courses, and Slides.

How do I set a thumbnail, a scene image, or a PDF from my system?

Upload the file with POST .../assets and a presigned PUT, then put the returned assetKey in the field. See Asset Uploads.

How do I stop my sync from overwriting an educator's edits?

Send the ETag you read as If-Match on the update. If the resource changed since, the answer is 412 and nothing is written. See Concurrency and ETags.

Can I cap what one integration spends?

Yes. Give its key a monthlyCreditLimit. See Monthly credit limit.

Why does my full-access key get 403 on the learner routes?

learners:read and learners:write are opt-in, even for keys with no scope list. An admin has to add them to the key. See Learners.

My webhook endpoint shows DISABLED. What happened?

TutorFlow turns an endpoint off after at least 20 failed attempts in a row over at least 3 days, and emails the organization's admins. Fix the receiver, then turn it back on and resend what failed; see Turn an endpoint back on.

Can I edit course chapters and lessons?

Yes, text lessons. See Course chapters and lessons.

What should I send to support?

The Request-Id header of the failed response (also in error.requestId), plus the fields in Contacting support. Never the full key.

Was this page helpful?