Skip to main content
Smartcar delivers webhook events to your configured endpoint. Each event notifies your application about changes to vehicle state, errors encountered during data retrieval, or verification challenges.

Event Types


VERIFY

A one-time event sent when you first create a webhook to verify that Smartcar can successfully deliver payloads to your callback URL.

When This Event Fires

The VERIFY event fires once when you:
  • Create a new webhook in the Smartcar Dashboard
  • Update the callback URL of an existing webhook
  • Click “Verify this webhook” in the Dashboard

Payload Structure

{
  "eventId": "52f6e0bb-1369-45da-a61c-9e67d092d6db",
  "eventType": "VERIFY",
  "data": {
    "challenge": "<random-string>"
  },
  "meta": {
    "version": "4.0",
    "webhookId": "5a8e5e38-1e12-4011-a36d-56f120053f9e",
    "webhookName": "Example Webhook",
    "deliveryId": "5d569643-3a47-4cd1-a3ec-db5fc1f6f03b",
    "deliveredAt": "2025-07-31T19:38:42.332Z"
  }
}

Required Response

Your endpoint must respond with a 200 status code and return the challenge hashed with your Application Management Token. Response Requirements:
  • Status code: 200
  • Content-Type: application/json
  • Body: { "challenge": "<HMAC-SHA256-hex>" }
Generating the HMAC: Create an HMAC-SHA256 hash of the challenge value using your Application Management Token as the secret key, then hex-encode the result.
import smartcar

hmac = smartcar.hash_challenge(
    application_management_token, 
    challenge
)

# Return in response body
return {"challenge": hmac}
If your endpoint fails to respond correctly, Smartcar will not activate the webhook. You can retry verification from the Dashboard at any time.
For step-by-step implementation guidance, see Callback URI Verification.

VEHICLE_STATE

Triggered when one or more signals you’ve configured as triggers change their value. This event delivers the updated signal data for all subscribed signals in the payload.

When This Event Fires

The VEHICLE_STATE event fires when Smartcar detects a signal value change for any trigger signal.
All Configured Signals Are Always IncludedEvery VEHICLE_STATE event contains all signals you configured in your webhook subscription, regardless of which signal(s) triggered the event. This ensures you always have complete vehicle state data.Example: If your webhook subscribes to 10 signals but only 1 trigger changes, you’ll receive all 10 signals in the payload.

Trigger Configuration

You configure which signals should trigger this event through the Smartcar Dashboard when creating or editing a webhook. For example: Triggers:
  • TractionBattery.StateOfCharge (code: tractionbattery-stateofcharge)
  • Charge.IsCharging (code: charge-ischarging)
  • Location.PreciseLocation (code: location-preciselocation)
Subscribed Signals:
  • TractionBattery.StateOfCharge
  • Charge.IsCharging
  • Location.PreciseLocation
  • Charge.Voltage
  • Odometer.TraveledDistance
If any of the trigger signals change, a VEHICLE_STATE event is delivered containing all five subscribed signals.

Identifying Which Triggers Fired

The webhook payload includes a triggers field that specifies which trigger signal(s) changed to prompt this delivery. This helps you identify what caused the event without comparing all signal values.

Trigger Types

When a monitored trigger signal changes value, the triggers array contains the signal(s) that changed.
{
  "triggers": [
    {
      "code": "tractionbattery-stateofcharge",
      "name": "StateOfCharge",
      "group": "TractionBattery"
    }
  ]
}
If multiple triggers change simultaneously, all will be included in the array.
When a webhook subscription is first created, a FIRST_DELIVERY trigger is sent to provide the initial state of the vehicle.
{
  "triggers": [
    {
      "code": "FIRST_DELIVERY",
    }
  ]
}
This initial delivery:
  • Occurs after vehicle subscription to a webhook
  • Contains all subscribed signals at their current values
  • Does not indicate any signal value changes
  • Helps establish baseline state for your application
This initial delivery typically occurs within seconds of subscription, but may be delayed if:
  • The vehicle is offline or not communicating with the OEM
When FIRST_DELIVERY is sent again:
  • When a vehicle is unsubscribed and then resubscribed to your webhook
  • If your endpoint fails to respond with a 2xx status code, Smartcar will retry delivery with the same FIRST_DELIVERY trigger
Use the triggers field to determine the delivery reason. Check for "code": "FIRST_DELIVERY" to identify initial state deliveries versus change-triggered deliveries.

Payload Structure

eventId
string
required
Unique identifier for this event. Use this for idempotency.
eventType
string
required
Always "VEHICLE_STATE" for this event type.
data
object
required
Container for event data.
meta
object
required
Webhook delivery metadata

Example Payloads

Delivered when a configured trigger signal changes value.
{
  "eventId": "550e8400-e29b-41d4-a716-446655440000",
  "eventType": "VEHICLE_STATE",
  "data": {
    "user": {
      "id": "93b3ea96-ca37-43a9-9073-f4334719iok7"
    },
    "vehicle": {
      "id": "9af13248-3b73-4c9d-9a4b-d937ce6bc8e2",
      "make": "TESLA",
      "model": "Model 3",
      "year": 2020
    },
    "triggers": [
      {
        "code": "tractionbattery-stateofcharge",
        "name": "StateOfCharge",
        "group": "TractionBattery"
      }
    ],
    "signals": [
      {
        "code": "tractionbattery-stateofcharge",
        "name": "StateOfCharge",
        "group": "TractionBattery",
        "body": {
          "unit": "percent",
          "value": 78
        },
        "meta": {
          "oemUpdatedAt": 1731940328000,
          "fetchedAt": 1731940330000
        }
      },
      {
        "code": "charge-ischarging",
        "name": "IsCharging",
        "group": "Charge",
        "body": {
          "value": true
        },
        "meta": {
          "oemUpdatedAt": 1731940328000,
          "fetchedAt": 1731940330000
        }
      },
      {
        "code": "charge-voltage",
        "name": "Voltage",
        "group": "Charge",
        "body": {
          "unit": "volts",
          "value": 240
        },
        "meta": {
          "oemUpdatedAt": 1731940328000,
          "fetchedAt": 1731940330000
        }
      }
    ]
  },
  "meta": {
    "version": "4.0",
    "deliveryId": "48b25f8f-9fea-42e1-9085-81043682cbb8",
    "deliveredAt": 1731940328000,
    "webhookId": "abde94ff-d57d-43b9-8d09-6020db2d977a",
    "webhookName": "Battery Monitoring",
    "signalCount": 3,
    "mode": "LIVE"
  }
}

Signal Reference

The signals array contains data structured according to the Signals Schema Reference. Each signal type has a specific shape:

Signal-Level Errors

Individual signals within a VEHICLE_STATE payload can contain errors if the vehicle doesn’t support that signal or if retrieval fails. When this occurs, the signal will have a status object with error details instead of a body with data:
{
  "code": "location-isathome",
  "name": "IsAtHome",
  "group": "Location",
  "status": {
    "error": {
      "code": "VEHICLE_NOT_CAPABLE",
      "type": "COMPATIBILITY"
    },
    "value": "ERROR"
  }
}
Partial data delivery: When some signals succeed and others fail, you’ll receive a VEHICLE_STATE event with successful signals containing body data and failed signals containing status errors. This allows you to process available data even when some signals are unavailable.
For a complete list of possible error codes and types, see the VEHICLE_ERROR section below.

VEHICLE_ERROR

Triggered when Smartcar encounters an error while attempting to retrieve signal data from a vehicle. This event helps you monitor data availability and handle errors gracefully.

When This Event Fires

The VEHICLE_ERROR event fires when:
  1. Smartcar detects an error while retrieving signal data
  2. The vehicle manufacturer’s API returns an error
  3. The vehicle is offline or unreachable
  4. Authentication, permission, or compatibility errors occur

Error Categories

Errors are categorized by type and include specific error codes:
Issues with the user’s account with the vehicle manufacturer.
TypeCodeDescription
CONNECTED_SERVICES_ACCOUNTACCOUNT_ISSUEGeneral account problem
CONNECTED_SERVICES_ACCOUNTAUTHENTICATION_FAILEDAuthentication credentials are invalid
CONNECTED_SERVICES_ACCOUNTPERMISSIONUser lacks necessary permissions
CONNECTED_SERVICES_ACCOUNTSUBSCRIPTIONRequired subscription is inactive or expired
CONNECTED_SERVICES_ACCOUNTVIRTUAL_KEY_REQUIREDVehicle requires a virtual key to be configured
Issues with the vehicle’s connectivity or state.
TypeCodeDescription
VEHICLE_STATEREMOTE_ACCESS_DISABLEDRemote access is disabled on the vehicle
VEHICLE_STATEASLEEPVehicle is in sleep mode
VEHICLE_STATEUNREACHABLEVehicle is not connected to the internet
Issues with signal availability for the specific vehicle.
TypeCodeDescription
COMPATIBILITYMAKE_NOT_COMPATIBLEVehicle manufacturer doesn’t support this signal
COMPATIBILITYSMARTCAR_NOT_CAPABLESmartcar cannot retrieve this signal yet
COMPATIBILITYVEHICLE_NOT_CAPABLEThis specific vehicle doesn’t support the signal
Issues with granted permissions.
TypeCodeDescription
PERMISSIONnullRequired permission not granted by user

Payload Structure

eventId
string
required
Unique identifier for this event. Use this for idempotency.
eventType
string
required
Always "VEHICLE_ERROR" for this event type.
data
object
required
Container for event data.
meta
object
required
Webhook delivery metadata (same structure as VEHICLE_STATE)

Example Payload

{
  "eventId": "5a537912-9ad3-424b-ba33-65a1704567e9",
  "eventType": "VEHICLE_ERROR",
  "data": {
    "user": {
      "id": "93b3ea96-ca37-43a9-9073-f4334719iok7"
    },
    "errors": [
      {
        "type": "COMPATIBILITY",
        "code": "VEHICLE_NOT_CAPABLE",
        "state": "ERROR",
        "description": "The vehicle is incapable of performing your request.",
        "suggestedUserMessage": "Your car is unable to perform this request.",
        "docURL": "https://smartcar.com/docs/errors/api-errors/compatibility-errors#vehicle-not-capable",
        "resolution": {
          "type": "CONTACT_SUPPORT"
        },
        "signals": [
          {
            "code": "location-preciselocation",
            "name": "PreciseLocation",
            "group": "Location"
          },
          {
            "code": "tractionbattery-stateofcharge",
            "name": "StateOfCharge",
            "group": "TractionBattery"
          }
        ]
      }
    ],
    "vehicle": {
      "id": "123e4567-e89b-12d3-a456-426614174000",
      "make": "TESLA",
      "model": "Model 3",
      "year": 2020
    }
  },
  "meta": {
    "version": "4.0",
    "deliveryId": "48b25f8f-9fea-42e1-9085-81043682cbb8",
    "deliveredAt": 1761896351529,
    "webhookId": "123e4567-e89b-12d3-a456-426614174000",
    "webhookName": "Bad Webhook",
    "mode": "LIVE"
  }
}

Error Handling Best Practices

Log and Monitor

Track error patterns to identify systemic issues or vehicles requiring attention

Retry with Backoff

For transient errors (ASLEEP, UNREACHABLE), implement exponential backoff retries

User Notifications

Use suggestedUserMessage to notify vehicle owners when action is required

Graceful Degradation

Handle missing data gracefully in your application UI
Use the docURL field in error payloads to link users to detailed troubleshooting documentation.

Common Error Scenarios

ScenarioTypeCodeRecommended Action
Vehicle offlineVEHICLE_STATEUNREACHABLERetry later; notify user if persistent
User revoked permissionsCONNECTED_SERVICES_ACCOUNTPERMISSIONPrompt user to re-authenticate
Connected services subscription expiredCONNECTED_SERVICES_ACCOUNTSUBSCRIPTIONDirect user to renew manufacturer subscription
Signal not supportedCOMPATIBILITYVEHICLE_NOT_CAPABLERemove signal from webhook or handle gracefully
Vehicle asleepVEHICLE_STATEASLEEPRetry later; avoid waking vehicle unnecessarily

Error Resolution

When an error condition is resolved (e.g., a vehicle comes back online or a user renews their subscription), Smartcar sends another VEHICLE_ERROR event with state set to "RESOLVED":
{
  "eventId": "8d9e0f1a-2b3c-4d5e-6f7a-8b9c0d1e2f3a",
  "eventType": "VEHICLE_ERROR",
  "data": {
    "user": {
      "id": "93b3ea96-ca37-43a9-9073-f4334719iok7"
    },
    "errors": [
      {
        "type": "VEHICLE_STATE",
        "code": "UNREACHABLE",
        "state": "RESOLVED",
        "description": "The vehicle is now reachable.",
        "signals": [
          {
            "code": "location-preciselocation",
            "name": "PreciseLocation",
            "group": "Location"
          }
        ]
      }
    ],
    "vehicle": {
      "id": "123e4567-e89b-12d3-a456-426614174000",
      "make": "TESLA",
      "model": "Model 3",
      "year": 2020
    }
  },
  "meta": {
    "version": "4.0",
    "deliveryId": "9f8e7d6c-5b4a-3c2b-1d0e-9f8e7d6c5b4a",
    "deliveredAt": 1761898351529,
    "webhookId": "123e4567-e89b-12d3-a456-426614174000",
    "webhookName": "Battery Monitoring",
    "mode": "LIVE"
  }
}
Track error state: Use the state field to differentiate between new errors ("ERROR") and resolved issues ("RESOLVED"). This allows you to implement automatic recovery workflows and user notifications.

Event Delivery Guarantees

All webhook events follow these delivery characteristics:
  • At-least-once delivery: Events may be delivered more than once. Use eventId for deduplication.
  • Ordering: Events are not guaranteed to arrive in chronological order. Use timestamps to determine sequence.
  • Idempotency: The eventId field remains constant across delivery retries for the same event.
  • Retries: Failed deliveries are retried with exponential backoff up to 3 days.
See Delivery Behavior for complete details.