# Verify Signatures

Each webhook request is signed with the signing secret of its endpoint, in the Standard Webhooks format. Check the signature before you trust the body.

## Headers

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `webhook-id` | string | No | The event id. Use it to ignore a delivery you already handled. |
| `webhook-timestamp` | integer | No | Unix time in seconds when Inboxjot signed the request. |
| `webhook-signature` | string | No | One or more signatures as `v1,<base64>`, separated by spaces. |

## How to Verify

Remove the `whsec_` prefix from the secret and decode the rest from base64. Sign `{webhook-id}.{webhook-timestamp}.{body}` with HMAC-SHA256 and that key, then encode the result in base64.

The request is valid when one signature in the header matches. Use the raw body as you received it, and refuse a timestamp that is more than 5 minutes old.

## Request

Node.js:

```javascript
import { verifyWebhook } from 'inboxjot';

export async function POST(request) {
  const event = await verifyWebhook({
    payload: await request.text(),
    headers: request.headers,
    secret: process.env.INBOXJOT_WEBHOOK_SECRET,
  });

  if (event.type === 'email.bounced') {
    console.log(event.data.email_id, event.data.bounce.type);
  }

  return new Response(null, { status: 204 });
}
```

Rust:

```rust
use inboxjot::webhooks::{self, WebhookEventData};

let event = webhooks::verify(&secret, &headers, &body)?;

if let WebhookEventData::EmailBounced(data) = event.data {
    println!("bounced {}: {:?}", data.email.email_id, data.bounce.kind);
}
```

Go:

```go
func handle(w http.ResponseWriter, r *http.Request) {
	payload, _ := io.ReadAll(r.Body)
	event, err := webhook.Verify(payload, r.Header, os.Getenv("INBOXJOT_WEBHOOK_SECRET"))
	if err != nil {
		http.Error(w, "invalid signature", http.StatusBadRequest)
		return
	}

	if event.Type == webhook.EmailBounced {
		log.Println(event.Email.EmailID, event.Email.Bounce.Type)
	}
	w.WriteHeader(http.StatusNoContent)
}
```

Python:

```python
import os

from inboxjot import verify_webhook

event = verify_webhook(
    payload=body,
    headers=headers,
    secret=os.environ["INBOXJOT_WEBHOOK_SECRET"],
)

if event["type"] == "email.bounced":
    print(event["data"]["email_id"], event["data"]["bounce"]["type"])
```
