curl -X POST "$BASE_URL/slides" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "topic": "Photosynthesis", "additionalInstructions": "Keep it visual." }'
{
"success": true,
"deck": {
"deck_title": "Sensors and Inputs",
"slides": [
{
"slide_number": 1,
"slide_type_id": "title_slide",
"content": { "title": "Sensors and Inputs", "subtitle": "Lesson 2 of 4" }
}
]
},
"metadata": {
"generatedAt": "2026-08-21T12:00:00.000Z",
"provider": "vertex-agent",
"flowId": "Flows-UnifiedResourceRouter",
"slideCount": 9
},
"usage": {
"provider": "vertex-agent",
"engine": "Flows-UnifiedResourceRouter",
"model": "gemini-2.5-flash",
"traceId": "9c02..."
}
}
Content
Slides
Build a presentation from a lesson plan or a topic.
POST
/
slides
curl -X POST "$BASE_URL/slides" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "topic": "Photosynthesis", "additionalInstructions": "Keep it visual." }'
{
"success": true,
"deck": {
"deck_title": "Sensors and Inputs",
"slides": [
{
"slide_number": 1,
"slide_type_id": "title_slide",
"content": { "title": "Sensors and Inputs", "subtitle": "Lesson 2 of 4" }
}
]
},
"metadata": {
"generatedAt": "2026-08-21T12:00:00.000Z",
"provider": "vertex-agent",
"flowId": "Flows-UnifiedResourceRouter",
"slideCount": 9
},
"usage": {
"provider": "vertex-agent",
"engine": "Flows-UnifiedResourceRouter",
"model": "gemini-2.5-flash",
"traceId": "9c02..."
}
}
Request
Supply either alessonPlan or a topic.
object
A lesson plan to build the deck from.
string
A topic, when there is no lesson plan to work from.
string
Free-text steer on tone, depth or emphasis.
object
Override the built-in nine default slide templates. Shape is
{ "slide_types": [ ] }. Use it to pass a subset, custom layouts, or a
different theme.curl -X POST "$BASE_URL/slides" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "topic": "Photosynthesis", "additionalInstructions": "Keep it visual." }'
Response
boolean
true when the deck generated.object
deck_title plus a slides array. Each slide carries slide_number,
slide_type_id naming the template it fills, and a content object whose
keys are the slot IDs of that template.object
generatedAt, provider, flowId and slideCount.object
provider, engine, model and traceId.{
"success": true,
"deck": {
"deck_title": "Sensors and Inputs",
"slides": [
{
"slide_number": 1,
"slide_type_id": "title_slide",
"content": { "title": "Sensors and Inputs", "subtitle": "Lesson 2 of 4" }
}
]
},
"metadata": {
"generatedAt": "2026-08-21T12:00:00.000Z",
"provider": "vertex-agent",
"flowId": "Flows-UnifiedResourceRouter",
"slideCount": 9
},
"usage": {
"provider": "vertex-agent",
"engine": "Flows-UnifiedResourceRouter",
"model": "gemini-2.5-flash",
"traceId": "9c02..."
}
}
Slides has no flow of its own. It runs the unified resource router with
resource_type: "PRESENTATION", which is why flowId and engine read
Flows-UnifiedResourceRouter — the same engine that serves
/resource. model is reported by the agent
per call rather than fixed by this endpoint.content is keyed by slot ID, and slot IDs come from the template named in
slide_type_id — they are not a fixed set. Read them from the slide type rather
than hard-coding key names, or a custom slideTypes override will silently
render blank slots.Slot constraints such as
max_chars are advisory input to the model, not
enforced on output. Validate lengths client-side before rendering into a fixed
layout.Errors
On failure the response is{ "success": false, "error": ... }. A topic that
matches nothing usable still returns a deck — the capability falls back to a
generic plan for the topic rather than erroring.