Skip to main content
Trackly SMS sends webhook events to notify you of message delivery updates, opt-outs, and inbound replies. These events are delivered to your configured webhook URL via HTTP POST.
Webhook delivery is configured per account in the dashboard under Settings > Webhooks. Contact support if you need to set up webhook endpoints.

Event Types

EventTriggerDescription
deliveryMessage delivered or failedDelivery status update from SMS provider
unsubscribeContact replies STOPContact opted out of messages
replyContact sends inbound SMSInbound reply from a contact

Delivery Event

Sent when a message delivery status is updated by the SMS provider.
{
  "event": "delivery",
  "message_id": "AbC12345",
  "to": "+14155551234",
  "list_number": "+18005551234",
  "status": "delivered",
  "status_detail": "DELIVERED_TO_HANDSET",
  "provider": "infobip",
  "timestamp": "2024-01-15T10:30:00.000Z"
}

Delivery Statuses

StatusDescription
deliveredMessage delivered to recipient’s handset
undeliverableMessage could not be delivered
expiredMessage expired before delivery
rejectedMessage rejected by carrier
pendingMessage is being processed

Delivery Failure Codes

When status is undeliverable or rejected, the status_detail field contains the provider-specific error:
DetailDescriptionAction Taken
REJECTED_SPAMFlagged as spamContact auto-removed
REJECTED_DESTINATIONInvalid destinationContact auto-removed
REJECTED_ABSENT_SUBSCRIBERRecipient not availableRetry threshold check
REJECTED_OPERATORRejected by carrierRetry threshold check
See Compliance for details on auto-removal rules.

Unsubscribe Event

Sent when a contact replies with an opt-out keyword (STOP, STOPALL, UNSUBSCRIBE, QUIT, CANCEL).
{
  "event": "unsubscribe",
  "phone_number": "+14155551234",
  "list_number": "+18005551234",
  "keyword": "STOP",
  "timestamp": "2024-01-15T10:35:00.000Z"
}
The contact is immediately marked as unsubscribed (active: false) on the corresponding list. Future sends are blocked automatically.

Reply Event

Sent when a contact sends an inbound SMS that is not an opt-out keyword. Replies are also stored and viewable in the dashboard under Messages > Replies.
{
  "event": "reply",
  "phone_number": "+14155551234",
  "list_number": "+18005551234",
  "body": "Yes, I'm interested!",
  "timestamp": "2024-01-15T10:40:00.000Z"
}

Webhook Delivery

Request Format

Events are delivered as HTTP POST requests with a JSON body:
POST https://your-webhook-url.com/trackly
Content-Type: application/json
X-Trackly-Signature: sha256=...

Retry Policy

If your endpoint returns a non-2xx status code, Trackly will retry up to 5 times with exponential backoff:
AttemptDelay
1st retry1 minute
2nd retry5 minutes
3rd retry15 minutes
4th retry1 hour
5th retry2 hours
The retry policy and HMAC-SHA256 signature apply to the partnerships webhook system (outbound event delivery). Raw provider webhook forwarding (DLR/reply forwarding to user-configured URLs via list settings) is fire-and-forget with no retries and no signature header.

Signature Verification

Each webhook request includes an X-Trackly-Signature header for verifying authenticity. The signature is an HMAC-SHA256 hash of the request body using your webhook secret.
import hmac
import hashlib

def verify_signature(payload_body, signature_header, webhook_secret):
    expected = hmac.new(
        webhook_secret.encode(),
        payload_body,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(f"sha256={expected}", signature_header)

Best Practices

Return a 200 status within 5 seconds. Process events asynchronously if needed.
Events may be delivered more than once. Use message_id + event as an idempotency key.
Always verify the X-Trackly-Signature header to ensure events are from Trackly.

Next Steps

Webhooks Integration

Configure webhook endpoints

Send Message

Send a message to trigger events