Phase 15 — API & Integration Marketplace
A public REST API v1 with 16 endpoints, API key authentication, a webhook system with HMAC-SHA256 signing, and a tenant-facing settings UI for managing keys and webhook endpoints.
What It Does
Phase 15 opens KaiVox data to external systems. Developers can read and write appointments, customers, calls, staff, and services via REST API. Businesses can subscribe to webhook events so their own systems get notified in real time when appointments are booked, calls end, or leads are created.
Key Routes (Settings UI)
| URL | Description |
|---|---|
GET /settings/api | API & Integrations settings page — keys, webhooks, delivery log, inline docs |
POST /settings/api/keys | Generate a new named API key |
POST /settings/api/keys/{id}/revoke | Revoke (disable) an API key |
DELETE /settings/api/keys/{id} | Delete an API key permanently |
POST /settings/api/webhooks | Add a webhook endpoint URL + event subscriptions |
DELETE /settings/api/webhooks/{id} | Delete a webhook endpoint |
API Endpoints (16 total)
See the API Reference page for full documentation on all 16 endpoints. Summary:
| Resource | Endpoints | Base URL |
|---|---|---|
| Appointments | 6 (list, create, show, update status, cancel, slots) | /api/v1/appointments |
| Customers | 4 (list, create, show, update) | /api/v1/customers |
| Calls | 2 (list, show with transcript) | /api/v1/calls |
| Staff | 2 (list, show) | /api/v1/staff |
| Services | 2 (list, show) | /api/v1/services |
Key Files
| Type | Path |
|---|---|
| Middleware | app/Http/Middleware/ApiKeyAuthentication.php |
| Service | app/Services/WebhookService.php — signed delivery + retry |
| Controller | app/Http/Controllers/Api/V1/AppointmentsApiController.php |
| Controller | app/Http/Controllers/Api/V1/CustomersApiController.php |
| Controller | app/Http/Controllers/Api/V1/CallsApiController.php |
| Controller | app/Http/Controllers/Api/V1/StaffApiController.php |
| Controller | app/Http/Controllers/Api/V1/ServicesApiController.php |
| Model | app/Models/ApiKey.php |
| Model | app/Models/WebhookEndpoint.php |
| Model | app/Models/WebhookDelivery.php |
| Table | api_keys — tenant_id, name, key (hashed), is_active, last_used_at |
| Table | webhook_endpoints — tenant_id, url, events (JSON array), secret, is_active |
| Table | webhook_deliveries — endpoint_id, event, payload, http_status, response_body, attempt_count, delivered_at |
Authentication Middleware
ApiKeyAuthentication middleware is applied to all /api/v1/* routes. It accepts the key in three ways:
Authorization: Bearer kv1_xxx...headerX-API-Key: kv1_xxx...header?api_key=kv1_xxx...query parameter
The key is hashed for storage — the plaintext key is only shown once on generation. The middleware resolves the tenant from the key and scopes all subsequent queries.
Webhook System
Event Subscriptions
When adding a webhook endpoint, tenants select which events to subscribe to:
appointment.createdappointment.cancelledcall.endedcall.missed
Delivery and Signing
Event fires (e.g. appointment created in AppointmentsController)
↓
WebhookService::dispatch($tenant, 'appointment.created', $payload)
↓
Find all active webhook_endpoints subscribed to this event
↓
For each endpoint:
1. Sign payload: HMAC-SHA256(json_encode($payload), $endpoint->secret)
2. Add header: X-KaiVox-Signature: sha256={signature}
3. POST payload to endpoint URL (Guzzle, 10s timeout)
4. Log result in webhook_deliveries (HTTP status, response body)
5. If fail (non-2xx or timeout) → retry up to 3 times
Response Format
All API responses use a consistent JSON envelope:
{
"success": true,
"data": { ... }, // single object or array
"meta": { // present on paginated lists
"page": 1,
"per_page": 20,
"total": 142
}
}
What's Complete
- All 16 REST API v1 endpoints across 5 resources
- ApiKeyAuthentication middleware (Bearer / X-API-Key / query param)
- API key management UI (generate, revoke, delete, show once on creation)
- Webhook system with HMAC-SHA256 signing
- Webhook delivery log with retry (max 3 attempts)
- WebhookService wired into: appointment booked/cancelled (AppointmentsController), call ended/missed (VobizService)
- Settings → API & Integrations page with inline docs
- Standardised JSON response format
- CSRF exempt for all /api/v1/* routes
- Sidebar nav item "API & Integrations" added
What's Deferred
- Swagger/OpenAPI spec file (auto-generated)
- Zapier app (requires Zapier developer account + approval)
- POS integrations (Square, etc.)
- EMR integrations (Epic, etc.)
- CMS integrations (WordPress embed)
- Partner/developer ecosystem + API marketplace