Admin API
This endpoint requires admin-level roles (platform_admin, tenant_admin, or system_admin). Accessible via the API gateway at /v1/platform/*.
Webhooks API
Configure webhooks, manage event subscriptions, and monitor delivery status.
Overview
| Attribute | Value |
|---|---|
| Base Path | /api/v1/webhooks |
| Authentication | Bearer Token |
| Required Roles | platform_admin, system_admin, super_admin |
Webhook Endpoints
List Webhooks
GET /api/v1/webhooks
Response
{
"webhooks": [
{
"id": "wh_001",
"url": "https://api.example.com/webhooks/olympus",
"description": "Main integration endpoint",
"status": "active",
"events": ["order.created", "order.completed", "payment.received"],
"created_at": "2025-06-01T00:00:00Z",
"stats": {
"deliveries_24h": 1250,
"success_rate": 0.998,
"avg_latency_ms": 245
}
},
{
"id": "wh_002",
"url": "https://accounting.example.com/hooks",
"description": "Accounting system sync",
"status": "active",
"events": ["payment.*", "refund.*"],
"created_at": "2025-08-15T00:00:00Z",
"stats": {
"deliveries_24h": 85,
"success_rate": 1.0,
"avg_latency_ms": 180
}
}
],
"total": 5
}
Create Webhook
POST /api/v1/webhooks
Request Body
{
"url": "https://api.example.com/webhooks/olympus",
"description": "Main integration endpoint",
"events": [
"order.created",
"order.updated",
"order.completed",
"payment.received",
"payment.refunded"
],
"secret": "whsec_your_secret_key",
"metadata": {
"integration": "custom_pos",
"version": "2.0"
}
}
Response
{
"id": "wh_003",
"url": "https://api.example.com/webhooks/olympus",
"status": "active",
"events": [
"order.created",
"order.updated",
"order.completed",
"payment.received",
"payment.refunded"
],
"secret": "whsec_abc123...",
"signing_key": "sk_webhook_xyz789",
"created_at": "2026-01-24T19:30:00Z"
}
Get Webhook
GET /api/v1/webhooks/{webhook_id}
Response
{
"id": "wh_001",
"url": "https://api.example.com/webhooks/olympus",
"description": "Main integration endpoint",
"status": "active",
"events": [
"order.created",
"order.updated",
"order.completed",
"payment.received",
"payment.refunded"
],
"secret_last4": "...3abc",
"headers": {
"X-Custom-Header": "value"
},
"metadata": {
"integration": "custom_pos"
},
"settings": {
"timeout_seconds": 30,
"retry_policy": {
"max_attempts": 5,
"backoff": "exponential"
},
"batch_events": false
},
"stats": {
"total_deliveries": 125000,
"successful_deliveries": 124750,
"failed_deliveries": 250,
"success_rate": 0.998,
"avg_latency_ms": 245,
"last_delivery": "2026-01-24T19:29:55Z",
"last_success": "2026-01-24T19:29:55Z",
"last_failure": "2026-01-23T08:15:00Z"
},
"created_at": "2025-06-01T00:00:00Z",
"updated_at": "2026-01-20T00:00:00Z"
}
Update Webhook
PUT /api/v1/webhooks/{webhook_id}
Request Body
{
"url": "https://api.example.com/webhooks/v2/olympus",
"events": [
"order.*",
"payment.*",
"inventory.low_stock"
],
"settings": {
"timeout_seconds": 60
}
}
Delete Webhook
DELETE /api/v1/webhooks/{webhook_id}
Rotate Webhook Secret
POST /api/v1/webhooks/{webhook_id}/rotate-secret
Response
{
"id": "wh_001",
"new_secret": "whsec_new_secret_xyz",
"old_secret_valid_until": "2026-01-25T19:30:00Z",
"rotated_at": "2026-01-24T19:30:00Z"
}
Event Types
List Available Events
GET /api/v1/webhooks/events
Response
{
"events": [
{
"category": "order",
"events": [
{
"name": "order.created",
"description": "Fired when a new order is created",
"payload_example": {
"event": "order.created",
"data": {"order_id": "ord_xxx", "...": "..."}
}
},
{
"name": "order.updated",
"description": "Fired when an order is modified"
},
{
"name": "order.completed",
"description": "Fired when an order is marked complete"
},
{
"name": "order.cancelled",
"description": "Fired when an order is cancelled"
}
]
},
{
"category": "payment",
"events": [
{
"name": "payment.received",
"description": "Fired when payment is successfully processed"
},
{
"name": "payment.failed",
"description": "Fired when payment processing fails"
},
{
"name": "payment.refunded",
"description": "Fired when a refund is processed"
}
]
},
{
"category": "inventory",
"events": [
{
"name": "inventory.low_stock",
"description": "Fired when item falls below threshold"
},
{
"name": "inventory.out_of_stock",
"description": "Fired when item becomes unavailable"
},
{
"name": "inventory.restocked",
"description": "Fired when item is restocked"
}
]
},
{
"category": "customer",
"events": [
{
"name": "customer.created",
"description": "Fired when new customer is created"
},
{
"name": "customer.updated",
"description": "Fired when customer info is updated"
}
]
},
{
"category": "reservation",
"events": [
{
"name": "reservation.created",
"description": "Fired when reservation is made"
},
{
"name": "reservation.confirmed",
"description": "Fired when reservation is confirmed"
},
{
"name": "reservation.cancelled",
"description": "Fired when reservation is cancelled"
},
{
"name": "reservation.no_show",
"description": "Fired when customer doesn't arrive"
}
]
},
{
"category": "employee",
"events": [
{
"name": "employee.clocked_in",
"description": "Fired when employee clocks in"
},
{
"name": "employee.clocked_out",
"description": "Fired when employee clocks out"
}
]
},
{
"category": "loyalty",
"events": [
{
"name": "loyalty.points_earned",
"description": "Fired when points are awarded"
},
{
"name": "loyalty.points_redeemed",
"description": "Fired when points are redeemed"
},
{
"name": "loyalty.tier_changed",
"description": "Fired when member tier changes"
}
]
}
]
}
Deliveries
List Deliveries
GET /api/v1/webhooks/{webhook_id}/deliveries
Query Parameters
| Parameter | Type | Description |
|---|---|---|
status | string | success, failed, pending |
event | string | Filter by event type |
start_date | datetime | Period start |
end_date | datetime | Period end |
Response
{
"deliveries": [
{
"id": "del_001",
"webhook_id": "wh_001",
"event": "order.created",
"status": "success",
"response_code": 200,
"latency_ms": 185,
"attempt": 1,
"payload_size_bytes": 1250,
"delivered_at": "2026-01-24T19:30:00Z"
},
{
"id": "del_002",
"webhook_id": "wh_001",
"event": "payment.received",
"status": "failed",
"response_code": 500,
"error": "Internal Server Error",
"latency_ms": 30045,
"attempt": 3,
"next_retry": "2026-01-24T19:45:00Z",
"delivered_at": "2026-01-24T19:28:00Z"
}
],
"pagination": {
"total": 1250,
"page": 1,
"limit": 50
}
}
Get Delivery Details
GET /api/v1/webhooks/deliveries/{delivery_id}
Response
{
"id": "del_001",
"webhook_id": "wh_001",
"event": "order.created",
"status": "success",
"request": {
"url": "https://api.example.com/webhooks/olympus",
"method": "POST",
"headers": {
"Content-Type": "application/json",
"X-Olympus-Signature": "sha256=...",
"X-Olympus-Event": "order.created",
"X-Olympus-Delivery": "del_001",
"X-Olympus-Timestamp": "1706124600"
},
"body": {
"id": "evt_001",
"event": "order.created",
"created_at": "2026-01-24T19:30:00Z",
"data": {
"order_id": "ord_12345",
"order_number": "42",
"location_id": "loc_123",
"total": 85.50,
"items": ["..."]
}
}
},
"response": {
"status_code": 200,
"headers": {
"Content-Type": "application/json"
},
"body": "{\"received\": true}"
},
"timing": {
"sent_at": "2026-01-24T19:30:00.000Z",
"response_at": "2026-01-24T19:30:00.185Z",
"latency_ms": 185
},
"attempt": 1,
"max_attempts": 5
}
Retry Delivery
POST /api/v1/webhooks/deliveries/{delivery_id}/retry
Response
{
"delivery_id": "del_003",
"original_delivery_id": "del_002",
"status": "pending",
"scheduled_at": "2026-01-24T19:31:00Z"
}
Testing
Send Test Event
POST /api/v1/webhooks/{webhook_id}/test
Request Body
{
"event": "order.created",
"data": {
"order_id": "test_ord_001",
"order_number": "TEST-42",
"total": 100.00
}
}
Response
{
"delivery_id": "del_test_001",
"status": "success",
"response_code": 200,
"response_body": "{\"received\": true}",
"latency_ms": 195
}
Verify Webhook Signature
POST /api/v1/webhooks/verify-signature
Request Body
{
"payload": "{\"event\":\"order.created\",...}",
"signature": "sha256=abc123...",
"timestamp": "1706124600",
"secret": "whsec_your_secret"
}
Response
{
"valid": true,
"timestamp_valid": true,
"signature_match": true
}
Webhook Logs
Get Webhook Logs
GET /api/v1/webhooks/{webhook_id}/logs
Query Parameters
| Parameter | Type | Description |
|---|---|---|
level | string | info, warning, error |
start_date | datetime | Period start |
Response
{
"logs": [
{
"timestamp": "2026-01-24T19:30:00Z",
"level": "info",
"message": "Webhook delivered successfully",
"delivery_id": "del_001",
"event": "order.created"
},
{
"timestamp": "2026-01-24T19:28:00Z",
"level": "error",
"message": "Delivery failed: timeout after 30s",
"delivery_id": "del_002",
"event": "payment.received",
"details": {
"attempt": 3,
"will_retry": true
}
},
{
"timestamp": "2026-01-24T08:15:00Z",
"level": "warning",
"message": "Endpoint returned 429 Too Many Requests",
"delivery_id": "del_xxx",
"details": {
"retry_after": 60
}
}
]
}
Statistics
Get Webhook Statistics
GET /api/v1/webhooks/{webhook_id}/stats
Query Parameters
| Parameter | Type | Description |
|---|---|---|
period | string | hour, day, week, month |
Response
{
"webhook_id": "wh_001",
"period": "day",
"summary": {
"total_deliveries": 1250,
"successful": 1247,
"failed": 3,
"success_rate": 0.9976,
"avg_latency_ms": 245,
"p95_latency_ms": 450,
"p99_latency_ms": 850
},
"by_event": [
{
"event": "order.created",
"count": 450,
"success_rate": 1.0
},
{
"event": "order.completed",
"count": 420,
"success_rate": 0.998
},
{
"event": "payment.received",
"count": 380,
"success_rate": 0.992
}
],
"by_hour": [
{"hour": "00:00", "deliveries": 25, "success_rate": 1.0},
{"hour": "01:00", "deliveries": 15, "success_rate": 1.0}
],
"errors": {
"timeout": 2,
"connection_refused": 1,
"5xx": 0
}
}
Webhook Payload Format
All webhook payloads follow this structure:
{
"id": "evt_unique_id",
"event": "event.type",
"created_at": "2026-01-24T19:30:00Z",
"api_version": "2026-01-01",
"data": {
"object": "...",
"...": "..."
},
"metadata": {
"tenant_id": "tenant_abc",
"location_id": "loc_123"
}
}
Signature Verification
Verify webhook authenticity using HMAC-SHA256:
import hmac
import hashlib
def verify_signature(payload, signature, secret, timestamp):
signed_payload = f"{timestamp}.{payload}"
expected = hmac.new(
secret.encode(),
signed_payload.encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(f"sha256={expected}", signature)
Error Responses
| Status | Code | Description |
|---|---|---|
| 400 | invalid_url | Webhook URL is invalid |
| 400 | invalid_events | One or more events are invalid |
| 404 | webhook_not_found | Webhook ID not found |
| 409 | url_already_exists | URL already registered |
| 429 | rate_limited | Too many webhook operations |
Related Documentation
- Pub/Sub Events - Internal event system
- WebSocket Events - Real-time events
- API Gateway - API infrastructure