# Analytics API Source: https://docs.voiceflow.com/api-reference/analytics-api/overview Query usage metrics, access transcripts, and evaluate conversation quality. The Analytics API gives you programmatic access to data about how your agent is performing. You can use it to [query aggregate usage metrics](/api-reference/usage/query-usage), [retrieve conversation transcripts](/api-reference/transcript/search-transcripts), and [run automated evaluations](/api-reference/transcript-evaluation/run-transcript-evaluation) to assess conversation quality at scale. ## Endpoints | Endpoint | Description | | | ------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------- | | **Usage** | | | | POST [Query usage](/api-reference/usage/query-usage) | Query aggregate usage metrics for a project. Supports interactions, sessions, unique users, top intents, credit consumption, function usage, API calls, knowledge base documents, integrations, transcripts, and per-agent activity. | | | **Transcript** | | | | POST [Search transcripts](/api-reference/transcript/search-transcripts) | Search for transcripts matching a set of filters. Supports filtering by date range, environment, session ID, custom properties, and evaluation results. | | | GET [Get transcript](/api-reference/transcript/get-transcript) | Fetch a single transcript with its full conversation logs, properties, and evaluation results. | | | DELETE [Delete transcript](/api-reference/transcript/delete-transcript) | Permanently remove a transcript along with its logs and all evaluation results. | | | POST [End transcript](/api-reference/transcript/end-transcript) | Mark a transcript as complete. Triggers any enabled evaluations to run automatically. | | | **Transcript property** | | | | GET [Get all transcript properties](/api-reference/transcript-property/get-all-transcript-properties) | List all custom property definitions for a project. | | | GET [Get transcript property](/api-reference/transcript-property/get-transcript-property) | Fetch the definition of a single transcript property. | | | POST [Create transcript property](/api-reference/transcript-property/create-transcript-property) | Define a new custom property for tagging transcripts in a project. | | | PATCH [Update transcript property](/api-reference/transcript-property/update-transcript-property) | Update the name or type of an existing transcript property definition. | | | DELETE [Delete transcript property](/api-reference/transcript-property/delete-transcript-property) | Remove a property definition and its values from all transcripts in the project. | | | **Transcript property value** | | | | GET [Get all transcript property values](/api-reference/transcript-property-value/get-all-transcript-property-values) | Retrieve all property values set on a specific transcript. | | | POST [Set transcript property value](/api-reference/transcript-property-value/set-transcript-property-value) | Attach a value to a property on a specific transcript. | | | DELETE [Delete transcript property value](/api-reference/transcript-property-value/delete-transcript-property-value) | Remove a single property value from a transcript without affecting the property definition. | | | **Transcript evaluation** | | | | GET [Get all evaluations](/api-reference/transcript-evaluation/get-all-evaluations) | List all evaluation definitions for a project, including result counts per evaluation. | | | GET [Get transcript evaluation](/api-reference/transcript-evaluation/get-transcript-evaluation) | Fetch the definition of a single evaluation. | | | POST [Create transcript evaluation](/api-reference/transcript-evaluation/create-transcript-evaluation) | Define a new LLM-based evaluation. Supports boolean, numeric rating, free-text, and option types. | | | PATCH [Update transcript evaluation](/api-reference/transcript-evaluation/update-transcript-evaluation) | Update the definition of an existing evaluation, including its prompt, model settings, and type-specific fields. | | | DELETE [Delete transcript evaluation](/api-reference/transcript-evaluation/delete-transcript-evaluation) | Remove an evaluation definition along with all its results across every transcript. | | | POST [Run transcript evaluation](/api-reference/transcript-evaluation/run-transcript-evaluation) | Run a single evaluation against a specific transcript and return the result immediately. | | | POST [Batch run transcript evaluations](/api-reference/transcript-evaluation/batch-run-transcript-evaluations) | Queue up to 10 evaluations across up to 100 transcripts in a single request. | | | POST [Estimate transcript evaluation](/api-reference/transcript-evaluation/estimate-transcript-evaluation) | Calculate the expected cost of running evaluations against transcripts matching a set of filters before committing to a batch run. | ## Concepts | ### Transcripts [Transcripts](/documentation/measure/transcripts) are full records of each conversation. You can [search](/api-reference/transcript/search-transcripts), [retrieve](/api-reference/transcript/get-transcript), and [delete](/api-reference/transcript/delete-transcript) them, or [mark them as ended](/api-reference/transcript/end-transcript). Ending a transcript signals that the conversation is complete and triggers any enabled evaluations to run automatically. Transcript properties are custom metadata fields you define at the project level and attach to individual transcripts. They're useful for tagging conversations with context that isn't captured automatically, such as a support ticket ID or a user segment. Once defined, you can filter transcript searches by property values. ### Evaluations [Evaluations](/documentation/measure/evaluations) are automated, LLM-based quality assessments that run against your transcripts. You define an evaluation with a prompt describing what you're measuring and an output type - a pass/fail boolean, a numeric rating, a free-text response, or a selection from a predefined set of options. Evaluations can run automatically whenever a transcript ends, or you can [trigger them manually against individual transcripts](/api-reference/transcript-evaluation/run-transcript-evaluation) or [in batches](/api-reference/transcript-evaluation/batch-run-transcript-evaluations). # Overview Source: https://docs.voiceflow.com/api-reference/api-overview Build custom integrations and manage your agents programmatically. Voiceflow's APIs let you build custom interfaces, manage your knowledge base programmatically, access transcripts and analytics, and integrate Voiceflow into your existing systems. To get started, you'll need a Voiceflow API key. Open **Settings** → **API keys** in your project to generate one. ## APIs Interact with your AI Agents via API. Pull your usage data, transcripts, evaluations, and more. Manage and query your Knowledge Base. Manage your Voiceflow projects and environments. ## Webhooks Receive events whenever phone calls start or end. Receive events when projects are created, published, or deleted. # Authentication Source: https://docs.voiceflow.com/api-reference/authentication Connecting to your agent via Voiceflow's APIs. All requests to Voiceflow's APIs require an API key, a project ID, and in most cases an environment alias. These three values tell the API who you are, which agent you're targeting, and which environment of it to run. ## Finding your API key API keys are managed in **Settings** → **API keys**. Each project has its own API key, and all Voiceflow API keys begin with `VF.DM.`. Clean Shot 2026 03 13 At 12 43 30@2x You can have a primary key and a secondary key active at the same time. This is useful for rotating keys without downtime - generate a secondary key, update your integration to use it, then promote it to primary and delete the old one. To create a secondary key, click the **...** menu next to your primary key and select **Create secondary key**. Once you're ready to rotate, click **Promote** next to the secondary key to make it primary. Pass your API key in the `Authorization` header of every request: ```bash theme={null} Authorization: VF.DM.your_api_key ``` Never share your API key or commit it to source control. ## Project ID and environment alias Your project ID is available in **Settings** → **General** under the **Metadata** section. Clean Shot 2026 03 13 At 12 45 30@2x The **Project ID** identifies your agent and is required for most API requests. To identify which environment to target, pass its **alias**. Every environment in a project has a short, URL-safe alias you can copy from the **Alias** column in **Settings** → **Environments**. By default, a new project has a single environment called **Main** with alias `main`. Aliases are static, so you can rename an environment without breaking any integrations that point at it. Using an alias (rather than a specific version ID) means your integration always targets whichever version is currently live for that environment, so your users pick up changes as soon as you publish them. See [Environments](/documentation/deploy/environments) for the full model. If your project was created before environments launched and has not yet been migrated, you can continue to use the legacy `development`, `staging`, and `production` aliases. After migrating, switch your integrations to use your new environment aliases. # Interact - legacy (stream) Source: https://docs.voiceflow.com/api-reference/conversation/interact--legacy-stream /specs/general-runtime/openapi.public.json post /v2/project/{projectID}/user/{userID}/interact/stream This endpoint is deprecated. Use the [Interact (stream)](/api-reference/conversation/interact-stream) endpoint instead. This legacy endpoint will continue to work for now, and we'll communicate a timeline for removal when one is available. We recommend migrating as soon as possible. Returns a stream of trace events followed by an end event using [SSE](https://en.wikipedia.org/wiki/Server-sent_events). # Completion Events Source: https://docs.voiceflow.com/api-reference/conversations-api/completion-events When conversing with LLMs such as ChatGPT or Claude, you notice that unlike human communications, where we send complete message by complete message, it "streams" in the text one piece at a time, and not even necessarily in complete words. LLMs work by generating their responses token by token. It can take quite long for an LLM to write a complete paragraph - even for the fastest models. With the **Response AI / Prompt** step, by default the API will wait for the entire response to be generated before sending the text back. This can often take a few seconds and mean users have to wait a long time and then suddenly get a very long message. By setting the `?completion_events=true` query parameter in the [Interact Stream](/api-reference/v4interact/interact-stream) API, Voiceflow will return output from the **Response AI / Prompt** steps as a text stream as it's generated, which can be shown to the user on an interface capable of handling partial responses. > 📘 Only the **Response AI / Prompt** step produces completion events ## Example Response `completion_events=false` ```json Response theme={null} event: trace id: 1 data: { "type": "text", "payload": { "message": "Welcome to our service. How can I help you today? Perhaps you're interested in our latest offers or need assistance with an existing order? Let me know if you have any other questions!", }, "time": 1725899197143 } event: end id: 2 ``` This is what a response might look like normally. The user might have to wait a bit before seeing the message. ## Example Response `completion_events=true` ```json Response theme={null} event: trace id: 1 data: { "type": "completion", "payload": { "state": "start" }, "time": 1725899197143 } event: trace id: 2 data: { "type": "completion", "payload": { "state": "content", "content": "Welcome to our service. How can I help you today? Perh", }, "time": 1725899197144 } event: trace id: 3 data: { "type": "completion", "payload": { "state": "content", "content": "aps you're interested in our latest offers or need ", }, "time": 1725899197145 } event: trace id: 4 data: { "type": "completion", "payload": { "state": "content", "content": "assistance with an existing order? Let", }, "time": 1725899197146 } event: trace id: 5 data: { "type": "completion", "payload": { "state": "content", "content": " me know if you have any other questions!", }, "time": 1725899197147 } event: trace id: 6 data: { "type": "completion", "payload": { "state": "end", }, "time": 1725899197148 } event: end id: 7 ``` With `completion_events` turned on, it still takes the same total time to get the entire message, but the user will be able to see the first chunk of text within milliseconds: *Welcome to our servi..."* Enabling `completion_events` means the API will return a `completion` trace instead of a `text` (or `speak`) trace. There is a `payload.state` property which is one of three values: * `state: "start"` to signal the start of a completion stream. * `state: "content"` to stream in additional text to the same text block, under the `content` property * `state: "end"` to signal that the completion is now finished, and the final LLM token usage These trace types facilitate the delivery of text streaming as the large language model (LLM) generates the response message. Note, the `content` data may not always be in complete sentences or words. It is the responsibility of the API caller to stitch the data together and have it reflect live on the conversation interface. ## Examples See our [`streaming-wizard`](https://github.com/voiceflow/streaming-wizard) demo (NodeJS). Note the use of the `"end"` state as a marker to start a new line in the conversation. ## Deterministic and Streamed Messages It may be jarring to pair this with existing deterministic messages that come out fully completed. Some messages stream in, while others are sent as whole. To mitigate this, you can either: * create a fake streaming effect for deterministic messages that matches what messages streamed through completion events look like * accumulate enough completion traces to form a complete sentence, and send group streamed responses into sentences before displaying them. Look for delimiters such as `.` `?` `!` `;` `\n` (newline). You can then send the completion as a group of smaller complete messages. # Interact (socket) Source: https://docs.voiceflow.com/api-reference/conversations-api/interact-socket The Voiceflow WebSocket runtime uses [socket.io](https://socket.io/) to establish persistent, bidirectional connections for real-time conversational AI interactions. Find the [socket.io client](https://github.com/socketio) in your respective development language. This documentation will use javascript, but the fundamentals remain the same. ## Connection configuration ```js theme={null} import { io } from 'socket.io-client'; const socket = io('https://general-runtime.voiceflow.com', { path: '/v4/interact/socket', timeout: 10000, transports: ['websocket', 'polling', 'webtransport'], // optional fallbacks reconnection: true, tryAllTransports: true, reconnectionDelay: 1000, reconnectionAttempts: 5, reconnectionDelayMax: 5000, }); ``` [socket.io](http://socket.io) allows for fallback transports if the end-client does not allow the websocket protocol (wss\://), common in many firewalls and enterprise settings. ## Lifecycle A session is not the same as the socket.io connection. You can disconnect/reconnect multiple times and still continue the same conversation session. For more information on socket.io lifecycle management, reference [documentation](https://socket.io/docs/v4/client-api/). ### Initialization sequence 1. Wait for `connect`. This is a socket.io level connection established. 2. Send `client.start`. Send voiceflow project metadata/config + optional `sessionKey`. 3. Wait for `client.started`. Client handshake, confirms configuration. 4. If `client.started` specifies `newSessionRequired`: 1. Send `session.create`. 2. Wait for `session.created`. Save returned `sessionKey` for future use. 5. Agent is now ready for interactions ```ts theme={null} // save sessionKey on client side for future reconnections let sessionKey: string | undefined; // socket.io level connection socket.on('connect', () => { // voiceflow client handshake socket.emit('client.start', { sessionKey, ...metadata }); socket.once('client.started', (payload: { newSessionRequired: boolean }) => { if (payload.newSessionRequired === false) { return ready(); } // session create handshake socket.emit('session.create', {}); socket.once('session.created', (payload: { sessionKey: string }) => { sessionKey = payload.sessionKey; ready(); }); }); }) ``` ### Action Lifecycle Once the session is ready, you can now send actions to the agent and get responses back. 1. send new action with `action.send`, i.e. `{ type: 'text', payload: 'hello' }` 2. get back a status `action.status` either `status: 'accepted' | 'rejected'` 3. if `status: accepted`: 1. get back agent responses with `action.trace`, display to user 2. get `action.status` with `status: 'completed'` This represents the back and forth conversation with the agent. Try to not send a new action while an existing action is running. While this is supported, it can make it harder to debug user state and lead to certain race conditions. Instead wait for `status: 'completed'` or `status: 'rejected'` after sending an action. ### Conversation Lifecycle #### Start To start the conversation from the beginning, your first action should be: ```ts theme={null} socket.emit('action.send', { action: { type: 'launch', payload: {} } }); ``` It is also possible to launch from specific points in the conversation with [events](https://docs.voiceflow.com/docs/introduction-to-events): ```ts theme={null} socket.emit('action.send', { action: { type: 'event', payload: { event: { name: 'event_name' } } } }); ``` #### End The session ending also signals that the conversation has ended. This can also occur because of timeouts. ```ts theme={null} socket.on('session.ended', () => { // cleanup code }) ``` ## Client events ### `client.start` Initial Voiceflow metadata and configuration to validate and set up the client. This is aways the first message that the client should send to the server after socket.io successfully connects. Server will respond with `client.started`. #### Payload `?:` denotes optional properties. ```ts theme={null} interface ClientStartPayload { userID: string; // primary user identifier projectID: string; // voiceflow projectID // alias of the environment to use. Omit to route the session via the project's // traffic split (hashed by userID, so a given userID routes consistently). environmentID?: string; // session to reconnect to, ignore if new session sessionKey?: string | null; // voiceflow project API Key (under settings), do not set for public facing clients authorization?: string; config?: { // break up LLM responses into live chunks [default: false] completionEvents: boolean; // timezone in IANA (tz database) for the vf_user_timezone variable userTimezone?: string; audioEvents: boolean; // enable TTS audio chunk responses audioEncoding?: 'audio/x-mulaw' | 'audio/pcm'; // audio response format }; } ``` #### Example Call ```ts theme={null} socket.emit('client.start', { userID: 'test@test.com', projectID: '6939bedf69c7ce5ee7a108ed', authorization: 'VF.DM...', config: { completionEvents: true }; }); ``` ### `session.create` Creates a new session for the user. Should be sent after `client.started` indicates `newSessionRequired: true`. Server will respond with `session.created`. #### Example Call ```ts theme={null} socket.emit('session.create', {}); ``` ### `action.send` Sends a user action to the server. A valid session must already exist. Server will respond with `action.status` and `action.trace` events. [See possible action types in the `action` body of interaction requests.](/api-reference/v4interact/interact-stream). #### Payload ```ts theme={null} interface ActionSendPayload { action: { // request type: "text" | "intent" | "launch" | "event" | "action" | etc. type: string; // action-specific payload payload?: string | object; }; } ``` #### Example Call ```ts theme={null} socket.emit('action.send', { action: { type: 'text', payload: 'Hello, how are you?' } }); ``` ## Server events ### `client.started` Server ack to `client.start`, informs if a new session needs to be created #### Payload ```ts theme={null} interface ClientStartedPayload { newSessionRequired: boolean } ``` #### Example ```ts theme={null} socket.on('client.started', (payload: ClientStartedPayload) => { if (payload.newSessionRequired) { socket.emit('session.create', {}); } else { // session is now ready for interactions } }); ``` ### `session.created` Confirms that a new session has been created. Client should store the `sessionKey` for future reconnections. #### Payload ```ts theme={null} interface SessionCreatedPayload { sessionKey: string; // JWT session key to store and use for reconnections } ``` #### Example ```ts theme={null} socket.on('session.created', (payload: SessionCreatedPayload) => { localStorage.setItem('sessionKey', payload.sessionKey); // session is now ready for interactions }); ``` ### `session.ended` Indicates that the conversation session has ended. Client should close the session and optionally display a workflow to create a new one. #### Payload ```ts theme={null} interface SessionEndedPayload { // reason for session ending (e.g., "end_of_diagram", "inactivity_timeout", etc.) reason: string; } ``` ### `action.trace` Represents agent responses and debugging information for an action. [See possible trace types](/api-reference/trace-types). #### Payload ```ts theme={null} type ActionTracePayload = { // trace object containing agent response data (speak, text, audio, etc.) trace: Trace; // message identifier matching the action.send messageID messageID: string; } ``` #### Example ```ts theme={null} socket.on('action.trace', (payload: ActionTracePayload) => { // Handle trace data (speech, text, audio chunks, etc.) console.log('Trace received:', payload.trace); }); ``` ### `action.status` Indicates the status of an action that was sent via `action.send`. This event is sent when an action is accepted, rejected, or completed. #### Payload ```ts theme={null} interface ActionStatusPayload { status: 'accepted' | 'rejected' | 'completed'; // action status messageID: string; // message identifier matching the action.send messageID reason?: string; // optional reason for rejection or completion } ``` ### `server.restart` Server is gracefully shutting down and informing the client to reconnect to a different server instance. #### Payload ```ts theme={null} interface ServerRestartPayload { action?: { type: string; payload?: string | object; diagramID?: string; time?: number; }; // optional action to replay after reconnection } ``` ### `error` General error message from the server. May occur at any point during the connection. #### Payload ```ts theme={null} interface ErrorPayload { code?: string; // optional error code error: string; // error message } ``` # Conversations API Source: https://docs.voiceflow.com/api-reference/conversations-api/overview Use the Conversations API to run turns, manage session state, inject variables, and control your Voiceflow agent's runtime over HTTP. Voiceflow's Conversations API allows you to programmatically interact with a Voiceflow agent. This allows you to build custom interfaces for users to access your agent through, or to pull information about active sessions into your tooling. You can use the Conversations API to run [conversation turns](/api-reference/v4interact/interact-non-stream), [send events](/api-reference/session/emit-session-event), [read](/api-reference/state/get-conversation-state) and [modify session state](/api-reference/state/update-conversation-state), and [inject variables](/api-reference/state/update-conversation-variables) - giving you full control over how your agent runs inside your own application. ## Available endpoints | Endpoint | Description | | -------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Conversation** | | | POST [Interact (non-stream)](/api-reference/v4interact/interact-non-stream) | Returns an array of traces in response to a user interaction. Accepts state variables, request, action, and config in the body. | | POST [Interact (stream)](/api-reference/v4interact/interact-stream) | SSE endpoint that returns a stream of `trace` events followed by an `end` event. Supports audio, completion streaming, modality selection, and state return. | | POST [Interact - legacy (non-stream)](/api-reference/state/interact--legacy-non-stream) | **Deprecated** Returns an array of traces in response to a user interaction. Accepts state variables, request, action, and config in the body. | | POST [Interact - legacy (stream)](/api-reference/conversation/interact--legacy-stream) | **Deprecated** SSE endpoint that returns a stream of `trace` events followed by an `end` event. Supports audio, completion streaming, modality selection, and state return. | | **State** | | | GET [Get conversation state](/api-reference/state/get-conversation-state) | Fetches the current state of a user's conversation, including stack, variables, and storage. | | PUT [Update conversation state](/api-reference/state/update-conversation-state) | Replaces the full state of a user's conversation (stack, variables, storage). | | DEL [Delete conversation state](/api-reference/state/delete-conversation-state) | Deletes all state and session data for a user's conversation. | | PATCH [Update conversation variables](/api-reference/state/update-conversation-variables) | Merges the provided variables into the user's current conversation state. | | **Session** | | | POST [Start session](/api-reference/v4interact/start-session-specific-environment) | Starts a new voiceflow conversation session. Used for v4 session management. | | POST [Emit session event](/api-reference/session/emit-session-event) | Sends an event to an active session. Useful for injecting actions mid-conversation. | ## Actions and traces When a user [interacts](/api-reference/v4interact/interact-non-stream) with your agent, the request goes to Voiceflow's runtime - the engine that processes each conversation turn, runs your agent's logic, and produces a response. The Conversations API is your interface to that runtime. Each turn follows a request-response pattern. Your application sends an **action** describing what happened on the user's side, and the runtime processes it and returns a set of **traces** describing how the agent responds. An action can be a user's message, a launch request to start a new conversation, a button selection, a system event, a no-reply signal, or a handoff continuation. The most common is `text`: ```json theme={null} { "action": { "type": "text", "payload": "I need help with my order" } } ``` Traces are the agent's output. Each turn returns an array of trace objects - a single response often contains several in sequence. For example, a `text` trace with a message, then a `choice` trace presenting reply options. Your application is responsible for rendering each trace type appropriately. See [Trace types](/api-reference/trace-types) for a complete reference. ## Session state Voiceflow maintains state for each user across turns using the `userID` you provide. In most cases this is automatic, but the state endpoints give you direct access when you need it. You can [fetch a user's current state](/api-reference/state/get-conversation-state), [update it](/api-reference/state/update-conversation-state), or [delete it to reset the session](/api-reference/state/delete-conversation-state) - useful for testing, debugging, or building custom session management into your integration. ## Variables Variables let you pass context into an agent's session that it can reference during a conversation. You can [update a user's variables at any point](/api-reference/state/update-conversation-variables) without replacing the full session state. This is useful for pre-loading information before a conversation begins (eg: the user's name, account tier, or current page) so the agent can personalize its responses from the first turn. Note that variables are not automatically reset when a conversation's state is reset. ## Environments Each request runs against a specific environment in your project. Pass the environment's alias in the `environment` parameter to target it. By default, new projects have a single environment called **Main** with alias `main`; see [Environments](/documentation/deploy/environments) for how to create more. If your project was created before environments launched and has not yet been migrated, the legacy `development`, `staging`, and `production` aliases continue to work. # Overview Source: https://docs.voiceflow.com/api-reference/conversations-api/state-overview In Voiceflow, a dialog state is assigned to a unique `userID`. This `userID` can be any string and is typically something unique that easily references the person on the session - such as an username, email, device ID, or phone number. (e.g. `user54646`, `user@gmail.com`, `1-647-424-4242`, etc.). If you're not sure what to call it just for testing purposes, you can just pick a random `userID`. The response schema consists of two main properties: 1. Stack 2. Variables We will cover each property below, as well as an overview of the Voiceflow context model. ## Stack The stack is an array of flows that are currently active in the conversation. Each flow contains: * `programID`: the ID of the flow, which can be found in the URL of the address bar `https://creator.voiceflow.com/project/{versionID}/canvas/{programID}` * `nodeID`: current block this flow is on * `variables`: flow-scoped variables * `storage`: internal flow parameters for runtime * `commands` In the example below, you can see that there are three flows available on the stack (`620e669eac2f70001cf9d85a`, `620e669eac2f70001cf9d85b` and `620e669eac2f70001cf9d85c`) and we are currently sitting on flow `620e669eac2f70001cf9d85c`, as denoted by the `nodeID` pointing to a block within this flow. Note: the `programID` of the first flow in the stack is always the `versionID` of the Agent. Example stack: ```json theme={null} { "stack": [ { "nodeID": null, "programID": "620e669eac2f70001cf9d85a", //<-- versionID of the agent "storage": {}, "commands": [], "variables": {} }, { "nodeID": null, "programID": "620e669eac2f70001cf9d85b", //<-- starting flow "storage": { "output": [ { "children": [ { "text": "What size?" } ] } ] }, "commands": [], "variables": {} }, { "nodeID": "61f40992f0e4e70a1f2328d1", "programID": "620e669eac2f70001cf9d85c",//<-- top-level flow "storage": { "outputMap": null, "output": [ { "children": [ { "text": "You can get an additional pizza for half the price today. Would you like to do that?" } ] } ] }, "commands": [], "variables": { "discount_code": "DEAL4TWO" } } ] } ``` ## Variables The two ways you can create variable keys in your Interaction Model is through: 1. Entities 2. Variables The difference between Entities and Variables is how they are assigned values at runtime. An entity value is assigned through a user interaction (e.g. utterance) whereas a variable is dynamically assigned a value from the design itself based on a user action (e.g. through an API call or custom code). Variable examples ```json theme={null} { "variables": { "type": "pepperoni", "size": "large", "amount": 6, "sessions": 0, "user_id": "1234", "timestamp": 1645112935, "platform": 0, "locale": 0, "side": 0, "intent_confidence": 100, "last_utterance": "large" } } ``` ## Voiceflow Context Model In this video, we'll explain Voiceflow's entire Context Model in more detail.