Javascript API

Table of contents

onArrive and onMessage

Each node must contain one onArrive and one onMessage function.

onArrive is called when the user enters the node for the first time.

export const onArrive = async (api) => {
  /* place your code here */

onMessage is called each time the user sends a message or makes a choice.

export const onMessage = async (msg, api) => {
  /* place your code here */

The code that defines the behaviour of the node is placed between the { and }

In the Handlers tab, these functions are provided automatically for you.


Move the player to a different node on the same board:


Advanced: Move the player on a different board:

api.moveTo("node1", {channelKey: "board2"})

This does not change the node on the current board.

Sending messages


Sends a text message to the player.



Sends an image message to the user.


The first parameter is the media file key. To get the media file key, go to the Media tab, open ⋮ menu, copy key.

Images are normally scaled and cropped to fit (“cover” mode). To make sure that everything on the image is visible, you can switch to “contain” mode:

  { objectFit: "contain" }

Images are by default zoomable (enlarge on click or tap). Prevent zoom:

  { zoomable: false }

Send an image with a link that the user can click on:

  { url: "" }

Trigger an action on the client by clicking an image

  {action: {trigger: "triggerName", payload: payloadObject}}



The first parameter is the media file key. To get the media file key, go to the Media tab, open ⋮ menu, copy key.



The first parameter is the media file key. To get the media file key, go to the Media tab, open ⋮ menu, copy key.


Send a choice, presented as multiple choic buttons.

  a: "option a",
  b: "option b"

See the responding to messages section below for reponding to a choice made by a user


Send a system message das is displayed in the center of the chat. Useful for error messages or neutral informational content.

api.sendSystem("Someone entered the channel")


Send a system image displayed in the center of the chat.


Set a custom width for the image

  {width: "200px"}

Place the system image on either side of the chat

  {placement: "me"}
  {placement: "other"}


Add a label to identify a sender.

api.sendText("hello", {label: "bot"})

You can add labels in the same way to the other types of messages.


Use the dealy option to schedule events for later delivery. This works for sendText, sendChoice, sendImage and moveTo.

Send a message 10 seconds later

api.sendText("hello", {delay: 10}) 

Send a message 1 hour, 30 minutes later

api.sendText("hello", {delay: {hours: 1, minutes: 30}}) 

Send a message the “next 13 o’clock”, either later today, or tomorrow (in the server’s timezone!)

api.sendText("hello", {delay: {nextHour: 13}}) 

Add between 0 and 60 minutes, randomly

api.sendText("hello", {delay: {nextHour: 13, randomHours: 1}})

Responding to messages

The onMessage method receives a msg parameter that you can evaluate to respond conditionally to messages.

if(msg.payload.text == "foo") {
  // do something

If the user made a multiple choice selection, the key attribute on msg.payload will be set.

if(msg.payload.key == "a") {
  // do something

msg.payload.type contains information about the type of message that the user sent.


To create, multiplayer chatrooms, you need to forward incoming messages to other users.

echo forwards a message to other users currently in the same node.


The user variable “name” is used by default as a label.

msg is supposed to be a whole message object like the one received in onMessage(api, msg).

Sending to specific recipients

By default, the recipient of a message sent by any api.send...() function is the current user.

All api.send...() functions accept further options to specify the recipients:

  • channelKey optionally send this message on a different channel
  • recipients an array of recipients user ids.
api.sendText("hello", {
  channelKey: "other_board",
  recipients: ["ohpppdsCZ9CXZ4Ds4", "bREC5nMSLoRNjSRn3"], 

To broadcast a message to all users that are currently in a node, specify the nodeId inside the recipients

api.sendSystem("The bus will arrive in 5 minutes", {
  recipients: {
    nodeId: "waitingforthebus"

You can also get the explicit list of users in a node with getUsersInNode({ channelKey, nodeId }).


Set a variable for this user, for example set the user’s “name” to “alice”.

await api.setUserVar("name", "alice")

Get a variable for this user, for example the variable called “name”

await api.getUserVar("name")

These operations read from the database, so await is needed.

Database rows

Load rows from a sheet

await api.getRows("elements")

Add a row to a sheet

await api.addRow("elements", {title: "hello"})

Update a row

await api.updateRow("elements", "rowKey", {title: "bye"})

These operations read from the database, so await is needed.

Data annotations

Set or get a data annotation (formerly called element properties) about an element for this user. Data annotations are user specific data that is added to database rows, for example bookmarks.

The first parameter is the row key, the second the annotation name, the third, the value you want to set.

await api.setElementProperty("f00ba420-0123-4567-89abcdef012356789", "discovered", true)
await api.getElementProperty("f00ba420-0123-4567-89abcdef012356789", "discovered")

These operations read from the database, so await is needed.


You can set what interface the chat could display to the user. For example if you want users to be able to take photos or not. These settings persist across nodes per board.

The default is text entry, with photo turned off.

Hide the interface for sending messages:

api.setInterface({text: false})
api.setInterface({text: true}) // turn it back on 

Allow user to take pictures and send them into chat:

api.setInterface({text: true, photo: true}) // text and photo entry
api.setInterface({text: false, photo: true}) // just photo entry

Set preferred camera (front or back):

api.setInterface({photo: true, cameraFacingMode: "environment"}) // or "user" for selfie mode

The interface can be also set per message.

api.sendText('Give me a photo', { setInterface: { photo: true, text: false } })


To get a user’s location, we can present the user with a button that enables them to send their location.

api.requestLocation("Send Location", {cancel: "Cancel"}) // you can also leave the cancel option blank

Responding to a location looks like this

if(msg.payload.type == "locationResponse") {
  // do something
  if(api.distance(msg.payload.location, {lat: 56, lng: 12}) < 100) {
    api.sendText("you're close!")
if(msg.payload.type == "locationRequestCanceled") {


See the i18n guide for general intro to interkit’s i18n system.

Access the current language

api.sendText('your language: ' + api.userLang)
api.sendText('your language, index: ' + api.userLangIndex)

Set language

api.setLang('de', 1) 

The second argument has to match the index (0-based) in the AppBase blockly field

Use current language

if (api.userLang === 'en') ...
if (api.userLangIndex === 1) ...
let text1 = ['Deutsch', 'Englisch'][api.userLangIndex]
let text2 = {de: 'Deutsch', en: 'Englisch'}[api.userLang]

Use text localized to current user language

export const onMessage = async (msg, api, t) => {
  api.sendChoice({ a: t('Ja|Yes'), b: t('Nein|No') })

The t helper function takes pipe-separated strings, arrays or objets:

api.sendText(t(['Ja', 'Yes']))
api.sendText(t({ de: 'Ja', en: 'Yes' })) // order-independant

You can use sendTextT, sendChoiceT, sendSystemT shortcuts, equivalently

api.sendChoiceT({ a: 'Ja|Yes', b: ['Nein', 'No'] })
api.sendSystemT('Chat verlassen|Left the chat')