Making API calls
Publish events, launch flows, and more
While the API & Webhook setup guide explains how to send entries to your webhook, this guide covers how to create entries using the API side of the API & Webhook integration.
With the API, you can do things like:
- send arbitrary entries to the Grid,
- start flows for the user,
- create entries as if they were from another integration.
Keep reading to learn how.
Supported entry types
Only event entries can be created via the API. If you try to create a non-event entry (e.g.
meya.flow.entry.label
), you'll get a400
error with the messageUnhandled entry
.Event entries have
event
somewhere in their type name. A quick search of the reference docs reveals that almost all entries are events, so this isn't really a limitation, just something to be aware of.
Prerequisites
There are a few key pieces of information you'll almost always need when creating entries. In this section, you'll learn how to retrieve the most common required fields.
Bot ID
If you want to create an entry as if the bot had created it—to send a message to the user from the bot, for example—you'll need to know the bot's user ID.
The bot ID can be found by going to the Logs panel and finding an entry that was created by the bot. It has the format: u-xxxxxx
. For example, the image below highlights the bot ID in this meya.text.event.say
entry:
The bot's user ID doesn't change, so you only need to retrieve it once.
Thread ID
A thread is like a conversation. It represents a connection between the app and one or more users.
Like the Meya user ID, you can find the thread ID in some log entries. For a programmatic approach, you can supply the known integration thread ID to ThreadView.lookup()
, like this:
user_id = await ThreadView.lookup(
integration_thread_id, integration_id=integration_id
)
Authentication credentials
When you added the API & Webhook integration to your app you would have specified a password for your API.
The API uses basic auth, which means you need to supply a username and password with each request. The username is always meya
.
Base64 encoding
In the cURL examples below, you'll see references to the Base64 encoded version of the username and password. To get this value, just Base64 encode this text
meya:<your_password>
(note the colon:
).If you're using an app like Postman or Insomnia to make your API calls, they will handle this for you.
Examples
Let's take a look at two common use-cases for the API: sending a message, and starting a flow.
First time?
If this is your first time using the API, be sure to read the first example since it goes into the most detail. The second example is more concise.
Sending a message
For this example, we'll work with a meya.text.event.say
which will let us send a message to the user. According to the reference docs, this is what the entry looks like:
{
"type": "meya.text.event.say",
"data": {
"parent_entry_ref": {
"ledger": "STRING",
"id": "STRING",
"data": {
"STRING": "STRING"
}
},
"trace_id": "STRING",
"sensitive": false,
"user_id": "STRING",
"thread_id": "STRING",
"integration_id": "STRING",
"context": {
"STRING": "ANY"
},
"composer": {
"focus": "file|image|text|blur",
"placeholder": "STRING",
"visibility": "collapse|hide|show"
},
"quick_replies": [
{
"url": "STRING",
"javascript": "STRING",
"button_id": "STRING",
"context": {
"STRING": "ANY"
},
"text": "STRING",
"icon": {
"url": "STRING",
"color": "STRING"
}
}
],
"markdown": [
"format|linkify|breaks|typographer"
],
"text": "STRING"
}
}
The type
property tells the Grid what type of entry we're creating.
The data
property contains information needed to create an entry of this type. The exact fields contained in the data
property varies by entry type. Let's take a look at the information we can include in a say
entry.
`meya.text.event.say properties
Property | Required | Description |
---|---|---|
parent_entry_ref | No | This refers to the entry that spawned this entry. In this case, there is no parent entry, so you can safely remove this from the payload. |
trace_id | No | This is a unique identifier associated with this interaction. You can filter your logs by trace_id , which is very handy for troubleshooting.You don't need to set this since it will be set automatically by the Grid, so feel free to remove it from the payload. |
sensitive | No | This can be used to flag the entry as sensitive data. For this example, our message isn't going to contain sensitive information, so go ahead and remove it from the payload (it will default to false ). |
user_id | Yes | This is a Meya user ID (u-xxxxx ). In this case, because we're sending the message as the bot, we need to use the bot's Meya user ID, not the recipient's user ID. |
thread_id | Yes | The Grid needs to know what thread this comment should be sent to. |
integration_id | Yes | Here's a subtle nuance: Because we're sending this message from the bot, we need to set this to meya , not the integration the user is actually using. |
context | No | This can be used to put data on flow scope.For this example, you can leave this out of the payload. |
composer | No | If you're using the Orb integration, you can control how the composer appears. For this example, we'll leave this out. |
quick_replies | No | As the name suggests, you can include quick replies in a say event. While this isn't a required property, we'll include a couple quick replies for demonstration purposes. |
markdown | No | If your text includes Markdown, you can configure how it should be processed. For this example, you can ignore this property. |
text | Yes | Finally, you'll need to enter some text to send! |
Now that you understand the properties that are available, let's take a look at a few examples.
{
"type": "meya.text.event.say",
"data": {
"text": "Hi!",
"user_id": "BOT_USER_ID",
"thread_id": "THREAD_ID",
"integration_id": "meya"
}
}
{
"type": "meya.text.event.say",
"data": {
"text": "Hi!",
"user_id": "BOT_USER_ID",
"thread_id": "THREAD_ID",
"quick_replies": [
{
"text": "I want to talk to support"
}
],
"integration_id": "meya"
}
}
{
"type": "meya.text.event.say",
"data": {
"text": "Hi!",
"sensitive": true,
"user_id": "BOT_USER_ID",
"thread_id": "THREAD_ID",
"integration_id": "meya",
"context": {
"foo": "bar"
},
"composer": {
"placeholder": "Say something",
"visibility": "show"
},
"quick_replies": [
{
"text": "I want to talk to support"
}
],
"markdown": [
"format"
]
}
}
user
andthread
In addition to the entry itself, there are two other fields we always need to send:
user
andthread
. These are referring to the integration user ID and integration thread ID. These are more relevant when you want to create an entry as if it had come from the end user instead of the bot.In this example, these values aren't relevant, but we still need to set them in order to be syntactically correct. We'll just set them to dummy values.
We're finally ready to make our API call! Here's how to make the call using cURL:
curl --request POST \
--url 'https://grid.meya.ai/gateway/v2/webhook/APP_ID/integration.webhook' \
--header 'Authorization: Basic BASE64_ENCODED_AUTH' \
--header 'Content-Type: application/json' \
--data '{
"entry": {
"type": "meya.text.event.say",
"data": {
"text": "Hi!",
"user_id": "BOT_USER_ID",
"thread_id": "THREAD_ID",
"quick_replies": [
{
"text": "I want to talk to support"
}
],
"integration_id": "meya"
}
},
"user": {
"id": "123"
},
"thread": {
"id": "123"
}
}
'
Make sure you swap out the APP_ID
, BASE64_ENCODED_AUTH
, BOT_USER_ID
, and THREAD_ID
values for the actual values.
Great! You now know how to send messages to the user from the bot.
Now that you know the basics, the rest of the examples will be a bit more concise. Let's take a look at some more common use-cases.
Starting a flow
Let's say you have a flow you want to run every day, perhaps to send a daily digest, reminder, or status update to your users. You can do that by creating a meya.lifecycle.event.event
entry.
Lifecycle trigger
Any flow that you want to start via the API will need to use the
meya.lifecycle.trigger
in itstriggers
section.
Why not
meya.flow.entry.start
?Although the name might sound like it would be the right choice,
meya.flow.entry.start
does not cause a flow to start, rather it records that a flow has started.Also, notice that the type name does not include the word
event
. As mentioned above, the API only accepts event entries.
Create a flow
First let's create a simple flow we can trigger.
triggers:
- lifecycle_id: started_from_api
steps:
- say: Here's the data that was passed in (@ flow )
- say: That's all!
Format the payload
Not all entry properties are required. Check out the code box below for examples of basic and complete entries.
{
"entry": {
"type": "meya.lifecycle.event.event",
"data": {
"user_id": "BOT_USER_ID",
"thread_id": "THREAD_ID",
"lifecycle_id": "started_from_api"
}
},
"user": {
"id": "123"
},
"thread": {
"id": "123"
}
}
{
"entry": {
"type": "meya.lifecycle.event.event",
"data": {
"user_id": "BOT_USER_ID",
"thread_id": "THREAD_ID",
"lifecycle_id": "started_from_api",
"sensitive": true,
"context": {
"foo": "bar"
},
"text": "Let's start a flow..."
}
},
"user": {
"id": "123"
},
"thread": {
"id": "123"
}
}
As in the first example, we're using the bot's Meya user ID and the Meya thread ID, so we we can put any value for the
user
andthread
properties which represent the integration user ID and integration thread ID.
Okay, let's give it a try!
curl --request POST \
--url 'https://grid.meya.ai/gateway/v2/webhook/APP_ID/integration.webhook' \
--header 'Authorization: Basic BASE64_ENCODED_AUTH' \
--header 'Content-Type: application/json' \
--data '{
"entry": {
"type": "meya.lifecycle.event.event",
"data": {
"user_id": "BOT_USER_ID",
"thread_id": "THREAD_ID",
"lifecycle_id": "started_from_api",
"sensitive": true,
"context": {
"foo": "bar"
},
"text": "Let'\''s start a flow..."
}
},
"user": {
"id": "123"
},
"thread": {
"id": "123"
}
}
'
Make sure you swap out the APP_ID
, BASE64_ENCODED_AUTH
, BOT_USER_ID
, and THREAD_ID
values for the actual values.
Here's the result:
This should be enough to get you started with making API calls to your app.
If you have questions about how to create a particular type of entry, you can contact our support team via your shared Slack channel, or at [email protected]
Updated over 3 years ago