# Events from CoderHelm's relay

Source: https://docs.coderhelm.com/api/reference/webhooks/receive-relayed-event

`POST /webhooks/relay`

On a hybrid self-hosted install, where CoderHelm's hosted relay forwards the events of CoderHelm's GitHub App (and Jira app) after checking the provider's own signature. Each request is signed with the install's relay key: `X-CoderHelm-Relay-Signature: t=<unix seconds>,d=<delivery id>,v1=<hex>`, the HMAC-SHA256 of `<t>.<d>.<raw body>`. Requests older than 5 minutes are refused, and so is a delivery id the install has already taken (`409`). `X-CoderHelm-Relay-Source` is `github` or `jira`; for GitHub, `X-CoderHelm-Relay-Event` is GitHub's event type and the body is GitHub's payload, unchanged.

## Authentication

Verified by the request itself (see the description above). See [Webhooks](https://docs.coderhelm.com/api/webhooks).

## Parameters

### Headers

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `X-CoderHelm-Relay-Signature` | string | yes | `t=<unix seconds>,d=<delivery id>,v1=<hex HMAC-SHA256>`. |
| `X-CoderHelm-Relay-Source` | string | yes | Where the event came from: `github` or `jira`. |
| `X-CoderHelm-Relay-Event` | string or null | no | The provider's event type. |

## Request body

`application/json`: The provider's payload, unchanged.

## Responses

### 200

Handled (or acknowledged and ignored).

### 401

The signature is missing, wrong, or more than 5 minutes old.

### 404

This install isn't registered for the relay.

### 409

This delivery id was already received; the copy was refused.

## Example request

cURL:

```bash
curl -X POST 'https://api.coderhelm.com/webhooks/relay' \
  -H 'X-CoderHelm-Relay-Signature: t=1761436800,d=72d3162e-cc78-11e3-81ab-4c9367dc0958,v1=5d1a…' \
  -H 'X-CoderHelm-Relay-Source: github' \
  -H 'Content-Type: application/json' \
  -d '{}'
```

TypeScript:

```ts
const res = await fetch("https://api.coderhelm.com/webhooks/relay", {
  method: 'POST',
  headers: {
    "X-CoderHelm-Relay-Signature": "t=1761436800,d=72d3162e-cc78-11e3-81ab-4c9367dc0958,v1=5d1a…",
    "X-CoderHelm-Relay-Source": "github",
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({}),
});
if (!res.ok) {
  const { error, code } = await res.json();
  throw new Error(`${res.status} ${code}: ${error}`);
}
const data = await res.json();
```

Python:

```python
import requests

headers = {
    "X-CoderHelm-Relay-Signature": "t=1761436800,d=72d3162e-cc78-11e3-81ab-4c9367dc0958,v1=5d1a…",
    "X-CoderHelm-Relay-Source": "github",
}
body = {}
res = requests.request("POST", "https://api.coderhelm.com/webhooks/relay", headers=headers, json=body)
if not res.ok:
    raise RuntimeError(f"{res.status_code}: {res.json().get('error')}")
data = res.json()
```
