# Test Webhook

## Test Webhook Endpoint

The Test Webhook endpoint allows customers to send a sample test payload to a given URL to verify its connectivity and signature validation logic before creating a webhook configuration. This helps ensure your webhook handler is working correctly.

### Authentication

Include the following headers in your requests:

```
Access-Token: <your-access-token>
```

### Permissions

Ensure your API user has a role with `admin` or `test-alert-webhook-endpoint` permission.

### Endpoint

* **URL**: `https://api.genlogs.io/alerts/webhook/test`
* **Method**: `POST`

### Request Body

| Field         | Type   | Required | Description                                           |
| ------------- | ------ | -------- | ----------------------------------------------------- |
| `webhook_url` | string | Yes      | The HTTPS URL to send the test payload to             |
| `secret`      | string | Yes      | The secret that will be used to sign the test payload |

### Request example

```
curl --location 'https://api.genlogs.io/alerts/webhook/test' \
--header 'access-token: <access-token>' \
--header 'x-api-key: <x-api-key>' \
--header 'Content-Type: application/json' \
--data '{
    "webhook_url": "https://example-host.com/webhooks/genlogs-alerts",
    "secret": {your-webhook-secret}
}'
```

#### Field Requirements

* **webhook\_url**: Must be a valid HTTPS URL that can receive POST requests
* **secret**: Must be at least 16 characters long (same as used for webhook creation)

### Response Codes

| Code                        | Description                                                                       |
| --------------------------- | --------------------------------------------------------------------------------- |
| `200 OK`                    | The test was sent successfully and your endpoint responded with a 2xx status code |
| `400 Bad Request`           | The provided URL or secret is invalid                                             |
| `401 Unauthorized`          | Authentication credentials missing or incorrect                                   |
| `403 Forbidden`             | User lacks permission to test webhooks                                            |
| `500 Internal Server Error` | The test failed (timeout, non-2xx response, connection error, etc.)               |

### Response Body

#### Success Response

| Field     | Type    | Description                                          |
| --------- | ------- | ---------------------------------------------------- |
| `success` | boolean | `true` if the test was successful                    |
| `status`  | integer | HTTP status code (always `200` for successful tests) |
| `message` | string  | Success confirmation message                         |

#### Error Response

| Field     | Type    | Description                                         |
| --------- | ------- | --------------------------------------------------- |
| `success` | boolean | `false` when the test failed                        |
| `status`  | integer | HTTP status code (typically `500` for failed tests) |
| `message` | string  | Error description explaining why the test failed    |

### Test Payload Structure

The test endpoint sends a sample payload with the following structure to verify your webhook handler:

```json
{
  "event": "alert.test",
  "webhook_id": "test-webhook-id",
  "customer_id": 123,
  "alert_details": [{
    "alert_name": "Test Alert",
    "email": "test@example.com",
    "description": "This is a test alert"
  }],
  "matches": [{
    "result_url": "https://app.genlogs.com/search/result/test",
    "front_view_url": "https://example.com/image1.jpg",
    "side_view_url": "https://example.com/image2.jpg",
    "rear_view_url": "https://example.com/image3.jpg",
    "time": "2024-01-01T12:00:00Z",
    "city": "Test City",
    "state": "TS",
    "road": "Test Road",
    "lat_long": "40.7128, -74.0060",
    "license_plate": "TEST123",
    "vin": "1HGBH41JXMN109186",
    "usdot": "123456",
    "mc": "MC-123456",
    "cab_number": "CAB123",
    "trailer_logo": "Test Logo",
    "trailer_number": "TRL123",
    "deep_search": "Test Match"
  }],
  "total_matches": 1,
  "timestamp": "2024-01-01T12:01:00.123456+00:00"
}
```

### Request Examples

## Validate Webhook Endpoint

> Test a webhook endpoint with a sample alert payload

```json
{"openapi":"3.1.0","info":{"title":"Alert API","version":"0.0.1"},"security":[{"APIKeyHeader":[]}],"components":{"securitySchemes":{"APIKeyHeader":{"type":"apiKey","description":"JWT Access Token required for authentication","in":"header","name":"Access-Token"}},"schemas":{"WebhookTestSchema":{"properties":{"webhook_url":{"type":"string","maxLength":2083,"minLength":1,"format":"uri","title":"Webhook Url"},"secret":{"type":"string","title":"Secret"}},"additionalProperties":false,"type":"object","required":["webhook_url","secret"],"title":"WebhookTestSchema","description":"Schema for testing webhook endpoints"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/alerts/webhook/test":{"post":{"tags":["Webhook Alerts"],"summary":"Validate Webhook Endpoint","description":"Test a webhook endpoint with a sample alert payload","operationId":"validate_webhook_endpoint_alerts_webhook_test_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookTestSchema"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

### Response Examples

#### Success Response (200 OK)

```json
{
  "success": true,
  "status": 200,
  "message": "Webhook test successful"
}
```

#### Error Response (500 Internal Server Error)

```json
{
  "success": false,
  "status": 500,
  "message": "Webhook test failed: Connection timeout"
}
```

### Signature Validation Example

```python
import hmac
import hashlib

def verify_signature(payload_body: bytes, signature_header: str, secret: str) -> bool:
    """Verifies the HMAC-SHA512 signature of a webhook payload."""
    if not signature_header:
        return False
    
    hash_object = hmac.new(
        secret.encode('utf-8'),
        msg=payload_body,
        digestmod=hashlib.sha512
    )
    expected_signature = "sha512=" + hash_object.hexdigest()
    
    return hmac.compare_digest(expected_signature, signature_header)

# Usage in your webhook handler
signature = request.headers.get('X-GenLogs-Signature')
payload_body = request.get_data()  # Raw bytes
webhook_secret = "your-super-secret-key-at-least-16-chars"

if verify_signature(payload_body, signature, webhook_secret):
    # Signature is valid, process the webhook
    payload = request.get_json()
    return {"status": "success"}, 200
else:
    # Invalid signature
    return {"error": "Invalid signature"}, 401
```

### What to Verify in Your Webhook Handler

When you receive the test payload, verify:

1. **Signature Verification**: Ensure you can properly verify the HMAC-SHA512 signature in the `X-GenLogs-Signature` header
2. **JSON Parsing**: Confirm you can parse the JSON payload correctly
3. **Response Time**: Respond within 5 seconds (the webhook timeout)
4. **HTTP Status**: Return a 2xx status code to indicate success
5. **Headers**: Check that you receive all expected headers:
   * `Content-Type: application/json`
   * `User-Agent: GenLogs-Webhook/1.0`
   * `X-GenLogs-Signature: sha512=...`
   * `X-GenLogs-Event: alert.test`
   * `X-GenLogs-Timestamp: ...`

### Common Test Failure Reasons

* **Connection timeout** (webhook endpoint not responding within 5 seconds)
* **Invalid SSL certificate** on the webhook URL
* **Non-2xx HTTP response** from your endpoint
* **Connection refused** (endpoint not accessible)
* **DNS resolution failure** for the webhook URL
* **Invalid URL format** or non-HTTPS URL
