Webhooks, Make, n8n, Zapier & REST

Two directions of integration. Outbound webhooks tell your systems the moment something happens in Silux Chat — a conversation starting or being handed to your team, a customer message, a ticket raised or updated, a customer verified, a comment added or an SMS delivery report settling. Lookup connectors let the bot read from a Make or n8n workflow, or from a JSON API of your own, with no Account Connect build.
12 min readhttps://www.siluxchat.comcurl · Python · PHP · Node.js

Overview

You want to…UseDirection
Be told when conversations, messages, tickets, verifications, comments or SMS reports happenOutbound webhooksSilux Chat → you
Let the bot look customers and orders up through a no-code workflowMake / n8n / Zapier webhook connectorBot → your workflow
Let the bot read from a simple JSON API you already haveYour own REST API connectorBot → your API
Full verified account access with one-time codes you sendAccount ConnectBot → your endpoints

Outbound webhooks

Instead of polling, register an HTTPS address and Silux Chat will POST each event to it as it happens. Every delivery is signed with a secret that only you and the platform know, retried if your endpoint is down, and recorded in a delivery log you can query.

  • Signed, always — X-Silux-Signature is an HMAC-SHA256 of the exact request body under your endpoint’s secret.
  • Never slows the chat — deliveries happen in the background; a slow or failing endpoint cannot delay a customer’s reply.
  • Retried, then paused — three attempts per event; an endpoint that fails 15 times in a row is deactivated with the reason recorded.
  • Logged — every attempt, with your response code, so “we never received it” can be settled in seconds.

Register an endpoint

POSThttps://www.siluxchat.com/api/sandbox/webhooksX-API-Key

Despite the path, this registers the endpoint on whichever account the key belongs to: your live API key (Dashboard → API Settings) registers it on your live account; a sbx_ sandbox key registers it on your sandbox.

FieldTypeNotes
urlstring, requiredWhere to POST events. Must start with https:// (http:// is accepted but not recommended). Max 512 characters.
eventsstring[], optionalEvents to receive. Omit to receive all of them. Unknown names are rejected with HTTP 400 listing the valid ones.
descriptionstring, optionalYour own label, up to 255 characters.
Register a webhook endpoint
curl -s -X POST "https://www.siluxchat.com/api/sandbox/webhooks" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://your-system.example.com/hooks/silux","events":["comment.created","sms.delivery_report"],"description":"CRM sync"}'
201 Created
{
  "success": true,
  "webhook": {
    "id": 12,
    "url": "https://your-system.example.com/hooks/silux",
    "events": ["comment.created", "sms.delivery_report"],
    "description": "CRM sync",
    "is_active": true,
    "consecutive_failures": 0,
    "last_error": null,
    "last_delivered_at": null,
    "created_at": "2026-09-26T10:00:00+00:00",
    "secret": "k3v…(43 characters)…"
  },
  "note": "Store the secret now — it is not shown again. Verify X-Silux-Signature = HMAC-SHA256(secret, raw_body)."
}

The secret is returned once

Store webhook.secret in your secrets manager straight away. It is not shown again; if it is lost, delete the endpoint and register it afresh.

Manage endpoints

MethodPathWhat it does
GET/api/sandbox/webhooksList your endpoints and every valid event name
POST/api/sandbox/webhooksRegister an endpoint (returns the secret once)
POST/api/sandbox/webhooks/{id}/testDeliver a real, signed test event now and report the result
GET/api/sandbox/webhooks/deliveries?limit=25Recent delivery attempts with status and your response code
DELETE/api/sandbox/webhooks/{id}Remove an endpoint
manage endpoints
KEY=YOUR_API_KEY
BASE=https://www.siluxchat.com/api/sandbox/webhooks

curl -s $BASE -H "X-API-Key: $KEY"                        # list endpoints + every valid event
curl -s -X POST $BASE/12/test -H "X-API-Key: $KEY"        # send a real signed test event now
curl -s "$BASE/deliveries?limit=25" -H "X-API-Key: $KEY"  # every attempt, with your response code
curl -s -X DELETE $BASE/12 -H "X-API-Key: $KEY"           # remove endpoint 12

A wrong or missing key returns HTTP 401 {"detail":"Invalid API key"}.

Events and payload

Every event below is sent. Events are raised when the change is saved, whichever way it happened — web chat, WhatsApp, your dashboard, the agent app or the API — and only after it is committed, so a change that was rolled back is never announced.

EventFires whendata carries
conversation.startedA new conversation begins (any channel)conversation_id, channel, customer_name, customer_phone, customer_email, status, started_at
message.receivedA customer message arrives (not the bot’s or your team’s replies)conversation_id, message_id, content, language, created_at
conversation.handed_overThe conversation is handed to your teamthe conversation fields + handed_over_at, handed_over_to_user_id
conversation.endedThe conversation is closed (status becomes completed)the conversation fields + ended_at
customer.identifiedA customer passes identity verification (method "verified"), or is recognised as a returning customer (method "recognised", with customer_profile_id)the conversation fields + method (+ customer_profile_id)
ticket.createdA support ticket is raised — by the bot, your team, or POST /api/chatbot-api/create-ticketticket_id, ticket_number, subject, description, priority, status, conversation_id, customer_name, customer_email, customer_phone, assigned_to_user_id, created_at
ticket.updatedA ticket’s status, priority or assignee changes (a notes-only edit does not fire)the ticket fields + changes, e.g. {"status": {"from": "open", "to": "resolved"}}
comment.createdA comment is added to a conversation through the Conversations APIconversation_id, comment_id, comment, author, external_ref, identity
sms.delivery_reportAn SMS you sent through Silux Chat settles: delivered, failed, dead or cancelledtenant_id, message_id, client_msg_id, mobile_number, status, handled_by, attempts, last_error, sms_log_id
  • Timestamps are ISO 8601. A value the platform has not stored yet (for example a server-set time on a brand-new row) is null.
  • Test and quality-check traffic (our own verification harnesses and owner test sessions) is never delivered to you.
  • After you register an endpoint, events start within about 15 seconds.

The /test call always delivers a conversation.started sample (marked "test": true) so you can prove your receiver before real events arrive.

Every delivery is one compact JSON object with the same envelope; data depends on the event.

what your endpoint receives
POST /hooks/silux HTTP/1.1
Content-Type: application/json
X-Silux-Event: comment.created
X-Silux-Signature: 5d41c0…(64 hex characters)
X-Silux-Delivery: 90412
User-Agent: SiluxChat-Webhooks/1.0

{"event":"comment.created","tenant_id":42,"created_at":"2026-09-26T10:00:00.123456+00:00","data":{ … }}
HeaderMeaning
X-Silux-EventThe event name, so you can route before parsing
X-Silux-SignatureHex HMAC-SHA256 of the raw body, keyed with your endpoint secret
X-Silux-DeliveryUnique delivery ID — the same across retries, so use it to de-duplicate
User-AgentSiluxChat-Webhooks/1.0
the event sent by POST /webhooks/{id}/test
{
  "event": "conversation.started",
  "tenant_id": 42,
  "created_at": "2026-09-26T10:00:00.123456+00:00",
  "data": {
    "test": true,
    "conversation_id": 0,
    "channel": "whatsapp",
    "identity": {"match_key": "lid:77712345678901@lid", "display_name": "Alex Morgan"}
  }
}

Verify the signature

Check the signature before you trust anything in the body. An unverified webhook is an open door to anyone who learns your URL.

  • Compute HMAC-SHA256 over the raw request bytes, not a re-serialised object — any change in key order or whitespace changes the hash.
  • Compare in constant time.
  • Reply 2xx quickly (within 10 seconds) and do slow work afterwards, from a queue.
  • De-duplicate on X-Silux-Delivery: a retry after a timeout can deliver the same event twice.
Webhook receivers (tested: valid → 204, tampered body → 401, wrong secret → 401)
# Flask receiver for Silux Chat webhooks.  pip install flask
import hashlib, hmac, os
from flask import Flask, abort, request

SECRET = os.environ["SILUX_WEBHOOK_SECRET"]   # returned once when you registered the endpoint
app = Flask(__name__)

def valid(raw_body: bytes, signature: str) -> bool:
    expected = hmac.new(SECRET.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature or "")

@app.post("/hooks/silux")
def silux_hook():
    raw = request.get_data()                    # the RAW bytes — never a re-serialised object
    if not valid(raw, request.headers.get("X-Silux-Signature", "")):
        abort(401)
    event = request.get_json()
    delivery = request.headers.get("X-Silux-Delivery")   # unique per delivery: use it to de-duplicate
    print(delivery, event["event"], event["data"])        # hand off to a queue; reply fast
    return "", 204

Retries and the delivery log

BehaviourValue
Timeout per attempt10 seconds
Attempts per event3, with back-off between them
Counts as deliveredAny 2xx response
RetriedAny non-2xx response, timeout or connection error
Automatic deactivationAfter 15 consecutive failed deliveries; last_error records why
Delivery logGET /api/sandbox/webhooks/deliveries — status, attempts, your response code, error, timestamps

To re-enable a deactivated endpoint, fix the cause, delete it and register it again, then use the /test call to confirm.

Test in the sandbox first

Your sandbox is a separate shadow account linked to yours, with its own sbx_ key and seeded sample conversations. It has no WhatsApp connection, so it physically cannot message a real person. Register your webhook there, fire test events, and switch to the live key only when your receiver is proven.

MethodPathWhat it does
GET/api/sandboxWhether a sandbox exists, and its key
POST/api/sandboxCreate and seed it (call with your live key; returns the sbx_ key)
POST/api/sandbox/resetWipe and re-seed
DELETE/api/sandboxRemove it entirely

The complete platform reference — chat, conversations, tickets, SMS — is in the API documentation (sign in to view).

Make, n8n & Zapier: lookups through a workflow

The Make / n8n / Zapier webhook connector lets the bot find customers and read their orders through a workflow you build — useful when your data is in a spreadsheet, a database your workflow tool can reach, or several systems at once. The platform sends a POST with an action field to your catch-hook address; your workflow replies with JSON.

find_customer

we send
{"action": "find_customer", "email": "jane@example.com", "phone": "07700900123",
 "full_name": "Jane Smith", "postcode": "SW1A 1AA"}
you reply
{"customers": [
  {"id": "123", "name": "Jane Smith", "email": "jane@example.com",
   "phone": "07700900123", "postcode": "SW1A 1AA"}
]}

orders

we send
{"action": "orders", "customer_id": "123", "email": "jane@example.com"}
you reply
{"orders": [
  {"order_number": "1001", "placed": "2026-09-20", "status": "dispatched",
   "total": "39.99", "tracking": "TT123456789GB", "courier": "Royal Mail"}
]}
  • Reply {"customers": []} or {"orders": []} when there is nothing — never an error for “not found”.
  • Only return the customer who matches the email or phone sent. The bot still checks the name and one more detail before sending a one-time code to the contact you return.
  • Answer within a few seconds; each call is allowed about 15 seconds.
  • The unguessable hook address is the credential. Keep it private, and create a new hook if it ever leaks.

Zapier catch hooks can't answer lookups

A Zapier “Catch Hook” always replies with a fixed acknowledgement, not with your data, so the bot would never see a customer. Use Make or n8n for lookups. Zapier remains a good fit for receiving outbound webhooks.

Build it in Make

  1. 1
    Create a scenario starting with Webhooks → Custom webhook. Copy its address (for example hook.eu1.make.com/abc123…).
  2. 2
    Add a Router with two routes filtered on action: find_customer and orders.
  3. 3
    On each route, search your data (Google Sheets, Airtable, a database, an HTTP call…) by email/phone or by customer_id.
  4. 4
    End each route with Webhooks → Webhook response, status 200, header Content-Type: application/json, and a body shaped exactly like the replies above.
  5. 5
    Turn the scenario on (scheduling: immediately).
  6. 6
    In Dashboard → Integrations → Connectors, choose Make / n8n / Zapier webhook, paste the hook address without https://, and press Connect & test.

Build it in n8n

  1. 1
    Add a Webhook node: HTTP method POST, Respond set to Using ‘Respond to Webhook’ node. Use the production URL.
  2. 2
    Add a Switch node on {{ $json.body.action }} with outputs for find_customer and orders.
  3. 3
    Look the data up on each branch, then shape it with a Code or Set node into {"customers": [...]} or {"orders": [...]}.
  4. 4
    Finish each branch with Respond to Webhook → Respond With: JSON.
  5. 5
    Activate the workflow, then connect it on the dashboard as above.

How the connection test works

When you connect, the platform makes real calls with a made-up customer (connection-test@example.com). An empty list is a pass — it proves the workflow answers. Details in Troubleshooting.

Your own REST API

If you already have a JSON API with customer and order lists, the Your own REST API connector reads it directly with a bearer token. You enter the API base address (without https://), a customer lookup path, an orders path and the token; the platform calls:

customer lookup
GET https://api.yourcompany.com/v1/customers?email=jane%40example.com&phone=07700900123
Authorization: Bearer <your token>
Accept: application/json

200
{"data": [{"id": "123", "name": "Jane Smith", "email": "jane@example.com",
           "phone": "07700900123", "postcode": "SW1A 1AA"}]}
orders
GET https://api.yourcompany.com/v1/orders?customer_id=123
Authorization: Bearer <your token>
Accept: application/json

200
{"data": [{"order_number": "1001", "placed": "2026-09-20", "status": "dispatched",
           "total": "39.99", "tracking": "TT123456789GB", "courier": "Royal Mail"}]}
FieldAccepted source fields
id, name, email, phone, postcodesame names, inside data[]
order_numberorder_number, else id
placedplaced, else created_at (shortened to a date)
status, total, tracking, couriersame names
  • Filter by the email or phone query parameter — return only that customer, never a whole list.
  • Serve over HTTPS with a token that can only read.
  • Return {"data": []} for no match, not a 404 or 500.

The REST connector reads; verification still happens on our side (name plus one more detail, then a one-time code to the contact your API returns). If you would rather send the code yourself and control sessions, build Account Connect instead.

Which route to choose

Account ConnectREST connectorMake / n8nOutbound webhooks
Code on your sideFive endpointsTwo GET endpointsNone (visual workflow)One receiver
Who sends the one-time codeYouSilux ChatSilux Chat—
Data the bot can readAccount, orders, invoicesCustomers, ordersCustomers, orders—
Best forBespoke platformsExisting JSON APIsSheets, Airtable, mixed systemsTicket, conversation, comment and SMS-status sync

Get help

Talk to our integration team

Not sure which route fits, or want a second pair of eyes on a workflow? Email support@siluxcall.co.uk with the tools you use and what the bot should answer.

Need help with your integration?

Our integration team can review your endpoints, help you choose the right connector and check a test run with you. Tell us which system you use and what you would like the bot to answer.

support@siluxcall.co.uk