Outbound webhooks
Sloggr signed webhook events — catalog, payloads, HMAC verification, subscription API, and delivery logs for n8n, Zapier, and custom backends.
Sloggr can push signed JSON to your HTTPS endpoints when sales and support events happen. Use this with n8n, Zapier, Make, Slack bots, or your own backend.
- REST API (pull): API reference
- OpenAPI: api-v1.yaml
- Manage in app: Settings → Outbound Webhooks, or via API below
This page documents subscription webhooks (integrator-managed URLs). Visual Automations → Send webhook uses the same signing style but is configured inside the automation canvas.
How delivery works
- You register an endpoint with one or more event types.
- When a matching event occurs, Sloggr POSTs JSON to your URL.
- The body is signed with the endpoint secret.
- Deliveries are logged; failed attempts can be inspected via the API/UI.
POST https://your-server.example/hooks/sloggr
Content-Type: application/json
User-Agent: sloggr/1.0
X-Sloggr-Signature: <hex hmac-sha256 of raw body>
X-Sloggr-Event: deal.won
Respond with 2xx quickly. Non-2xx responses are marked failed and retried later.
Verifying signatures
- Read the raw request body bytes (do not re-serialize JSON first).
- Compute
HMAC-SHA256(secret, body)as lowercase hex. - Compare to
X-Sloggr-Signatureusing a constant-time compare.
Python sketch:
import hashlib
import hmac
def verify(body: bytes, secret: str, header: str) -> bool:
expected = hmac.new(secret.encode("utf-8"), body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, header or "")
Node sketch:
const crypto = require("crypto");
function verify(bodyBuffer, secret, header) {
const expected = crypto.createHmac("sha256", secret).update(bodyBuffer).digest("hex");
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(header || ""));
}
The signature secret is shown once when the endpoint is created (or rotated). Store it like an API key.
Event catalog
Only events that correspond to real Sloggr entities are emitted.
| Event type | When it fires |
|---|---|
deal.created | Sales deal created |
deal.won | Deal marked won |
deal.lost | Deal marked lost (may include lost_reason) |
deal.activity.created | Timeline activity logged on a deal (UI, automation, or API) |
support.ticket.opened | Support ticket opened |
support.ticket.closed | Support ticket closed |
support.log.created | Support log / update created |
There are no separate invent customer.* / task.* webhook types today. Customer changes are reflected through orgs/deals/tickets; follow-ups live on deal timeline metadata and are queryable via the API.
Payload shape
Payloads are JSON objects. Common fields:
| Field | Description |
|---|---|
event_type | Same as X-Sloggr-Event |
org_id | Customer (target) org id related to the entity |
timestamp | ISO-8601 UTC time of emission |
| Entity fields | e.g. deal_id + deal, slog_id + slog, activity, support_log_id + support_log |
Account isolation: only endpoints registered on the account org receive events for that account’s customers.
Examples
deal.won
{
"event_type": "deal.won",
"org_id": 14673,
"deal_id": 42,
"deal": {
"id": 42,
"title": "Acme annual plan",
"status": "won"
},
"timestamp": "2026-08-11T10:15:30.123456+00:00"
}
deal.lost (optional lost reason)
{
"event_type": "deal.lost",
"org_id": 14673,
"deal_id": 43,
"deal": { "id": 43, "title": "Pilot", "status": "lost" },
"lost_reason": { "code": "price", "label": "Price" },
"timestamp": "2026-08-11T11:00:00+00:00"
}
deal.activity.created
{
"event_type": "deal.activity.created",
"org_id": 14673,
"deal_id": 42,
"entity_type": "deal_activity",
"entity_id": 991,
"activity": {
"id": 991,
"event_type": "note",
"message": "Welcome email sent"
},
"timestamp": "2026-08-11T12:00:00+00:00"
}
support.ticket.opened / closed
{
"event_type": "support.ticket.opened",
"org_id": 14673,
"slog_id": 71743,
"slog": {
"id": 71743,
"title": "Cannot export diary entries",
"status": "open"
},
"timestamp": "2026-08-11T09:00:00+00:00"
}
support.log.created
{
"event_type": "support.log.created",
"org_id": 14673,
"support_log_id": 128901,
"support_log": {
"id": 128901,
"note": "Asked for screenshots",
"channel": "email"
},
"timestamp": "2026-08-11T09:05:00+00:00"
}
Exact nested object fields may grow over time; treat unknown keys as forward-compatible. Use the REST API to fetch full current state when needed.
Subscription API
Requires a Bearer API key with webhooks:write (create) or webhooks:read (list/log). See API scopes.
Create endpoint
POST /api/v1/webhooks/endpoints
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{
"name": "n8n deal won",
"url": "https://automata.example.com/webhook/abc",
"event_types": ["deal.won", "deal.lost"],
"enabled": true
}
201 returns endpoint including secret (shown once).
Allowed event_types are exactly the catalog above (including deal.activity.created).
List endpoints
GET /api/v1/webhooks/endpoints
Authorization: Bearer YOUR_API_KEY
Secrets are omitted from list responses.
Delivery log
GET /api/v1/webhooks/deliveries?event_type=deal.won&status=failed&limit=50
Authorization: Bearer YOUR_API_KEY
Useful filters: event_type, status (e.g. sent, failed, pending), limit.
n8n / Zapier tips
- Create a Catch Hook / Webhook trigger URL.
- Register that URL via the API or Settings → Outbound Webhooks.
- Store the endpoint secret in credentials.
- Verify
X-Sloggr-Signaturebefore acting on the payload. - Branch on
X-Sloggr-Eventorevent_type.
For pull-based workflows (analytics, overdue follow-ups), use a read-only API key on a schedule instead of (or in addition to) webhooks.
Security checklist
- Use HTTPS endpoints only.
- Verify HMAC signatures on every request.
- Treat endpoint secrets like passwords; rotate if leaked.
- Remember payloads may contain customer names, emails, and ticket/deal content — restrict who can receive them.
- API keys and webhook endpoints are account-scoped; never share keys across unrelated businesses.