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 a 400 error with the message Unhandled 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:

Finding the bot's user ID in a log entry.Finding the bot's user ID in a log entry.

Finding the bot's user ID in a log 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 and thread

In addition to the entry itself, there are two other fields we always need to send: user and thread. 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 its triggers 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 and thread 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]