Setting Up Webhooks

Real-time notifications for RCManager events sent to your application

Real-Time Event Notifications

Webhooks allow your application to receive real-time notifications when events occur in RCManager. Instead of polling for changes, webhooks push data to your endpoints instantly. Get notified about new maintenance tasks, parts inventory changes, vehicle updates, and more. Build responsive integrations that react immediately to changes in your RC fleet data.

Instant Updates

Real-time notifications

Secure Delivery

Signed payloads

Reliable

Automatic retries

How Webhooks Work

Event Flow

Webhooks follow a simple request-response pattern:

  1. 1
    Event Occurs

    User creates maintenance task, updates vehicle, etc.

  2. 2
    Webhook Triggered

    RCManager prepares event payload with relevant data

  3. 3
    HTTP POST Request

    Event sent to your configured endpoint URL

  4. 4
    Your App Responds

    Return 200 OK to acknowledge receipt

Example Webhook Payload
{
  "id": "evt_1a2b3c4d5e",
  "type": "maintenance.task.created",
  "created": "2024-12-25T10:30:00Z",
  "data": {
    "task": {
      "id": "mnt_9z8y7x6w5v",
      "vehicle_id": "veh_4u3t2s1r0q",
      "type": "oil_change",
      "scheduled_date": "2024-12-30",
      "description": "Regular oil change",
      "status": "scheduled"
    }
  }
}

Webhook Configuration

Creating Webhook Endpoints

Configure webhooks through the API or dashboard:

Via Dashboard

  1. 1. Go to Settings → Webhooks
  2. 2. Click "Add Endpoint"
  3. 3. Enter your endpoint URL
  4. 4. Select event types
  5. 5. Save and activate

Via API

POST /v1/webhooks
{
  "url": "https://app.com/hook",
  "events": [
    "vehicle.*",
    "maintenance.task.*",
    "parts.inventory.low"
  ]
}
Create Webhook with cURL
curl -X POST https://api.pro-pitbox.com/v1/webhooks \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://yourapp.com/webhooks/pro-pitbox",
    "events": ["vehicle.created", "vehicle.updated", "maintenance.task.created"],
    "description": "Production webhook endpoint"
  }'

Webhook Security

Verify webhook authenticity with signature validation:

Signature Verification

Every webhook includes a signature header for verification:

  • Header: X-ProPitbox-Signature
  • Algorithm: HMAC-SHA256
  • Secret: Your webhook signing secret
Verify Webhook Signature (Node.js)
const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, secret) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}

// In your webhook handler
app.post('/webhooks/pro-pitbox', (req, res) => {
  const signature = req.headers['x-propitbox-signature'];
  const payload = JSON.stringify(req.body);
  
  if (!verifyWebhookSignature(payload, signature, WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }
  
  // Process webhook...
  res.status(200).send('OK');
});

Available Webhook Events

Event Types

Subscribe to specific events or use wildcards for categories:

EventDescriptionPayload
vehicle.createdNew vehicle addedVehicle object
vehicle.updatedVehicle details changedUpdated fields
vehicle.deletedVehicle removedVehicle ID
maintenance.task.createdNew maintenance scheduledTask object
maintenance.task.completedMaintenance completedTask & results
parts.inventory.lowLow stock alertPart & quantity
parts.order.createdParts order placedOrder details
session.endedDriving session loggedSession data

Wildcard Events: Use vehicle.* to subscribe to all vehicle events.

Testing Webhooks

Test Events

Send test events to verify your endpoint:

  1. 1. Go to webhook settings
  2. 2. Select your endpoint
  3. 3. Click "Send Test Event"
  4. 4. Choose event type
  5. 5. Verify delivery

Event Logs

Monitor webhook delivery status:

  • • View recent deliveries
  • • Check response codes
  • • Inspect payloads
  • • Debug failures
  • • Retry failed events

Local Testing with ngrok

Test webhooks on your local development environment:

# Install ngrok
npm install -g ngrok

# Expose local port
ngrok http 3000

# Use the HTTPS URL for webhook endpoint
https://abc123.ngrok.io/webhooks/pro-pitbox

Webhook Best Practices

Build Reliable Webhook Handlers

Respond Quickly: Return 200 OK immediately, process asynchronously
Verify Signatures: Always validate webhook authenticity before processing
Handle Retries: Make your handler idempotent to handle duplicate events
Store Event IDs: Track processed events to prevent duplicate processing
Monitor Failures: Set up alerts for webhook processing errors

Delivery & Retries

Automatic Retry Policy

RCManager automatically retries failed webhook deliveries:

Retry Schedule

Exponential Backoff

  • • 1st retry: 5 seconds
  • • 2nd retry: 30 seconds
  • • 3rd retry: 2 minutes
  • • 4th retry: 10 minutes
  • • 5th retry: 1 hour

Success Conditions

  • • HTTP 200-299 response
  • • Within 30 seconds
  • • Valid response body
  • • No connection errors
  • • Endpoint reachable

Failed Webhooks: After 5 retry attempts, the webhook is marked as failed and can be manually retried from the dashboard.

Example Webhook Handler

Complete Express.js Webhook Handler
const express = require('express');
const crypto = require('crypto');
const app = express();

// Store processed events to prevent duplicates
const processedEvents = new Set();

app.post('/webhooks/pro-pitbox', express.json(), async (req, res) => {
  // 1. Verify webhook signature
  const signature = req.headers['x-propitbox-signature'];
  const payload = JSON.stringify(req.body);
  
  if (!verifySignature(payload, signature, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }
  
  // 2. Respond immediately
  res.status(200).send('OK');
  
  // 3. Process asynchronously
  setImmediate(async () => {
    const event = req.body;
    
    // Check for duplicate events
    if (processedEvents.has(event.id)) {
      console.log('Duplicate event, skipping:', event.id);
      return;
    }
    
    processedEvents.add(event.id);
    
    try {
      // Handle different event types
      switch (event.type) {
        case 'vehicle.created':
          await handleVehicleCreated(event.data);
          break;
        case 'maintenance.task.created':
          await handleMaintenanceCreated(event.data);
          break;
        case 'parts.inventory.low':
          await handleLowInventory(event.data);
          break;
        default:
          console.log('Unhandled event type:', event.type);
      }
    } catch (error) {
      console.error('Error processing webhook:', error);
      // Send to error tracking service
    }
  });
});

async function handleVehicleCreated(data) {
  console.log('New vehicle:', data.vehicle.name);
  // Add to internal database, send notification, etc.
}

async function handleMaintenanceCreated(data) {
  console.log('Maintenance scheduled:', data.task.type);
  // Update calendar, send reminder, etc.
}

async function handleLowInventory(data) {
  console.log('Low stock alert:', data.part.name);
  // Create purchase order, notify team, etc.
}

Start Receiving Events

Ready to set up real-time notifications? Here's what to do next: