# What Relay Is: An Overview

<div><figure><img src="/files/lus7jE661MUFPXoCycNF" alt="" width="375"><figcaption><p>RelayX</p></figcaption></figure> <figure><img src="/files/YKhDyVp43UFSdAiEeBKH" alt="" width="375"><figcaption><p>Relay+</p></figcaption></figure></div>

Relay is a hardware-based platform for voice and mobile IoT applications. As an enterprise-first platform, it brings a modern software stack, an easy-to-use programming interface, and a quick path to integration. The goal of Relay is to enable your active workers to have two-way connections to the tools and people in the rest of your organization. And to do so with high capability, easy deployment, and low expense.

Relay's first success was in the voice communications space, with its push-to-talk capabilities and built-in connectivity. As a smart device, Relay can do more than push-to-talk communications. In the following sections we explain the "more".

### Jump right in

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Relay Capabilities</strong></td><td>More details on Relay products</td><td><a href="/files/kP5BciPXi4cCIc3YNgp7">/files/kP5BciPXi4cCIc3YNgp7</a></td><td></td><td><a href="/pages/JjjojIyKxaiBPzzLwvtg">/pages/JjjojIyKxaiBPzzLwvtg</a></td></tr><tr><td><strong>FAQs</strong></td><td>Answers to commonly asked questions</td><td><a href="/files/gjxPpNvQYKhqBu55rEj1">/files/gjxPpNvQYKhqBu55rEj1</a></td><td></td><td><a href="/pages/7aUFmnCMx9m4smGncsXL">/pages/7aUFmnCMx9m4smGncsXL</a></td></tr><tr><td><strong>Alerts</strong></td><td>Use our API to send alerts via Relay</td><td><a href="/files/FGdJ9yleWQC9WSErmXFh">/files/FGdJ9yleWQC9WSErmXFh</a></td><td></td><td><a href="/pages/cEHgDv7NGBquDGHeLyQ4">/pages/cEHgDv7NGBquDGHeLyQ4</a></td></tr></tbody></table>


# Relay Capabilities

<figure><img src="/files/KQ3vMHTQPZYSAPa8144J" alt=""><figcaption></figcaption></figure>

With both cell and WiFi connectivity, Relay devices can go nationwide, extending beyond the reach of walkie talkies, without needing to install proprietary infrastructure. With IPX8 it survives moisture, dust, and shock, gracefully handling the active workplace. It is both uniquely portable, and at the same time capable and simplified. It includes the following:

* LTE connectivity over multiple cellular carriers included in the base price.
* Outdoor location positioning, including geofences.
* An enterprise solution for room-level indoor location that doesn't require an expensive infrastructure, and it can be self-deployed.
* Other sensors such as Bluetooth and NFC.
* Headsets for discreet audio communication via USB or Bluetooth.
* Generated speech (text to speech) and phrase recognition (speech to text).
* Playback of dynamic and pre-recorded audio.
* Push-to-talk audio communication.
* Relay-manufactured NFC tags with increased capabilities that can very inexpensively and securely identify your important locations.
* Controllable vibration and LED indicators (full color, individually addressable).
* A limited number of buttons for user simplicity, with detection of multi-tap sequences.


# FAQs

* Do I have to bring my own cellular connectivity?\
  No, we manage connectivity with leading cellular providers and include it on your devices.
* Are Relay devices rugged?\
  Our devices are rated IPX8, waterproof to more than 3 feet of water and dust resistant. Relay+ and RelayX are Military Standard Temperature, Drop, Vibration, Humidity and Fog certified (810G and 810H respectively).
* How is GPS data transmitted?\
  We provide Lat/Long coordinates updated as frequently as every 30 seconds (frequency is configurable)
* Do you support Speech-to-Text and Text-to-Speech?\
  Yes, we use our own proprietary algorithm to provide cloud-based text-to-speech and speech-to-text capability.

For questions on how to use your device or account management visit our [Customer Support page](https://support.relaypro.com/portal/en/kb/relay-pro).


# Alerts

## About

Relay’s Alert APIs notify your Relay users of any urgent events. Whether you’re a hotel, and want to quickly alert your housekeeping team or you’re a hospital, and need to alert the EVS team when a room needs to be turned over - the Relay Alert API can make it happen.

With the Alerts API, notifications are sent to specified groups on your account with a custom Text-to-Speech message and, optionally, an acknowledgement. The API allows you to send notifications that are either an **Alert** or a **Broadcast**. Notifications are done through a simple HTTP API. This allows you to effortlessly integrate these notifications into your own platform with an HTTP request. For example, if you had a ticketing system, broadcasting a message on a group of devices every time a ticket is added is done with an HTTP request to the `/broadcast` endpoint at the time of ticket creation.

Learn more below about how you can create different groups on your account, as well as how to make these API calls.

## Workflow Groups

Workflow Groups provide a way to organize users on your account.

A group is a set of one or more users on your account. In order to create a group, simply navigate to your Relay Dash home page and click on the **Incidents** section to the left. From there, you should see **Workflow Groups** option. Next, select **Create Workflow Group.** After entering a name for your group, select **No Type** and then you should be able to see your empty group in the **Workflow** **Groups** section. After selecting your group, you can then use the **Edit Membership** option to the left to add or remove users from the group.&#x20;

<figure><img src="/files/7NONDixXRNdBUlVFyKYk" alt=""><figcaption></figcaption></figure>


# Triggering an Alert

An alert is a message that is played out on devices within a specified group every 30 seconds until it is acknowledged.

An alert can be started through a simple `POST` request to our server into our `/alerts` endpoint.&#x20;

The `POST` command to send an alert should take the following form:

```http
POST /subscribers/{id}/api/v1/alerts
Authorization: RelayApiKey {apikey}
Content-type: application/json

{
   "notification": "hello world",
   "groups": ["mygroup"],
}
```

### Headers and Subscriber ID Path

* `apikey` : If you are on the enterprise plan, you can create an API key by navigating to **Help** → **API Keys** in [Relay Dash](https://dash.relaypro.com/api-keys). Your key should be included within the Authorization header. Don’t forget to include “RelayApiKey” before your actual key.
* `id` : your subscriber ID, which can be found on [Relay Dash](https://dash.relaypro.com/diagnostic-logs) through **Help** → **Diagnostic Logs** → **Server Details** under **Subscriber**

### **Required Content**

* `notification` : custom message to be spoken on the group of devices. The Relay server will automatically convert your written text into spoken audio (text-to-speech)
* `groups` : a list containing the group names or URNs to send the alert to.

### Example

The following example is a curl command that sends an alert request up to our server.

```sh
$ export subscriber_id=yourcustomersID
$ export apikey=myapikey123
$ curl -X POST -H "Authorization: RelayApiKey $apikey" "https://api.relaypro.com/subscribers/$subscriber_id/api/v1/alerts" -d '{"notification": "Cleanup needed in the lounge", "groups": ["housekeeping"]}' -i

HTTP/2 200 
date: Mon, 11 Dec 2023 14:31:36 GMT
content-type: application/json
content-length: 38
server: nginx/1.20.0
location: /subscribers/xxx/api/v1/alerts/P9CThKfTsEbJx23trAArHCD

{"task_id":"P9CThKfTsEbJx23trAArHCD"}
```

This curl command alerts the group “housekeeping” that there is “Cleanup needed in the lounge”. The alert will continue to sound on a user’s device every 30 seconds until it is acknowledged by the user tapping the talk button. Once the user taps the talk button, the alert will stop sounding on the device. If the user does not acknowledge the alert after 5 minutes, the alert will timeout and cease playing. See what this alert looks like on the device in the video below.

{% embed url="<https://www.youtube.com/watch?v=cvM9Oq4-t5g>" %}


# Customizing Your Alerts

In addition to the `notification` and `groups` keys, alerts give you the option to further customize your notification. There are 6 optional keys that you can include in your payload when sending the request:

* `on_ack` : custom message to be spoken on the device that acknowledged the alert (default: nothing is spoken)
* `quorum` : remaining alerts are canceled after this number of acknowledgements (default: all devices in the group must acknowledge the alert)
* `on_quorum` : custom message to be spoken on devices that have not yet acknowledged the alert after `quorum` is met (default: nothing is spoken)
* `timeout` : remaining alerts are canceled after this time (seconds) (default: 300)
* `on_timeout` : custom message to be spoken on the devices that have not acknowledged the alert after timeout (default: nothing is spoken)
* `name` : gives user agents control over serial / concurrent alerting. This also appears in the analytics events for correlation (default: “alerts”)

Upon adding these to the request, our `POST` command could take the following form:

```http
POST /subscribers/{id}/api/v1/alerts
Authorization: RelayApiKey {apikey}
Content-type: application/json

{
   "notification": "hello world",
   "groups": ["mygroup"],
   "on_ack": "thank you",
   "quorum": 1,
   "on_quorum": "already accepted",
   "timeout": 120,
   "on_timeout": "too slow",
   "name": "myname"
}
```

Let's see how we can customize our alert using some of these options. In the first example, we saw how we could send a simple alert to a group of devices using all of the default configuration settings. In the curl command below, we again trigger an alert with the message “Cleanup needed in the lounge” to the group “housekeeping”. However, this time we include four more key-value pairs into the request. We added in the `quorum` key with a value of 1, making it so our alert will only require that one device acknowledges the alert as opposed to all devices in the group. Once a device acknowledges the alert, the alert will terminate on all devices. We also included an `on_ack` key with a value of “thank you”. With this, after the user acknowledges the alert the device will say “thank you” to that user. This acts as a confirmation to the user that they acknowledged the alert. We also added in the `timeout` and `on_timeout` keys, making it so if the alert times out because no device tapped the talk button in an allocated 120 seconds, the devices will say “alert timed out!” on all of the devices in the group.

Putting all of this together, we get the curl command below.

```sh
$ export subscriber_id=yourcustomersID
$ export apikey=myapikey123
$ curl -X POST -H "Authorization: RelayApiKey $apikey" "https://api.relaypro.com/subscribers/$subscriber_id/api/v1/alerts" -d '{"notification": "Cleanup needed in the lounge", "groups": ["housekeeping"], "on_ack": "thank you","quorum": 1, "timeout": 120, "on_timeout": "alert timed out!" }' -i

HTTP/2 200 
date: Mon, 11 Dec 2023 14:31:36 GMT
content-type: application/json
content-length: 38
server: nginx/1.20.0
location: /subscribers/xxx/api/v1/alerts/P9CThKfTsEbJx23trAArHCD

{"task_id":"P9CThKfTsEbJx23trAArHCD"}
```

See this example in action below, where we run the curl command above to fire the alert, and a device acknowledges the alert by tapping the talk button. Notice that now, after a device acknowledges the alert, the device now says “thank you” to that user, and the alert terminates.

{% embed url="<https://www.youtube.com/watch?v=Q6DAMF5aIz0>" %}


# Advanced Configuration

### Cancel an Alert

Alerts will be repeated every 30 seconds on all devices that have not yet acknowledged the alert. However, you can explicitly cancel an alert on these devices through an API `DELETE` request.

The `DELETE` request should take the following form:

```http
DELETE /subscribers/{id}/api/v1/alerts/{task_id}
Authorization: RelayApiKey {apikey}
```

The following curl command deletes the alert we created above.

```sh
$ export subscriber_id=yourcustomersID
$ export apikey=myapikey123
$ curl -H "authorization: RelayApiKey $apikey" "https://api.relaypro.com/subscribers/$subscriber_id/api/v1/alerts/P9CThKfTsEbJx23trAArHCD" -X DELETE
```

{% hint style="info" %}
Notice that we add a `task_id` to the end of the path. This ID matches the returned `task_id` value from the response of the curl command that started the alert above, canceling that alert on all remaining devices.
{% endhint %}

### Analytics

An analytic event is created each time an alert has been acknowledged or has timed out. These events are logged on your account, and can be retrieved via the [Relay CLI](https://github.com/relaypro/relay-cli) command `relay analytics`.

For example, the following analytic event would be logged if the alert above has been acknowledged by a device named Mary:

```
  => Showing up to 20 events  
  Workflow ID                                           Type   Category Instance ID                Timestamp                   User ID Content  
  ───────────────────────────────────────────────────── ────── ──────── ────────────────────────── ─────────────────────────── ─────── ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────  
  ...  
  wf_y9CSxgI2V4goVt2Q9AemmEKA_YXcZ4rRCQxfS8QmpNUx9AYA   user   tasks    GzpGAKVPGlhfHt4H3kuWXA     2023-12-18T15:01:12.262552Z         {"device":"Mary","task":{"id":"P9CThKfTsEbJx23trAArHCD","name":"alerts","task_type":{"major":1,"minor":1,"name":"alerts","namespace":"system"}},"type":"acknowledged"}  
  ...
```

However, if the alert timed out before any acknowledgement, the following analytic event would be logged:

```
=> Showing up to 20 events  
  Workflow ID                                           Type   Category Instance ID                Timestamp                   User ID Content  
  ───────────────────────────────────────────────────── ────── ──────── ────────────────────────── ─────────────────────────── ─────── ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────  
  ...  
  wf_k6WtQtSdgU2vS1uIT9CED9CD_R8isRGD5R0da55PB7pgY4C    user   tasks    GzpGAKVPGlhfHt4H3kuWXA     2023-12-18T15:03:00.000345Z         {"task":{"id":"P9CThKfTsEbJx23trAArHCD","name":"alerts","task_type":{"major":1,"minor":1,"name":"alerts","namespace":"system"}},"type":"timed_out"}  
  ...
```

The workflow analytics command will show the 20 most recent events in the last 7 days by default. To view more events (up to 7 days), use the `--limit=100` option to increase the number of events displayed.


# Broadcasts

A broadcast is a message that is played out once on devices within the specified group, and no acknowledgement is needed.

A broadcast can be started through a simple `POST` request to our server into our `/broadcasts` endpoint. This can be done through an API platform like [Postman](https://www.postman.com/) or [Insomnia](https://insomnia.rest/), through simple curl commands in the shell, or within your codebase.

### Triggering a Broadcast

The `POST` command to send the broadcast should take the following form:

```http
POST /subscribers/{id}/api/v1/broadcasts
Authorization: RelayApiKey {apikey}
Content-type: application/json

{
   "notification": "hello world",
   "groups": ["mygroup"]
}
```

### Headers and Subscriber ID Path

* `apikey` : If you are on the enterprise plan, you can create an API key by navigating to **Help** → **API Keys** in [Relay Dash](https://dash.relaypro.com/api-keys). Your key should be included within the Authorization header. Don’t forget to include “RelayApiKey” before your actual key.
* `id` : your subscriber ID, which can be found on [Relay Dash](https://dash.relaypro.com/diagnostic-logs) through **Help** → **Diagnostic Logs** → **Server Details** under **Subscriber**

### Required Content

* `notification` : custom message to be spoken on the group of devices. The Relay server will automatically convert your written text into spoken audio (text-to-speech)
* `groups` : a list containing the group names or URNs to send the broadcast to

### Example

The following example shows a curl command that sends a broadcast request up to our server.

```sh
$ export subscriber_id=yourcustomersID
$ export apikey=myapikey123
$ curl -X POST -H "Authorization: RelayApiKey $apikey" "https://api.relaypro.com/subscribers/$subscriber_id/api/v1/broadcasts" -d '{"notification": "All rounds must be done by 10pm tonight.", "groups": ["security1", "security2"]}' -i
```

This curl command broadcasts the message “All rounds must be done by 10pm tonight” to two different groups, security1 and security2. The message will only be broadcasted one time on all devices that are in either of those groups. See what this broadcast looks like on the device in the video below. Notice how no acknowledgement is needed from the user.

{% embed url="<https://www.youtube.com/watch?v=wFJOVJsZ9zE>" %}


# Events

An analytic event is created each time an alert has been triggered or acknowledged. Each event has an associated `task_id` that is the returned value from the response of an alert API call.&#x20;

{% hint style="info" %}
Analytic events also have an associated `name` field for correlation that can be programmatically set when an alert is sent via the `/alerts` endpoint. See [Customizing Your Alerts](/docs/relay-alerts-api/customizing-your-alerts).
{% endhint %}

Events can be retrieved through a simple `GET` request to our server into our `/events` endpoint.&#x20;

The `GET` command to send the broadcast should take the following form:

```http
GET /subscribers/{id}/api/v1/events
Authorization: RelayApiKey {apikey}
Content-type: application/json
```

### Headers and Subscriber ID Path

* `apikey` : If you are on the enterprise plan, you can create an API key by navigating to **Help** → **API Keys** in [Relay Dash](https://dash.relaypro.com/api-keys). Your key should be included within the Authorization header. Don’t forget to include “RelayApiKey” before your actual key.
* `id` : your subscriber ID, which can be found on [Relay Dash](https://dash.relaypro.com/diagnostic-logs) through **Help** → **Diagnostic Logs** → **Server Details** under **Subscriber**

### **Optional Query Parameters**

* `oldest`: An iso8601 timestamp which defaults to 7 days ago&#x20;
* `limit`: The maximum number of events returned which defaults to 100, the API will return no more than 100 events

### Example

The following example shows a curl command that retrieves the oldest analytic event from August 8th  from our server.

<pre class="language-sh"><code class="lang-sh"><strong>$ export subscriber_id=yourcustomersID
</strong>$ export apikey=apikey123
$ curl -s -H "authorization: RelayApiKey $apikey" "https://api.relaypro.com/subscribers/$subscriber_id/api/v1/events?oldest=2024-08-08T12:00:30Z&#x26;limit=1" | jq
[
 {
  "category": "tasks",
  "content": {"type":"start"},
  "task": {"id": "mCcJawrh3shriXHombQxXA","name": "alerts","task_type": { "major": 1,
  "minor": 4, "name": "alerts", "namespace": "system"}},
  "event_id": "a195f66af5514cacbdbeea09c8e785f6",
  "timestamp": "2024-08-08T18:25:40.923947Z"
 }
]

</code></pre>

In the JSON object that gets returned details information about the event and the following fields determine what kind of analytic event it is:

* `content`: This field contains information on the event type as well as any external metadata that may have been sent with the event
  * `type`: This field represents the kind of event that is being returned and can equal the following:
    * `start`: event for when the alert was triggered
      * `end`: event for when the alert is completed (through time out, acknowledgement or error)
      * `acknowledged`: event for when device acknowledges an alert
      * `timed_out`: event for when an alert times out and no one has acknowledged it
  * `device`: This field will be present if the event `type` is `acknowledged` and represented the user profile associated with the device that acknowledged the alert
  * `status`: This field will be present if the event `type` is `end` and the alert has been completed, if the alert was completed without error this should equal `normal`
* `task` : The JSON object for the specific event
  * `id` : Identifier for the task that will be same for every event relevant to the triggered alert (start, acknowledge, time\_out, end), this allows you to track a task throughout each different stages
  * `name` : Correlation identifier that can be set when event is triggered, defaults to `alert`
* `event_id`: An unique identifier for the returned analytic event&#x20;
* `timestamp`: The time at which the event occured

The following is an example returned for an event for when an alert was triggered:

<pre class="language-json"><code class="lang-json">{
<strong>  "category": "tasks",
</strong>  "content": {  
              "type":"start"
              },
  "task": {
    "id": "mCcJawrh3shriXHombQxXA",
    "name": "alerts",
    "task_type": {
      "major": 1,
      "minor": 4,
      "name": "alerts",
      "namespace": "system"
    }
  },
  "event_id": "XXX",
  "timestamp": "2024-08-08T18:25:40.923947Z"
}
</code></pre>

The following is an example returned for an event for when an alert was acknowledged by user 'bob' on a device or virtual account:

```json
{
  "category": "tasks",
  "content": {
              "type":"acknowledged",
              "device": "bob" 
            },
  "task": {
    "id": "9C9AbxNELsQphK9Afhzr6yG6C",
    "name": "alerts",
    "task_type": {
      "major": 1,
      "minor": 2,
      "name": "alerts",
      "namespace": "system"
    }
  },
  "event_id": "XXX",
  "timestamp": "2024-08-08T18:25:40.923947Z"
}
```

The following is an example returned for an event for when an alert that timed out:

<pre class="language-json"><code class="lang-json">{
<strong>  "category": "tasks",
</strong>  "content": {  
              "type":"timed_out"
              },
  "task": {
    "id": "mCcJawrh3shriXHombQxXA",
    "name": "alerts",
    "task_type": {
      "major": 1,
      "minor": 2,
      "name": "alerts",
      "namespace": "system"
    }
  },
  "event_id": "XXX",
  "timestamp": "2024-08-08T18:25:40.923947Z"
}
</code></pre>

The following is an example returned for an event for when an alert was completed:

<pre class="language-json"><code class="lang-json">{
<strong>  "category": "tasks",
</strong>  "content": {  
              "type":"end",
              "status": "normal"
              },
  "task": {
    "id": "9C9AbxNELsQphK9Afhzr6yG6C",
    "name": "alerts",
    "task_type": {
      "major": 1,
      "minor": 2,
      "name": "alerts",
      "namespace": "system"
    }
  },
  "event_id": "XXX",
  "timestamp": "2024-08-08T18:25:40.923947Z"
}
</code></pre>


# Workflows


# Registering Your Workflows


# Triggers, Events and Commands


# Example Use Cases


