Table of Contents
Prerequisites
Before using webhooks:
Webhooks must be enabled via Enable Webhook Notifications
The API Access license package must be active
You must provide a valid HTTPS endpoint that accepts
POSTrequests
Webhook Creation
Webhooks are managed in:
/en/administration/settings/webhooks
Step 1: Enable Webhooks Globally
Go to the Webhooks administration page
Toggle Enable Webhook Notifications
Save your changes
⚠️ If this is disabled, no webhooks will be sent.
Step 2: Create a New Webhook
Click + Add New Webhook and configure:
Field | Description |
Type | Choose one of the available webhook types |
Secret Key | 32-character hex key (auto-generated) |
Label | Internal name for identification |
URL | Full webhook endpoint URL |
Custom Headers | Optional additional HTTP headers |
Supported webhook types:
Customer Profile Update Notification
Run Results Notification
Session Results Notification
Click ✓ Save Webhook to activate.
Managing Webhooks
You can:
Edit existing webhooks
Delete webhooks
View webhook delivery logs
Webhooks become active immediately after saving.
How Webhooks Work
Flow Overview
Event Occurs > Check if Webhooks Enabled > Generate JSON Payload > Queue Background Job > Send HTTP POST > Log Response > Retry if Failed (max 3 times)
Delivery Timing
Webhook Type | When It Is Sent |
Customer Profile Update | Immediately |
Run Results | 4 minutes after run completion |
Session Results | 4 minutes after session completion |
The delay ensures race data is fully processed before delivery.
Webhook Types
1. Customer Profile Update
Type ID: 1
Topic: customer-profile-update
Trigger: Profile created or updated
Delay: None
Payload Structure
{
"topic": "customer-profile-update",
"data": {
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"first_name": "John",
"last_name": "Doe",
"nickname": "Johnny",
"email": "[email protected]",
"dob": "1990-05-15",
"country": "US",
"zip_code": "12345",
"phone_code": "1",
"phone_number": "5551234567",
"external_id": null,
"wristband_number": "WB123456",
"gender": "m",
"guardian_first_name": null,
"guardian_last_name": null,
"guardian_dob": null,
"allowed_speedsets": [
"550e8400-e29b-41d4-a716-446655440001",
"550e8400-e29b-41d4-a716-446655440002"
],
"total_heats": 15,
"total_visits": 8,
"loyalty_points": 250,
"last_best_lap": "1:23.456",
"last_best_lap_times": [
{
"track_configuration_uuid": "550e8400-e29b-41d4-a716-446655440003",
"last_best_lap": "1:23.456"
}
],
"avatar": "http://fasttrack.test/assets/images/avatars/550e8400-e29b-41d4-a716-446655440000.jpg",
"created_at": "2026-01-15 10:30:14",
"updated_at": "2026-02-13 14:03:24",
"erp_values": [],
"notes": [
{
"message": "VIP customer",
"created_at": "2026-02-10 12:00:00",
"is_warning": false
}
],
"can_email": true,
"can_show_photo": true,
"city": "New York"
}
}Key Data Fields
Field | Type | Description |
uuid | string | Customer UUID |
first_name | string | First name |
last_name | string | Last name |
string | Email address | |
dob | string | Date of birth (YYYY-MM-DD) |
total_heats | integer | Total runs completed |
total_visits | integer | Total visits |
loyalty_points | integer|null | Loyalty balance |
last_best_lap | string|null | Best lap (M:SS.mmm) |
avatar | string | Avatar image URL |
created_at | string | Creation timestamp |
updated_at | string | Last update timestamp |
can_email | boolean | Email consent |
can_show_photo | boolean | Photo consent |
Additional arrays:
allowed_speedsetslast_best_lap_timesnoteserp_values
2. Run Results Notification
Type ID: 2
Topic: run-results
Trigger: Individual run finishes
Delay: 4 minutes
Payload Overview
{
"topic": "session-results",
"data": {
"scheduled_at": "2026-02-13 15:00:00",
"uuid": "550e8400-e29b-41d4-a716-446655440010",
"start_time": "2026-02-13 15:05:23",
"end_time": "2026-02-13 15:15:45",
"rank_type": "Best Time",
"track_configuration": {
"name": "Main Track",
"uuid": "550e8400-e29b-41d4-a716-446655440011"
},
"sub_track": {
"name": "North Section",
"uuid": "550e8400-e29b-41d4-a716-446655440012"
},
"speedset": {
"name": "Standard Speed",
"uuid": "550e8400-e29b-41d4-a716-446655440015"
},
"runs": [
{
"position": 1,
"kart": "Kart #42",
"kart_type": {
"name": "Adult Kart",
"uuid": "550e8400-e29b-41d4-a716-446655440013"
},
"client": {
"name": "Jane Smith",
"uuid": "550e8400-e29b-41d4-a716-446655440016"
},
"best_lap": "1:20.123",
"total_time": "10:30.456",
"total_laps": 8,
"uuid": "550e8400-e29b-41d4-a716-446655440017",
"speedset": {
"name": "Standard Speed",
"uuid": "550e8400-e29b-41d4-a716-446655440015"
}
},
{
"position": 2,
"kart": "Kart #15",
"kart_type": {
"name": "Adult Kart",
"uuid": "550e8400-e29b-41d4-a716-446655440013"
},
"client": {
"name": "John Doe",
"uuid": "550e8400-e29b-41d4-a716-446655440000"
},
"best_lap": "1:23.456",
"total_time": "10:45.123",
"total_laps": 8,
"uuid": "550e8400-e29b-41d4-a716-446655440014"
}
]
}
}
Heat Object
Session-level information:
scheduled_at
start_time
end_time
rank_type
track_configuration
sub_track (conditional)
Run Object
Driver-level information:
client (name, uuid)
kart_type
kart
position
total_drivers
best_lap
total_time
speedset (conditional)
laps array
Lap Object
Field | Description |
lap_number | 1-indexed lap number |
time | Lap time or "Pit Box" |
s1–s4 | Sector times |
started_at_decoder_timestamp | Milliseconds timestamp |
3. Session Results Notification
Type ID: 3
Topic: session-results
Trigger: Session/heat completes
Delay: 4 minutes
Payload Overview
{
"topic": "session-results",
"data": {
"scheduled_at": "2026-02-13 15:00:00",
"uuid": "550e8400-e29b-41d4-a716-446655440010",
"start_time": "2026-02-13 15:05:23",
"end_time": "2026-02-13 15:15:45",
"rank_type": "Best Time",
"track_configuration": {
"name": "Main Track",
"uuid": "550e8400-e29b-41d4-a716-446655440011"
},
"sub_track": {
"name": "North Section",
"uuid": "550e8400-e29b-41d4-a716-446655440012"
},
"speedset": {
"name": "Standard Speed",
"uuid": "550e8400-e29b-41d4-a716-446655440015"
},
"runs": [
{
"position": 1,
"kart": "Kart #42",
"kart_type": {
"name": "Adult Kart",
"uuid": "550e8400-e29b-41d4-a716-446655440013"
},
"client": {
"name": "Jane Smith",
"uuid": "550e8400-e29b-41d4-a716-446655440016"
},
"best_lap": "1:20.123",
"total_time": "10:30.456",
"total_laps": 8,
"uuid": "550e8400-e29b-41d4-a716-446655440017",
"speedset": {
"name": "Standard Speed",
"uuid": "550e8400-e29b-41d4-a716-446655440015"
}
},
{
"position": 2,
"kart": "Kart #15",
"kart_type": {
"name": "Adult Kart",
"uuid": "550e8400-e29b-41d4-a716-446655440013"
},
"client": {
"name": "John Doe",
"uuid": "550e8400-e29b-41d4-a716-446655440000"
},
"best_lap": "1:23.456",
"total_time": "10:45.123",
"total_laps": 8,
"uuid": "550e8400-e29b-41d4-a716-446655440014"
}
]
}
}
Important Notes
Only non-canceled runs are included
Runs are ordered by
positionascendingsub_trackandspeedsetare conditional fields
Request Headers
Every webhook request includes:
Standard Headers
Header | Description |
Content-Type | application/json |
rf-secret-key | Webhook secret key |
track-id | Track identifier |
Custom Headers
You may configure additional headers.
Example:
Authorization: Bearer your-api-token
Common use cases:
API authentication
Version control
Tracking
Error Handling & Retries
Expected Success Response
The webhook is considered successful only if your endpoint returns:
HTTP 200 OK
Retry Logic
Maximum 3 retries
Retries occur 1 minute apart
Processed via
webhooksqueue
Retry Flow
Initial Attempt > Failure (non-200) > Retry #1 (after 1 min) > Retry #2 > Retry #3 > Stop
If any retry succeeds (200), retries stop.
Logging
All webhook attempts are logged with:
Webhook ID
URL
Payload
Response code
Response body
Attempt count
Timestamps
Logs are available in the administration interface.
Response Requirements
Your endpoint must:
Accept
POSTAccept JSON body
Return
200 OKRespond within 10 seconds
Validate
rf-secret-key
Recommended Success Response
{ "status": "success", "message": "Webhook received" }To Trigger Retry
Return a non-200 status code:
{ "status": "error", "message": "Temporary error" }Security Best Practices
✅ Validate
rf-secret-key✅ Use HTTPS
✅ Validate payload structure
✅ Implement idempotency (use UUIDs)
✅ Consider rate limiting
✅ Optionally use IP whitelisting
Testing Webhooks
You can test using:
webhook.site
RequestBin
How to Test
Generate a test endpoint
Create a webhook in RaceFacer
Trigger an event
Inspect the received payload
Troubleshooting
If webhooks are not working:
Check webhook logs
Confirm global webhook toggle is enabled
Verify URL accessibility
Confirm correct secret key validation
Ensure your endpoint returns 200
Document Version: 1.0
Last Updated: February 13, 2026
