Skip to main content

Stacks API Integrations

Stacks can integrate with APIs exposed over HTTP.

The functions get and post do HTTP calls. HTTP calls allow for the following parameters:

stack Stack do
card GetCard do
get_response = get("",
timeout: 60_000,
cache_ttl: 60_000,
query: [
["name", ""],
["whatsapp_id", "@contact.whatsapp_id"]

card PostCard do
post_response = post("",
timeout: 60_000,
cache_ttl: 60_000,
body: """
{"username": @contact.whatsapp_id}
headers: [["content-type", "application/json"]]
bodyThe body of the HTTP request
cache_ttlHow long to cache a response for, in milliseconds (60_000 or 60000 is 60 seconds)
headersA list of lists with HTTP headers, [["X-Foo", "Bar"]] would add the X-Foo header to the HTTP request.
mode"sync" or "async"
queryA list of lists with keys & values to use as query parameters [[key, value]] adds ?key=value to the request
timeoutHow long a request is allowed to take, in milliseconds
urlThe HTTP endpoint

The HTTP headers and query parameters can be expressions that are evaluated.

RSS feed integration

Here is an example that reads the RSS feed for the BBC's Global News Podcast and allows users to navigate through the episodes and listen to them.

stack BBCWorldService, "BBC World Service" do
card Init, "⏮ Latest episode", then: Start do
# Initialize the cursor with a value of zero, this means we always start
# with the first, most recent, entry from the RSS feed
cursor = 0
# Use the public API at to convert the RSS feed that the
# BBC publishes for their world service podcast to a JSON file that
# we can read.
webhook =

items = webhook.body.items
# Keep track of the total number of items
total_items = count(items)

card Start do
# Read the current item
item = items[cursor]

# send the audio file first, since this is a _big_ file it takes longer to arrive
# on the phone than the messages we send later.

# generate the buttons
buttons([Init, NextCard]) do
# send the title as a caption


_Episode @(cursor + 1) of @(total_items)_
_Published at @(item.pubDate)_
# The feed unfortunately doesn't have images and so we're just using a static
# image from the BBC website

# We change the text on the button depending on whether or not we have any further
# episodes. If we do we display "Next episode ➡️", if we don't we display "⏮ First episode"
# Also if we reach the end of the total number of episodes, we reset the counter to 0
# which has us starting at the beginning again.
card NextCard, "@IF(cursor + 1 < total_items, \"Next episode ➡️\", \"⏮ First episode\")",
then: Start do
cursor = if cursor + 1 < total_items, do: cursor + 1, else: 0