openapi: '3.1.0' info: version: 1.1.0 title: Voiceflow Dialog Management API description: > # Overview The **Dialog Manager API (DM API)** exposes the Voiceflow runtime and allows clients to start a conversation with a Voiceflow project. You can design a conversational interface using our [Voiceflow Creator](https://creator.voiceflow.com), then easily integrate the conversation into a variety of interfaces: chatbot, voice assistant, IVR, web chat, and more. Voiceflow IVR Integration **Note**: The Dialog Manager API can only be used to integrate Voiceflow **general projects**, that is, projects without a pre-existing third-party upload. Thus, Alexa, Google Actions, and Dialogflow ES projects on Voiceflow are instead accessed through their associated 3rd party platform, e.g, Alexa projects can be accessed by an Amazon Alexa device. # Quick Start To see the DM API in action, follow these steps: 1. **Create a project** - Build a conversational flow on the [Voiceflow Creator](https://creator.voiceflow.com). 2. **Render your project** - Ensure you're on the Designer tab by checking the left side bar. Then, click the Run button on the top-right corner to compile your project and make it available through the DM API. 3. **Get an API key** - Go to the Integration tab using the left sidebar and copy your project's API key. 4. **Copy a test call** - Copy one of the "API Call Examples" below and replace the API key variable with the API key you copied in step 2. 5. **Start the conversation** - Execute the API call to start a conversation and get a response from your Voiceflow app. 6. **Continue the conversation** - Change the user input variable and execute the API call again. The DM API tracks the current state of the conversation and may produce a different response to advance the conversation.
View API Call Examples
cURL command line API_KEY='VF.DM.xxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' USER_ID='user_123' USER_INPUT='Hello world!' curl --request POST "https://general-runtime.voiceflow.com/state/user/$USER_ID/interact" \ --header "Authorization: $API_KEY" \ --header "Content-Type: application/json" \ --header "versionID: 'development'" \ --data-raw "{ \"request\": { \"type\": \"text\", \"payload\": \"$USER_INPUT\" } }"
Node.js const axios = require('axios'); const apiKey = 'VF.DM.xxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; const userID = 'user_123'; // Unique ID used to track conversation state const userInput = 'Hello world!'; // User's message to your Voiceflow project const body = { action: { type: 'text', payload: userInput, }, }; async function startInteract() { // Start a conversation const response = await axios({ method: 'POST', baseURL: 'https://general-runtime.voiceflow.com', url: `/state/user/${userID}/interact`, headers: { Authorization: apiKey, versionID: 'development', }, data: body, }); // Log the response console.log(response.data); } startInteract().catch((error) => console.error(error));
Python import requests api_key = "VF.DM.xxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" user_id = "user_123" # Unique ID used to track conversation state user_input = "Hello world!" # User's message to your Voiceflow project body = {"action": {"type": "text", "payload": user_input}} # Start a conversation response = requests.post( f"https://general-runtime.voiceflow.com/state/user/{user_id}/interact", json=body, headers={ "Authorization": api_key, "versionID": "development" }, ) # Log the response print(response.json())
# Endpoint URL The standard URL base for all Dialog Management API calls is shown below: ``` https://general-runtime.voiceflow.com ``` *Note: This will be different if you are self-hosting or on a private cloud.* tags: - name: API Reference description: > The Dialog Manager API (DM API) allows any application to talk with a Voiceflow diagram using HTTP calls to the **interact endpoint**. ## Conversation State The DM API automatically creates and manages the conversation state. Identical requests to the DM API may produce different responses depending on your diagram's logic and the previous request that the API received. Note that this means the DM API is **not a REST API** as it does not satisfy the [statelessness property](https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm). The DM API's responses depend not only on the request, but also stored state within the server. Keep this in mind while working with the DM API. ### Tracking conversation state All endpoints take in a `userID` parameter, which is used to identify the caller and assign them a unique conversation state object. The interact endpoint can also receive updated variables via the `state.variables` body parameter. #### Multiple conversation sessions Multiple conversation sessions to the same Voiceflow project can be running simultaneously. Each session is identified by the `userID` that you specify. For example, customer A should communicate with `/state/user/customerA/interact` whereas customer B should communicate with `/state/user/customerB/interact`. When customer A gives a response, such as "I would like a large pizza", it will advance their specific conversation session identified by `/state/user/customerA/interact`. For example, the app might then ask what toppings customer A wants. Meanwhile, `/state/user/customerB/interact`'s session remains unchanged, e.g, it might be waiting for customer B to give their order. #### Format of `userID` The format of `userID` is up to you. You can choose any string that fits your particular domain such as `user1234` or `507f191e810c19729de860ea`. There are a few best practices to defining a `userID` format: 1. **Unique** - The `userID` should be unique to each user. Otherwise, if two users share the same `userID`, the Voiceflow app may leak information about user A's conversation to user B, which is a potential privacy violation. 2. **Non-sensitive** - It is not recommended to use sensitive or private information in the `userID` such as emails, real names, or phone numbers. ## versionID DM API endpoints also accept a `versionID` header whose value is a **version alias** that points to a particular version of your Voiceflow project. The currently supported aliases are: - `development` - The version displayed on the Voiceflow Creator's canvas - `production` - The version that has been published Use the `development` alias whenever you are experimenting with your API and the `production` version when integrating Voiceflow with your web app. ### Updating your version To update the `'development'` version exposed by the DM API, you must: 1. Make your changes on the canvas and NLU manager 2. Hit the blue Run button in the Voiceflow canvas to compile the diagram 3. Hit the "Train Assistant" button in the Prototype tool to train the NLU model To update the `'production'` version exposed by the DM API, you must: 1. Make your changes on the canvas and NLU manager 2. Hit the Publish button at the top-right corner of the Voiceflow canvas - name: Custom Actions description: > ### Overview The **Custom Action step** allows you to perform any kind of integration to a Voiceflow project. A Custom Action step is similar to an event handler. A Voiceflow application can be commanded to stop on a Custom Action step and wait for your client application to send back an event, a Custom Action request, telling the Voiceflow diagram which logic it should execute next. Before sending back this event, your client application can perform a variety of tasks including, but not limited to: 1. Triggering navigation on your website 2. Processing a credit card payment 3. Opening the windows on a car 4. Handing off the call to a human ### Execution of a Custom Action Here is how a Custom Action works: 1. Your **user** interacts with your client app, e.g, saying "talk to a human" 2. Your **client** sends an interact request normally, but also specifies the name of Custom Action steps that the Voiceflow diagram should stop on. 3. Our **DM API** executes your diagram normally, but returns early if it encounters one of the Custom Actions specified in Step 1 and sends back a corresponding Custom Action trace, e.g, a `"dial"` type trace defined by your Voiceflow project. 4. Your **client** receives the Custom Action trace. Your code can detect this trace and perform any necessary processing. 5. Your **client** sends a Custom Action request back, e.g, a `"call success"` type request. 6. Our **DM API** follows the path in your diagram chosen by the Custom Action request. It will produce responses as normal, such as a message `"have a great day!"` 7. Your **client** can display the response `"have a great day"` on your application to the user. ![Custom Action Flow](https://media.voiceflow.com/image/dialog-manager-api-docs/custom-actions-flow.png) ### Example - Stripe Integration As a concrete example, let's look at how we can implement an integration for Stripe to charge our user's credit cards. ![Credit Card Custom Action](https://user-images.githubusercontent.com/5643574/115419275-333b7d80-a1c8-11eb-9a70-30398f4c9358.png) First, on the Voiceflow Creator, add a Custom Action Step to your diagram with the name "Pay Credit Card" and three paths named "success", "denied", and "pending" Second, in our client code, we send a normal interact request, but specify in `config.stopTypes` that the Voiceflow diagram should stop whenever it encounters a Custom Action step named "Pay Credit Card" ```json { "action": { "type": "text", "payload": "hello!" } // any request type here, "config": { "stopTypes": ["Pay Credit Card"] } } ``` Third, the client app will receive a list of traces in the response as usual, but the last trace will be a Custom Action trace corresponding to the Custom Action step you just defined. ```json [ ...other_traces, { "type": "Pay Credit Card", "payload": "{ 'amount': 25 }", "defaultPath": 0, "paths": [ { "event": { "type": "success" } }, { "event": { "type": "denied" } }, { "event": { "type": "pending" } } ] } ] ``` Your client code might extract this last trace, detect that it is a custom "Pay Credit Card" trace, and then perform some logic such as calling the Stripe API to charge your user's credit card. ```js const traces = await dmapiInteract({ "action": { "type": "text", "payload": "hello!" } // any request type here, "config": { "stopTypes": ["Pay Credit Card"] } }); const customActionTrace = traces[traces.length - 1]; const customActionPayload = JSON.parse(customActionTrace.payload); if (customActionTrace.type === "Pay Credit Card") { const ok = await stripeAPI.chargeUserCreditCard(customActionPayload.amount); await dmapiInteract({ action: { type: ok ? "success" : "denied" } }); } else if (customActionType.trace === "Some Other Custom Action") { // do something else } ``` Finally, the client application should send an appropriate response based on the results of the logic in step 3. For example, if the Stripe API reported that the user's credit card was successfuly charged, we might send back the following: ```json { "action": { "type": "success" } } ``` where a value of `"success"` for `type` might indicate that your Voiceflow diagram should execute the logic corresponding to a successful credit card payment. Your diagram might then print a confirmation message such as "your order was successful!". If the `type` field is not one of the path names of your Custom Action (`"success"`, `"denied"`, or `"pending"` in this case), the Custom Action will behave as though it was a "dead-end" block with no lines connecting to other blocks. - name: Custom NLP/NLU description: | Instead of using the default NLP service (VFNLU) provided by Voiceflow, it's easy to use a preferred custom NLP service. When making an API request, instead of using a `TextRequest` where the raw string of the user input is provided, use an `IntentRequest` and the default Voiceflow NLP is skipped. **Example Text Request:** ``` { "action": { "type": "text", "payload": "can I get a pepperoni pizza?" } } ``` **NLP Resolved Intent Request:** ``` { "action": { "type": "intent", "payload": { "query": "can I get a pepperoni pizza?", // (optional) original raw string of user input "intent": { "name": "order_pizza_intent" // name of the intent, as specified on Voiceflow }, "entities": [ // array of matched entities, can be empty { "name": "pizza_type", // name of entity "value": "pepperoni" // value of entity } ] } } } ``` So long as the intent generated by the custom NLP service is passed in as the `IntentRequest` format, Voiceflow will be able to generate the appropriate response. To export the model to use with your NLP service, go to the interaction model modal (M), and select the export option. NLP Export Pick your NLP service of choice. Interaction Model If your current NLP service is not supported you can consider creating a translation layer for the generalized model in the `.vf`, or contact Voiceflow. ### Entity/Slot filling If the intent on Voiceflow has required entities (i.e `{pizza_size}` for `order_pizza_intent`) and it is not filled in the initial request, the entity will be prompted for and you can send a subsequent request with the same intent and the `entities` and Voiceflow will be able to automatically merge the initial entities with the new entities. For example, on the Voiceflow project for the `order_pizza_intent`, both `{pizza_type}` and `{pizza_size}` are required. 1. The user says "can I get a pepperoni pizza?", 2. This gets resolved through the NLP service and sent to Voiceflow as `order_pizza_intent` with entity `{pizza_type}` equal to `pepperoni` 3. The response will ask "what size pizza do you want?". 4. The user says "small" 5. The next request is `order_pizza_intent` with entity `{pizza_size}` equal to `small` 6. Voiceflow continues the conversation knowing the the user wants a small pepperoni pizza. *Note: on Step 5 any intent can be sent and resolved, it just needs to be the same intent to continue the entity filling* - name: No Reply Response description: | When the user gives no response at all - remaining silent or away from keyboard - we can use no reply feature. Under any "User Input" type step, there is an option to "Add No Reply Response" and designate a timeout period. ![Screen Shot 2021-12-02 at 11 29 26 AM](https://user-images.githubusercontent.com/5643574/144462791-b8e0f8bf-626e-453d-9dfb-78b0006ceaed.png) To handle interactions within the Dialog Manager API, we can reference the `no-reply` trace: ``` trace: [ ...otherTraces, { type: "no-reply", payload: { timeout: 5 } } ] ``` The responsibility of handling this is on your client calling the API. This would require a timer function of some kind that detects if the user has not responded within the `timeout` number of seconds. In which case, the next `request` is simply `null` to denote that the user has no replied, and the API will handle the following logic: ``` { action: { type: "no-reply" // BaseRequest.RequestType.NO_REPLY }, // state, config, and other metadata here } ``` - name: API Key Differences description: > It is **required** to use a **Dialog Manager API Key** to access the Dialog Manager API. A DM API key has the prefix `VF.DM.` and it provides the most up-to-date features such as version aliasing. - name: Production description: > Voiceflow allows to publish a version of your project to a production slot. Publishing "freezes" a version of your project, so that you have a stable copy of the project to serve to your users. To publish a project through the Voiceflow Creator, see the following [documentation](https://www.voiceflow.com/docs/documentation-project-versioning#toc-2). You can access this production version through the DM API, by setting your `versionID` header to the string `'production'`. Once this is done, you can freely edit the diagram on canvas, without affecting the version that users see on your live application. If you want to update the production version, click the Publish button on the Voiceflow Creator again as described in the documentation linked above. This will replace the previous production version with the version displayed on your canvas. **NOTE**: For the `'development'` alias, you must hit the Run button to compile the version and click the "Train Assistant" button in the Prototype tool to update the project's NLU. For `'production'`, doing all of this is unneccessary. The Publish button is a one-click flow that includes the compilation and training steps so that your live app will have the most recent diagram structure and NLU model. - name: Best Practices description: > There are a number of best practices when working with the DM API: ### Use version aliases In previous iterations of the DM API, you needed to specify the explicit `versionID` to interact with a particular version of the Voiceflow project. With the introduction of version aliases, this is unnecessary. A version alias will always refer to whichever version occupies its corresponding slot and you can avoid the hassle of updating an explicit version ID by simplying pushing a new version into the slot. For the `production` alias, you can update its slot by pressing the Publish button on the Voiceflow canvas. See the Production section for further details. For the `development` alias, the version's diagram is updated as you edit on the canvas and the associated NLU is updated when you press "Train Assistant" in the Prototyping tool. ### Avoid the Stateless API Previously, the Dialog Manager API had an older version named the Stateless API. This API is now deprecated in favour of the current "State API". It is **strongly recommended** to move away from the Stateless API for production code. ### Avoid security violations in `userId` The `userId` can be used to identify the conversation session of your Voiceflow application with one of your customers. **Resist the temptation to use identifying information** like real names, emails, telephone numbers, or other identifying information in the `userId`. While this may seem convenient, it is a potential security hazard. If your app is compromised by a cyber attack, then it may be possible for attackers to scrape personal information off of the `userId`. Additionally, you should **avoid any `userId` collisions**. Since the `userId` identifies a conversation, if two users have the same `userId`, then their conversation data may become mixed and leak information about one user to another. If one user gave sensitive information over their conversation, this may lead to a privacy leak. ### Use the `'production'` alias for production apps The `'development'` alias points to the version on your canvas and this version's data updates in real-time as you modify it on canvas. Therefore, if you use the `'development'` alias on your live application, users may see your incomplete changes as you modify the diagram. Use the `'production'` alias for live apps instead, as this version will only update when you explicitly press the Publish button on canvas. servers: - url: 'https://general-runtime.voiceflow.com' paths: '/state/user/{userID}/interact': parameters: - $ref: '#/components/parameters/userID' - $ref: '#/components/parameters/versionID' post: tags: - API Reference summary: Interact description: >- Sends a request to advance the conversation session with your Voiceflow project. ### Requests There are different types of requests that can be sent. To see a list of all request types, check out the documentation for the `action` field below. To start a conversation, you should send a **launch request**. Then, to pass in your user's response, you should send a **text request**. If you have your own NLU matching, then you may want to directly send an **intent request**. See the Request **Examples** on the right panel for more examples of valid request bodies. ### Response Traces After processing your request, the Dialog Manager API will then respond with an array of "traces" which are pieces of the overall response from the project: ```json [{ "type": "speak", "payload": { "type": "message", "message": "would you like fries with that?" } }, { "type": "visual", "payload": { "image": "https://voiceflow.com/pizza.png" } }] ``` In the example above, the Voiceflow project responded by saying "would you like fries with that?" and an image of a pizza. You can then display the chatbot's response and the image in your app. There are many types of response traces. Each trace is produced by a particular block on your Voiceflow project. Expand the documentation for the 200 OK response below to see a list of possible response traces. ### Runtime Logs The `logs` query parameter can be used to enable [debug logging](https://developer.voiceflow.com/reference/logs-reference), which includes `log` traces in the response. ### Legacy responses For legacy compatibility, you set the `verbose` query parameter to `true` to get a response similar to our legacy Stateless API. ```json // <- simplified verbose response body { "state": { "stack": [{ "programID": "home flow", "nodeID": "yes no choice node" }], "storage": {}, "variables": { "pizza_type": "pepperoni" } }, "trace": [{ "type": "speak", "payload": { "type": "message", "message": "would you like fries with that?" } }, { "type": "visual", "payload": { "image": "https://voiceflow.com/pizza.png" } }] } ``` operationId: stateInteract security: - DialogManagerAPIKey: [] parameters: - $ref: '#/components/parameters/versionID' - $ref: '#/components/parameters/userID' - name: verbose in: query description: > Enables verbose responses similar to the legacy Stateless API. This parameter exists for legacy compatibility reasons. New projects should always have this value set to `false`. required: false schema: type: boolean example: false - name: logs in: query description: configure debug logs required: false schema: allOf: - $ref: '#/components/schemas/DebugLogsConfig' - default: 'off' requestBody: required: true content: application/json: schema: type: object properties: action: $ref: '#/components/schemas/Request' config: $ref: '#/components/schemas/Config' state: $ref: '#/components/schemas/InteractState' required: - request examples: Text Request: value: action: type: text payload: Can I order a large pepperoni pizza state: variables: x_var: "hello" Intent Request: value: action: type: intent payload: query: I want a large pepperoni pizza intent: name: order_pizza_intent entities: - name: size value: large - name: type value: pepperoni confidence: 0.5 state: variables: x_var: 1 Launch Request: value: action: type: launch state: variables: x_var: 2 With Config: value: action: type: text payload: I would like to order a huge pepperoni pizza config: tts: false stripSSML: true stopTypes: - Pay Credit Card state: variables: x_var: true responses: '200': description: A sequential array of response "traces" to display back to the user. They can take a variety of types - common types are defined here. content: application/json: schema: oneOf: - title: Verbose Response type: object description: Verbose response, only returned if you enabled the `verbose` parameter properties: trace: $ref: '#/components/schemas/Trace' state: $ref: '#/components/schemas/State' action: $ref: '#/components/schemas/Request' required: - trace - $ref: '#/components/schemas/Trace' examples: Dialog Example: value: - type: speak payload: type: message message: one large pepperoni pizza is that correct? - type: speak payload: type: audio src: 'https://voiceflow.com/chime.mp3' message: "