# Webhooks

Fivexer delivers events to your HTTPS endpoint as signed `POST` requests. The signature lets you verify the event came from Fivexer and protects against replay attacks.

## Event types

- `task.matched` — a task has been tentatively matched to a worker.
- `task.accepted` — a worker accepted a task.
- `task.rejected` — a worker rejected a task.
- `task.completed` — a task was completed.
- `task.comment.created` — a comment was added to a task.

## Signature format

The `x-fivexer-signature` header looks like:

```
t=<unix-ms>,v1=<hex-hmac>
```

The HMAC is `HMAC-SHA256(secret, "<t>.<raw-body>")`. Always verify using the **raw request body**, before any JSON parsing.

## Verification examples

```
pythonfrom fivexer import Webhook

event = Webhook.construct_event(
    payload=raw_body_bytes,
    header=request.headers["x-fivexer-signature"],
    secret="whsec_...",
)
print(event.event, event.data)
```

```
javaWebhookEvent event = Webhook.constructEvent(rawBodyBytes, signatureHeader, "whsec_...");
```

```
typescriptimport { verifyWebhookSignature, SIGNATURE_HEADER } from '@fivexer/sdk/webhook';

const ok = verifyWebhookSignature(secret, header, await request.text());
```

```
php$event = Webhook::constructEvent($rawBody, $header, 'whsec_...');
```

By default signatures older than 5 minutes are rejected.

## Endpoint requirements

- Must return `200 OK` promptly. Timeouts are treated as failures.
- Must be idempotent: the same event may be delivered more than once.
- Use HTTPS in production.
