Docs

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

typeExtra fieldsShow the personAnswer value
inputpath: the input field to fillThe question, for that fieldThat field's own shape
textmax_length, up to 2000A text boxText
numberinteger, min, maxA number fieldA number
booleanYes and notrue or false
dateA date pickerA date as YYYY-MM-DD
choiceoptions (2 to 20, each id and label), multipleThe optionsOne option id, or a list when multiple
slotoptions (1 to 10, each id, slot, and held_until)Each opening's time, place, and holdOne 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:

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, and field names it, such as answers[1].answer.value. Nothing is half applied.
  • An unavailable answer ends the action failed with declined_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.

On this page