Documentation Index Fetch the complete documentation index at: https://docs.vellosim.com/llms.txt
Use this file to discover all available pages before exploring further.
Quick Reference
Event Type Trigger Key Data esim.createdeSIM purchase complete, data ready Full eSIM details with QR code esim.activatedeSIM activated on device Status change, activation time esim.data_updatedData usage changes Usage amounts, remaining data esim.usage_updatedUsage requeried Full usage statistics esim.suspendedeSIM suspended Reason, previous status esim.expiredeSIM validity expired Expiration details esim.status_changedAny other status change Before/after status esim.requeriedManual data refresh Updated eSIM data
Common Payload Structure
All webhooks share this base structure:
{
"event" : "string" , // Event type
"id" : "string" , // Unique event ID
"timestamp" : "string" , // ISO 8601 timestamp
"data" : { // eSIM object (structure below)
// ... eSIM data ...
},
"previousStatus" : "string" , // Optional: for status changes
"newStatus" : "string" , // Optional: for status changes
"changes" : { // Optional: changed fields
"fieldName" : {
"old" : "value" ,
"new" : "value"
}
}
}
eSIM Data Object (Common to All Events)
{
// Identifiers
"id" : "507f1f77bcf86cd799439011" ,
"transactionId" : "esim_1762811805580_83" ,
"orderNo" : "ORD2024110001" ,
"packageCode" : "US-1GB-7D" ,
// eSIM Credentials
"iccid" : "8901234567890123456" ,
"imsi" : "123456789012345" ,
"msisdn" : "+1234567890" ,
"ac" : "LPA:1$smdp.example.com$ABC-DEF-123" ,
"eid" : "89012345678901234567890123456789012" ,
// Activation
"qrCodeUrl" : "https://api.vellosim.com/esim/qr/123.png" ,
"shortUrl" : "https://esim.vls.io/abc123" ,
// Status
"esimStatus" : "CREATED | ACTIVATED | SUSPENDED | EXPIRED | etc." ,
"smdpStatus" : "RELEASED | DOWNLOADED | INSTALLED | etc." ,
// Data & Validity
"totalVolume" : 1024 , // MB
"totalDuration" : 7 , // days
"dataUsage" : 512.5 , // MB used
"data_usage_remain" : 511.5 , // MB remaining
"totalData" : 1024 , // MB total allowance
"validity_usage_remain" : 5 , // days remaining
// Timestamps
"activateTime" : "2024-11-10T12:00:00.000Z" ,
"expiredTime" : "2024-11-17T12:00:00.000Z" ,
"lastUsageUpdate" : "2024-11-10T15:30:00.000Z" ,
"createdAt" : "2024-11-10T10:00:00.000Z" ,
"updatedAt" : "2024-11-10T15:30:00.000Z" ,
// Package Info
"packageDetails" : {
"name" : "USA 1GB - 7 Days" ,
"code" : "US-1GB-7D" ,
"slug" : "usa-1gb-7days" ,
"volume" : 1024 ,
"duration" : 7 ,
"location" : "United States" ,
"locationLogo" : "https://cdn.vellosim.com/flags/us.png" ,
"price" : 9.99 ,
"currency" : "USD" ,
"description" : "1GB data for USA, valid for 7 days" ,
"speed" : "4G LTE"
}
}
Event Type Details
1. esim.created
When : eSIM purchase completed and resource details retrieved from provider
Timing : 5-30 seconds after purchase
Full Example :
{
"event" : "esim.created" ,
"id" : "1699625400123_abc" ,
"timestamp" : "2024-11-10T15:30:00.000Z" ,
"data" : {
"id" : "507f1f77bcf86cd799439011" ,
"transactionId" : "esim_1762811805580_83" ,
"orderNo" : "ORD2024110001" ,
"packageCode" : "US-1GB-7D" ,
"iccid" : "8901234567890123456" ,
"imsi" : "123456789012345" ,
"msisdn" : "+12025550123" ,
"ac" : "LPA:1$smdp.provider.com$ACTIVATION123" ,
"qrCodeUrl" : "https://api.vellosim.com/esim/qr/507f1f77bcf86cd799439011.png" ,
"shortUrl" : "https://esim.vls.io/abc123" ,
"esimStatus" : "CREATED" ,
"smdpStatus" : "RELEASED" ,
"eid" : null ,
"totalVolume" : 1024 ,
"totalDuration" : 7 ,
"dataUsage" : 0 ,
"data_usage_remain" : 1024 ,
"totalData" : 1024 ,
"validity_usage_remain" : 7 ,
"activateTime" : null ,
"expiredTime" : null ,
"lastUsageUpdate" : null ,
"packageDetails" : {
"name" : "USA 1GB - 7 Days" ,
"code" : "US-1GB-7D" ,
"volume" : 1024 ,
"duration" : 7 ,
"location" : "United States" ,
"locationLogo" : "https://cdn.vellosim.com/flags/us.png" ,
"price" : 9.99 ,
"currency" : "USD" ,
"description" : "Stay connected in the USA with 1GB of high-speed data" ,
"speed" : "4G LTE"
},
"createdAt" : "2024-11-10T15:29:45.000Z" ,
"updatedAt" : "2024-11-10T15:30:00.000Z"
}
}
Use Cases :
Update your database with eSIM details
Send confirmation email with QR code
Display eSIM in user’s dashboard
Generate invoice/receipt
2. esim.activated
When : User installs and activates the eSIM profile on their device
Timing : When provider notifies activation (typically within minutes of installation)
Full Example :
{
"event" : "esim.activated" ,
"id" : "1699628000456_def" ,
"timestamp" : "2024-11-10T16:00:00.000Z" ,
"data" : {
"id" : "507f1f77bcf86cd799439011" ,
"transactionId" : "esim_1762811805580_83" ,
"orderNo" : "ORD2024110001" ,
"packageCode" : "US-1GB-7D" ,
"iccid" : "8901234567890123456" ,
"imsi" : "123456789012345" ,
"msisdn" : "+12025550123" ,
"esimStatus" : "ACTIVATED" ,
"smdpStatus" : "INSTALLED" ,
"eid" : "89012345678901234567890123456789012" ,
"totalVolume" : 1024 ,
"totalDuration" : 7 ,
"dataUsage" : 0 ,
"data_usage_remain" : 1024 ,
"validity_usage_remain" : 7 ,
"activateTime" : "2024-11-10T16:00:00.000Z" ,
"expiredTime" : "2024-11-17T16:00:00.000Z" ,
"lastUsageUpdate" : "2024-11-10T16:00:00.000Z" ,
"createdAt" : "2024-11-10T15:29:45.000Z" ,
"updatedAt" : "2024-11-10T16:00:00.000Z"
},
"previousStatus" : "CREATED" ,
"newStatus" : "ACTIVATED"
}
Key Fields :
activateTime: When activation occurred
expiredTime: Calculated expiration date
eid: Device identifier
previousStatus: Status before activation
newStatus: “ACTIVATED” or “IN_USE”
Use Cases :
Start usage tracking
Send activation confirmation
Update analytics/reports
Trigger welcome message
3. esim.data_updated
When : Data usage information changes (every few hours or at usage milestones)
Timing : Varies (typically when 25%, 50%, 75%, 90%, 100% thresholds reached)
Full Example :
{
"event" : "esim.data_updated" ,
"id" : "1699641600789_ghi" ,
"timestamp" : "2024-11-11T09:30:00.000Z" ,
"data" : {
"id" : "507f1f77bcf86cd799439011" ,
"transactionId" : "esim_1762811805580_83" ,
"iccid" : "8901234567890123456" ,
"esimStatus" : "ACTIVATED" ,
"totalVolume" : 1024 ,
"totalData" : 1024 ,
"dataUsage" : 512.5 ,
"data_usage_remain" : 511.5 ,
"lastUsageUpdate" : "2024-11-11T09:30:00.000Z" ,
"updatedAt" : "2024-11-11T09:30:00.000Z"
},
"changes" : {
"dataUsage" : {
"old" : 450.2 ,
"new" : 512.5
},
"data_usage_remain" : {
"old" : 573.8 ,
"new" : 511.5
}
}
}
Key Fields :
dataUsage: Current usage in MB
data_usage_remain: Remaining data in MB
changes: Shows what changed from previous state
Use Cases :
Track consumption patterns
Send low data alerts
Offer top-up/add-ons
Update usage charts
4. esim.usage_updated
When : Complete usage information refreshed (data + validity)
Timing : Periodic updates or after manual requery
Full Example :
{
"event" : "esim.usage_updated" ,
"id" : "1699655200321_jkl" ,
"timestamp" : "2024-11-11T13:00:00.000Z" ,
"data" : {
"id" : "507f1f77bcf86cd799439011" ,
"transactionId" : "esim_1762811805580_83" ,
"iccid" : "8901234567890123456" ,
"esimStatus" : "ACTIVATED" ,
"totalVolume" : 1024 ,
"totalDuration" : 7 ,
"dataUsage" : 768.3 ,
"data_usage_remain" : 255.7 ,
"validity_usage_remain" : 4 ,
"activateTime" : "2024-11-10T16:00:00.000Z" ,
"expiredTime" : "2024-11-17T16:00:00.000Z" ,
"lastUsageUpdate" : "2024-11-11T13:00:00.000Z" ,
"updatedAt" : "2024-11-11T13:00:00.000Z"
},
"changes" : {
"dataUsage" : {
"old" : 512.5 ,
"new" : 768.3
},
"data_usage_remain" : {
"old" : 511.5 ,
"new" : 255.7
},
"validity_usage_remain" : {
"old" : 5 ,
"new" : 4
}
}
}
Key Fields :
dataUsage + data_usage_remain: Data usage
validity_usage_remain: Days remaining
lastUsageUpdate: Timestamp of update
Use Cases :
Comprehensive usage sync
Dashboard updates
Analytics refresh
Billing updates
5. esim.suspended
When : eSIM is suspended (manual or automatic)
Timing : Immediately when suspension occurs
Full Example :
{
"event" : "esim.suspended" ,
"id" : "1699714800999_mno" ,
"timestamp" : "2024-11-11T16:30:00.000Z" ,
"data" : {
"id" : "507f1f77bcf86cd799439011" ,
"transactionId" : "esim_1762811805580_83" ,
"iccid" : "8901234567890123456" ,
"esimStatus" : "REVOKED" ,
"dataUsage" : 850.0 ,
"data_usage_remain" : 174.0 ,
"updatedAt" : "2024-11-11T16:30:00.000Z"
},
"previousStatus" : "ACTIVATED" ,
"newStatus" : "REVOKED"
}
Possible Status Values :
REVOKED: Profile revoked
CANCEL: Order cancelled
Use Cases :
Notify user of suspension
Display suspension reason
Offer reactivation options
Update access controls
6. esim.expired
When : eSIM reaches end of validity period or data exhausted
Timing : At expiration time or when data runs out
Full Example :
{
"event" : "esim.expired" ,
"id" : "1699801200123_pqr" ,
"timestamp" : "2024-11-17T16:00:00.000Z" ,
"data" : {
"id" : "507f1f77bcf86cd799439011" ,
"transactionId" : "esim_1762811805580_83" ,
"iccid" : "8901234567890123456" ,
"esimStatus" : "USED_EXPIRED" ,
"dataUsage" : 980.5 ,
"data_usage_remain" : 43.5 ,
"validity_usage_remain" : 0 ,
"activateTime" : "2024-11-10T16:00:00.000Z" ,
"expiredTime" : "2024-11-17T16:00:00.000Z" ,
"updatedAt" : "2024-11-17T16:00:00.000Z"
},
"previousStatus" : "ACTIVATED" ,
"newStatus" : "USED_EXPIRED"
}
Possible Status Values :
USED_UP: Data fully consumed
USED_EXPIRED: Data used + validity expired
UNUSED_EXPIRED: Expired with unused data
Use Cases :
Archive eSIM data
Offer renewal/repurchase
Generate usage report
Update analytics
7. esim.status_changed
When : Any status change not covered by specific events
Timing : Varies based on status change
Full Example :
{
"event" : "esim.status_changed" ,
"id" : "1699728000321_stu" ,
"timestamp" : "2024-11-11T19:46:40.000Z" ,
"data" : {
"id" : "507f1f77bcf86cd799439011" ,
"transactionId" : "esim_1762811805580_83" ,
"iccid" : "8901234567890123456" ,
"esimStatus" : "USED_UP" ,
"dataUsage" : 1024 ,
"data_usage_remain" : 0 ,
"validity_usage_remain" : 3 ,
"updatedAt" : "2024-11-11T19:46:40.000Z"
},
"previousStatus" : "ACTIVATED" ,
"newStatus" : "USED_UP"
}
Use Cases :
Catch all status changes
Handle edge cases
Maintain audit trail
Debug status transitions
8. esim.requeried
When : eSIM data manually refreshed from provider
Timing : After admin or system requery operation
Full Example :
{
"event" : "esim.requeried" ,
"id" : "1699732800456_vwx" ,
"timestamp" : "2024-11-11T21:00:00.000Z" ,
"data" : {
"id" : "507f1f77bcf86cd799439011" ,
"transactionId" : "esim_1762811805580_83" ,
"orderNo" : "ORD2024110001" ,
"iccid" : "8901234567890123456" ,
"esimStatus" : "ACTIVATED" ,
"dataUsage" : 892.7 ,
"data_usage_remain" : 131.3 ,
"validity_usage_remain" : 3 ,
"lastUsageUpdate" : "2024-11-11T21:00:00.000Z" ,
"updatedAt" : "2024-11-11T21:00:00.000Z"
}
}
Use Cases :
Sync latest provider data
Resolve data discrepancies
Force update in UI
Debugging/support
eSIM Status Values
Status Description Triggers Event PENDINGOrder placed, awaiting provider - CREATEDeSIM created, ready for activation esim.createdACTIVATEDActivated on device esim.activatedIN_USECurrently in use (same as ACTIVATED) esim.activatedSUSPENDEDTemporarily suspended esim.suspendedEXPIREDValidity expired esim.expiredUSED_UPData fully consumed esim.expiredUSED_EXPIREDData used + validity expired esim.expiredUNUSED_EXPIREDExpired with unused data esim.expiredCANCELOrder cancelled esim.suspendedREVOKEDProfile revoked esim.suspendedFAILEDOrder failed esim.status_changed
SMDP Status Values
Status Description RELEASEDProfile released, ready for download DOWNLOADEDProfile downloaded to device INSTALLEDProfile installed on device ENABLEDProfile enabled for use DISABLEDProfile disabled DELETEDProfile deleted from device
Data Units
All data-related fields use megabytes (MB) as the unit:
{
"totalVolume" : 1024 , // 1024 MB = 1 GB
"dataUsage" : 512.5 , // 512.5 MB used
"data_usage_remain" : 511.5 , // 511.5 MB remaining
"totalData" : 1024 // 1024 MB total allowance
}
Time/Duration Units
Validity duration typically in days :
{
"totalDuration" : 7 , // 7 days validity
"validity_usage_remain" : 5 // 5 days remaining
}
All timestamps are in ISO 8601 format (UTC):
{
"timestamp" : "2024-11-10T15:30:00.000Z" ,
"activateTime" : "2024-11-10T16:00:00.000Z" ,
"expiredTime" : "2024-11-17T16:00:00.000Z"
}
Every webhook request includes these headers:
Content-Type: application/json
X-Webhook-Signature: <hmac_sha256_signature>
X-Webhook-Event: <event_type>
X-Webhook-Id: <unique_event_id>
X-Webhook-Timestamp: <iso8601_timestamp>
User-Agent: Vellosim-Webhooks/1.0
Signature Verification
Verify webhook signatures to ensure requests are from Vellosim:
const crypto = require ( 'crypto' );
function verifyWebhookSignature ( payload , signature , secret ) {
const expectedSignature = crypto
. createHmac ( 'sha256' , secret )
. update ( JSON . stringify ( payload ))
. digest ( 'hex' );
return crypto . timingSafeEqual (
Buffer . from ( signature ),
Buffer . from ( expectedSignature )
);
}
// Express.js example
app . post ( '/webhooks/vellosim' , express . json (), ( req , res ) => {
const signature = req . headers [ 'x-webhook-signature' ];
const webhookSecret = process . env . VELLOSIM_WEBHOOK_SECRET ;
if ( ! verifyWebhookSignature ( req . body , signature , webhookSecret )) {
return res . status ( 401 ). send ( 'Invalid signature' );
}
const event = req . body ;
// Process the webhook event
handleWebhookEvent ( event );
res . status ( 200 ). send ( 'Webhook received' );
});
Handling Webhook Events
Process different event types appropriately:
function handleWebhookEvent ( event ) {
// Store event ID to prevent duplicate processing
if ( isEventProcessed ( event . id )) {
console . log ( `Event ${ event . id } already processed` );
return ;
}
switch ( event . event ) {
case 'esim.created' :
handleEsimCreated ( event . data );
break ;
case 'esim.activated' :
handleEsimActivated ( event . data , event . previousStatus );
break ;
case 'esim.data_updated' :
handleDataUpdated ( event . data , event . changes );
break ;
case 'esim.usage_updated' :
handleUsageUpdated ( event . data , event . changes );
break ;
case 'esim.suspended' :
handleEsimSuspended ( event . data , event . previousStatus );
break ;
case 'esim.expired' :
handleEsimExpired ( event . data );
break ;
case 'esim.status_changed' :
handleStatusChanged ( event . data , event . previousStatus , event . newStatus );
break ;
case 'esim.requeried' :
handleEsimRequeried ( event . data );
break ;
default :
console . log ( `Unhandled event type: ${ event . event } ` );
}
// Mark event as processed
markEventProcessed ( event . id );
}
function handleEsimCreated ( data ) {
// Update database with eSIM details
console . log ( `New eSIM created: ${ data . transactionId } ` );
// Send confirmation email with QR code
sendEsimConfirmation ( data . customerEmail , {
qrCodeUrl: data . qrCodeUrl ,
shortUrl: data . shortUrl ,
ac: data . ac ,
packageDetails: data . packageDetails
});
// Update order status
updateOrderStatus ( data . id , 'CREATED' );
}
function handleEsimActivated ( data , previousStatus ) {
// Notify customer that eSIM is active
console . log ( `eSIM activated: ${ data . iccid } ` );
sendActivationNotification ( data . customerEmail , {
iccid: data . iccid ,
activateTime: data . activateTime ,
expiredTime: data . expiredTime
});
// Update status and start tracking
updateOrderStatus ( data . id , 'ACTIVATED' );
startUsageTracking ( data . id );
}
function handleDataUpdated ( data , changes ) {
// Update usage in database
updateUsageStats ( data . id , {
dataUsage: data . dataUsage ,
data_usage_remain: data . data_usage_remain
});
// Check for low data threshold (e.g., 10% remaining)
const usagePercent = ( data . dataUsage / data . totalData ) * 100 ;
if ( usagePercent >= 90 && usagePercent < 100 ) {
sendLowDataAlert ( data . customerEmail , data );
}
}
Webhook Response Best Practices
Always return a 200 status code to acknowledge receipt. Process the webhook asynchronously if needed.
Your endpoint should respond within 5 seconds. For longer processing, queue the webhook for async processing.
Handle Duplicates (Idempotency)
Webhooks may be sent multiple times. Use the event ID to prevent duplicate processing.
Always verify webhook signatures to ensure authenticity and prevent spoofing.
Error Handling & Retry Logic
Retry Schedule
Failed webhooks are retried with exponential backoff:
Attempt 1 : Immediate
Attempt 2 : 1 minute later
Attempt 3 : 5 minutes later
Attempt 4 : 15 minutes later
Attempt 5 : 1 hour later
Attempt 6 : 2 hours later
Maximum : 5 retries (6 total attempts)
HTTP Status Codes
2xx : Success, no retry
410 Gone : Endpoint invalid, stop retrying
All others : Retry with backoff
Async Processing Example
const Queue = require ( 'bull' );
const webhookQueue = new Queue ( 'webhook-processing' );
// Webhook endpoint - responds immediately
app . post ( '/webhooks/vellosim' , express . json (), async ( req , res ) => {
const signature = req . headers [ 'x-webhook-signature' ];
if ( ! verifyWebhookSignature ( req . body , signature , WEBHOOK_SECRET )) {
return res . status ( 401 ). send ( 'Invalid signature' );
}
// Add to queue for async processing
await webhookQueue . add ({
event: req . body ,
receivedAt: new Date ()
});
// Respond immediately
res . status ( 200 ). send ( 'Webhook queued' );
});
// Process webhooks asynchronously
webhookQueue . process ( async ( job ) => {
const { event } = job . data ;
await handleWebhookEvent ( event );
});
Testing Webhooks
Local Testing with ngrok
Expose your local server for webhook testing:
# Start your local server
npm start
# In another terminal, start ngrok
ngrok http 3000
# Use the ngrok URL as your webhook endpoint
# Example: https://abc123.ngrok-free.app/webhooks/vellosim
Test with webhook.site
Use webhook.site to inspect webhook payloads:
Go to webhook.site
Copy the unique URL
Configure it as your webhook endpoint
Trigger events and inspect payloads in real-time
Integration Checklist
✅ Webhook URL configured in API key settings
✅ Signature verification implemented
✅ Idempotency handling (using event.id)
✅ Async processing (return 200 OK immediately)
✅ Error logging and monitoring
✅ Retry handling on your side (optional)
✅ Test with ngrok/webhook.site
✅ Monitor webhook delivery logs
Next Steps
Purchase eSIM Learn how to purchase eSIMs
Fetch eSIM Details Retrieve complete eSIM information
Top-up eSIM Add data to existing eSIMs
List All eSIMs Fetch all user eSIMs with pagination