> For the complete documentation index, see [llms.txt](https://docs.beamlabs.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.beamlabs.io/getting-started/webhooks.md).

# Webhooks

### Requesting Access

If you believe your application requires webhooks, please contact Beam Labs at <support@beamlabs.io>.

### Implementing Webhooks

Webhooks allows for better real-time awareness of events triggered within the Beam ecosystem. Currently, Beam Webhooks notify for:

* Door Open/Close Events

To implement webhooks, you need to supply Beam with a secure endpoint to which Beam can send an HTTP `POST` request. For example, if you have a service available at the address **api.example.com**, you could create a `POST` endpoint, accessible at <https://api.example.com/webhooks> or something similar.

{% hint style="warning" %}
**Your endpoint must be accessible over HTTPS.** This is because your API key is transmitted in the HTTP headers and needs to be encrypted. You cannot register a non-SSL URL for use with webhooks.
{% endhint %}

If, for example, an *example.com* user's garage door (who has authorized your app access to their Garageio account) opens, Beam would `POST` to your endpoint the following JSON body:

```javascript
{
   "id":"FE09DCDD7E75BD5202B662446690F40F",
   "eventType":"door_state_change",
   "toggleID":"B69048DB753BA907005E9B40DC5D7E36",
   "doorID":"8c76e7bb1250f55bebcc9928b04d1a60",
   "doorState":"OPEN",
   "channel":"Garageio Web",
   "deviceID":"d8cf720bb6c5cbc126b249a09ca086b9",
   "eventOccurred":1480651271,
   "eventOccurredUTC":"2016-12-02T04:01:11Z",
   "doorOwnerUserID":"01ba9fbf306adfe565ffc816f135a79d",
   "userThatToggled":{
      "firstName":"Garageio",
      "lastName":"Test",
      "emailAddress":"test@garageio.com"
   }
}
```

This request represents a single event for a single authenticated user. This means that your endpoint will be contacted (in real-time) each time a user's account experience an event. The following is an explanation of the fields:

| Attribute Name     | Data Type | Description                                                                                      |
| ------------------ | --------- | ------------------------------------------------------------------------------------------------ |
| `id`               | UUID      | A unique record ID for the webhook event.                                                        |
| `eventType`        | Enum      | Descriptor for the type of event. Valid values include "door\_state\_change", etc.               |
| `doorId`           | UUID      | The unique ID of the user's `Door` in which the event occurred.                                  |
| `doorState`        | Enum      | "OPEN" if the door is open and "CLOSED" if the door is closed.                                   |
| `channel`          | String    | Label of what service/controls triggered the event.                                              |
| `deviceId`         | UUID      | The unique ID of the user's `Device` in which the event originated.                              |
| `eventOccurred`    | Timestamp | In seconds. The exact (UNIX) time of the event (number of seconds since the epoch UTC).          |
| `eventOccurredUTC` | Timestamp | The exact time of the event in UTC.                                                              |
| `doorOwnerUserID`  | UUID      | The unique ID of the user who owns the `Device`.                                                 |
| `userThatToggled`  | Object    | The user who triggered the event. Contains only the first name, last name and email of the user. |

### Authenticating Requests

When Beam configures your app for webhook access, an API key is generated. This is a 96-character hexadecimal string which is unique to your app. **Treat this API key like a password.** To authenticate a received request on your webhook endpoint, Beam passes the API key through the HTTP header **X-Garageio-API-Key**. To verify a request:

1. Parse the HTTP headers, extracting the header named `X-Garageio-API-Key`.
2. Verify that it matches the key you were assigned by Garageio initially, returning an error (i.e. 401 or 403) if they are different.

### Responding to a Webhook Event Message

To acknowledge successful receipt, your webhook endpoint must return HTTP 200. To prevent timeout errors on complex processing/logic, your endpoint should return an HTTP 200 before continuing to process the event message.

{% hint style="warning" %}
Data you return in the response headers or response body will be logged and ignored.
{% endhint %}

An HTTP response code other than 200, will tell Garageio that you did not receive/refused the event message.

Information you return in the response body will be logged. Your webhook endpoint should return a JSON object indicating the reason for the failure. We suggest the following format:

```javascript
{
  "message":"Invalid API Key."
}
```

When an event message is not successfully accepted for any reason, Beam will delete the event message. **It will not retry the send.**
