> ## Documentation Index
> Fetch the complete documentation index at: https://docs.xpressbot.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Flow Dynamic Options and Endpoints

> Load WhatsApp Flow options and dates from your own server or from Google Calendar instead of typing them in, and keep the flow's endpoint working.

## What is this?

Normally you type a choice element's options into the [Flow Builder](/workspace/whatsapp/flows/builder). **Dynamic** options are loaded while the customer is using the flow instead — from a web address you control, or from open slots in a Google Calendar. This is how you build things like appointment booking, where the available times depend on the date a customer picks.

You choose this per element in its settings, under **Static / Dynamic source**. It is available on **Single choice**, **Multiple choice**, **Dropdown**, **Chips**, and **Navigation list**. **Date picker** and **Calendar** have their own endpoint options for minimum and maximum dates, and **Calendar** for unavailable dates.

\[SCREENSHOT: flows-dynamic-endpoint — The Static / Dynamic source section of a Dropdown set to Dynamic from endpoint, showing the How the endpoint is called help, the Endpoint URL box, Depends on field, and the Preview Resolve button]

<Info>
  A flow that loads data from your server needs the flow endpoint and encryption key to be in place. Flows you create with **Create Flow** use your workspace's endpoint automatically, and the **Versions / Endpoint** column on the [Flows](/workspace/whatsapp/flow) page shows whether it is set. Google Calendar options also need a connected Google account — see [Google Calendar](/workspace/google/calendars).
</Info>

## What can I do here?

* Load a choice element's options from your own URL
* Show available appointment slots from a Google Calendar
* Make a date picker's earliest or latest date follow today's date or your own URL
* Block specific calendar days from your own URL
* Check what a source returns with **Resolve** before you save

## How to use it

### Switch an element to a dynamic source

<Steps>
  <Step title="Select the element">
    Click the choice element in the preview and scroll to **Static / Dynamic source** in its settings.
  </Step>

  <Step title="Choose Dynamic">
    Click **Dynamic**. A **Source mode** list appears with **Dynamic from endpoint** and **Dynamic from Google Calendar**. Click **Static** at any time to go back to typing options (**Static options**, or **Navigation items** for a **Navigation list**).
  </Step>

  <Step title="Fill in the source">
    Complete the settings for the mode you chose (below), click **Resolve** to try it, then **Save** the flow.
  </Step>
</Steps>

### Dynamic from endpoint

Choose **Dynamic from endpoint** and enter an **Endpoint URL** (for example `https://api.example.com/flow/options`).

The panel **How the endpoint is called** explains how it works. In short:

* The platform sends a `GET` request to your URL exactly as you wrote it.
* If your options depend on an earlier answer, put the token `custom.<field_name>` in the URL where the value belongs, using the **Field name** of that answer. When the customer answers, the token is replaced with their value.
* If the URL already has parameters such as an API key, they are kept.

```text theme={null}
Configured: https://api.example.com/options?key=YOUR_KEY&date=custom.appointment_date
At runtime: https://api.example.com/options?key=YOUR_KEY&date=2026-04-10
```

Your URL must return JSON in the shape shown under **Expected response**:

<Tabs>
  <Tab title="Single choice, Multiple choice, Dropdown, Chips">
    ```json theme={null}
    [
      { "id": "opt1", "title": "Option 1" },
      { "id": "opt2", "title": "Option 2" }
    ]
    ```
  </Tab>

  <Tab title="Navigation list">
    ```json theme={null}
    [
      { "id": "item_1", "title": "Morning slot", "description": "09:00 AM" },
      { "id": "item_2", "title": "Afternoon slot", "description": "02:00 PM" }
    ]
    ```
  </Tab>
</Tabs>

**Depends on field (optional)** lets the options depend on a **Date picker** or **Calendar** earlier in the flow. Choose it, then use `custom.` followed by that field's name in the URL — the panel tells you the exact token to use. Leave it on **No dependency** if the options don't change. If the flow has no date field yet, the panel notes "Add a DatePicker field only if your endpoint needs the selected date to return values."

Under **Preview**, click **Resolve** to call the URL now. **Resolved values** lists up to ten returned options (an `id` and a title each), and a **Dynamic data resolved** message says how many values came back. "No values returned." means the URL answered with nothing. A **Resolve failed** message shows why a call failed, and **Dynamic source disabled** means you haven't turned **Dynamic** on for the element.

### Dynamic from Google Calendar

\[SCREENSHOT: flows-dynamic-calendar — A Dropdown set to Dynamic from Google Calendar showing Google Calendar, Lookahead days, Depends on date field, Slot duration (min), Working start, and Working end]

Choose **Dynamic from Google Calendar** to offer open time slots from one of your calendars. Settings:

| Setting | What it does |
| - | - |
| **Google Calendar** | The calendar to read, from the **Select calendar** list. If none appear you'll see "No calendars found for this channel. Connect Google Calendar first." — connect it under **Channels → Google** |
| **Lookahead days** | How many days ahead to look for slots, 1 to 90. Starts at 14 |
| **Depends on date field** | The **Date picker** or **Calendar** whose chosen date decides which day's slots to show. Required. If there is none yet you'll see "Add a DatePicker field first. Calendar time slots need the user's selected date." |
| **Slot duration (min)** | The length of each slot, 5 to 240 minutes. Starts at 30 |
| **Working start** / **Working end** | The hours slots are offered between, written like `09:00` and `18:00` |

Click **Resolve** (under **Preview values**) to see the slots the calendar would offer.

<Note>
  This only shows open slots. It does not reserve the one the customer picks, so the next customer could be offered the same time. To block the slot, add a **Google Calendar** step after the flow in your [automation](/workspace/automation/overview) to create the event.
</Note>

### Dates from an endpoint

On **Date picker** and **Calendar** elements, **Min Date** and **Max Date** can each be **Static** (a fixed date) or **Dynamic**. For **Dynamic**, choose a **Source mode**:

* **Current date** — "Uses current date at runtime."
* **Endpoint** — enter an **Endpoint URL** that returns a date, either `"2026-04-20"`, `{ "date": "2026-04-20" }`, or `{ "value": "2026-04-20" }`.

For a **Calendar**, **Unavailable Dates** can also be **Dynamic**: enter an **Endpoint URL** that returns a list such as `["2026-04-20", "2026-04-21"]` or `{ "dates": ["2026-04-20"] }`.

### Keep the flow's endpoint working

On the [Flows](/workspace/whatsapp/flow) page, the **Versions / Endpoint** column shows **Endpoint: OK**, **Mismatch**, or **Missing** for each flow. Click **Update Endpoint** on a row, or the link icon above the table to fix every flow at once. The key icon sends your encryption key to WhatsApp — see [Flows](/workspace/whatsapp/flow#the-three-icon-buttons-at-the-top).

## Troubleshooting / Technical Notes

* **Save says the endpoint URL is empty.** You chose **Dynamic from endpoint** but left **Endpoint URL** blank. Fill it in, or switch the element back to **Static**.
* **Save says no calendar is selected.** Choose a calendar under **Google Calendar**. If the list is empty, connect Google first.
* **Save says the date field is empty.** Calendar time slots need a **Depends on date field**. Add a **Date picker** to the flow and select it.
* **Resolve fails or returns nothing.** Check the URL in a browser, that it returns JSON in the shape above, and that any `custom.` token matches the exact **Field name** of the earlier answer.
* **Customers see old or no options.** Make sure the endpoint is **OK** on the Flows page and that the flow was saved after you changed the source.
* **Calendar slots don't match my hours.** Check **Working start**, **Working end**, and **Slot duration (min)**, and that the right calendar is selected.

## Related docs

* [Flow Builder](/workspace/whatsapp/flows/builder)
* [Flow content and settings](/workspace/whatsapp/flows/content-and-settings)
* [Flows](/workspace/whatsapp/flow)
* [Google Calendar](/workspace/google/calendars)
* [Google](/workspace/google/overview)
* [Automation Overview](/workspace/automation/overview)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.