Prerequisites
- A Quiz Quail account — sign up free
- An API key — generate one in Settings > API Keys
curl(or any HTTP client / language of your choice)
Your API key is a secret. Never expose it in client-side code, public repos, or browser requests. Always send it server-side via the
Authorization header.Base URL
All API requests are made to:Authorization: Bearer header:
If you get a
401, double-check your API key. If you get a 403, make sure your key has the quizzes:read scope.Let’s create your first quiz. The only required field is
title (and even that defaults to “Untitled Quiz” if omitted).{
"data": {
"id": "abc123-...",
"title": "My First API Quiz",
"status": "draft",
"rounds": [
{
"id": "round-456-...",
"title": "Round 1",
"order": 0,
"questions": []
}
],
"themes": null,
"created_at": "2026-03-15T...",
"updated_at": "2026-03-15T..."
}
}
Now let’s add a multiple-choice question to Round 1. Replace
QUIZ_ID and ROUND_ID with the IDs from the previous response.{
"data": {
"id": "q-789-...",
"question_type": "multiple_choice",
"content": {
"text": "What is the largest planet in our solar system?",
"options": ["Mars", "Jupiter", "Saturn", "Neptune"],
"correctOptionIndex": 1
},
"hint": "It has a famous Great Red Spot.",
"fact": "Jupiter is so large that over 1,300 Earths could fit inside it.",
"countdown_seconds": 10,
"difficulty": null,
"order": 0
}
}
multiple_choicetrue_falseimagerankingopen_revealemojiSee Quizzes Guide for the full list with content schemas.
Once your quiz has at least one question, you can render it to video. This kicks off an asynchronous job — the API responds immediately with a
202 Accepted and a job ID you can poll.{
"data": {
"id": "render-abc-...",
"quiz_id": "abc123-...",
"status": "pending",
"output_url": null,
"error_message": null,
"created_at": "2026-03-15T...",
"completed_at": null
}
}
The render endpoint returns
202 Accepted (not 200 OK), along with a Location header pointing to the job’s status URL. Only one render can be in progress per quiz at a time — attempting a second returns a 409 Conflict.The render job moves through these statuses:
pending -> claimed -> rendering -> done (or failed). Poll the status endpoint until it completes.Instead of polling, you can set up a webhook to receive a
render.completed or render.failed event when the job finishes.Full script
Here’s the entire flow as a single TypeScript script you can copy and run:full-example.ts
What’s next?
You just created a quiz, added questions, and rendered a video — all through the API. Here’s where to go from here:- Authentication — Scopes, key rotation, and security best practices
- Quizzes Guide — All 13 question types, rounds, and reordering
- Themes Guide — Customize colors, fonts, and layouts
- Rendering Guide — Resolution options, webhooks, and bulk rendering
- AI Generation Guide — Generate entire quizzes from a text prompt
- API Reference — Complete endpoint documentation