Introduction
The Flow.ai API is organized around REST. Our API has predictable, resource-oriented URLs, and uses HTTP response codes to indicate API errors. We use built-in HTTP features, like HTTP authentication and HTTP verbs, which are understood by off-the-shelf HTTP clients.
Our messaging API supports cross-origin resource sharing, allowing you to interact securely with our API from a client-side web application (though you should never expose your secret API key in any public client-side code). JSON is returned by all API responses, including errors.
Messaging API
An API to built conversational interfaces (e.g., chatbots, voice-powered apps and devices).
Audience
The API is specifically made for developers that want to use the Flow.ai engine within their own technology stack or solution.
Some example use cases:
- Combine Flow.ai with a customer service solution
- Use Flow.ai with any other backend service
- Hardware or other integrations
You call us, we'll call you
The Messaging API works asynchronous. Unlike other NLP APIs, Flow.ai will not return any direct reply to a Send call.
Instead, the API will call your configured webhook whenever a reply is being sent.
Sending messages
Many types of unstructured content can be sent to the Flow.ai platform, including text, audio, images, video, and files. Our powerful AI engine will process any query and send back replies using the provided webhook.
Any message that is send requires a threadId
that relates the message to a specific user, chat or thread. Optionally you can provide a traceId
that will help keep track of the message when you receive delivery events.
Endpoint
All the URLs referenced in the Messaging API have the following base:
https://api.flow.ai/v1/messaging/
Authentication
Authenticate your API requests by providing a Messaging API key as a bearer token. All API requests expect this bearer token to be present.
You can register a new Messaging API key within your organisation settings.
Text message
Sending a text message
POST /v1/messaging/message
Example Request:
POST /v1/messaging/message HTTP/1.1
Host: api.flow.ai
Content-Type: application/json
Authorization: Bearer MY_MESSAGING_API_KEY
{
"threadId": "6ecfd199-853a-448f-9f91-ef397588ff87",
"type": "text",
"text": "Hello"
}
import request from "async-request";
const result = await request({
method: 'POST',
url: 'https://api.flow.ai/v1/messaging/query',
headers: {
'Authorization': 'Bearer MY_MESSAGING_API_KEY',
'Content-Type': 'application/json'
},
body: {
threadId: '6ecfd199-853a-448f-9f91-ef397588ff87',
type: 'text',
text: 'Hello'
},
json: true
})
Example Response:
200 OK
{
"status": "ok"
}
Arguments
threadId string | Unique identifier for the target chat or user of the target channel |
traceId number | Optional unique number that is passed along to identify the message. Use this to verify message delivery. |
type string | Indicates the type of message. Should be text |
text string | The text or speech message to process. The maximum length of a message is 255 characters. |
lang string | Language code in ISO format (2 letters) |
timezone integer | UTF timezone offset in hours |
params object | Optional parameters |
Event message
POST /v1/messaging/message
Example Request:
POST /v1/messaging/message HTTP/1.1
Host: api.flow.ai
Content-Type: application/json
Authorization: Bearer MY_MESSAGING_API_KEY
{
"threadId": "6ecfd199-853a-448f-9f91-ef397588ff87",
"type": "event",
"eventName": "MY_EVENT"
}
import request from "async-request";
const result = await request({
method: 'POST',
url: 'https://api.flow.ai/v1/messaging/query',
headers: {
'Authorization': 'Bearer MY_MESSAGING_API_KEY',
'Content-Type': 'application/json'
},
body: {
threadId: '6ecfd199-853a-448f-9f91-ef397588ff87',
type: 'event',
eventName: "MY_EVENT"
},
json: true
})
Example Response:
200 OK
{
"status": "ok"
}
Trigger events within Flow.ai by sending an event message.
Arguments
threadId string | Unique identifier for the target chat or user of the target channel |
traceId number | Optional unique number that is passed along to identify the message. Use this to verify message delivery. |
type string | Indicates the type of message. Should be event |
eventName string | The name of the event to trigger |
lang string | Language code in ISO format (2 letters) |
timezone integer | UTF timezone offset in hours |
params object | Optional parameters |
Location message
POST /v1/messaging/message
Example Request:
POST /v1/messaging/message HTTP/1.1
Host: api.flow.ai
Content-Type: application/json
Authorization: Bearer MY_MESSAGING_API_KEY
{
"threadId": "6ecfd199-853a-448f-9f91-ef397588ff87",
"type": "location",
"lat": "1232122422",
"lng": "2433343343"
}
import request from "async-request";
const result = await request({
method: 'POST',
url: 'https://api.flow.ai/v1/messaging/query',
headers: {
'Authorization': 'Bearer MY_MESSAGING_API_KEY',
'Content-Type': 'application/json'
},
body: {
threadId: '6ecfd199-853a-448f-9f91-ef397588ff87',
type: 'location',
lat: "1232122422",
lng: "2433343343"
},
json: true
})
Example Response:
200 OK
{
"status": "ok"
}
Send coordinates
Arguments
threadId string | Unique identifier for the target chat or user of the target channel |
traceId number | Optional unique number that is passed along to identify the message. Use this to verify message delivery. |
type string | Indicates the type of message. Should be location |
lat string | Latitude |
lng string | Longitude |
lang string | Language code in ISO format (2 letters) |
timezone integer | UTF timezone offset in hours |
params object | Optional parameters |
Media message
POST /v1/messaging/message
Example Request:
POST /v1/messaging/message HTTP/1.1
Host: api.flow.ai
------WebKitFormBoundaryDJX0xmK2m2F6Mvka
Content-Disposition: form-data; name="file"; filename="image.png"
Content-Type: image/png
------WebKitFormBoundaryDJX0xmK2m2F6Mvka
Content-Disposition: form-data; name="query"
{
"threadId": "6ecfd199-853a-448f-9f91-ef397588ff87",
"type": "location",
"mediaType": "image",
"mimetype": "image/png"
}
------WebKitFormBoundaryDJX0xmK2m2F6Mvka--
------WebKitFormBoundary7MA4YWxkTrZu0gW--
import request from "async-request";
import { createReadStream } from 'fs';
import FormData from 'form-data';
// Stream the binary file
const stream = createReadStream('./test.png')
// Create a formData and append the file and query (JSON)
const formData = new FormData()
formData.append('file', stream)
formData.append('query', JSON.stringify(query: {
threadId: '6ecfd199-853a-448f-9f91-ef397588ff87',
type: 'media',
mediaType: 'image',
mimeType: "image/png"
}))
const result = await request({
method: 'POST',
url: 'https://api.flow.ai/v1/messaging/query',
headers: {
'Authorization': 'Bearer MY_MESSAGING_API_KEY'
},
body: formData
})
Example Response:
200 OK
{
"status": "ok"
}
The API allows you to send images, files and other media files.
For media you'll need to make a POST
call that is multipart/form-data
. The maximum file size you can upload is 250MB.
Arguments
threadId string | Unique identifier for the target chat or user of the target channel |
traceId number | Optional unique number that is passed along to identify the message. Use this to verify message delivery. |
type string | Indicates the type of message. Should be media |
mediaType string | Type of media, image , file , audio , or video |
mimeType string | Optionally specify the mime-type of the uploaded file |
lang string | Language code in ISO format (2 letters) |
timezone integer | UTF timezone offset in hours |
params object | Optional parameters |
Webhooks
Webhooks are the way Flow.ai will deliver replies and notify your app of other type of events.
Receiving calls
Creating a webhook endpoint on your server is no different from creating any page on your website.
Webhook data is sent as JSON in the POST
request body. The full event details are included and can be used directly, after parsing the JSON into an Event object.
Your webhook must meet with the following requirements:
- HTTPS support
- A valid SSL certificate
- An open port that accepts
GET
andPOST
requests
Responding to a call
To acknowledge receipt of a webhook call, your endpoint should return a 2xx HTTP status code. All response codes outside this range, including 3xx codes, will indicate to Flow.ai that you did not receive the webhook. This does mean that a URL redirection or a "Not Modified" response will be treated as a failure. Flow.ai will ignore any other information returned in the request headers or request body.
We will attempt to deliver your webhooks for up to two 4 hours with an exponential back off. Webhooks cannot be manually retried after this time.
Type of Events
This is a list of all the types of events we currently send. We may add more at any time, so in developing and maintaining your code, you should not assume that only these types exist.
message.reply
message.reply |
Called whenever Flow.ai is sending a reply message |
message.delivered |
Called when your message that you send has been successfully received |
control.handover |
Called when the AI engine is handing off to your solution and pausing operations |
The Webhook object
Example Response:
{
"webhookId": "9f91853a-448f-ef397588ff87-6ecfd199",
"organisationId": "853a-448f-9f91-ef397588ff87-6ecfd199",
"url": "https://myawesomeapp.com/webhook",
"verifyKey": "1234567",
"events": [
"message.delivered",
"message.reply",
"control.handover"
]
}
Each webhook object represents a webhook subscription Flow.ai will attempt to call whenever a subscribed event takes place.
Attributes
webhookId string | Unique ID of the webhook |
organisationId string | ID of the organisation this webhook will receive calls from |
url string | The url your app lives that Flow.ai shall call |
verifyKey string | Along with each call Flow.ai will send you this verify key. It enables you to verify that the call was made by Flow.ai |
events array | The list of events to subscribe to. You'll need to have at least one subscribed event |
Create a webhook
POST /v1/messaging/webhooks
Example Request:
POST /messages/v1/webhooks HTTP/1.1
Host: api.flow.ai
Content-Type: application/json
Authorization: Bearer MY_MESSAGING_API_KEY
{
"url": "https://myawesomeapp.com/webhook",
"verifyKey": "1234567",
"events": [
"message.delivered",
"message.reply",
"control.handover"
]
}
Example Response:
201 Created
Location: /messages/v1/webhooks/9f91853a-448f-ef397588ff87-6ecfd199
{
"webhookId": "9f91853a-448f-ef397588ff87-6ecfd199",
"organisationId": "853a-448f-9f91-ef397588ff87-6ecfd199",
"url": "https://myawesomeapp.com/webhook",
"verifyKey": "1234567",
"events": [
"message.delivered",
"message.reply",
"control.handover"
]
}
Creates a new webhook subscription.
Whenever you add a webhook we'll make a GET
request to verify the endpoint. This call should receive a 2xx
response code of your server.
Arguments
url required | The url your app lives that Flow.ai shall call |
verifyKey required | Along with each call Flow.ai will send you this verify key. It enables you to verify that the call was made by Flow.ai |
events required | A list of events to subscribe to. You'll need to have at least one subscribed event |
Retrieve a Webhook
GET /v1/messaging/webhooks/{WEBHOOK_ID}
Example Request:
GET /messages/v1/webhooks/9f91853a-448f-ef397588ff87-6ecfd199 HTTP/1.1
Host: api.flow.ai
Content-Type: application/json
Authorization: Bearer MY_MESSAGING_API_KEY
Example Response:
200 OK
{
"webhookId": "9f91853a-448f-ef397588ff87-6ecfd199",
"organisationId": "853a-448f-9f91-ef397588ff87-6ecfd199",
"url": "https://myawesomeapp.com/webhook",
"verifyKey": "1234567",
"events": [
"message.delivered",
"message.reply",
"control.handover"
]
}
Retrieves the details of an existing webhook subscription. Supply the unique webhook ID from either a webhook creation request or the webhook list, and Flow.ai will return the corresponding webhook information.
Update a Webhook
POST /v1/messaging/webhooks/{WEBHOOK_ID}
Example Request:
PUT /messages/v1/webhooks/9f91853a-448f-ef397588ff87-6ecfd199 HTTP/1.1
Host: api.flow.ai
Content-Type: application/json
Authorization: Bearer MY_MESSAGING_API_KEY
{
"organisationId": "853a-448f-9f91-ef397588ff87-6ecfd199",
"url": "https://myawesomeapp.com/webhook",
"verifyKey": "1234567",
"events": [
"message.reply",
"control.handover"
]
}
Example Response:
200 OK
{
"webhookId": "9f91853a-448f-ef397588ff87-6ecfd199",
"organisationId": "853a-448f-9f91-ef397588ff87-6ecfd199",
"url": "https://myawesomeapp.com/webhook",
"verifyKey": "1234567",
"events": [
"message.delivered",
"message.reply",
"control.handover"
]
}
Updates the specified webhook by setting the values of the parameters passed. Any parameters not provided will be left unchanged.
Arguments
url optional | The url your app lives that Flow.ai shall call |
verifyKey optional | Along with each call Flow.ai will send you this verify key. It enables you to verify that the call was made by Flow.ai |
events optional | The list of events to subscribe to. You'll need to have at least one subscribed event |
List all Webhooks
GET /v1/messaging/webhooks
Example Request:
GET /messages/v1/webhooks/9f91853a-448f-ef397588ff87-6ecfd199 HTTP/1.1
Host: api.flow.ai
Content-Type: application/json
Authorization: Bearer MY_MESSAGING_API_KEY
Example Response:
200 OK
{
"items": [{
"webhookId": "9f91853a-448f-ef397588ff87-6ecfd199",
"organisationId": "853a-448f-9f91-ef397588ff87-6ecfd199",
"url": "https://myawesomeapp.com/webhook",
"verifyKey": "1234567",
"events": [
"message.delivered",
"message.reply",
"control.handover"
]
}, {
"webhookId": "448f-9f91853a-6ecfd199-ef397588ff87",
"organisationId": "853a-448f-9f91-ef397588ff87-6ecfd199",
"url": "https://otherawesomeapp.com/webhook",
"verifyKey": "7654321",
"events": [
"message.reply"
]
}]
}
Returns a list of your webhook subscriptions. The webhooks are returned sorted by creation date, with the most recently created webhooks appearing first.
Delete a Webhook
DELETE /v1/messaging/webhooks/{WEBHOOK_ID}
Example Request:
DELETE /messages/v1/webhooks/9f91853a-448f-ef397588ff87-6ecfd199 HTTP/1.1
Host: api.flow.ai
Content-Type: application/json
Authorization: Bearer MY_MESSAGING_API_KEY
204 No Content
Example Response:
{
"webhookId": "9f91853a-448f-ef397588ff87-6ecfd199",
"organisationId": "853a-448f-9f91-ef397588ff87-6ecfd199",
"url": "https://myawesomeapp.com/webhook",
"verifyKey": "1234567",
"events": [
"message.delivered",
"message.reply",
"control.handover"
]
}
Permanently deletes a webhook subscription. It cannot be undone.
Management API
Authentication
To authorize, use this code:
# With shell, you can just pass the correct header with each request
curl "https://api.flow.ai/v1/management"
-H 'Authorization: Bearer MY_MANAGEMENT_API_KEY'
Make sure to replace
MY_MANAGEMENT_API_KEY
with your API key.
Authenticate your API requests by providing a Management API key as a bearer token. All API requests expect this bearer token to be present.
You can register a new Management API key within your organisation settings.
Flows
Example Flow object:
{
"flowId": "c48b0a06-9727-4735-8886-49286fae78e3",
"projectId": "db3e3895-fe06-4dcc-a7a0-35b0c0ec55c3",
"brainId": "86bc0fa0-25f7-4d3d-9dcf-eaa2a6f810b1",
"title": "Hello World",
"group": "Demo",
"createdAt": "2018-10-24T06:45:19.541Z",
"disabled": false,
"steps": [{
"stepId": "31aef3cf-8c96-442b-9871-7fc9be322da1",
"title": "Hello!",
"type": "INTENT",
"contexts": [],
"intent": {
"intentId": "67841005-31b1-45b3-b939-3879dfd377de",
"title": "Hello_World_Greeting",
"createdAt": "2018-10-24T06:45:19.484Z",
"examples": [{
"entities": [],
"query": "Hello"
}, {
"entities": [],
"query": "Good day"
}, {
"entities": [],
"query": "Good afternoon"
}, {
"entities": [],
"query": "good morning"
}, {
"entities": [],
"query": "hi"
}, {
"entities": [],
"query": "Hey"
}]
},
"actions": [{
"type": "TEXT",
"payload": {
"texts": [
"Hi there! This is a customer service demo bot! ",
"Hello! I am a customer service demo bot!"
],
"quickReplies": [],
"delay": 0
}
}]
}]
}
A Flow represents a conversation topic. It's combines a series of Step objects that the AI engine uses to determine what actions to perform.
The Flow object
Property | Description |
---|---|
flowId string | Unique ID of the Flow |
projectId string | Project ID the Flow belongs to |
brainId string | ID of the AI brain the Flow belongs to |
title string | Name of the Flow |
group string | Group name |
createdAt date string | Date the flow was created |
disabled boolean | Indicates if it should be ignored |
steps array | Collection of Step objects |
The Step object
Example
INTENT
Step:
{
"stepId": "31aef3cf-8c96-442b-9871-7fc9be322da1",
"title": "Hello!",
"type": "INTENT",
"contexts": [],
"actions": [{
"type": "TEXT",
"payload": {
"texts": [
"Simple reply"
],
"quickReplies": [],
"tags": []
}
}],
"intent": {
"intentId": "67841005-31b1-45b3-b939-3879dfd377de",
"title": "Hello_World_Greeting",
"createdAt": "2018-10-24T06:45:19.484Z",
"examples": [{
"entities": [],
"query": "Hello"
}, {
"entities": [],
"query": "hi"
}, {
"entities": [],
"query": "Hey"
}]
}
}
Example
EVENT
Step:
{
"stepId": "c7512efe-9c2e-4cd4-9fdc-11fc1d31dfb8",
"type": "EVENT",
"title": "EVENT NAME",
"contexts": ["31aef3cf-8c96-442b-9871-7fc9be322da1"],
"actions": [{
"type": "TEXT",
"payload": {
"texts": [
"Simple reply"
],
"quickReplies": [],
"tags": []
}
}]
}
Each Step is part of a Flow. Steps are used by the AI engine to determine what reply action to send when for example an intent is matched.
Steps can be related to other steps and configure complex tree like dialog structures,
Property | Description |
---|---|
stepId string | Unique ID of the Step |
title string | Name of the Step |
type string | Type of step. Should be a value of INTENT , EVENT , UNKNOWN , IMAGE , FILE , AUDIO , VIDEO , LOCATION , NOTHING , ANYTHING |
contexts array | Collection of stepIds that precede the step |
intent object | Intent object, required if type is INTENT |
actions array | Collection of Reply actions |
Create a Flow
Retrieve a Flow
GET /flows/info
{
"flowId": "c48b0a06-9727-4735-8886-49286fae78e3",
"projectId": "db3e3895-fe06-4dcc-a7a0-35b0c0ec55c3",
"brainId": "86bc0fa0-25f7-4d3d-9dcf-eaa2a6f810b1",
"title": "Hello World",
"group": "Demo",
"createdAt": "2018-10-24T06:45:19.541Z",
"disabled": false,
"steps": [{
"stepId": "31aef3cf-8c96-442b-9871-7fc9be322da1",
"title": "Hello!",
"type": "INTENT",
"contexts": [],
"intent": {
"intentId": "67841005-31b1-45b3-b939-3879dfd377de",
"title": "Hello_World_Greeting",
"createdAt": "2018-10-24T06:45:19.484Z",
"examples": [{
"entities": [],
"query": "Hello"
}, {
"entities": [],
"query": "Good day"
}, {
"entities": [],
"query": "Good afternoon"
}, {
"entities": [],
"query": "good morning"
}, {
"entities": [],
"query": "hi"
}, {
"entities": [],
"query": "Hey"
}]
},
"actions": [{
"actionId": "3320ae20-cb09-484f-b8d4-c5eb8afeaab2",
"createdAt": "2018-10-24T06:45:19.472Z",
"type": "TEXT",
"payload": {
"texts": [
"Hi there! This is a customer service demo bot! ",
"Hello! I am a customer service demo bot!"
],
"quickReplies": [],
"delay": 0
}
}]
}]
}
Update a Flow
List all Flows
This endpoint retrieves all Flows.
GET /flows/list
[{
"flowId": "53ced89e-08e4-40bc-89b8-f7ea02ba6cd5",
"projectId": "db3e3895-fe06-4dcc-a7a0-35b0c0ec55c3",
"brainId": "86bc0fa0-25f7-4d3d-9dcf-eaa2a6f810b1",
"title": "Get started",
"group": "Weather",
"createdAt": "2018-10-24T06:45:03.828Z",
"disabled": false,
"steps": [{
"stepId": "4237653c-ad8d-4bf8-8ff5-da9dd7cb5636",
"type": "INTENT",
"title": "Get started",
"contexts": [],
"actions": ["5bd014ef0838670032b1aa11"],
"intent": "5bd014ef0838670032b1aa16"
}]
}, {
"flowId": "f1a4c7fd-fa2b-4f67-a391-15b9e98d47ea",
"projectId": "db3e3895-fe06-4dcc-a7a0-35b0c0ec55c3",
"brainId": "86bc0fa0-25f7-4d3d-9dcf-eaa2a6f810b1",
"title": "Weather",
"group": "Weather",
"createdAt": "2018-10-24T06:45:03.820Z",
"disabled": false,
"steps": [{
"stepId": "ea8b18e6-eb07-4ad6-8df2-518c43c180e3",
"type": "INTENT",
"title": "What is the weather like",
"contexts": [],
"actions": ["5bd014ef0838670032b1aa13"]
}, {
"stepId": "e010bb48-a51b-48f3-ab46-81ce10f05454",
"type": "SLOT",
"title": "SLOT",
"contexts": ["ea8b18e6-eb07-4ad6-8df2-518c43c180e3"],
"actions": ["5bd014ef0838670032b1aa12"],
"slot": {
"validation": "REQUIRED",
"entityId": "system.query",
"label": "city"
}
}]
}]
Intents
The Intent object
Create an Intent
Retrieve an Intent
Update an Intent
List all Intents
This endpoint retrieves all Intents.
Entity types
The Entity type object
Create an Entity type
Retrieve an Entity type
Update an Entity type
List all Entity types
This endpoint retrieves all Entity types.
Projects
The Project object
Create a Project
Retrieve a Project
Update a Project
List all Projects
This endpoint retrieves all Flows.
Members
The Member object
List all Members
This endpoint retrieves all organisation members.
Web socket API
A real time messaging API that allows you to send and receive messages from Flow.ai using websockets.
Audience
The Websocket API is specifically intended for developers looking to integrate Flow.ai in a client facing app. For example:
- Building a custom web chat widget
- Integrating Flow.ai inside a mobile app
For server integrations we advice you to take a look at our Messaging API.
Getting started
An overview how the API works:
- Request (GET) a WebSocket endpoint
- Open a WebSocket connection (WSS)
- Send and receive messages
- Keep the connection alive
Request an endpoint
Example Request:
curl -X GET -H "Content-Type: application/json" "https://api.flow.ai/socket.info?clientId=YOUR_CLIENT_ID&sessionId=123432"
var request = require("request");
var options = { method: 'GET', url: 'https://api.flow.ai/socket.info/?clientId=YOUR_CLIENT_ID&sessionId=1234' };
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
var client = new RestClient("https://api.flow.ai/socket.info?clientId=YOUR_CLIENT_ID&sessionId=1234");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
var request = NSMutableURLRequest(URL: NSURL(string: "https://api.flow.ai/socket.info/?clientId=YOUR_CLIENT_ID&sessionId=1234")!,
cachePolicy: .UseProtocolCachePolicy,
timeoutInterval: 10.0)
Example response:
200 OK
{
"status": "ok",
"payload": {
"endpoint": "wss://api.flow.ai/ws/8c3b7d7ea9400..."
}
}
To start a connection you'll need to make a GET
call to the socket.info
API method to the API endpoint at https://api.flow.ai
. This provides a temporary WebSocket URL.
The socket.info
method requires a sessionId
and a clientId
.
Query param | Description |
---|---|
sessionId | The sessionId is something unique you need to create for every call. This can be something like a UIUID. Each connection is partly identified on our end using this key |
clientId | Check the Channels app of the dashboard to find your unique clientId. |
Open a connection
The Websocket URL provided by socket.info
are single-use and are only valid for 60 seconds, so make sure to connect directly.
Common format
{
"type": "...",
"payload": {
...
}
}
Any message or other kind of event you send or receive has the same JSON format.
Attributes
Property | Description |
---|---|
type required | The message type for example: message.send |
payload required | The body of the message |
Keep alive
Example Message:
{
"type": "ping"
}
Example Reply:
{
"type": "pong"
}
When a connection is made we will automatically disconnect if we do not receive any messages within 50 seconds.
In order to keep the connection live we support a ping message.
Sending Messages
Example Message:
{
"type": "message.send",
"payload": {
"threadId": "58ca9e327348ed3bd1439e7b",
"traceId": 1519091841664,
"speech": "Hi there!"
}
}
The easiest way to send a simple text message in real time
Attributes
Property | Description |
---|---|
threadId required | Unique key identifying a user or channel |
traceId optional | Optional number used to track message delivery |
speech required | Text of message |
Originator object
Example Message:
{
"type": "message.send",
"payload": {
"threadId": "58ca9e327348ed3bd1439e7b",
"traceId": 1519091841666,
"speech": "Turn off the lights in the Living room",
"originator": {
"name": "John Doe",
"role": "external"
},
}
}
Example Message:
{
"type": "message.send",
"payload": {
"threadId": "58ca9e327348ed3bd1439e7b",
"traceId": 1519091841667,
"speech": "has my milk expired?",
"originator": {
"name": "John Doe",
"role": "external",
"profile": {
"fullName": "John Doe",
"firstName": "John",
"lastName": "Doe",
"gender": "M",
"locale": "en-US",
"timezone": -5,
"country": "us",
"email": "johndoe@dmail.com",
"picture": "https://..."
}
}
}
}
Example Message:
{
"type": "message.send",
"payload": {
"threadId": "58ca9e327348ed3bd1439e7b",
"speech": "I want to book a flight between Amsterdam and Toronto",
"originator": {
"name": "John Doe",
"role": "external",
"metadata": {
"clientNumber": "asddaasq333ee332",
"preference": "A,B,G"
}
}
}
}
With each message you can customize information regarding the sender, user or as Flow.ai calls it, the originator of the message.
Attributes
Property | Description |
---|---|
name string | Name representing the originator |
role string | Either external , or moderator |
profile Profile object | Optional Profile object |
metadata object | Key value pairs with additional info |
Profile object
An originator can contain additional profile information using the profile object
Property | Description |
---|---|
fullName string | Complete name |
firstName string | First name |
lastName string | Family name |
gender string | Gender, M, F or U |
locale string | Locale code (ISO) |
timezone number | Number of hours of UTC |
country string | Two letter country code |
email string | Email address |
picture string | URL to profile picture |
Metadata
Example Message:
{
"type": "message.send",
"payload": {
"threadId": "58ca9e327348ed3bd1439e7b",
"speech": "I want to book a flight between Amsterdam and Toronto",
"originator": {
"name": "John Doe",
"role": "external"
},
"metadata": {
"language": "en-US",
"timezone": -6,
"params": {
"seats": [{
"value": "Business class"
}]
}
}
}
}
Along with every message you can send additional metadata. Some of this metadata is also used by the AI engine to determine the response.
Attributes
Property | Description |
---|---|
language string | Language code (ISO) of the message, not the user |
timezone number | Timezone of the message (where it was sent). Number of hours from UTC |
params Params object | Bag of parameters to use within the AI |
Params object
Example Params
{
"passengerCount": [{
"value": "2"
}]
}
{
"food": [{
"value": "food-item-22332",
"match": "Pizza Hawaii"
}, {
"value": "food-item-44525",
"match": "Pizza Calzone"
}]
}
The params object resembles the matched result created by the AI engine using entity classification. Each param itself is a list of [{ value }]
objects.
Property | Description |
---|---|
value required | The value of the param |
match optional | Represents a human value |
Attachment
Example Message:
{
"type": "message.send",
"payload": {
"threadId": "58ca9e327348ed3bd1439e7b",
"traceId": 1519091841665,
"speech": "event attachment",
"attachment": {
"type": "event",
"payload": {
"name": "INTRO"
}
}
}
}
Instead of simple text messages, Flow.ai also supports sending attachments like files or events.
Attachment attributes
Property | Description |
---|---|
type required | Attachment type. Currently this has to be event |
payload required | Attachment object |
Attachment object
Property | Description | Type |
---|---|---|
name required | Name of the event to trigger |
Responses
Example Reply:
{
"type": "message.delivered",
"payload": {
"traceId": 1,
"threadId": "31ea9df73ca74dfe9329bf68c09b61ce",
"traceId": 1489399519321,
"speech": "hi"
}
}
If there is an error processing a message the server will reply with an error. For example:
{
"type": "error",
"message": "Invalid message format ..."
}
A reply is sent (almost) instantly. The following is replied if the message is successfully delivered.
Receiving Messages
Messages that are replied are in almost the same format as the ones that are sent.
Example or reply
{
"type": "message.received",
"payload": {
"threadId": "57a8a2a8917250d54bcbb596",
"messages": [
{
"fallback": "hallo",
"responses": [
{
"type": "text",
"payload": {
"text": "hallo"
}
}
]
}
],
"originator": {
"userId": "7250d54bcbb59657a8a2a891",
"name": "Gijs van de Nieuwegiessen",
"role": "user",
"profile": {
"fullName": "Gijs van de Nieuwegiessen",
"firstName": "Gijs",
"lastName": "van de Nieuwegiessen",
"locale": "nl",
"gender": "M",
"picture": "https://flowai.s3.eu-central-1.amazonaws.com/identities/profile/5959ca45-318a-4d58-b5e1-b430934b8e23"
}
}
}
}
Example of advanced reply
{
"type": "message.received",
"payload": {
"threadId": "58ca9e327348ed3bd1439e7b",
"messages": [
{
"fallback": "Hi, how can we help?",
"silent": false,
"replyTo": "event attachment",
"originator": {
"userId": "flowai|system",
"name": "system",
"role": "bot",
"profile": {
"picture": "https://flow.ai/img/brains/flowai.svg"
}
},
"actions": [],
"responses": [
{
"type": "text",
"payload": {
"text": "Hi, how can we help?",
"quickReplies": [
{
"label": "Chat with flow.ai",
"value": "Chat with someone from flow.ai",
"type": "text"
},
{
"label": "Call flow.ai",
"value": "What is your phone number?",
"type": "text"
},
{
"label": "Ask a question",
"value": "I want to ask a question",
"type": "text"
}
]
},
"delay": 0
}
],
"flow": {
"flowId": "2afcb930-9335-4e74-abb3-5745d26707f7",
"title": "Intro"
},
"step": {
"stepId": "d3d46698-e526-4252-b70c-e6e5af3338e0",
"title": "INTRO",
"type": "EVENT"
},
"params": {
"event": [
{
"type": "custom",
"value": {
"name": "INTRO"
}
}
]
}
}
],
"originator": {
"userId": "flowai|system",
"name": "system",
"role": "bot",
"profile": {
"picture": "https://flow.ai/img/brains/flowai.svg"
}
}
}
}
Payload fields
Property | Description | Type |
---|---|---|
threadId | Required. Unique key identifying a user or channel | string |
messages | List of Message templates | array |
originator | Similar to the originator when sending messages | object |
Message fields
Property | Description | Type |
---|---|---|
fallback | Speech representation of the message | string |
silent | True if message does not have any output for a user | bool |
replyTo | Optionally contains the text the message is a direct reply to | string |
originator | Originator specific to this message | object |
actions | Optional action names being called | array |
responses | Collection of Response templates | array |
flow | Information about the flow being matched | object |
step | Information about the step being matched | object |
params | Hash table with Parameters | object |
Response fields
We have a complete reference of the JSON responses available
Example
We provide a JavaScript SDK, but the following example demonstrates opening a connection and sending a test message using vanilla JavaScript in the browser.
<html>
<body>
<script>
(function () {
// Vanilla JS example
// When executing this script. Check your development console for any messages
// This identifies the channel we want to connect with
var clientId = 'YOUR CLIENTID'
// Global references to our WebSocket and interval
var ws
var keepalive
// This methos is where we send test messages
function runTestMessages() {
console.info('runTestMessages')
var message = {
"type": "message.send",
"payload": {
"threadId": "jane.doe",
"speech": "event attachment",
"attachment": {
"type": "event",
"payload": {
"name": "MY EVENT"
}
},
"originator": {
"name": "Jane Doe",
"role": "external",
"profile": {
"fullName": "Jane Doe",
"firstName": "Jane",
"lastName": "Doe",
"gender": "F",
"locale": "en-US",
"timezone": -5,
"country": "us",
"email": "janedoe@gmail.com",
"picture": "https://en.wikipedia.org/wiki/File:YellowLabradorLooking_new.jpg"
},
"metadata": {
"clientNumber": "12345",
"preference": "A,B,G"
}
}
}
}
wsSendMessage(message)
}
// Get a new wss endpoint
function getWsEndpoint() {
console.info('Request endpoint')
// socket.info endpoint
var socketInfoUrl = 'https://api.flow.ai/socket.info?clientId=' + clientId + '&sessionId=' + Date.now();
// Create a GET request
var req = new XMLHttpRequest();
req.onload = wsEndpointResponse
req.responseType = 'json';
req.open('GET', socketInfoUrl, true);
req.send();
}
// Called when we get a response from socket.info
// validate the response and open a websocket connection
function wsEndpointResponse(e) {
console.info('Received endpoint')
var xhr = e.target;
if(xhr.response.status !== 'ok') {
// This is not OK..
console.error('Error while fetching wss url', xhr.response)
return
}
// Get the endpoint from the response
var endpoint = xhr.response.payload.endpoint
startWebsocket(endpoint)
}
// Open a new websocket connection
function startWebsocket(endpoint) {
console.info('Websocket start connection with endpoint', endpoint)
// Create a new socket
ws = new WebSocket(endpoint);
ws.onopen = wsOnOpen;
ws.onmessage = wsOnMessage;
}
// Handler called when the socket makes a connection
function wsOnOpen(e) {
console.info('Websocket connection open')
// Start the keepalive
wsStartKeepalive()
// Run our test messages
runTestMessages()
}
// Handler called when the socket receives a message
function wsOnMessage(e) {
var json = JSON.parse(e.data)
console.info('Websocket received json', json)
}
// Simple keep alive method (sending pings)
function wsStartKeepalive() {
clearInterval(keepalive)
// Send a ping 30 seconds
keepalive = setInterval(function() {
wsSendMessage({
"type": "ping"
})
}, 30 * 1000)
}
// Helper method for sending messages
function wsSendMessage(message) {
ws.send(JSON.stringify(message))
}
// Start with sending a GET request for a WSS endpoint
getWsEndpoint()
}());
</script>
</body>
</html>