Messaging & Nearby
Send a free-text message to the mobile app running on a vehicle, and find the mobiles closest to a given point — useful for assigning the nearest unit to a job.
All endpoints require a valid JWT token, API key, and tenant header. See Authentication.
Send Message
Queue a free-text message to the mobile app of a single vehicle. This is fire-and-forget: a success response means the message was queued, not that it was delivered or read. The mobile app picks it up the next time it polls for messages.
/apidev/v1/devices/{vehicle_id}/messagesPath Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
vehicle_id | string | Yes | Vehicle (mobile) unique identifier. Must belong to your tenant. |
Request Body
| Field | Type | Required | Max Length | Description |
|---|---|---|---|---|
text | string | Yes | 500 | Message to send to the mobile. Cannot be empty. |
push | boolean | No | — | Trigger a push notification (default true). |
Today every queued message also fires a push notification, so push: false is accepted but not yet honored. Send true (or omit it) to be future-proof.
Response Fields
| Field | Type | Description |
|---|---|---|
message_id | string | Identifier of the queued message (BigInt as string). May be omitted if the queue did not return one. |
vehicle_id | string | Echo of the target mobile identifier. |
delivery | string | Always "queued" — the message was accepted into the delivery queue. Queued is not the same as delivered or read. |
Code Example
- cURL
- JavaScript
- Python
curl -s -X POST "https://$TENANT/apidev/v1/devices/1013/messages" \
-H "Authorization: Bearer $TOKEN" \
-H "X-API-Key: $APIKEY" \
-H "tenant: $TENANT" \
-H "Content-Type: application/json" \
-d '{
"text": "Head back to base, end of shift."
}'
const response = await fetch(
`https://${TENANT}/apidev/v1/devices/1013/messages`,
{
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"X-API-Key": API_KEY,
"tenant": TENANT,
"Content-Type": "application/json",
},
body: JSON.stringify({ text: "Head back to base, end of shift." }),
}
);
const { data } = await response.json();
console.log(`Message ${data.message_id} → ${data.delivery}`);
response = requests.post(
f"https://{TENANT}/apidev/v1/devices/1013/messages",
headers={**headers, "Content-Type": "application/json"},
json={"text": "Head back to base, end of shift."},
)
data = response.json()["data"]
print(f"Message {data['message_id']} → {data['delivery']}")
Example Response
{
"success": true,
"data": {
"message_id": "8472910",
"vehicle_id": "1013",
"delivery": "queued"
},
"meta": {}
}
If the vehicle has no active device that can receive messages (no active IMEI), the request fails with 409 CONFLICT. This is different from 404, which means the vehicle does not exist in your tenant. Associate an active device with the mobile before sending it messages.
Nearby Mobiles
Find the mobiles closest to a point, sorted by distance. The search is bounded by a radius (up to 50 km) and can be narrowed by GPS freshness, GPS validity, and vehicle type.
/apidev/v1/devices/nearbyThis is a read in spirit, but it carries a structured body (a point plus filters) that does not fit cleanly into query parameters, and it performs a distance computation. It follows the same convention as the report endpoints, which also accept a POST body.
Request Body
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
point | object | Yes | — | Center of the search: { "lat": number, "lng": number }. lat in [-90, 90], lng in [-180, 180]. |
radius_m | number | Yes |