Webhooks Resource

Manage webhooks for real-time event notifications.

Basic Usage

use Samsara\Facades\Samsara;

// Get all webhooks
$webhooks = Samsara::webhooks()->all();

// Find a webhook
$webhook = Samsara::webhooks()->find('webhook-id');

// Create a webhook
$webhook = Samsara::webhooks()->create([
    'name' => 'My Webhook',
    'url' => 'https://example.com/webhook',
    'eventTypes' => ['VehicleCreated', 'DriverCreated'],
]);

// Update a webhook
$webhook = Samsara::webhooks()->update('webhook-id', [
    'name' => 'Updated Webhook',
]);

// Delete a webhook
Samsara::webhooks()->delete('webhook-id');

Webhook Events

Use the WebhookEvent enum for available event types:

use Samsara\Enums\WebhookEvent;

$webhook = Samsara::webhooks()->create([
    'name' => 'Fleet Events',
    'url' => 'https://example.com/webhook',
    'eventTypes' => [
        WebhookEvent::VEHICLE_CREATED->value,
        WebhookEvent::DRIVER_CREATED->value,
        WebhookEvent::GEOFENCE_ENTRY->value,
    ],
]);

Available Event Types

There are 27 available event types defined in the WebhookEvent enum.

Address Events

  • AddressCreated
  • AddressDeleted
  • AddressUpdated

Driver Events

  • DriverCreated
  • DriverUpdated

Vehicle Events

  • VehicleCreated
  • VehicleUpdated

Dispatch / Route Events

  • RouteStopArrival
  • RouteStopDeparture
  • RouteStopEarlyLateArrival
  • RouteStopEtaUpdated
  • RouteStopResequence

Safety Events

  • SevereSpeedingEnded
  • SevereSpeedingStarted
  • SpeedingEventEnded
  • SpeedingEventStarted

Geofence Events

  • GeofenceEntry
  • GeofenceExit

Industrial / Equipment Events

  • EngineFaultOff
  • EngineFaultOn
  • GatewayUnplugged

Maintenance Events

  • DvirSubmitted
  • PredictiveMaintenanceAlert

Document / Form Events

  • DocumentSubmitted
  • FormSubmitted
  • FormUpdated

Issue Events

  • IssueCreated

See the WebhookEvent enum for the full list of available event types.

Webhook Entity

$webhook = Samsara::webhooks()->find('webhook-id');

$webhook->id;         // string
$webhook->name;       // string
$webhook->url;        // string
$webhook->eventTypes; // array
$webhook->enabled;    // bool
$webhook->secret;     // ?string

Webhook Security

Samsara signs webhook payloads using HMAC-SHA256. The SDK provides a middleware and verifier class to validate signatures.

The easiest way to verify webhook signatures is with the VerifyWebhookSignature middleware:

// routes/api.php
use Samsara\Webhooks\VerifyWebhookSignature;

Route::post('/webhooks/samsara', [SamsaraWebhookController::class, 'handle'])
    ->middleware(VerifyWebhookSignature::class);

The middleware reads the secret from config('samsara.webhook_secret'). Add it to your .env:

SAMSARA_WEBHOOK_SECRET=your-base64-encoded-secret

Using the Verifier Class

For manual verification or custom logic, use the WebhookSignatureVerifier class:

use Samsara\Webhooks\WebhookSignatureVerifier;
use Samsara\Exceptions\InvalidSignatureException;

public function handle(Request $request)
{
    $verifier = new WebhookSignatureVerifier(config('samsara.webhook_secret'));

    try {
        $verifier->verifyFromRequest(
            $request->getContent(),
            $request->header('X-Samsara-Signature'),
            $request->header('X-Samsara-Timestamp')
        );
    } catch (InvalidSignatureException $e) {
        abort(401, 'Invalid webhook signature');
    }

    // Process webhook
    $event = $request->json();
    // ...
}

Signature Headers

Samsara sends two headers with each webhook request:

Header Description
X-Samsara-Signature The signature in format v1=<hexdigest>
X-Samsara-Timestamp Unix timestamp when the request was sent

Timestamp Tolerance

By default, the verifier rejects requests older than 300 seconds (5 minutes). Customize this:

// Middleware with custom tolerance (10 minutes)
Route::post('/webhooks/samsara', WebhookController::class)
    ->middleware(new VerifyWebhookSignature(null, 600));

// Or with the verifier class
$verifier->verifyFromRequest($payload, $signature, $timestamp, 600);

Example Webhook Handler

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;

class SamsaraWebhookController extends Controller
{
    public function handle(Request $request): JsonResponse
    {
        // Signature is already verified by middleware
        $eventType = $request->input('eventType');
        $data = $request->input('data');

        match ($eventType) {
            'VehicleCreated' => $this->handleVehicleCreated($data),
            'DriverCreated' => $this->handleDriverCreated($data),
            'GeofenceEntry' => $this->handleGeofenceEntry($data),
            default => null,
        };

        return response()->json(['status' => 'ok']);
    }

    protected function handleVehicleCreated(array $data): void
    {
        // Process vehicle created event
    }

    protected function handleDriverCreated(array $data): void
    {
        // Process driver created event
    }

    protected function handleGeofenceEntry(array $data): void
    {
        // Process geofence entry event
    }
}

Route Registration

// routes/api.php
use Samsara\Webhooks\VerifyWebhookSignature;

Route::post('/webhooks/samsara', [SamsaraWebhookController::class, 'handle'])
    ->middleware(VerifyWebhookSignature::class);

Note: When using the api routes, CSRF protection is not applied. If using web.php, exclude CSRF with ->withoutMiddleware(['csrf']).


Back to top

Copyright © 2024-2025 Erik Galloway. Distributed under the MIT License.