Ask questions about a video and get structured answers with the Mux Robots API. Use this workflow to extract information, classify videos, or build decision logic on video content.
Ask one or more questions about a video and get structured answers. This is a flexible workflow that lets you extract specific information from video content, classify videos, or build decision-making logic around video analysis. See the Ask Questions API referenceAPI for the full endpoint specification. See Mux Robots pricing for unit costs.
ask-questions jobcurl https://api.mux.com/robots/v0/jobs/ask-questions \
-H "Content-Type: application/json" \
-X POST \
-d '{
"parameters": {
"asset_id": "YOUR_ASSET_ID",
"questions": [
{ "question": "Does this video contain a product demonstration?", "answer_options": ["yes", "no"] },
{ "question": "Is the speaker using a presentation?", "answer_options": ["yes", "no"] },
{ "question": "What programming language is shown?", "answer_options": ["python", "javascript", "go", "other"] }
]
}
}' \
-u ${MUX_TOKEN_ID}:${MUX_TOKEN_SECRET}This request is asynchronous. The POST returns immediately with the job in pending status and does not include results. We strongly recommend listening for the robots.job.ask_questions.completed webhook — the payload contains the full completed job, so no follow-up API call is needed. If webhooks aren't an option, you can poll GET /robots/v0/jobs/ask-questions/{JOB_ID} with the id from the response until the status is completed.
| Parameter | Type | Description |
|---|---|---|
asset_id | string | Required. The Mux asset ID of the video to analyze. |
questions | array | Required. One or more questions to ask about the video. All questions are evaluated in a single AI call. |
questions[].question | string | The question to ask about the video content. |
questions[].answer_options | array | Allowed answer values the AI must choose from. Defaults to ["yes", "no"]. Can be customized to any set of options, e.g. ["high", "medium", "low"]. |
language_code | string | BCP 47 language code of the caption track to analyze (e.g. en, fr). When omitted, the SDK uses the default track. |
The outputs object is included in the job once its status is completed. You'll receive it on the robots.job.ask_questions.completed webhook (recommended), or you can fetch it with GET /robots/v0/jobs/ask-questions/{JOB_ID}. It contains:
| Field | Type | Description |
|---|---|---|
answers | array | One answer per question, in the same order as the input questions. |
answers[].question | string | The original question that was asked. |
answers[].answer | string or null | The answer, constrained to one of the provided answer_options. Null when the question was skipped. |
answers[].skipped | boolean | true if the question could not be answered from the video content. |
answers[].confidence | number | Confidence score from 0.0 to 1.0. |
answers[].reasoning | string | Explanation citing specific visual or audio evidence from the video. |
Confidence scores give you a signal for how certain the AI is: values above 0.9 indicate clear, unambiguous evidence; 0.7-0.9 strong evidence with minor ambiguity; 0.5-0.7 moderate evidence; below 0.5 weak or uncertain evidence.
Questions can be skipped if the AI determines the question is not relevant to the video content. When a question is skipped, answer is null, skipped is true, and confidence is 0. Your code should handle skipped answers — see the example response below.
This is the payload delivered to the robots.job.ask_questions.completed webhook, and the same shape you get from GET /robots/v0/jobs/ask-questions/{JOB_ID}:
{
"data": {
"id": "rjob_jkl012",
"workflow": "ask-questions",
"status": "completed",
"units_consumed": 1,
"parameters": {
"asset_id": "YOUR_ASSET_ID",
"questions": [
{ "question": "Does this video contain a product demonstration?", "answer_options": ["yes", "no"] },
{ "question": "Is the speaker using a presentation?", "answer_options": ["yes", "no"] },
{ "question": "What programming language is shown?", "answer_options": ["python", "javascript", "go", "other"] }
]
},
"outputs": {
"answers": [
{
"question": "Does this video contain a product demonstration?",
"answer": "yes",
"skipped": false,
"confidence": 0.95,
"reasoning": "The video shows a screen recording of a product interface with the speaker walking through features and clicking through different screens."
},
{
"question": "Is the speaker using a presentation?",
"answer": "no",
"skipped": false,
"confidence": 0.88,
"reasoning": "The video shows a live product demo and code editor rather than a slide deck."
},
{
"question": "What programming language is shown?",
"answer": null,
"skipped": true,
"confidence": 0,
"reasoning": "No code or programming language is visible in the video."
}
]
}
}
}The answer_options field lets you constrain answers to any set of values, making it easy to build classification and routing logic. The default is ["yes", "no"], but you can use any set of strings. Since answer_options is specified per question, you can use different options for different questions in the same job.
Classify production quality:
{
"parameters": {
"asset_id": "YOUR_ASSET_ID",
"questions": [
{ "question": "What is the production quality of this video?", "answer_options": ["professional", "semi-professional", "amateur"] }
]
}
}Auto-categorize uploads for a video library:
{
"parameters": {
"asset_id": "YOUR_ASSET_ID",
"questions": [
{ "question": "What type of content is this video?", "answer_options": ["tutorial", "interview", "product-demo", "vlog", "other"] }
]
}
}