Templates

Quiz

Creation returns immediately, so poll the video or listen with webhooks.

POST/v1/quiz-videos

Create a quiz video

Starts a new video, credits are charged the same way as videos created in the app.
Body
itemsrequired
object[]
The questions, in the order they play, with comments in between if you want them. At least one question and up to 100 items. See item fields.
template
"standard" | "multi-levels"
Standard shows every answer and highlights the correct one. Multi levels climbs a ladder of levels instead, showing one answer per question.
default: standard
language
string
Language of the questions, as named in the language picker, such as Spanish or Japanese. Anything other than English narrates with the multilingual voice model.
default: English
voiceId
string
ElevenLabs voice to narrate with. Defaults to Adam. Questions, answers and comments all use it. List the ids with Voices.
default: pNInz6obpgDQGcFmaJgB
voiceProvider
"11" | "aws" | "openai"
Which text to speech service the voiceId belongs to. Voices lists ElevenLabs ids, the other two are for ids you already know.
default: 11
voiceStyle
object
Fine tunes the narration. Every field is a percentage, matching the voice sliders in the editor. Pass only the ones you want to change, see voiceStyle fields.
answerTemplate
string
How the voice reads the answer out, with {{answer}} standing in for the answer text. Set it to something like "The answer is {{answer}}" to have it announced. It only changes the narration, not what is on screen.
default: {{answer}}
generateBackgroundImage
boolean
Generates the images the quiz plays over. Turned off, the video uses your workspace background video instead.
default: true
backgroundImagePrompt
string
What the background images show. Keep it simple and generic, it is reused for every image. Other prompts the app offers are earth planet, hidden world, fantasy world, galaxy and natural world.
default: Bible times, pyramids, Egypt, pharaoh
generateQuestionImage
boolean
Illustrates each question with its own generated image, drawn from the question and its correct answer.
default: true
imageStyle
"CINEMATIC" | "ANIME" | "3D" | "CINEMATIC_DARK" | "ANIME_DARK" | "COMIC" | "CARTOON" | "PUNK" | "PSY"
Art style of the background images.
default: ANIME
render
object
Export the mp4 as soon as the narration and images are ready, taking the same fields as the render endpoint, see render fields. Pass an empty object to accept the defaults. Left out, the video stays an editable project you can render later. Rendering charges export credits and requires a paid plan.
webhookUrl
string
HTTPS callback fired once the video reaches a terminal status. See Webhooks for details.
item fields
textrequired
string
The question, or what the comment says. Read out by the voice and written on screen. Up to 400 characters.
type
"question" | "comment"
A question runs the timer and reveals its answer. A comment is a line narrated over the background on its own, handy for an intro or a closing thought.
default: question
answers
object[]
The choices, one to four of them, required on questions and ignored on comments. The multi levels template takes only the correct one. See answer fields.
level
number, 1 to 4
Which rung of the ladder the question sits on, multi levels template only. Levels must not go down as the questions go on, so order the easy ones first.
default: 1
answer fields
textrequired
string
The choice as it appears on screen. Prefix it yourself if you want lettered choices, such as "A) Paris".
correct
boolean
The answer the quiz reveals and narrates. Exactly one answer of a question needs it, unless the question has a single answer, which is then the correct one.
default: false
voiceStyle fields
voiceStyle.stability
number, 0 to 100
Lower values let the voice vary more between takes, higher values keep it flat and predictable.
default: 38
voiceStyle.similarityBoost
number, 0 to 100
How closely the output sticks to the original voice.
default: 75
voiceStyle.style
number, 0 to 100
Style exaggeration. Higher values push the delivery harder, at some cost to stability.
default: 0
voiceStyle.speed
number, 70 to 120
Speaking rate as a percentage of the voice’s natural pace.
default: 100
render fields
render.format
"standard" | "greenscreen"
Standard renders the finished video. Green screen drops the background and renders the captions and overlays on a solid green fill, ready to key out in your own editor.
default: standard
render.frameRate
30 | 60
Frames per second. Rendering costs 30 credits per minute of video at 30fps and 60 credits per minute at 60fps.
default: 30
Request
curl -X POST "https://api.vsub.io/v1/quiz-videos" \
  -H "Authorization: Bearer vp_a1b2c3d4e5f60718293a4b5c6d7e8f90a1b2c3d4e5f60718293a4b5c6d7e8f90" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      { "type": "comment", "text": "Only 1 in 10 people get all of these right" },
      {
        "text": "Which planet is closest to the sun?",
        "answers": [
          { "text": "Venus" },
          { "text": "Mercury", "correct": true },
          { "text": "Mars" }
        ]
      },
      {
        "text": "How many bones are in the human body?",
        "answers": [
          { "text": "206", "correct": true },
          { "text": "218" },
          { "text": "194" }
        ]
      }
    ],
    "backgroundImagePrompt": "galaxy",
    "webhookUrl": "https://your-app.example.com/hooks/vsub-video"
  }'
Response 200
{
  "id": "9f0c1d5e-3a1b-4c2f-9d7e-8b1a2c3d4e5f",
  "status": "processing",
  "step": "create-vocal",
  "render": false,
  "createdAt": "2026-08-05T09:20:11.000Z",
  "editorUrl": "https://vsub.io/workspace/editor/9f0c1d5e-3a1b-4c2f-9d7e-8b1a2c3d4e5f"
}

Generation runs in the background. Follow the video with Video status or let a webhook tell you when it's done.

More examples

Each of these is the body of the same request, the url and headers don't change.

Climbing the levels

The multi levels template draws a ladder of four levels and moves up it as the questions get harder, so each question carries a level and only its correct answer. Questions of the same level stay together, and the level never goes back down.

Body
{
  "template": "multi-levels",
  "items": [
    { "text": "What is the capital of France?", "level": 1, "answers": [{ "text": "Paris" }] },
    { "text": "What is the capital of Australia?", "level": 2, "answers": [{ "text": "Canberra" }] },
    { "text": "What is the capital of Kazakhstan?", "level": 3, "answers": [{ "text": "Astana" }] },
    { "text": "What is the capital of Bhutan?", "level": 4, "answers": [{ "text": "Thimphu" }] }
  ]
}

Announcing the answer in another language

answerTemplate wraps the answer before the voice reads it, which is how you turn a bare word into a sentence. Setting language switches the narration to the multilingual model, and turning the generated images off falls back to your workspace background video.

Body
{
  "language": "Spanish",
  "answerTemplate": "La respuesta es {{answer}}",
  "voiceId": "aEO01A4wXwd1O8GPgGlF",
  "voiceStyle": { "stability": 50, "speed": 95 },
  "generateBackgroundImage": false,
  "generateQuestionImage": false,
  "items": [
    {
      "text": "¿Cuál es el río más largo del mundo?",
      "answers": [
        { "text": "El Nilo" },
        { "text": "El Amazonas", "correct": true },
        { "text": "El Danubio" }
      ]
    }
  ]
}

The gameplay behind the quiz, the fonts, the answer colours and the timer come from your workspace defaults, the same ones the app starts a quiz video with. Anything the request doesn't cover, such as swapping a generated image or retiming a question, is still yours to change in the editor before rendering.