Workflows as APIs

Using APIs it is possible to make a HTTP request to initiate a story run and receive event data back from the story. This can be configured via API settings:

Retrieving data can be achieved by making a HTTP request to the webhook entry action.

The endpoint will return the event data emitted by the exit action. For example:

HTTP/1.1 200 OK

    "message":"The random number is: 4"

In the case where there are multiple exit actions, the event data from first exit action to execute will be returned.

Response body, status, and headers 

By default, the payload of the exit action is returned in the webhook HTTP response body. You can gain more fine-grained control over the response by adopting an exit action payload convention.

If your exit action contains the status and body keys and the status field is a valid HTTP response code, the status field will be used to set the HTTP status line and the body field will be used as the HTTP response body.

Furthermore, you can include a headers object to include custom HTTP response headers. For example, the following exit action payload will generate the HTTP response below.

  "status": "202",
  "headers": {
    "X-Tines-Story": "<<>>",
    "X-Tines-Change-Control-Test": "<<META.story.is_test>>"
  "body": {
    "random_number": "The generated random number is <<generate_random_number.number>>"

HTTP/1.1 202 Accepted
X-Tines-Story: My Story
X-Tines-Change-Control-Test: true

    "random_number":"The generated random number is 4"

Content types 

Responses can be returned in a variety of formats. To request a specific format you can use the HTTP accept header to specify the content type you want to receive. We currently support the following data types:

  • application/json - the default format

  • text/csv - you can receive your array data in CSV format

  • text/plain - for data that doesn't need any fancy formatting

  • File handling - if you return binary or Base64 encoded files. you can specify the format to support many, many more data types like image/png, application/pdf or audio/aac

We also support wildcards and will default to JSON.

Below is an example showing the difference between JSON and CSV:

HTTP/1.1 200 OK
Accept: application/json

HTTP/1.1 200 OK
Accept: text/csv


You can hard code a specific content type and content disposition headers in your response action.

For example, the following exit action payload will generate a HTTP response below with the content type always set to application/pdf and a content disposition of attachment; filename=report.pdf, so the file downloads with the name report.pdf.

  "status": "202",
  "headers": {
    "Content-Type": "application/pdf",
    "Content-Disposition": "attachment; filename=report.pdf"
  "body": "<<http_request.body.base64encodedcontents>>"


Included in the response will be a set of HTTP headers containing metadata about the status of the request, the event, and the action producing the data:

  • X-Tines-Status: The status of the request, values include:

    • data_received - the story executed and data is included in the response

    • ok - the story is executing but did not return data in time

    • error - there was an error processing the request

  • X-Tines-Event-ID: The ID of the event containing the data that was returned

  • X-Tines-Exit-Action-ID: The ID of the exit action that produced the event

  • X-Tines-Limit-Reached: If the request reached a limit, the limit that was reached will be included here

  • X-Tines-Response-Location: a URL where the response will be available in JSON format if and when they become available.


There are limits on how much this feature can be used. In order to return data in a timely manner, story runs must complete within 30 seconds.

Stories executed this way are guaranteed to run. This means even if your story run does not complete within 30 seconds, it will be executed to completion. In these cases a response of HTTP/1.1 504 Gateway Timeout will be returned, rather than a 200 status code.

HTTP/1.1 504 Gateway Timeout

    "limit_reached": "time",
    "response_url": ""

Included in the timeout response is a URL where the response will be available in JSON format if and when they become available. This is also available in the X-Tines-Response-Location header.

There are also limits on the number of these requests that can be run simultaneously. In the cases where these limits are exceeded, a response of HTTP/1.1 201 Created will be returned, rather than a 200 status code, and the story will continue to run.

More information is included in the X-Tines-Status and X-Tines-Limit-Reached HTTP headers.

Was this helpful?