Fleet AI Partner API
This reference covers the full integration surface for Fleet AI marketplace partners. Use it to send vehicle telemetry, receive breakdown risk predictions, register webhooks, and notify Fleet AI when maintenance is performed so vehicle baselines stay calibrated.
X-API-Key credentials. The key must have tier partner_ml to access prediction endpoints.
How it works
Your platform sends telemetry samples to POST /api/partner/predict. Fleet AI returns a risk assessment and maintenance guidance for use inside your product. Response time depends on service availability and request size. The API does not provide access to model files or another customer's records.
Use POST /api/partner/predict/batch for up to 50 vehicles and 20,000 submitted samples per call, within the 256 KB request-body limit. At most 1,000 samples per vehicle are processed. Register a webhook to receive risk notifications.
Keep your API key on your server, never in browser code, a mobile app, URLs, or source control. Access is assigned by Fleet AI; knowing an endpoint URL does not grant access. Keys assigned to the same organization share that organization's partner data. Use separate organizations for unrelated customers.
Browser widgets use one-time tickets from POST /api/partner/stream-ticket. Your backend must authenticate the user and authorize the requested vehicle before obtaining a ticket. Send {"vehicleId":"truck-2701"} to restrict the ticket to that vehicle; omitting it grants organization-wide stream access. Tickets expire after 60 seconds and are consumed once. Open streams recheck key access every 25 seconds, fail closed if it cannot be verified within the 35-second authorization lease, and reconnect with a fresh ticket after 15 minutes. Each key is limited to 20 outstanding tickets and five simultaneous streams per server process.
Quickstart
Get a risk prediction for one vehicle in under 5 minutes.
Step 1 — Make your first prediction
Send the last few telemetry readings for a vehicle. At minimum you need vehicleId and one sample with at least one recognized metric field.
curl -X POST https://your-domain.com/api/partner/predict \ -H "X-API-Key: fai_your_key_here" \ -H "Content-Type: application/json" \ -d '{ "vehicleId": "truck-2701", "samples": [ { "ts": "2026-06-06T10:00:00Z", "rpm": 1850, "coolantTemp": 94, "batteryVoltage": 14.1, "engineLoad": 67, "vehicleSpeed": 58, "fuelRate": 8.2 } ], "vehicleMeta": { "year": 2019, "make": "Freightliner", "model": "Cascadia", "vehicleClass": "heavy" } }'
Step 2 — Read the response
The key fields to display in your UI are riskProbability, prediction, advisoryText, and diagnosis.primarySubsystem.
{ "success": true, "vehicleId": "truck-2701", "riskProbability": 0.82, // 0–1. ≥0.75 = critical, 0.35–0.74 = warning "prediction": "breakdown_risk", // see Data types section "confidence": 0.94, "advisoryText": "Cooling system showing progressive degradation. Thermostat response has slowed over the last 14 days.", "diagnosis": { "primarySubsystem": "cooling_system", "rootCause": "Thermostat response delay combined with sustained coolant temp elevation", "confidence": 0.91 }, "stageSystem": { "confirmed": true, "signalAgreement": 0.89 }, "modelInfo": { "predictionSource": "python_ensemble", "latencyMs": 342 } }
Step 3 — Register a webhook (optional but recommended)
Instead of polling, let Fleet AI push a notification when a vehicle crosses the critical threshold.
curl -X POST https://your-domain.com/api/partner/webhooks \ -H "X-API-Key: fai_your_key_here" \ -H "Content-Type: application/json" \ -d '{ "url": "https://hooks.your-platform.com/fleetai", "events": ["risk_threshold_crossed", "stage2_confirmed"], "threshold": 0.75 }'
secret from the response — it's shown once. Use it to verify X-FleetAI-Signature headers on incoming payloads.Authentication
All partner API requests must include your API key in the X-API-Key request header. Keys use the prefix fai_ followed by 48 hex characters.
X-API-Key: fai_a3f9c2d8e14b...
Keys are tier-gated. Prediction endpoints require tier partner_ml. A key with the wrong tier returns HTTP 403 with code INSUFFICIENT_TIER.
Base URL & versioning
All partner endpoints are under /api/partner/. There is no version prefix in the path — the API version is communicated via the X-FleetAI-Version response header and the api_version field in webhook payloads.
Breaking changes are announced with at least 60 days notice. Non-breaking additions (new fields, new event types) are made without notice and your integration should ignore unknown fields.
POST /api/partner/predict
Score a single vehicle. Send the last N telemetry readings and receive a breakdown risk probability, component diagnosis, and recommended action.
Request body
| Field | Type | Description |
|---|---|---|
| vehicleIdrequired | string | Your internal vehicle identifier. Used to track per-vehicle baselines. |
| samplesrequired | array | Array of telemetry readings. See metric field aliases below. Max 5000 samples. |
| dtcCodesoptional | string[] | Active OBD-II or J1939 fault codes (e.g. "P0128"). Improves diagnosis accuracy significantly. |
| vehicleMetaoptional | object | Year, make, model, VIN, vehicleClass. Used for fleet normalization comparisons. |
Accepted metric field names
Each sample object accepts the following metric fields. Aliases are all treated equivalently.
| Canonical | Accepted aliases |
|---|---|
| rpm | rpm, engineRpm, engine_rpm |
| coolantTemp | coolantTemp, coolant_temp, engine_temp |
| batteryVoltage | batteryVoltage, battery_voltage |
| engineLoad | engineLoad, engineLoadPct, engine_load |
| vehicleSpeed | vehicleSpeed, speed, speedKph |
| fuelRate | fuelRate, fuelRateLph, fuel_rate |
| oilTemp | oilTemp, oil_temp |
| dpfSootLoad | dpfSootLoad, dpf_soot, dpfSootLoadPct |
| intakeAirTemp | intakeAirTemp, iat |
| throttlePos | throttlePos, throttlePosPct |
Response fields
| Field | Type | Description |
|---|---|---|
| riskProbability | number | 0.0–1.0. Primary signal. ≥0.75 = critical, 0.35–0.74 = warning, <0.35 = healthy. |
| prediction | string | breakdown_risk, normal, insufficient_data |
| confidence | number | Model confidence 0.0–1.0. Below 0.6 treat as indicative, not definitive. |
| advisoryText | string | Human-readable explanation ready to display in your UI. |
| diagnosis | object | primarySubsystem, rootCause, confidence. May be null when data is thin. |
| activeFaults | object|null | DTC analysis: codes, riskScore, systemsAffected, topCodes. Null if no DTCs sent. |
| stageSystem | object|null | Additional model assessment when available. confirmed: true is a model result, not a confirmed mechanical failure or proof of field accuracy. |
| sensorRisks | object | Per-metric risk scores from the EWMA baseline model. Useful for drilling into which sensor drove the prediction. |
| modelInfo | object | predictionSource, latencyMs, sampleCount, mlServiceAvailable. |
POST /api/partner/predict/batch
Score up to 50 vehicles in a single request, subject to the 20,000-sample and 256 KB body limits. Use this for fleet sweeps or on-demand health checks.
{ "vehicles": [ { "vehicleId": "truck-2701", "samples": [ { ... } ], "dtcCodes": ["P0128"], "vehicleMeta": { ... } }, { "vehicleId": "van-044", "samples": [ { ... } ] } ] }
{ "success": true, "processed": 2, "summary": { "critical": 1, "warning": 0, "healthy": 1, "errors": 0 }, "vehicles": [ { "vehicleId": "truck-2701", "riskProbability": 0.82, "prediction": "breakdown_risk", "success": true, /* ... */ }, { "vehicleId": "van-044", "riskProbability": 0.18, "prediction": "normal", "success": true } ], "latencyMs": 580 }
Vehicles that fail validation (missing vehicleId, no samples) return success: false with an error string in that vehicle's entry. The overall request still returns HTTP 200.
GET /api/partner/fleet
Returns all vehicles scored in the last 24 hours, sorted by riskProbability descending — highest risk first. Useful for building a fleet-wide risk dashboard.
| Query param | Type | Default | Description |
|---|---|---|---|
| limit | integer | 100 | Max vehicles to return. Maximum 500. |
| minRisk | number | 0 | Filter to vehicles with riskProbability ≥ this value. Use 0.35 to see only at-risk vehicles. |
{ "success": true, "partner": "motive", "asOf": "2026-06-06T10:00:00Z", "summary": { "critical": 3, "warning": 8, "healthy": 142, "total": 153 }, "vehicles": [ { "vehicleId": "truck-2701", "riskProbability": 0.82, "confidence": 0.94, "prediction": "breakdown_risk", "advisoryText": "Cooling system showing progressive degradation.", "stage2Confirmed": true, "topSignal": "coolantTemp", "lastSeenAt": "2026-06-06T09:45:00Z" } ] }
GET /api/partner/status
Check whether the ML service has sufficient data for a vehicle before sending a prediction request. Useful to surface a "Not enough data yet" state in your UI rather than a low-confidence result.
GET /api/partner/status?vehicleId=truck-2701
{ "success": true, "vehicleId": "truck-2701", "status": { "mlServiceAvailable": true, "modelLoaded": true, "sampleCount": 420, "baselineEstablished": true } }
GET /api/partner/vehicles/:vehicleId/history
Risk score trend for a vehicle over the last N days. Returns a time-series of risk probabilities with trend analysis (improving / stable / deteriorating).
| Query param | Type | Default | Description |
|---|---|---|---|
| days | integer | 30 | History window in days. Maximum 90. |
{ "vehicleId": "truck-2701", "days": 30, "trend": "deteriorating", // improving | stable | deteriorating | insufficient_data "averageRisk7d": 0.7412, "dataPoints": 84, "history": [ { "ts": "2026-05-07T10:00:00Z", "riskProbability": 0.31, "prediction": "normal" }, { "ts": "2026-06-06T10:00:00Z", "riskProbability": 0.82, "prediction": "breakdown_risk" } ] }
GET /api/partner/vehicles/:vehicleId/rul
Advisory service-timing estimate based on recent risk history. Requires at least 3 prior prediction data points. This is not a validated time-to-failure forecast; its displayed range is not a statistically validated confidence interval. Arrange qualified inspection when a concern is raised.
{ "vehicleId": "truck-2701", "available": true, "urgency": "high", // critical | high | moderate | stable | improving "estimatedDaysToService": 4, "confidenceInterval": { "low": 2, "high": 5 }, "currentRisk": 0.82, "degradationRate": 0.042, // risk increase per day "drivenBySignal": "coolantTemp", "subsystem": "cooling_system", "recommendation": "Schedule cooling_system inspection within 4 days. Monitor closely on every run." }
POST /api/partner/vehicles/:vehicleId/maintenance
Notify Fleet AI that maintenance was performed on a vehicle. This resets the ML baseline for the affected subsystem so the model recalibrates from the vehicle's post-service state rather than continuing to flag a resolved issue.
{ "maintenanceType": "cooling_system", // cooling, battery, oil, brake, dpf, fuel, transmission, tire "description": "Replaced thermostat and coolant flush", "mileage": 142000, "performedAt": "2026-06-05T14:00:00Z", "parts": ["thermostat", "coolant"] }
{ "success": true, "vehicleId": "truck-2701", "resetSignals": ["engine_temp", "coolant_temp_oscillation", "engine_temp_delta_30d"], "note": "Vehicle baseline will recalibrate over the next 50 telemetry observations." }
POST /api/partner/webhooks
Register an HTTPS endpoint to receive real-time fleet events. Fleet AI will POST to your URL when a vehicle crosses your configured risk threshold or a DTC fault is detected.
| Field | Type | Description |
|---|---|---|
| urlrequired | string | HTTPS URL that will receive POST requests. Must be publicly reachable. |
| eventsoptional | string[] | Event types to subscribe to. Defaults to ["risk_threshold_crossed", "stage2_confirmed"]. Pass ["*"] for all events. |
| thresholdoptional | number | Risk probability threshold that triggers risk_threshold_crossed. Default 0.35. Set to 0.75 for critical-only alerts. |
| secretoptional | string | Your own signing secret, or omit to have one generated. Used to compute X-FleetAI-Signature. |
{ "success": true, "webhook": { "id": "wh_clx9a2...", "url": "https://hooks.your-platform.com/fleetai", "events": ["risk_threshold_crossed", "stage2_confirmed"], "threshold":0.75, "secret": "a3f9c2d8e14b...", // shown once — save immediately "active": true }, "note": "Save the secret — it will not be shown again." }
GET /api/partner/webhooks
List all webhooks registered under your API key. The secret field is never returned after initial creation.
DELETE /api/partner/webhooks/:id
Remove a webhook by its ID. Fleet AI will stop delivering events to that URL immediately.
Webhook event payloads
All events POST to your registered URL with Content-Type: application/json. The top-level structure is consistent across event types.
risk_threshold_crossed
Fires when a vehicle's riskProbability crosses the threshold configured on the webhook (default 0.35).
{ "event": "risk_threshold_crossed", "vehicleId": "truck-2701", "partner": "motive", "riskProbability": 0.82, "prediction": "breakdown_risk", "advisoryText": "Cooling system showing progressive degradation.", "diagnosis": { "primarySubsystem": "cooling_system", /* ... */ }, "timestamp": "2026-06-06T10:22:00Z" }
stage2_confirmed
Fires when a second independent model confirms the risk. This is the highest-confidence signal Fleet AI produces — treat it as a definitive service recommendation.
dtc_critical
Fires when a DTC code associated with high-risk system failure is detected (e.g. P0217 — engine overtemp, P0087 — fuel pressure low).
Signature verification
Every webhook request includes an X-FleetAI-Signature header. Verify it before processing the payload to ensure the request came from Fleet AI and was not tampered with.
const crypto = require('crypto'); function verifyFleetAI(req, secret) { const signature = req.headers['x-fleetai-signature']; const body = JSON.stringify(req.body); const expected = 'sha256=' + crypto .createHmac('sha256', secret) .update(body) .digest('hex'); return crypto.timingSafeEqual( Buffer.from(signature), Buffer.from(expected) ); } // In your Express route: app.post('/hooks/fleetai', (req, res) => { if (!verifyFleetAI(req, process.env.FLEETAI_WEBHOOK_SECRET)) { return res.status(401).send('Invalid signature'); } const { event, vehicleId, riskProbability } = req.body; // handle event... res.status(200).send('ok'); });
crypto.timingSafeEqual, not ===. String comparison is vulnerable to timing attacks.Fleet AI retries failed deliveries up to 3 times with exponential backoff (1s, 2s). Return HTTP 200 to acknowledge receipt. Any non-2xx status triggers a retry.
Data types
prediction values
breakdown_riskModel detected developing fault pattern. Action required.
normalNo anomalies detected against vehicle baseline.
insufficient_dataFewer than 10 samples sent. Result is low confidence.
riskProbability thresholds
| Range | Label | Recommended action |
|---|---|---|
0.75 – 1.00 | Critical | Do not dispatch. Schedule inspection immediately. |
0.35 – 0.74 | Warning | Flag for maintenance within service window. |
0.00 – 0.34 | Healthy | No action required. Continue monitoring. |
urgency values (RUL endpoint)
criticalRisk already at or above critical threshold. Service immediately.
highWill reach critical within 7 days at current rate.
moderateWill reach warning threshold within 21 days.
stableNo significant degradation trend detected.
improvingRisk decreasing, likely post-maintenance recovery.
Error codes
All errors return a consistent JSON envelope:
{ "success": false, "error": { "code": "MISSING_VEHICLE_ID", "message": "vehicleId is required." } }
| HTTP | Code | Meaning |
|---|---|---|
| 401 | API_KEY_MISSING | No X-API-Key header sent. |
| 403 | API_KEY_INVALID | Key does not exist or has been revoked. |
| 403 | INSUFFICIENT_TIER | Key tier does not allow this endpoint. Contact Fleet AI to upgrade. |
| 400 | MISSING_VEHICLE_ID | Required field vehicleId not provided. |
| 400 | NO_SAMPLES | The samples array was empty. |
| 400 | NO_VALID_METRICS | Samples contained no recognized metric field names. |
| 400 | BATCH_TOO_LARGE | Batch request exceeded 200 vehicles. |
| 400 | MISSING_URL | Webhook registration missing url field. |
| 400 | INVALID_URL | Webhook URL is not a valid HTTPS URL. |
| 500 | SERVER_ERROR | Internal error. Retry after a short delay. Contact support if persistent. |
Rate limits
Rate limits are applied per API key. Current limits for partner_ml tier:
| Endpoint | Limit | Window |
|---|---|---|
POST /predict | 600 requests | Per minute |
POST /predict/batch | 60 requests | Per minute |
GET /fleet | 120 requests | Per minute |
All other endpoints | 300 requests | Per minute |
Rate limit headers are not currently sent in responses. If you hit a limit, you will receive HTTP 429. Implement exponential backoff starting at 1 second.
Changelog
| Date | Change |
|---|---|
2026-06-06 | Bug fixes: per-webhook threshold field now respected (webhooks below a partner's configured threshold are suppressed); fleet view now returns advisoryText and stageSystem data; webhook retry backoff corrected to 1s, 2s, 4s. |
2026-06-01 | Initial partner API release. Endpoints: predict, predict/batch, fleet, status, webhooks, history, rul, maintenance. |