---
title: Workflows as APIs
url: https://www.tines.com/docs/stories/apis/
updated: 2026-06-08T23:48:36+00:00
---

*[tines.com](https://www.tines.com/llms.txt) › [Docs](https://www.tines.com/llms.txt) › [Stories](https://www.tines.com/llm/docs/stories.md)*

# Workflows as APIs

*[View on tines.com](https://www.tines.com/docs/stories/apis/)*

> **NOTE:** Not seeing this feature? Talk to your tenant admin or [reach out to the Tines team](https://www.tines.com/contact-support/) to learn more.

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:

![](https://www.datocms-assets.com/55802/1684156508-cleanshot-2023-05-15-at-14-14-51-2x.png)

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:

```json

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.

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

```json

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:

```json
HTTP/1.1 200 OK
Accept: application/json

[["1","2","3"],["4","5","6"]]
```

```json
HTTP/1.1 200 OK
Accept: text/csv

1,2,3
4,5,6
```

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`.

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

### Metadata

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.

### Limits

An Exit Action must generate an event within 30 seconds of the request being made in order to return event data in the response. Otherwise, a `HTTP/1.1 504 Gateway Timeout` response will be returned.

```json

HTTP/1.1 504 Gateway Timeout

{ 
    "limit_reached": "time",
    "response_url": "https://tenant.tines.com/webhook/path/secret/id"
}
```

The story run will continue after this timeout response is returned. If/when an Exit Action produces an event for this story run, the `response_url` returned in body of the timeout response can be visited to access the event data. The response URL can also be found 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.
