Fast mode evaluates one or more typed questions against shared input. The HTTP response contains the completed answers.
Endpoint
POST /aiservices/decisions/decide
Include a Zoom AI Services JWT 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-standard (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 | What to evaluate about the shared input. |
name | string | No | Identifier returned in the corresponding answer. Names must be unique within the request. |
choices | object[] | For choice | Allowed options, each with a unique string or boolean value and an optional description. |
levels | object[] | For score | 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": "req_123",
"answers": [
{
"type": "predicate",
"name": "needs_escalation",
"probability": 0.9842558435145301
}
],
"model": "zoom-decisions-standard",
"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 }
],
"confidence": 0.99
}
Choice values must be unique within a question. Preserve the value's type when reading the answer: a boolean choice returns a boolean, rather than a string.
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,
"label": "Cosmetic",
"probability": 0.0014679791237446312
},
{
"value": 1,
"label": "Workaround available",
"probability": 0.9969693652332221
},
{
"value": 2,
"label": "Fully blocked",
"probability": 0.0015626556430332545
}
],
"confidence": 0.99
}
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 the level's label from your request.
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 name, when supplied.
{
"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 | Model tier used to process the request. |
usage | Metered usage, including input_units, output_units, and unit_type. Optional details can contain additional token counts. |
For choice and score, confidence indicates the model's confidence in the result, from 0 to 1. Use it together with the probability distribution in your application's 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 input and at least one question. Every question needs a supported type and instructions. Use unique question names and unique choice values. Image requests require explicit opt-in and a valid image encoding.
Invalid requests return HTTP 400 with a reason and a message that identifies the problem:
{
"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 | An unsupported question type or model, a duplicate question name, 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 for troubleshooting failed requests. Do not treat an error or refusal as a scored answer.