A one-time event sent when you first create a webhook to verify that Smartcar can successfully deliver payloads to your callback URL.
Required Before Data Delivery Your endpoint must successfully respond to the VERIFY event before Smartcar will deliver any VEHICLE_STATE or VEHICLE_ERROR events. This confirms your endpoint is configured correctly and ready to receive webhooks.
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
Version 4.0 (Current)
Version 2.0 (Legacy)
{
"eventId" : "52f6e0bb-1369-45da-a61c-9e67d092d6db" ,
"eventType" : "VERIFY" ,
"data" : {
"challenge" : "3a5c8f72-e6d9-4b1a-9f2e-8c7d6a5b4e3f"
},
"meta" : {
"version" : "4.0" ,
"webhookId" : "5a8e5e38-1e12-4011-a36d-56f120053f9e" ,
"webhookName" : "Example Webhook" ,
"deliveryId" : "5d569643-3a47-4cd1-a3ec-db5fc1f6f03b" ,
"deliveredAt" : 1761896351529
}
}
{
"version" : "2.0" ,
"webhookId" : "5a8e5e38-1e12-4011-a36d-56f120053f9e" ,
"eventName" : "verify" ,
"payload" : {
"challenge" : "3a5c8f72-e6d9-4b1a-9f2e-8c7d6a5b4e3f"
}
}
Payload Fields
Unique identifier for this verification event.
Always "VERIFY" for this event type.
Container for the challenge. Random string that must be hashed with your Application Management Token and returned in your response.
Required Response
Your endpoint must respond with:
Status code : 200 OK
Content-Type header : application/json
Response body : JSON object with the HMAC-SHA256 hash
{
"challenge" : "a3f5c8e9d2b4a1f6e8c7d9a5b3e1f2c4d6a8b9c1e3f5a7b9c2d4e6f8a1b3c5d7"
}
Generate the HMAC
Create an HMAC-SHA256 hash of the challenge string using your Application Management Token as the secret key, then hex-encode the result:
Our backend SDKs have helper methods to generate the HMAC automatically.
import smartcar
hmac = smartcar.hash_challenge(
application_management_token,
challenge
)
# Return in response body
return { "challenge" : hmac}, 200
const smartcar = require ( 'smartcar' );
const hmac = smartcar . hashChallenge (
application_management_token ,
challenge
);
// Return in response body
res . status ( 200 ). json ({ challenge: hmac });
import com.smartcar.sdk.Smartcar;
String hmac = Smartcar . hashChallenge (
application_management_token,
challenge
);
// Return in response body
return ResponseEntity . ok ( Map . of ( "challenge" , hmac));
require 'smartcar'
hmac = Smartcar . hash_challenge (
application_management_token,
challenge
)
# Return in response body
{ challenge: hmac }
Complete Handler Example
Here’s a complete webhook handler that responds to the VERIFY event:
Node.js (Express)
Python (Flask)
Java (Spring Boot)
Ruby (Sinatra)
const express = require ( 'express' );
const smartcar = require ( 'smartcar' );
const app = express ();
app . use ( express . json ());
app . post ( '/webhooks/smartcar' , ( req , res ) => {
const { eventType , data } = req . body ;
if ( eventType === 'VERIFY' ) {
// Generate HMAC challenge response
const hmac = smartcar . hashChallenge (
process . env . SMARTCAR_MANAGEMENT_TOKEN ,
data . challenge
);
return res . status ( 200 ). json ({ challenge: hmac });
}
// Handle other event types...
res . status ( 200 ). json ({ status: 'received' });
});
from flask import Flask, request, jsonify
import smartcar
import os
app = Flask( __name__ )
@app.post ( '/webhooks/smartcar' )
def webhook_handler ():
payload = request.get_json()
event_type = payload.get( 'eventType' )
if event_type == 'VERIFY' :
# Generate HMAC challenge response
hmac = smartcar.hash_challenge(
os.environ[ 'SMARTCAR_MANAGEMENT_TOKEN' ],
payload[ 'data' ][ 'challenge' ]
)
return jsonify({ "challenge" : hmac}), 200
# Handle other event types...
return jsonify({ "status" : "received" }), 200
@ RestController
public class WebhookController {
@ Value ( "${smartcar.management.token}" )
private String managementToken ;
@ PostMapping ( "/webhooks/smartcar" )
public ResponseEntity < ? > handleWebhook (@ RequestBody Map < String , Object > payload ) {
String eventType = (String) payload . get ( "eventType" );
if ( "VERIFY" . equals (eventType)) {
// Generate HMAC challenge response
Map < String , Object > data = ( Map < String, Object > ) payload . get ( "data" );
String challenge = (String) data . get ( "challenge" );
String hmac = Smartcar . hashChallenge (managementToken, challenge);
return ResponseEntity . ok ( Map . of ( "challenge" , hmac));
}
// Handle other event types...
return ResponseEntity . ok ( Map . of ( "status" , "received" ));
}
}
require 'sinatra'
require 'json'
require 'smartcar'
post '/webhooks/smartcar' do
payload = JSON . parse (request. body . read )
event_type = payload[ 'eventType' ]
if event_type == 'VERIFY'
# Generate HMAC challenge response
hmac = Smartcar . hash_challenge (
ENV [ 'SMARTCAR_MANAGEMENT_TOKEN' ],
payload[ 'data' ][ 'challenge' ]
)
status 200
content_type :json
return { challenge: hmac }. to_json
end
# Handle other event types...
status 200
content_type :json
{ status: 'received' }. to_json
end
Troubleshooting
Verification fails in Dashboard
Common causes:
Wrong Application Management Token used
HMAC not hex-encoded
Response body doesn’t match { "challenge": "..." } format
Endpoint returns non-200 status code
Response takes longer than 15 seconds
Solution: Use the Dashboard’s verification modal to see the expected challenge and response. Compare your implementation against the provided code snippets.
How do I test VERIFY locally?
Use ngrok or similar to expose your local server: Then use the ngrok URL as your callback URI in the Dashboard. The Dashboard will send a real VERIFY event to your local endpoint.
Can I re-verify my webhook?
Yes! You can click “Verify this webhook” in the Dashboard at any time to send a new VERIFY event to your endpoint.
Do I need to handle VERIFY in production?
Yes, your production webhook endpoint should always handle the VERIFY event type, even after initial verification. This allows you to re-verify from the Dashboard if needed.
Timeout Requirement Your endpoint must respond to the VERIFY event within 15 seconds . If verification times out, Smartcar will not activate the webhook.
Next Steps
After successfully responding to the VERIFY event, your webhook is activated and will begin receiving vehicle data.
VEHICLE_STATE Event Learn about signal data deliveries
VEHICLE_ERROR Event Handle error notifications
Callback Verification Guide Complete step-by-step implementation
Receiving Webhooks Build a complete webhook handler