Fast mode evaluates one or more typed questions against shared input. The HTTP response contains the completed answers.
Endpoint
POST /aiservices/decisions/decide
Authenticate with your Zoom AI Services credentials. The examples on this page send a token in the Authorization: Bearer header. Send a JSON request with Content-Type: application/json.
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
input | string or object[] | Yes | Shared evidence: a text string, or user messages containing text and image parts. |
questions | object[] | Yes | One or more independent decision questions. |
model | string | No | zoom-decisions (default) or zoom-decisions-pro. |
enable_image_input | boolean | No | Set to true when the input contains images. Defaults to false. |
reference_id | string | No | Caller-provided identifier for correlation and tracing. It is not returned in the response. |
Each question has these fields:
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | predicate, choice, or score. |
instructions | string | Yes | Instructions for evaluating the input. |
name | string | Yes | A name, unique within the request. |
choices | object[] | For choice | At least two allowed options, each with a unique string or boolean value and an optional description. |
levels | object[] | For score | At least two ordered levels, each with a label and an optional description. Indices start at 0. |
Write instructions that describe the decision and provide the evidence separately in input. Descriptions help distinguish similar choices or scoring levels.
Predicate
Use predicate to estimate whether a condition is true.
curl -X POST "https://api.zoom.us/v2/aiservices/decisions/decide" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"input": "Our production deployment has failed and all customers are currently unable to sign in. Engineering is investigating.",
"questions": [
{
"type": "predicate",
"name": "needs_escalation",
"instructions": "Does this customer request require escalation?"
}
]
}'
A successful request returns HTTP 200. This example shows the response fields used to handle a predicate; probability values depend on the input and model.
{
"request_id": "WEB_8d4f2a6c1e9b47d3a5f0c2e8b6d1a9f4",
"answers": [
{
"type": "predicate",
"name": "needs_escalation",
"probability": 0.9842558435145301
}
],
"model": "zoom-decisions",
"usage": {
"input_units": 121,
"output_units": 1,
"unit_type": "tokens"
}
}
probability ranges from 0 to 1. Choose an application-specific threshold for acting on the result. The API does not return a separate true-or-false answer.
Choice
Use choice to select one of your allowed values. This request body routes a customer request to a team.
{
"input": "I was charged twice for my subscription this month. Please refund the duplicate charge.",
"questions": [
{
"type": "choice",
"name": "route",
"instructions": "Which team should handle this customer request?",
"choices": [
{
"value": "sales",
"description": "Sales inquiries and purchasing."
},
{
"value": "support",
"description": "Technical issues and product assistance."
},
{
"value": "billing",
"description": "Payments, invoices, and refunds."
}
]
}
],
"reference_id": "customer-request-123"
}
The corresponding answer contains the selected value and a probability for each option:
{
"type": "choice",
"name": "route",
"choice": "billing",
"probabilities": [
{ "value": "sales", "probability": 0.00016004903988422927 },
{ "value": "support", "probability": 0.00028680817166698986 },
{ "value": "billing", "probability": 0.9995531427884488 }
]
}
Choice values must be unique within a question. The API treats Boolean true and string "true" as duplicates.
For Boolean choices, choice is a Boolean, while probabilities[].value is the string "true" or "false".
Score
Use score to evaluate input against an ordered scale. Order levels from the lowest to the highest score.
{
"input": "The Export button does nothing in Safari. I can still download the report by opening it in Chrome, but switching browsers is inconvenient.",
"questions": [
{
"type": "score",
"name": "severity",
"instructions": "Rate how much this bug prevents the user from completing their task.",
"levels": [
{
"label": "Cosmetic",
"description": "A visual issue that does not affect completing the task."
},
{
"label": "Workaround available",
"description": "The task is disrupted, but the user can complete it using a workaround."
},
{
"label": "Fully blocked",
"description": "The user cannot complete the task and has no workaround."
}
]
}
]
}
The corresponding answer contains a probability-weighted average of the level indices:
{
"type": "score",
"name": "severity",
"score": 1.0000946765192886,
"probabilities": [
{ "value": 0, "probability": 0.0014679791237446312 },
{ "value": 1, "probability": 0.9969693652332221 },
{ "value": 2, "probability": 0.0015626556430332545 }
]
}
For N levels, score is between 0 and N - 1 and may fall between discrete levels. It is calculated as the sum of each level index multiplied by its probability. It is not a selected level index.
Each entry in probabilities contains the level index in value and its probability. The response does not repeat the level's label; look it up in the submitted levels[value].label.
Multiple questions
Combine independent predicate, choice, and score questions in the same questions array to evaluate the same evidence in one request. Answers correspond to the questions in request order and repeat each question's required name.
{
"input": "Our production deployment has failed and all customers are unable to sign in.",
"questions": [
{
"type": "predicate",
"name": "needs_escalation",
"instructions": "Does this require escalation?"
},
{
"type": "choice",
"name": "route",
"instructions": "Which team should handle this?",
"choices": [
{
"value": "support",
"description": "Customer support issues."
},
{
"value": "engineering",
"description": "Product or infrastructure failures."
}
]
}
]
}
If one decision depends on another, wait for the first result and submit a separate request containing the next question.
Text and image messages
For structured input, provide an array of messages with role set to user. Each message contains a content array of input_text and/or input_image parts.
{
"enable_image_input": true,
"input": [
{
"role": "user",
"content": [
{
"type": "input_text",
"text": "Evaluate the condition of this package."
},
{
"type": "input_image",
"image_url": "data:image/jpeg;base64,<BASE64_IMAGE_DATA>",
"detail": "auto"
}
]
}
],
"questions": [
{
"type": "choice",
"name": "package_condition",
"instructions": "Classify the visible condition of the package.",
"choices": [
{ "value": "undamaged", "description": "No visible damage." },
{
"value": "minor_damage",
"description": "Minor cosmetic damage."
},
{
"value": "major_damage",
"description": "Significant visible damage."
}
]
}
]
}
Replace <BASE64_IMAGE_DATA> with the image's Base64-encoded bytes. Images must use inline data URLs. The optional image detail field accepts auto, low, high, or original.
Requests containing images must set enable_image_input to true. Files, audio, tool calls, function-call results, and message roles other than user are not supported.
Handle responses
| Field | Description |
|---|---|
request_id | Request identifier for tracing and support. |
answers | Ordered answers for the submitted questions. |
model | Canonical model identifier used to process the request. Requests using the zoom-decisions-standard alias return zoom-decisions. |
usage | Metered usage, including input_units, output_units, and unit_type. Optional details can contain additional token counts. |
Choice and score answers may omit confidence. Use the returned probabilities in your decision rules.
A question can return type: "refusal" instead of a decision result. Check the answer type before accessing its decision fields. Other independent questions in the request can still return answers.
{
"type": "refusal",
"name": "needs_escalation"
}
Request validation and errors
Provide text or user messages in input and at least one question. Each question needs a unique name, a supported type, and instructions. Choice questions need at least two unique values; score questions need at least two levels. Image requests require explicit opt-in and valid image encoding.
Invalid requests return HTTP 400 with a reason and a message. The message can identify a specific field or give general guidance to check the request:
{
"code": 400,
"reason": "INVALID_INPUT",
"message": "input_image requires \"enable_image_input\": true",
"metadata": {}
}
| Reason | Example cause |
|---|---|
VALIDATION_MISSING_FIELD | A question has no instructions. |
INVALID_INPUT | A missing or duplicate question name, fewer than two choices or levels, an unsupported question type or model, a duplicate choice value, or an image without enable_image_input. |
Requests exceeding the service's input, payload, question, choice, level, or image limits are rejected. Account rate limits and concurrency quotas also apply. For rate-limited requests, follow the Retry-After header when it is provided. If the service is temporarily unavailable, it returns HTTP 503; retry after the number of seconds in metadata.retry_after_seconds.
Keep request_id when it is provided for troubleshooting. Error bodies can omit it. Do not treat an error or refusal as a scored answer.