Create Slide

Generate an AI-powered slide deck from a prompt and receive edit/preview URLs. Designed for autonomous agents.

POST /v1/platform/slides

Creates a slide-deck request. The AI generates a structured deck, uploads the content to S3, and returns edit and preview URLs. Generated decks currently start as <slide>...</slide> HTML blocks. The editor may later save the same field as its current editor-content string, so treat content as an opaque editor payload unless you are using TutorFlow's editor contract directly.

The endpoint is fully self-contained: one POST returns everything an agent needs to either hand the deck off to a human (previewUrl) or render a public landing page (publicUrl). No follow-up calls are required for the happy path.

Agent Quick Reference

You want…Call thisResult
A finished deck right nowPOST /v1/platform/slides with mode: "sync"Response in 15–40 s with both URLs
To kick off generation in the backgroundPOST /v1/platform/slides with mode: "async"Returns immediately. Poll GET /v1/platform/slides/:id
Idempotent retry safetyAdd Idempotency-Key headerSame key returns the original response
To edit the deck programmaticallyUse editToken from the responseSee Edit by Token
To export to PowerPointPOST /v1/platform/slides/edit/:editToken/pptxReturns S3 URL of the .pptx file
To regenerate a single imagePOST /v1/platform/slides/edit/:editToken/generate/imageReturns S3 key for the new image

Request Body

FieldTypeRequiredDescription
promptstringYesPrompt describing the deck to generate. Specific prompts produce better decks (include audience, tone, key facts).
titlestringNoOverride the AI-generated title.
descriptionstringNoOverride the AI-generated description.
languagestringNoOutput language (default: en). Use ISO 639-1 codes such as en, ko, ja, zh-CN.
slideCountnumberNoTarget number of slides (1–100, default: 10). The AI may produce slightly fewer if the topic is narrow.
themestringNoVisual theme hint (e.g. modern, minimal, dark). Affects styling tokens applied to the deck.
classroomIdstringNoClassroom UUID to create the slide deck in. Uses the workspace default classroom if omitted.
tierstringNoLegacy request value only: basic, standard, or advanced. Omit for new integrations. Do not send default; default is a response/catalog tier.
modestringNosync (default) or async. See Async Mode.
idempotencyKeystringNoPrevents duplicate processing. Can also be sent as Idempotency-Key HTTP header.

Pricing

The Slide API is billed per slide for the base creation flow. AI image generation is an optional sub-event billed independently when invoked via the image-generation endpoint. Most slides are text-only, so customers pay only for what they actually generate.

EventEndpointPrice
Base slide generationPOST /v1/platform/slides (per slide)$0.03 / slide
AI image generationPOST /v1/platform/slides/edit/:editToken/generate/image$0.07 / image

Slide content is generated as a single HTML blob, not N rows; the slideCount parameter is the requested target and serves as the billable unit count for the base creation event.

The priceSnapshot on the create response covers only the base creation. Each call to the image-generation endpoint produces its own PlatformUsageRecord row with a slide_image priceSnapshot.

Legacy tier field: still accepted for backwards compatibility but has no effect on price. Omit it in new integrations. If you send it, use one of the legacy request values: basic, standard, or advanced.

Example Request

curl -X POST https://api.tutorflow.io/v1/platform/slides \
  -H "Authorization: Bearer tf_platform_..." \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Introduction to the Mediterranean diet for adults: foods, health benefits, and a sample weekly meal plan",
    "language": "en",
    "slideCount": 6
  }'

Response Fields

FieldTypeDescription
idstringSlide request ID. Use this to poll, list, or refresh.
slideIdstring | nullInternal slide content ID. null until generation completes.
statusstringPENDING, PROCESSING, COMPLETED, or FAILED.
isTerminalbooleantrue once status is COMPLETED or FAILED. Stop polling.
titlestring | nullAI-generated or overridden title.
descriptionstring | nullShort summary of the deck.
languagestring | nullOutput language (echoed).
themestring | nullVisual theme (echoed).
slideCountnumber | nullRequested target slide count. This is also the billable unit count for base slide generation.
slugstring | nullURL-friendly slug.
tierstringPricing tier used.
modestring | nullsync or async.
priceSnapshotobject | nullPricing details captured at request time.
shareTokenstring | nullPermanent token for the public read-only URL.
editTokenstring | nullHourly-rotating token used by the editor and edit-time mutations.
editTokenExpiresAtstring | nullISO 8601 timestamp the current editToken expires at. Refresh by calling any GET /v1/platform/slides/edit/:editToken route, expiry is extended automatically (sliding window).
previewUrlstring | nullEditor URL, /{locale}/platform/slides/edit/{editToken}. Anyone with the link can edit without logging in.
publicUrlstring | nullPublic read-only viewer, /{locale}/platform/slides/{shareToken}. Permanent.
pollAfterMsnumber | nullSuggested polling interval (async only).
idempotencyKeystring | nullEchoed idempotency key.
idempotentReplayboolean | nulltrue if this is a replay, false for a fresh request, null when no key was supplied.
createdAtstringISO 8601 timestamp.
completedAtstring | nullISO 8601 timestamp generation finished.

Example Response

{
  "id": "61f1b111-0df3-4de3-a83f-d4b10304949d",
  "slideId": "669b977b-0007-40b9-8339-2b4e1d8e7c8e",
  "status": "COMPLETED",
  "isTerminal": true,
  "title": "The Mediterranean Diet, Explained",
  "description": "A 6-slide overview of the Mediterranean diet's foods, health benefits, and a one-week meal plan.",
  "language": "en",
  "theme": null,
  "slideCount": 6,
  "slug": "the-mediterranean-diet-explained-1602dc2c",
  "tier": "default",
  "mode": "sync",
  "priceSnapshot": {
    "category": "slide",
    "catalogKey": "slide.default",
    "tier": "default",
    "unit": "slide",
    "unitPrice": 0.03,
    "units": 6,
    "amountUsd": 0.18,
    "currency": "USD",
    "source": "platform_pricing_catalog_v2"
  },
  "shareToken": "fda025e5ea364bf30ea46671582d6859",
  "editToken": "187d1d98e7cfe5190da4e2cc24bbf65d",
  "editTokenExpiresAt": "2026-04-25T14:14:40.890Z",
  "previewUrl": "https://tutorflow.io/en/platform/slides/edit/187d1d98e7cfe5190da4e2cc24bbf65d",
  "publicUrl": "https://tutorflow.io/en/platform/slides/fda025e5ea364bf30ea46671582d6859",
  "idempotencyKey": null,
  "idempotentReplay": null,
  "createdAt": "2026-04-25T04:14:15.756Z",
  "completedAt": "2026-04-25T04:14:40.940Z",
  "pollAfterMs": null
}

Preview URL vs Public URL

URLPurposeAuthExpiry
previewUrlEditor, change title, content, outline, regenerate images, export PPTXNone (token-gated)editToken extends on each access; effectively never expires while you keep using it
publicUrlPublic read-only viewerNonePermanent

The previewUrl is the link you hand to a human reviewer or paste into a chat reply. Opening it loads the slide editor. If the deck contains image placeholders, the editor can resolve them through the image-generation endpoint.

Image Generation in the Editor

AI-generated decks contain <img data-prompt="..." data-auto-image-id="..."> placeholders. When a human (or your own headless browser) opens the editor for the first time, each placeholder triggers a call to:

POST /v1/platform/slides/edit/:editToken/generate/image

The image generator calls Gemini, uploads the result to a workspace-scoped S3 path, and patches the <img> node in place. The editor handles this for you. You do not need to call the endpoint manually unless you want to regenerate a specific image.

To regenerate manually:

curl -X POST https://api.tutorflow.io/v1/platform/slides/edit/{editToken}/generate/image \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Olive oil, fresh vegetables, and whole grains arranged on a wooden board",
    "aspectRatio": "3:4",
    "imageStyle": "photorealistic"
  }'
FieldTypeRequiredDescription
contentstringYes (or prompt)Slide text content used to derive an image prompt automatically.
promptstringNoExplicit prompt. Overrides content-based derivation.
aspectRatiostringNo21:9, 3:4, 1:1, etc. Defaults based on layout.
isInfographicbooleanNoGenerates an infographic-style image when true.
themeNamestringNoTheme hint passed to the image prompt builder.
imageStylestringNodefault, photorealistic, minimalist, isometric.

Response:

{ "data": [{ "key": "platform/{workspaceId}/slides/{slideId}/images/...png" }] }

Use the returned key with the STORAGE URL prefix (see Authentication) to display the image.

PPTX Export

Convert any deck to a downloadable .pptx file:

curl -X POST https://api.tutorflow.io/v1/platform/slides/edit/{editToken}/pptx \
  -H "Content-Type: application/json" \
  -d '{
    "html": "<slide>...</slide><slide>...</slide>",
    "theme": { "backgroundColor": "#ffffff", "textColor": "#0f172a", "...": "..." }
  }'

The endpoint reuses the same PPTX builder as the classroom slide editor. The html field is the rendered slide HTML, typically captured from the editor DOM. Captured base64 images can also be supplied via capturedImages, capturedMathImages, and capturedContentImages fields for high-fidelity export of charts and math.

Response:

{
  "url": "https://{bucket}.s3.{region}.amazonaws.com/platform/{workspaceId}/slides/{slideId}/pptx/1714060000.pptx",
  "key": "platform/{workspaceId}/slides/{slideId}/pptx/1714060000.pptx"
}

The URL is publicly readable. Stream it to the user or store the key for later retrieval.

Edit Token API

The edit URL provides access to these public endpoints (no API key needed):

MethodPathDescription
GET/v1/platform/slides/edit/:editTokenGet slide content string, title, outline, metadata.
PATCH/v1/platform/slides/edit/:editTokenUpdate title, description, outline, theme, content, thumbnail, visibility, metadata.
POST/v1/platform/slides/edit/:editToken/generate/imageGenerate a single AI image.
POST/v1/platform/slides/edit/:editToken/pptxExport the deck to PowerPoint.

Update Slide

curl -X PATCH https://api.tutorflow.io/v1/platform/slides/edit/{editToken} \
  -H "Content-Type: application/json" \
  -d '{
    "title": "The Mediterranean Diet, Updated",
    "outline": "1. Foundations\n2. Daily Habits\n3. Weekly Plan"
  }'
FieldTypeDescription
titlestringUpdated deck title.
descriptionstring | nullUpdated description.
outlinestring | nullPlain-text outline (markdown supported).
themestringVisual theme.
contentstringFull editor content string. Generated decks start as <slide>...</slide> HTML, while editor saves may store TipTap JSON. The server treats it as an opaque string, uploads it to S3, and bumps contentVersion.
thumbnailstring | nullThumbnail HTML snippet (rendered first slide).
visibilitystringPUBLIC or PRIVATE.
metadataobjectFree-form metadata.

Response is the full SlideEditResDto, see Get Slide for the shape.

Async Mode

Set mode: "async" to queue generation as a background job. The response returns immediately with status: "PENDING" and a pollAfterMs value. Poll GET /v1/platform/slides/:id until isTerminal is true.

Idempotency

Pass an idempotencyKey in the request body or Idempotency-Key header to prevent duplicate slide generation. Reusing the same key returns the original response with idempotentReplay: true.