# Events

Signed webhooks that wake an agent when mail arrives or is held.

Calls go to https://address.seleya.ai/api. Errors are `{"error": {"code", "message"}}` with the HTTP status: https://address.seleya.ai/docs/reference/errors.md

## Subscribe to events

`POST /v1/subscriptions`, called with a key or a person signed in

Subscribes a webhook to an address's events. Events carry ids only, signed with Standard Webhooks. The endpoint must echo a challenge before it is saved.

| Field | Type | | |
| --- | --- | --- | --- |
| `address` | string | required | The address whose events it receives. |
| `url` | string | required | An HTTPS endpoint that answers the challenge. |

```bash
curl -X POST https://address.seleya.ai/api/v1/subscriptions \
  -H "Authorization: Bearer $SELEYA_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "address": "desk@acme.seleya.email",
  "url": "https://agent.acme.com/hooks/mail"
}'
```

```python
import os, requests

r = requests.post(
    "https://address.seleya.ai/api/v1/subscriptions",
    headers={"Authorization": f"Bearer {os.environ['SELEYA_KEY']}"},
    json={
      "address": "desk@acme.seleya.email",
      "url": "https://agent.acme.com/hooks/mail"
    },
)
print(r.status_code, r.json())
```

```typescript
const r = await fetch("https://address.seleya.ai/api/v1/subscriptions", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.SELEYA_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "address": "desk@acme.seleya.email",
    "url": "https://agent.acme.com/hooks/mail"
  }),
});
console.log(r.status, await r.json());
```

Answers:

- 201: Made
- 401: No valid key, session or token
- 404: Not found, or not yours to see
- 422: A value is refused; the message says which

| Field (201) | Type | | |
| --- | --- | --- | --- |
| `id` | string | required |  |
| `address` | string | optional |  |
| `url` | string | required |  |
| `status` | string | required |  |
| `secret` | string | optional |  |

```json
{
  "address": "ct-a@beta.com",
  "id": "7f3c9a2e-0000-4000-8000-000000000026",
  "secret": "whsec_…",
  "status": "active",
  "url": "https://juiw7rjojt3cahaammkuzf3di40ycqbj.lambda-url.eu-central-1.on.aws/ok/contract"
}
```

## An address's subscriptions

`GET /v1/subscriptions`, called with a key or a person signed in

An address's webhook subscriptions.

| Parameter | Type | | |
| --- | --- | --- | --- |
| `address` | string, in query | optional | One address. |

```bash
curl https://address.seleya.ai/api/v1/subscriptions \
  -H "Authorization: Bearer $SELEYA_KEY"
```

```python
import os, requests

r = requests.get(
    "https://address.seleya.ai/api/v1/subscriptions",
    headers={"Authorization": f"Bearer {os.environ['SELEYA_KEY']}"},
)
print(r.status_code, r.json())
```

```typescript
const r = await fetch("https://address.seleya.ai/api/v1/subscriptions", {
  method: "GET",
  headers: { Authorization: `Bearer ${process.env.SELEYA_KEY}` },
});
console.log(r.status, await r.json());
```

Answers:

- 200: Done
- 401: No valid key, session or token
- 404: Not found, or not yours to see

| Field (200) | Type | | |
| --- | --- | --- | --- |
| `subscriptions` | array of objects | required |  |

```json
{
  "subscriptions": [
    {
      "address_id": "7f3c9a2e-0000-4000-8000-000000000014",
      "failures": 0,
      "id": "7f3c9a2e-0000-4000-8000-000000000026",
      "status": "active",
      "url": "https://juiw7rjojt3cahaammkuzf3di40ycqbj.lambda-url.eu-central-1.on.aws/ok/contract"
    },
    {
      "address_id": "7f3c9a2e-0000-4000-8000-000000000014",
      "failures": 0,
      "id": "7f3c9a2e-0000-4000-8000-000000000027",
      "status": "failed",
      "url": "https://example.com/no-echo"
    }
  ]
}
```

## Revoke a subscription

`DELETE /v1/subscriptions/{id}`, called with a key or a person signed in

Ends a subscription; no more events go to its URL.

| Parameter | Type | | |
| --- | --- | --- | --- |
| `id` | string, in path | required | Its id. |

```bash
curl -X DELETE https://address.seleya.ai/api/v1/subscriptions/ID \
  -H "Authorization: Bearer $SELEYA_KEY"
```

```python
import os, requests

r = requests.delete(
    "https://address.seleya.ai/api/v1/subscriptions/ID",
    headers={"Authorization": f"Bearer {os.environ['SELEYA_KEY']}"},
)
print(r.status_code, r.text)
```

```typescript
const r = await fetch("https://address.seleya.ai/api/v1/subscriptions/ID", {
  method: "DELETE",
  headers: { Authorization: `Bearer ${process.env.SELEYA_KEY}` },
});
console.log(r.status);
```

Answers:

- 204: Done, with no body
- 401: No valid key, session or token
- 404: Not found, or not yours to see

