OMX Logo
Documentation
Push Sending

Send Push Notifications

Send targeted push notifications across iOS, Android, and web platforms with advanced scheduling and personalization.

Sending Push Notifications

Send push notifications across multiple platforms with advanced targeting, personalization, and delivery optimization. Support for iOS, Android, and web push notifications with unified API.

Quick Start

Send your first push notification in minutes:

import { OMXClient } from '@omx-sdk/push-notification';

const omx = new OMXClient({
  clientId: 'your_client_id',
  secretKey: 'your_secret_key'
});

// Send a simple push notification
const result = await omx.pushNotification.send({
  to: 'device_token_or_user_id',
  title: 'Welcome to Our App!',
  body: 'Thanks for installing our app. Get started now!',
  
  // Platform-specific data
  data: {
    screen: 'onboarding',
    userId: '12345'
  }
});

console.log('Push notification sent:', result.messageId);

Platform-Specific Notifications

Send notifications optimized for each platform:

// iOS-specific notification
const iosNotification = await omx.pushNotification.send({
  to: 'ios_device_token',
  
  // iOS-specific payload
  ios: {
    alert: {
      title: 'New Message',
      subtitle: 'From John Doe',
      body: 'Hey, check out this amazing feature!'
    },
    
    badge: 1,
    sound: 'default',
    category: 'MESSAGE_CATEGORY',
    
    // Rich notifications
    mutableContent: true,
    contentAvailable: true,
    
    // Action buttons
    actions: [
      { id: 'REPLY', title: 'Reply', type: 'textInput' },
      { id: 'VIEW', title: 'View', type: 'foreground' }
    ],
    
    // Custom data
    customData: {
      conversationId: 'conv_123',
      senderId: 'user_456'
    },
    
    // Media attachments
    mediaUrl: 'https://yourapp.com/images/notification.jpg',
    
    // Threading (group similar notifications)
    threadId: 'messages_thread'
  }
});

// Android-specific notification
const androidNotification = await omx.pushNotification.send({
  to: 'android_registration_token',
  
  // Android-specific payload
  android: {
    notification: {
      title: 'New Message',
      body: 'Hey, check out this amazing feature!',
      icon: 'ic_notification',
      color: '#4F46E5',
      sound: 'default',
      channelId: 'messages',
      
      // Rich notifications
      image: 'https://yourapp.com/images/notification.jpg',
      
      // Action buttons
      actions: [
        {
          action: 'REPLY',
          title: 'Reply',
          icon: 'ic_reply'
        },
        {
          action: 'MARK_READ',
          title: 'Mark as Read',
          icon: 'ic_check'
        }
      ]
    },
    
    // Data payload
    data: {
      conversationId: 'conv_123',
      senderId: 'user_456',
      type: 'message'
    },
    
    // Android-specific options
    priority: 'high',
    timeToLive: 86400, // 24 hours
    collapseKey: 'messages',
    
    // Direct boot mode
    directBootOk: true
  }
});

// Web push notification
const webNotification = await omx.pushNotification.send({
  to: 'web_push_subscription',
  
  // Web push payload
  web: {
    notification: {
      title: 'New Message',
      body: 'Hey, check out this amazing feature!',
      icon: '/icons/notification-icon.png',
      image: '/images/notification-banner.jpg',
      badge: '/icons/badge.png',
      
      // Interaction options
      requireInteraction: true,
      renotify: true,
      tag: 'message_123',
      
      // Action buttons
      actions: [
        {
          action: 'reply',
          title: 'Reply',
          icon: '/icons/reply.png'
        },
        {
          action: 'view',
          title: 'View Message',
          icon: '/icons/view.png'
        }
      ],
      
      // Custom data
      data: {
        conversationId: 'conv_123',
        url: '/messages/conv_123'
      }
    },
    
    // Web push options
    options: {
      ttl: 86400, // 24 hours
      urgency: 'normal', // 'very-low', 'low', 'normal', 'high'
      topic: 'messages'
    }
  }
});

Bulk and Targeted Notifications

Send notifications to multiple recipients with advanced targeting:

// Send to multiple devices
const bulkNotification = await omx.pushNotification.sendBulk({
  recipients: [
    'device_token_1',
    'device_token_2',
    'device_token_3'
  ],
  
  title: 'Flash Sale Started!',
  body: 'Get 50% off everything. Limited time only!',
  
  // Personalization for each recipient
  personalizeData: true,
  data: {
    saleId: 'flash_sale_2024',
    deepLink: '/sale'
  }
});

// Send to user segments
const segmentNotification = await omx.pushNotification.sendToSegment({
  segment: 'premium_users',
  
  title: 'Exclusive Premium Feature',
  body: 'New premium features are now available just for you!',
  
  // Segment-specific customization
  customization: {
    premium_users: {
      title: 'Exclusive Premium Feature',
      icon: 'premium_icon'
    },
    regular_users: {
      title: 'Upgrade to Premium',
      icon: 'upgrade_icon'
    }
  }
});

// Geotargeted notifications
const geoNotification = await omx.pushNotification.sendGeoTargeted({
  location: {
    lat: 40.7128,
    lng: -74.0060,
    radius: 5000 // 5km
  },
  
  title: 'Special Local Offer!',
  body: 'Visit our nearby store for an exclusive discount.',
  
  // Location-specific data
  data: {
    storeId: 'store_nyc_001',
    offerCode: 'LOCAL20',
    storeAddress: '123 Main St, New York, NY'
  },
  
  // Delivery preferences
  delivery: {
    respectQuietHours: true,
    timezone: 'America/New_York'
  }
});

// Send based on user behavior
const behaviorNotification = await omx.pushNotification.sendToBehavior({
  criteria: {
    lastAppOpen: '> 7d', // Users who haven't opened app in 7 days
    purchaseHistory: 'has_purchased',
    engagementLevel: 'high'
  },
  
  title: 'We miss you!',
  body: 'Come back and see what's new. You have exclusive offers waiting!',
  
  // Re-engagement specific
  data: {
    campaignType: 're-engagement',
    incentive: 'exclusive_offers',
    deepLink: '/offers'
  }
});

Rich and Interactive Notifications

Create engaging notifications with rich media and interactive elements:

// Rich media notification
const richNotification = await omx.pushNotification.send({
  to: 'device_token',
  title: 'Your Order is Ready!',
  body: 'Your pizza order #12345 is ready for pickup.',
  
  // Rich media
  media: {
    type: 'image',
    url: 'https://yourapp.com/images/pizza-ready.jpg',
    alt: 'Delicious pizza ready for pickup'
  },
  
  // Interactive actions
  actions: [
    {
      id: 'directions',
      title: 'Get Directions',
      type: 'foreground',
      icon: 'directions_icon',
      data: { action: 'open_maps' }
    },
    {
      id: 'call_store',
      title: 'Call Store',
      type: 'background',
      icon: 'phone_icon',
      data: { action: 'call', phone: '+1-555-123-4567' }
    },
    {
      id: 'track_order',
      title: 'Track Order',
      type: 'foreground',
      icon: 'track_icon',
      data: { action: 'track', orderId: '12345' }
    }
  ],
  
  // Progress tracking
  progress: {
    current: 4,
    total: 4,
    label: 'Ready for pickup'
  }
});

// Carousel notification (multiple images/items)
const carouselNotification = await omx.pushNotification.send({
  to: 'device_token',
  title: 'New Arrivals Just for You!',
  body: 'Swipe to see products we think you'll love.',
  
  // Carousel content
  carousel: [
    {
      image: 'https://yourapp.com/images/product1.jpg',
      title: 'Wireless Headphones',
      subtitle: '$99.99',
      action: { type: 'deeplink', url: '/products/123' }
    },
    {
      image: 'https://yourapp.com/images/product2.jpg',
      title: 'Smart Watch',
      subtitle: '$299.99',
      action: { type: 'deeplink', url: '/products/456' }
    },
    {
      image: 'https://yourapp.com/images/product3.jpg',
      title: 'Bluetooth Speaker',
      subtitle: '$79.99',
      action: { type: 'deeplink', url: '/products/789' }
    }
  ]
});

// Form input notification
const formNotification = await omx.pushNotification.send({
  to: 'device_token',
  title: 'Quick Feedback',
  body: 'How was your recent order? Rate us!',
  
  // Form elements
  form: {
    type: 'rating',
    fields: [
      {
        id: 'rating',
        type: 'rating',
        label: 'Rate your experience',
        max: 5,
        required: true
      },
      {
        id: 'comment',
        type: 'text',
        label: 'Additional comments',
        placeholder: 'Tell us more...',
        maxLength: 200
      }
    ],
    submitAction: {
      type: 'webhook',
      url: 'https://yourapp.com/feedback'
    }
  }
});

// Live activity notification (iOS)
const liveActivity = await omx.pushNotification.startLiveActivity({
  userId: 'user_123',
  activityType: 'food_delivery',
  
  content: {
    title: 'Pizza Delivery',
    subtitle: 'Order #12345',
    
    // Dynamic content
    dynamicContent: {
      status: 'preparing',
      estimatedTime: '15 min',
      driverName: null
    },
    
    // Static content
    staticContent: {
      orderNumber: '12345',
      restaurant: 'Tony's Pizza',
      items: ['Large Pepperoni Pizza', 'Garlic Bread']
    }
  },
  
  // Update schedule
  updateSchedule: 'real-time'
});

// Update live activity
await omx.pushNotification.updateLiveActivity(liveActivity.id, {
  dynamicContent: {
    status: 'on_the_way',
    estimatedTime: '8 min',
    driverName: 'Mike'
  }
});

Scheduled and Automated Notifications

Schedule notifications for optimal delivery times and automate based on triggers:

// Schedule notification for later
const scheduledNotification = await omx.pushNotification.schedule({
  to: 'device_token',
  title: 'Don't forget your appointment',
  body: 'Your appointment is tomorrow at 2 PM.',
  
  // Schedule for 1 hour before appointment
  sendAt: '2024-01-20T13:00:00Z',
  timezone: 'America/New_York',
  
  data: {
    appointmentId: 'apt_123',
    reminderType: 'appointment'
  }
});

// Send at optimal time for each user
const optimizedNotification = await omx.pushNotification.sendOptimized({
  recipients: ['user_1', 'user_2', 'user_3'],
  title: 'Weekly Summary',
  body: 'Your weekly activity summary is ready!',
  
  // AI-powered send time optimization
  optimization: {
    method: 'engagement_prediction', // When user is most likely to engage
    fallbackTime: '10:00',
    timezoneAware: true,
    
    // Constraints
    constraints: {
      earliestTime: '08:00',
      latestTime: '22:00',
      respectQuietHours: true,
      avoidWeekends: false
    }
  }
});

// Automated drip campaign
const dripCampaign = await omx.pushNotification.createDripCampaign({
  name: 'Onboarding Sequence',
  trigger: 'user_signup',
  
  notifications: [
    {
      delay: 0, // Immediate
      title: 'Welcome to YourApp!',
      body: 'Thanks for joining us. Let's get you started!',
      data: { screen: 'onboarding_step_1' }
    },
    {
      delay: '1d', // 1 day later
      title: 'Complete Your Profile',
      body: 'Add a photo and preferences to personalize your experience.',
      data: { screen: 'profile_setup' },
      
      // Conditional sending
      conditions: {
        profileIncomplete: true
      }
    },
    {
      delay: '3d', // 3 days after signup
      title: 'Discover Key Features',
      body: 'Learn about the features that make us special.',
      data: { screen: 'feature_tour' }
    },
    {
      delay: '7d', // 1 week later
      title: 'You're All Set!',
      body: 'Congratulations on completing your setup!',
      data: { screen: 'onboarding_complete' }
    }
  ],
  
  // Campaign settings
  settings: {
    respectUserTimezone: true,
    preferredSendTime: '10:00',
    pauseOnWeekends: false,
    stopOnUninstall: true
  }
});

// Behavior-triggered notifications
const behaviorTrigger = await omx.pushNotification.createBehaviorTrigger({
  name: 'Cart Abandonment',
  
  trigger: {
    event: 'cart_updated',
    conditions: {
      cartValue: '> 50',
      timeSinceUpdate: '> 30m',
      userEngagement: 'high'
    }
  },
  
  notification: {
    title: 'Complete Your Purchase',
    body: 'You have {{itemCount}} items waiting in your cart. Complete your order now!',
    
    // Dynamic content based on cart
    dynamicData: {
      itemCount: '{{cart.itemCount}}',
      cartValue: '{{cart.total}}',
      firstItem: '{{cart.items[0].name}}'
    },
    
    actions: [
      {
        id: 'complete_purchase',
        title: 'Complete Purchase',
        type: 'foreground',
        data: { screen: 'checkout' }
      },
      {
        id: 'save_for_later',
        title: 'Save for Later',
        type: 'background'
      }
    ]
  },
  
  // Frequency controls
  frequency: {
    maxPerDay: 1,
    maxPerWeek: 3,
    cooldownPeriod: '24h'
  }
});

Personalization and Localization

Personalize notifications with user data and localize for global audiences:

// Personalized notification
const personalizedNotification = await omx.pushNotification.send({
  to: 'user_123',
  
  // Template with placeholders
  template: 'welcome_back',
  
  // User-specific data
  personalization: {
    firstName: 'John',
    lastVisit: '5 days ago',
    favoriteCategory: 'Electronics',
    loyaltyPoints: 1250,
    
    // Dynamic recommendations
    recommendations: await getUserRecommendations('user_123'),
    
    // Location-based content
    localOffers: await getLocalOffers(user.location),
    
    // Behavioral data
    streakDays: 7,
    completedGoals: 3
  },
  
  // A/B test variants
  variant: await getNotificationVariant('user_123', 'welcome_back_test')
});

// Multi-language notification
const localizedNotification = await omx.pushNotification.send({
  to: 'device_token',
  
  // Localized content
  localizations: {
    'en': {
      title: 'New Message',
      body: 'You have a new message from John.'
    },
    'es': {
      title: 'Nuevo Mensaje',
      body: 'Tienes un nuevo mensaje de John.'
    },
    'fr': {
      title: 'Nouveau Message',
      body: 'Vous avez un nouveau message de John.'
    },
    'de': {
      title: 'Neue Nachricht',
      body: 'Sie haben eine neue Nachricht von John.'
    }
  },
  
  // Auto-detect user language or fallback
  languageDetection: {
    method: 'user_preference', // 'device_setting', 'user_preference', 'location'
    fallback: 'en'
  },
  
  // Locale-specific formatting
  formatting: {
    currency: true,
    datetime: true,
    numbers: true
  }
});

// Conditional content based on user segments
const segmentedNotification = await omx.pushNotification.send({
  to: 'user_456',
  
  // Different content for different user types
  contentRules: [
    {
      condition: { userTier: 'premium' },
      content: {
        title: 'Exclusive Premium Offer',
        body: 'Get 30% off your next premium purchase!',
        icon: 'premium_crown'
      }
    },
    {
      condition: { userTier: 'standard' },
      content: {
        title: 'Special Offer',
        body: 'Get 15% off your next purchase!',
        icon: 'discount_tag'
      }
    },
    {
      condition: { isNewUser: true },
      content: {
        title: 'Welcome Bonus',
        body: 'Get 20% off as a welcome gift!',
        icon: 'gift_box'
      }
    }
  ],
  
  // Fallback content
  fallback: {
    title: 'Special Offer',
    body: 'Check out our latest deals!',
    icon: 'default_offer'
  }
});

// Dynamic content generation
const dynamicNotification = await omx.pushNotification.send({
  to: 'user_789',
  
  // Content generators
  contentGenerators: {
    title: async (user) => {
      const weather = await getWeather(user.location);
      return `Good ${getTimeOfDay()}, ${user.firstName}! It's ${weather.description} today.`;
    },
    
    body: async (user) => {
      const recommendations = await getPersonalizedRecommendations(user.id);
      return `We found ${recommendations.length} new items you might like!`;
    },
    
    data: async (user) => {
      return {
        weatherInfo: await getWeather(user.location),
        recommendations: await getPersonalizedRecommendations(user.id),
        localEvents: await getLocalEvents(user.location)
      };
    }
  }
});

Delivery Optimization

Optimize notification delivery for better engagement and user experience:

// Frequency capping
const frequencyCappedNotification = await omx.pushNotification.send({
  to: 'user_123',
  title: 'Daily Deals',
  body: 'Check out today's amazing deals!',
  
  // Frequency controls
  frequencyCap: {
    maxPerHour: 1,
    maxPerDay: 3,
    maxPerWeek: 10,
    
    // Respect user preferences
    respectUserSettings: true,
    
    // Category-specific limits
    categoryLimits: {
      'promotional': { maxPerDay: 2 },
      'transactional': { maxPerDay: 10 },
      'marketing': { maxPerDay: 1 }
    }
  }
});

// Quiet hours and Do Not Disturb
const respectfulNotification = await omx.pushNotification.send({
  to: 'user_456',
  title: 'Important Update',
  body: 'Your order status has been updated.',
  
  // Delivery preferences
  deliveryPreferences: {
    // Respect user's quiet hours
    quietHours: {
      enabled: true,
      start: '22:00',
      end: '08:00',
      timezone: 'user_timezone'
    },
    
    // Handle Do Not Disturb mode
    doNotDisturb: {
      respectDeviceSettings: true,
      emergencyOverride: false, // Set to true for critical notifications
      priorityThreshold: 'high'
    },
    
    // Weekend preferences
    weekendDelivery: {
      enabled: true,
      differentTiming: true,
      laterStartTime: '10:00'
    }
  }
});

// Smart delivery optimization
const smartNotification = await omx.pushNotification.sendSmart({
  to: 'user_789',
  title: 'Weekly Summary',
  body: 'Your activity summary for this week is ready!',
  
  // AI-powered optimization
  smartDelivery: {
    // Optimize send time based on user behavior
    timeOptimization: {
      enabled: true,
      model: 'engagement_prediction',
      factors: ['historical_opens', 'app_usage', 'timezone', 'day_of_week']
    },
    
    // Content optimization
    contentOptimization: {
      enabled: true,
      testVariants: ['title_a', 'title_b'],
      optimizeFor: 'open_rate'
    },
    
    // Delivery method optimization
    channelOptimization: {
      enabled: true,
      alternatives: ['push', 'email', 'sms'],
      selectBest: true
    }
  }
});

// Progressive delivery
const progressiveNotification = await omx.pushNotification.sendProgressive({
  campaign: 'flash_sale_announcement',
  title: 'Flash Sale Alert!',
  body: '24-hour flash sale starting now. Up to 70% off!',
  
  // Progressive rollout
  rollout: {
    strategy: 'percentage',
    phases: [
      { percentage: 10, duration: '30m' }, // Test with 10% of users first
      { percentage: 50, duration: '1h' },  // If successful, expand to 50%
      { percentage: 100, duration: '2h' } // Full rollout
    ],
    
    // Success criteria for progression
    successCriteria: {
      openRate: '> 0.15',
      errorRate: '< 0.01',
      uninstallRate: '< 0.001'
    },
    
    // Rollback conditions
    rollbackConditions: {
      errorRate: '> 0.05',
      complaintRate: '> 0.01'
    }
  }
});

// Delivery retry logic
const reliableNotification = await omx.pushNotification.send({
  to: 'device_token',
  title: 'Payment Confirmation',
  body: 'Your payment of $99.99 has been processed successfully.',
  
  // Retry configuration for important notifications
  retryPolicy: {
    maxRetries: 3,
    retryIntervals: ['5m', '30m', '2h'],
    backoffStrategy: 'exponential',
    
    // Retry conditions
    retryConditions: [
      'device_not_reachable',
      'temporary_failure',
      'rate_limited'
    ],
    
    // Fallback channels
    fallbackChannels: [
      { type: 'email', delay: '1h' },
      { type: 'sms', delay: '4h' }
    ]
  }
});

Error Handling and Monitoring

Handle delivery failures and monitor notification performance:

// Error handling
try {
  const result = await omx.pushNotification.send(notificationData);
  console.log('Notification sent:', result.messageId);
} catch (error) {
  switch (error.code) {
    case 'INVALID_TOKEN':
      console.error('Device token is invalid or expired');
      await omx.devices.markInvalid(error.deviceToken);
      break;
      
    case 'RATE_LIMITED':
      console.log('Rate limited, retrying in:', error.retryAfter);
      setTimeout(() => omx.pushNotification.send(notificationData), error.retryAfter * 1000);
      break;
      
    case 'QUOTA_EXCEEDED':
      console.error('Daily quota exceeded');
      await alerting.notifyAdmins('Push notification quota exceeded');
      break;
      
    case 'INVALID_PAYLOAD':
      console.error('Notification payload is invalid:', error.details);
      break;
      
    case 'CERTIFICATE_ERROR':
      console.error('iOS certificate error:', error.message);
      await alerting.notifyAdmins('iOS certificate issue');
      break;
      
    default:
      console.error('Notification sending failed:', error);
  }
}

// Delivery status tracking
const deliveryStatus = await omx.pushNotification.getDeliveryStatus('msg_123');
console.log(deliveryStatus);
// {
//   messageId: 'msg_123',
//   status: 'delivered',
//   deliveredAt: '2024-01-15T10:30:00Z',
//   openedAt: '2024-01-15T10:35:00Z',
//   platform: 'ios',
//   deviceType: 'iPhone',
//   attempts: 1,
//   latency: 1.2 // seconds
// }

// Bulk delivery monitoring
const bulkStatus = await omx.pushNotification.getBulkDeliveryStatus('campaign_123');
console.log(bulkStatus);
// {
//   campaignId: 'campaign_123',
//   total: 10000,
//   delivered: 9756,
//   failed: 244,
//   pending: 0,
//   deliveryRate: 0.976,
//   avgLatency: 2.1,
//   errors: {
//     'invalid_token': 156,
//     'device_not_registered': 88
//   }
// }

// Real-time monitoring
const monitor = omx.pushNotification.createMonitor({
  events: ['sent', 'delivered', 'opened', 'failed'],
  
  alerts: {
    deliveryRate: { threshold: 0.95, email: 'alerts@yourapp.com' },
    errorRate: { threshold: 0.05, slack: '#push-alerts' },
    latency: { threshold: 5000, webhook: 'https://yourapp.com/alerts' }
  }
});

monitor.on('alert', (alert) => {
  console.log('Push notification alert:', alert);
  handleAlert(alert);
});

Best Practices

  • Timing: Send notifications at optimal times for your users
  • Frequency: Respect user preferences and avoid notification fatigue
  • Personalization: Use user data to make notifications relevant
  • Clear CTAs: Include clear calls-to-action in your notifications
  • Testing: A/B test notification content and timing
  • Monitoring: Track delivery rates and user engagement

Next Steps