Skip to content

Webhook Events

Complete reference for all webhook events sent by YeboLink.

Event Types

message.queued

Fired when a message is queued for sending.

Payload:

json
{
  "event": "message.queued",
  "timestamp": "2025-11-02T12:00:00Z",
  "data": {
    "message_id": "550e8400-e29b-41d4-a716-446655440000",
    "channel": "sms",
    "recipient": "+1234567890",
    "status": "queued",
    "credits_used": 1,
    "metadata": {
      "user_id": "12345"
    }
  }
}

message.sent

Fired when a message is sent to the carrier/provider.

Payload:

json
{
  "event": "message.sent",
  "timestamp": "2025-11-02T12:00:30Z",
  "data": {
    "message_id": "550e8400-e29b-41d4-a716-446655440000",
    "channel": "sms",
    "recipient": "+1234567890",
    "status": "sent",
    "provider_message_id": "SM1234567890",
    "metadata": {
      "user_id": "12345"
    }
  }
}

message.delivered

Fired when a message is successfully delivered to the recipient.

Payload:

json
{
  "event": "message.delivered",
  "timestamp": "2025-11-02T12:01:30Z",
  "data": {
    "message_id": "550e8400-e29b-41d4-a716-446655440000",
    "channel": "sms",
    "recipient": "+1234567890",
    "status": "delivered",
    "provider_message_id": "SM1234567890",
    "delivered_at": "2025-11-02T12:01:30Z",
    "metadata": {
      "user_id": "12345"
    }
  }
}

message.failed

Fired when a message delivery fails.

Payload:

json
{
  "event": "message.failed",
  "timestamp": "2025-11-02T12:02:00Z",
  "data": {
    "message_id": "550e8400-e29b-41d4-a716-446655440000",
    "channel": "sms",
    "recipient": "+1234567890",
    "status": "failed",
    "error_code": "30006",
    "error_message": "Landline or unreachable carrier",
    "provider_message_id": "SM1234567890",
    "metadata": {
      "user_id": "12345"
    }
  }
}

Common Error Codes

SMS Error Codes

Error CodeDescriptionAction
30006Landline or unreachable carrierVerify phone number is mobile
30007Message filtered (spam)Review message content
30008Unknown destinationVerify phone number format
30034Exceeded max priceCheck pricing settings

Event Data Fields

FieldTypeDescriptionAlways Present
message_idstringUnique message identifierYes
channelstringMessaging channelYes
recipientstringRecipient phone/emailYes
statusstringCurrent message statusYes
credits_usednumberCredits consumedqueued, sent only
provider_message_idstringProvider's message IDsent, delivered, failed
error_codestringError code if failedfailed only
error_messagestringError description if failedfailed only
delivered_atstringDelivery timestampdelivered only
metadataobjectCustom metadataIf provided

Subscribing to Events

When creating a webhook, specify which events you want to receive:

bash
curl -X POST https://api.yebolink.com/api/v1/webhooks \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -d '{
    "url": "https://your-app.com/webhooks",
    "events": ["message.delivered", "message.failed"]
  }'

Handling Events

Example: Update Database on Delivery

javascript
function handleWebhookEvent(event, data) {
  switch (event) {
    case 'message.delivered':
      // Update message status in database
      db.messages.update(data.message_id, {
        status: 'delivered',
        delivered_at: data.delivered_at
      });

      // Notify user if needed
      if (data.metadata?.notify_user) {
        notifyUser(data.metadata.user_id, 'Message delivered');
      }
      break;

    case 'message.failed':
      // Log failure
      db.messages.update(data.message_id, {
        status: 'failed',
        error_code: data.error_code,
        error_message: data.error_message
      });

      // Alert support for critical messages
      if (data.metadata?.critical) {
        alertSupport(data);
      }
      break;
  }
}

Example: Track Delivery Metrics

javascript
const metrics = {
  sent: 0,
  delivered: 0,
  failed: 0
};

function handleWebhookEvent(event, data) {
  if (event === 'message.sent') {
    metrics.sent++;
  } else if (event === 'message.delivered') {
    metrics.delivered++;
  } else if (event === 'message.failed') {
    metrics.failed++;
  }

  // Calculate delivery rate
  const deliveryRate = (metrics.delivered / metrics.sent * 100).toFixed(2);
  console.log(`Delivery rate: ${deliveryRate}%`);
}

Event Timing

Events are sent in this typical sequence:

  1. message.queued - Immediately when message is queued
  2. message.sent - Within seconds of queuing
  3. message.delivered OR message.failed - Within seconds to minutes

TIP

Some carriers may take several minutes to report delivery status. If you don't receive a delivered/failed event within 10 minutes, you can poll the Messages API.

Next Steps

Built with VitePress