SSoftLinkSMSDocs

Webhooks

Get a signed HTTP request the moment a message is delivered, fails or bounces.

Instead of polling, give us a URL and we POST an event to it whenever a message reaches a final outcome. Every event is signed, retried for up to 45 hours, and kept in an event log you can query and replay for 30 days.

Set up an endpoint

Expose a URL

Add a route to your server that accepts POST with a JSON body and returns any 2xx status. It must be:

  • https://, on the default port 443
  • reachable from the public internet (private and internal addresses are refused)
  • able to respond within 10 seconds

Register it

curl -X PUT https://api.softlinksms.co.ke/api/v1/webhook-endpoint \
  -H "X-Api-Key: $SOFTLINK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/webhooks/softlinksms",
    "events": ["sms.delivered", "sms.failed"]
  }'

Leave out events to receive every event type. The first time you register, the response includes the endpoint's signing secret, shown only once:

{
  "object": "webhook_endpoint",
  "url": "https://example.com/webhooks/softlinksms",
  "events": ["sms.delivered", "sms.failed"],
  "secret_hint": "whsec_…Q2fA",
  "secret": "whsec_hT9xV2...Q2fA",
  "created_at": "2026-10-19T08:00:00Z",
  "updated_at": "2026-10-19T08:00:00Z"
}

Store it alongside your API key. Lost it? Rotate it.

Verify signatures

Every request carries a Softlink-Signature header. Check it before trusting the body; see Verify signatures for code in four languages.

Send a test event

curl -X POST https://api.softlinksms.co.ke/api/v1/webhook-endpoint/test \
  -H "X-Api-Key: $SOFTLINK_API_KEY"

You'll receive a signed webhook.test event within a few seconds. The response includes the event's id, so you can check how delivery went with GET /webhook-events/{id}.

What a request looks like

POST /webhooks/softlinksms HTTP/1.1
Host: example.com
Content-Type: application/json
User-Agent: SoftLinkSMS-Webhooks/1.0
Softlink-Event-Id: evt_6a1f0c2e9b8d4f3aa1c27e5d9b0f4e21
Softlink-Event-Type: sms.delivered
Softlink-Signature: t=1792396502,v1=5f2b0c0e7a9d...

{"id":"evt_6a1f0c2e9b8d4f3aa1c27e5d9b0f4e21","type":"sms.delivered","created_at":"2026-10-19T08:15:02Z","account_id":1042,"data":{"object":"sms","id":"3fae8b8e-9c3a-4e9a-9d3a-7e8e9c3a4e9a","recipient":"+254712345678","status":"delivered",...}}

See Events for every event type and its payload.

Best practices

Managing the endpoint

TaskRequest
See the current endpointGET /webhook-endpoint
Change the URL or eventsPUT /webhook-endpoint (the secret stays the same)
Rotate the signing secretPOST /webhook-endpoint/rotate-secret
Stop all eventsDELETE /webhook-endpoint

Changing the endpoint needs the webhooks:write scope; reading it and the event log needs webhooks:read. You can also set the URL in the dashboard under Settings → Notifications.

On this page