Tenant API & Webhooks — Developer Guide
Platform (non-Marketplace) integration surface for operators replacing other tools: integration API tokens and outbound event webhooks.
UI: Settings → Developers (settings.manage_developers).
API tokens
- Sanctum personal access tokens with
token_type=integrationand name prefixintegration:. - Plaintext bearer secret uses prefix
es_and is returned once on create/rotate. - Authz is unchanged Spatie permissions on the creating user (abilities remain
['*']). - Call existing
/api/tenant/v1/*withAuthorization: Bearer es_…plus tenant headers (X-Tenant-Domain). - Do not put SPA/marketing origins in
sanctum.stateful— Bearer-only SPA auth remains.
Management routes (authenticated SPA user with settings.manage_developers):
| Method | Path |
|---|---|
| GET | /api/tenant/v1/developers/api-tokens |
| POST | /api/tenant/v1/developers/api-tokens |
| POST | /api/tenant/v1/developers/api-tokens/{id}/rotate |
| DELETE | /api/tenant/v1/developers/api-tokens/{id} |
Outbound webhooks
Independent of module:automation. Domain events fan out through IntegrationEventDispatcher:
- Active
tenant_webhook_endpointsthat subscribe to the event - Automation engine when Automation is entitled (unchanged)
Event catalog (v1)
lead.created/lead.updated/lead.assignedtask.created/task.completed/task.assignedopportunity.created/opportunity.stage_changed/opportunity.assignedmeeting.created/meeting.completedcustomer_invoice.createdcustomer_payment.posted(when payment status becomesposted)customer_credit_note.appliedhelp_desk.ticket_created/help_desk.ticket_status_changed/help_desk.sla_breachedwhatsapp.message_received
Envelope
json
{
"id": "evt_…",
"type": "lead.created",
"created_at": "2026-08-21T00:00:00+00:00",
"tenant_id": "…",
"data": { }
}Headers & signature
| Header | Value |
|---|---|
X-EloSync-Event | Event type |
X-EloSync-Delivery | Delivery UUID |
X-EloSync-Timestamp | Unix timestamp string |
X-EloSync-Signature | hmac_sha256("{timestamp}.{body}", signing_secret) |
Automation outbound webhooks keep body-only HMAC for backward compatibility.
Delivery
- Queue:
webhooks(DeliverTenantWebhookJob) - Up to 5 attempts with backoff
[30, 60, 120, 300];next_retry_atis set on retryable HTTP failures - After 10 consecutive permanent event failures, endpoint is deactivated (UI Enable restores)
- Manual Send test (
webhook.test) does not increment the failure budget - SSRF:
SignedOutboundHttpClientblocks loopback / private hosts and does not follow redirects - Retention:
webhooks:prune-deliveries --days=90(scheduled weekly)
Verify signature (PHP)
php
$timestamp = $request->header('X-EloSync-Timestamp');
$signature = $request->header('X-EloSync-Signature');
$body = $request->getContent();
$expected = hash_hmac('sha256', $timestamp.'.'.$body, $signingSecret);
if (! hash_equals($expected, (string) $signature)) {
abort(401);
}Related
- Tenant Developers API
- Tenant Settings user guide
- Custom Lead Webhook (inbound — separate)
- Automation (workflow webhook action)
- Production readiness