Questions
What an action asks you, and how to answer.
Sometimes a place needs something from you before it can help. The action then asks you a typed question.
An action asks only between calls, never while someone waits on the phone. The
call wraps up ("I'll check with the patient and call you back"). Then the
action moves to waiting_for_answer and sends action.question to your
webhook. It waits until you answer or cancel. There is no timeout, but a
question can say when something lapses, such as a held slot's held_until.
The question object
Every question has an id (q_...), the call_id of the call that raised
it, the question to show, an optional help line, a type, the fields that
type adds, an answer that is null while it is open, and asked_at and
answered_at times. The action reference
lists every field.
Types
type | Extra fields | Show the person | Answer value |
|---|---|---|---|
input | path: the input field to fill | The question, for that field | That field's own shape |
text | max_length, up to 2000 | A text box | Text |
number | integer, min, max | A number field | A number |
boolean | Yes and no | true or false | |
date | A date picker | A date as YYYY-MM-DD | |
choice | options (2 to 20, each id and label), multiple | The options | One option id, or a list when multiple |
slot | options (1 to 10, each id, slot, and held_until) | Each opening's time, place, and hold | One option id, or { "preferred_windows": [...] } to try other times |
Answer with { "value": ... }, or { "unavailable": true, "note": "..." }
when you cannot answer. The note is optional. An answer that breaks its type
or limits is refused with 400, and the question stays open.
The types each action type may ask:
- Pharmacy status:
input,text,number,boolean,date,choice - Pharmacy transfer:
input,text,number,boolean,date,choice - Pharmacy stock check:
input,text,number,boolean,date,choice - Find availability:
input,text,number,boolean,date,choice - Book appointment:
input,text,number,boolean,date,choice,slot - Reschedule appointment:
input,text,number,boolean,date,choice,slot - Cancel appointment:
input,text,number,boolean,date,choice
Slot questions
When nothing is open in the preferred windows, the office offers other times.
held_until says how long the office holds an opening, or is null.
{
"id": "<question_id>",
"call_id": "<call_id>",
"question": "Nothing was open in the preferred windows. Which of these times works?",
"help": "The office holds the first one until Tuesday at 5 PM.",
"type": "slot",
"options": [
{
"id": "opt_1",
"slot": {
"starts_at": "2026-11-10T09:30:00-08:00",
"duration_minutes": 40,
"provider": { "first_name": "Maya", "last_name": "Chen", "credential": "MD" },
"location": { "line1": "3000 Telegraph Ave", "city": "Oakland", "state": "CA", "postal_code": "94609" }
},
"held_until": "2026-11-03T17:00:00-08:00"
},
{
"id": "opt_2",
"slot": {
"starts_at": "2026-11-12T14:00:00-08:00",
"provider": { "first_name": "Maya", "last_name": "Chen", "credential": "MD" }
},
"held_until": null
}
],
"answer": null,
"asked_at": "2026-11-02T19:20:00.000Z",
"answered_at": null
}Input questions
An input question names one of the action type's optional input fields
that your request left empty, such as insurance or
prescription.rx_number. Vene checks your answer with that field's own rules
and saves it into the action's input.
A field inside an optional object, such as referral.referral_number, can be
asked only when the request sent that object. When the object is missing, the
question names the whole object, such as referral, and your answer is the
whole object.
The fields an input question can name, by action type:
- Pharmacy status:
pharmacy.address.line2,pharmacy.npi,pharmacy.phone,prescription.strength,prescription.form,prescription.quantity,prescription.rx_number,prescription.prescriber,prescription.prescriber.credential,prescription.prescriber.npi,prescription.prescriber.specialty,prescription.prescriber.practice,prescription.prescriber.practice.name,prescription.prescriber.practice.address.line2,prescription.prescriber.practice.phone,include_cash_price - Pharmacy transfer:
prescription.strength,prescription.form,prescription.quantity,prescription.rx_number,prescription.prescriber,prescription.prescriber.credential,prescription.prescriber.npi,prescription.prescriber.specialty,prescription.prescriber.practice,prescription.prescriber.practice.name,prescription.prescriber.practice.address.line2,prescription.prescriber.practice.phone,from_pharmacy.address.line2,from_pharmacy.npi,from_pharmacy.phone,to_pharmacy.address.line2,to_pharmacy.npi,to_pharmacy.phone,insurance,insurance.plan_name,insurance.group_number,insurance.rx_bin,insurance.rx_pcn,insurance.rx_group - Pharmacy stock check:
drug.form,include_cash_price - Find availability:
provider.credential,provider.npi,provider.specialty,provider.practice,provider.practice.name,provider.practice.address.line2,provider.practice.phone,reason,insurance_plan,insurance_plan.plan_name - Book appointment:
provider.credential,provider.npi,provider.specialty,provider.practice,provider.practice.name,provider.practice.address.line2,provider.practice.phone,insurance,insurance.plan_name,insurance.group_number,insurance.rx_bin,insurance.rx_pcn,insurance.rx_group,referral,referral.referring_provider.credential,referral.referring_provider.npi,referral.referring_provider.specialty,referral.referring_provider.practice,referral.referring_provider.practice.name,referral.referring_provider.practice.address.line2,referral.referring_provider.practice.phone,referral.referral_number - Reschedule appointment:
appointment.duration_minutes,appointment.provider.credential,appointment.provider.npi,appointment.provider.specialty,appointment.provider.practice,appointment.provider.practice.name,appointment.provider.practice.address.line2,appointment.provider.practice.phone,appointment.location,appointment.location.line2,appointment.confirmation_number,appointment.arrival_instructions - Cancel appointment:
appointment.duration_minutes,appointment.provider.credential,appointment.provider.npi,appointment.provider.specialty,appointment.provider.practice,appointment.provider.practice.name,appointment.provider.practice.address.line2,appointment.provider.practice.phone,appointment.location,appointment.location.line2,appointment.confirmation_number,appointment.arrival_instructions
Free questions
A text, number, boolean, date, or choice question can be about
anything a place said it needs, such as which pharmacy the patient prefers.
When "none" is a fair answer, the action offers it as a choice option.
Free answers reach the action as facts for its next call. They never change the input. Your software may not know them, so be ready to show the question to a person, or to hand it to an AI that can answer for the patient.
{
"id": "<question_id>",
"call_id": "<call_id>",
"question": "Which pharmacy should the new prescription go to?",
"help": "The office will send it today.",
"type": "choice",
"options": [
{ "id": "opt_walgreens", "label": "Walgreens on Broadway" },
{ "id": "opt_cvs", "label": "CVS on College Ave" },
{ "id": "opt_none", "label": "Neither" }
],
"answer": null,
"asked_at": "2026-11-03T16:40:00.000Z",
"answered_at": null
}Answering a batch
An action can open several questions at once, in one action.question event.
The open ones have answer: null. It opens new questions only after every
open one is answered, and action.questions keeps every question with its
answer.
- Answer them in one request, or one at a time, each by its
question_id. The action continues once every open question is answered. - Vene checks every answer in a request before it records any. One invalid
answer refuses the whole request with
400 invalid_request, andfieldnames it, such asanswers[1].answer.value. Nothing is half applied. - An
unavailableanswer ends the actionfailedwithdeclined_by_you. Every other open question is closed with{ "unavailable": true, "note": "..." }.
{
"answers": [
{ "question_id": "<question_id>", "answer": { "value": "opt_walgreens" } },
{ "question_id": "<question_id_2>", "answer": { "unavailable": true, "note": "The patient does not know." } }
]
}The second answer is unavailable, so the action ends failed with
declined_by_you. See Answer questions
for the endpoint.