Visibility
Record asset location
Record where a driver, truck, or trailer is from a third-party source, so partner telematics data drives Alvys load and asset tracking alongside first-party ELD feeds.
POST
/
api
/
p
/
v
{version}
/
assets
/
{assetId}
/
locations
Record an asset's current location
curl --request POST \
--url https://integrations.alvys.com/api/p/v{version}/assets/{assetId}/locations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json-patch+json' \
--data '
{
"Coordinates": {
"Latitude": "<string>",
"Longitude": "<string>"
},
"RecordedAt": "2023-11-07T05:31:56Z",
"Address": {
"Street": "<string>",
"City": "<string>",
"State": "<string>",
"ZipCode": "<string>",
"Country": "<string>"
},
"TripId": "<string>",
"Odometer": 123,
"OdometerReadingAt": "2023-11-07T05:31:56Z"
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json-patch+json'},
body: JSON.stringify({
Coordinates: {Latitude: '<string>', Longitude: '<string>'},
RecordedAt: '2023-11-07T05:31:56Z',
Address: {
Street: '<string>',
City: '<string>',
State: '<string>',
ZipCode: '<string>',
Country: '<string>'
},
TripId: '<string>',
Odometer: 123,
OdometerReadingAt: '2023-11-07T05:31:56Z'
})
};
fetch('https://integrations.alvys.com/api/p/v{version}/assets/{assetId}/locations', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://integrations.alvys.com/api/p/v{version}/assets/{assetId}/locations"
payload = {
"Coordinates": {
"Latitude": "<string>",
"Longitude": "<string>"
},
"RecordedAt": "2023-11-07T05:31:56Z",
"Address": {
"Street": "<string>",
"City": "<string>",
"State": "<string>",
"ZipCode": "<string>",
"Country": "<string>"
},
"TripId": "<string>",
"Odometer": 123,
"OdometerReadingAt": "2023-11-07T05:31:56Z"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json-patch+json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://integrations.alvys.com/api/p/v{version}/assets/{assetId}/locations",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'Coordinates' => [
'Latitude' => '<string>',
'Longitude' => '<string>'
],
'RecordedAt' => '2023-11-07T05:31:56Z',
'Address' => [
'Street' => '<string>',
'City' => '<string>',
'State' => '<string>',
'ZipCode' => '<string>',
'Country' => '<string>'
],
'TripId' => '<string>',
'Odometer' => 123,
'OdometerReadingAt' => '2023-11-07T05:31:56Z'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json-patch+json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://integrations.alvys.com/api/p/v{version}/assets/{assetId}/locations"
payload := strings.NewReader("{\n \"Coordinates\": {\n \"Latitude\": \"<string>\",\n \"Longitude\": \"<string>\"\n },\n \"RecordedAt\": \"2023-11-07T05:31:56Z\",\n \"Address\": {\n \"Street\": \"<string>\",\n \"City\": \"<string>\",\n \"State\": \"<string>\",\n \"ZipCode\": \"<string>\",\n \"Country\": \"<string>\"\n },\n \"TripId\": \"<string>\",\n \"Odometer\": 123,\n \"OdometerReadingAt\": \"2023-11-07T05:31:56Z\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json-patch+json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://integrations.alvys.com/api/p/v{version}/assets/{assetId}/locations")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json-patch+json")
.body("{\n \"Coordinates\": {\n \"Latitude\": \"<string>\",\n \"Longitude\": \"<string>\"\n },\n \"RecordedAt\": \"2023-11-07T05:31:56Z\",\n \"Address\": {\n \"Street\": \"<string>\",\n \"City\": \"<string>\",\n \"State\": \"<string>\",\n \"ZipCode\": \"<string>\",\n \"Country\": \"<string>\"\n },\n \"TripId\": \"<string>\",\n \"Odometer\": 123,\n \"OdometerReadingAt\": \"2023-11-07T05:31:56Z\"\n}")
.asString();{
"AssetId": "<string>",
"AssetType": "<string>",
"Source": "<string>",
"Coordinates": {
"Latitude": "<string>",
"Longitude": "<string>"
},
"RecordedAt": "2023-11-07T05:31:56Z",
"ReceivedAt": "2023-11-07T05:31:56Z",
"Address": {
"Street": "<string>",
"City": "<string>",
"State": "<string>",
"ZipCode": "<string>",
"Country": "<string>"
},
"FormattedAddress": "<string>",
"TripId": "<string>",
"TripNumber": "<string>",
"Odometer": 123,
"OdometerReadingAt": "2023-11-07T05:31:56Z"
}{
"Errors": {},
"Type": "<string>",
"Title": "<string>",
"Status": 123,
"Detail": "<string>",
"Instance": "<string>"
}{
"Type": "<string>",
"Title": "<string>",
"Status": 123,
"Detail": "<string>",
"Instance": "<string>"
}{
"Type": "<string>",
"Title": "<string>",
"Status": 123,
"Detail": "<string>",
"Instance": "<string>"
}{
"Type": "<string>",
"Title": "<string>",
"Status": 123,
"Detail": "<string>",
"Instance": "<string>"
}{
"Type": "<string>",
"Title": "<string>",
"Status": 123,
"Detail": "<string>",
"Instance": "<string>"
}{
"Type": "<string>",
"Title": "<string>",
"Status": 123,
"Detail": "<string>",
"Instance": "<string>"
}{
"Type": "<string>",
"Title": "<string>",
"Status": 123,
"Detail": "<string>",
"Instance": "<string>"
}Records where an asset is — position, and optionally the odometer. Use this when an external system knows an asset’s location: a third-party ELD, or a vehicle reporting its own position.
To send speed, fuel, or temperature readings taken at the same moment, use Record asset telemetry instead. This endpoint is position-only by design.
This also makes retries safe: resending a reading you already delivered does not move the asset or fire a duplicate tracking update.
The request body is limited to 8 KB. Send one reading per request.
A
This endpoint requires the
visibility:create scope. See Authentication.assetId is the Alvys id of a driver, truck, or trailer — the Id returned by the drivers, trucks, and trailers endpoints. It is not a unit number.
Ordering and duplicate readings
Positions are ordered per asset byRecordedAt. A reading older than, or equal to, the one already held for this source is discarded and answered 409 Conflict.
A
409 is a normal out-of-order outcome, not a failure. Do not retry it — resending the same reading will keep answering 409. Send the next reading instead.Endpoint
POST /api/p/v{version}/assets/{assetId}/locations
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| version | string | Yes | API version to use (1.0). |
| assetId | string | Yes | Alvys id of the driver, truck, or trailer. Not a unit number. |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| Coordinates | Object | Yes | Where the asset is. A missing, out-of-range, or (0, 0) value is rejected with 400. |
| Coordinates.Latitude | string | Yes | Latitude, as a string. |
| Coordinates.Longitude | string | Yes | Longitude, as a string. |
| RecordedAt | string (datetime) | No | When the reading was taken, ISO-8601. Defaults to the time Alvys receives it. Positions are ordered by this field. |
| Address | Object | No | Street, City, State, ZipCode, Country. Omit it and Alvys resolves an address from the coordinates. |
| TripId | string | No | The trip to attribute the reading to. Omit it and Alvys selects the asset’s active trip with the nearest stop. |
| Odometer | number | No | Odometer reading in miles. |
| OdometerReadingAt | string (datetime) | No | When the odometer was read, ISO-8601. |
Pass
TripId when you know it. On an asset running more than one active trip — a team, drop-and-hook, or multi-stop asset — Alvys otherwise picks the trip with the nearest stop, and the tracking update, ETA, and customer tracking page follow that choice.Example Request Body
{
"Coordinates": {
"Latitude": "32.7767",
"Longitude": "-96.7970"
},
"RecordedAt": "2026-08-21T14:32:00Z",
"Odometer": 154302.5,
"OdometerReadingAt": "2026-08-21T14:32:00Z"
}
Example CURL request
curl --location 'https://integrations.alvys.com/api/p/v1/assets/{assetId}/locations' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"Coordinates": {
"Latitude": "32.7767",
"Longitude": "-96.7970"
},
"RecordedAt": "2026-08-21T14:32:00Z",
"Odometer": 154302.5,
"OdometerReadingAt": "2026-08-21T14:32:00Z"
}'
Response Fields
| Field | Type | Description |
|---|---|---|
| AssetId | string | Alvys id of the asset. |
| AssetType | string | Driver, Truck, or Trailer. |
| Source | string | Tracking source. Always PublicApi for positions submitted through this endpoint. |
| Coordinates.Latitude | string | Latitude of the recorded position. |
| Coordinates.Longitude | string | Longitude of the recorded position. |
| Address | Object | The address you supplied, or the one resolved from the coordinates. |
| FormattedAddress | string | That address as a single display string. |
| RecordedAt | string (datetime) | Observation time the position is ordered by. |
| ReceivedAt | string (datetime) | When Alvys accepted the position. |
| TripId | string | The asset’s trip at the time of the reading, if any. |
| TripNumber | string | Number of that trip, if any. |
| Odometer | number | Odometer reading in miles, as reported. |
| OdometerReadingAt | string (datetime) | When the odometer was read, as reported. |
Example Response
201 Created{
"AssetId": "TR2517179655771527026",
"AssetType": "Truck",
"Source": "PublicApi",
"Coordinates": {
"Latitude": "32.7767",
"Longitude": "-96.7970"
},
"Address": {
"Street": "201 Main St",
"City": "Dallas",
"State": "TX",
"ZipCode": "75201",
"Country": "US"
},
"FormattedAddress": "201 Main St, Dallas, TX 75201",
"RecordedAt": "2026-08-21T14:32:00Z",
"ReceivedAt": "2026-08-21T14:32:04Z",
"TripId": "9d4b1327-2774-d32c-fb33-87a288c2722c",
"TripNumber": "T-100234",
"Odometer": 154302.5,
"OdometerReadingAt": "2026-08-21T14:32:00Z"
}
Status Codes
| Status | Description |
|---|---|
| 201 | Position recorded. |
| 400 | Invalid body — missing, out-of-range, or (0, 0) coordinates, or a malformed field. |
| 401 | Missing or invalid access token. |
| 403 | Token lacks the visibility:create scope. |
| 404 | Asset not found, or outside your credential’s subsidiary scope. |
| 409 | A newer position is already recorded for this asset from this source. The reading was discarded. Do not retry. |
| 422 | RecordedAt is more than 5 minutes ahead of the server clock. A future-dated reading would suppress every later position for this asset until real time caught up. |
| 429 | Rate limit exceeded. |
409 carries the error type https://api.alvys.com/errors/Conflict/StaleLocation and reports the RecordedAt of the position currently held, so you can tell how far behind your feed is.
Rate Limits
All endpoints are subject to rate limits to protect the API from traffic spikes. See Rate Limits.Authorizations
OAuth 2.0 client-credentials access token. Obtain one from https://auth.alvys.com/oauth/token (grant_type=client_credentials, audience=https://api.alvys.com/public/), then paste it here. The playground sends it as Authorization: Bearer <token>.
Path Parameters
API version (e.g., 1.0)
Example:
"1.0"
Body
application/json-patch+jsonapplication/jsontext/jsonapplication/*+json
Response
Created
Show child attributes
Show child attributes
Show child attributes
Show child attributes
⌘I
Record an asset's current location
curl --request POST \
--url https://integrations.alvys.com/api/p/v{version}/assets/{assetId}/locations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json-patch+json' \
--data '
{
"Coordinates": {
"Latitude": "<string>",
"Longitude": "<string>"
},
"RecordedAt": "2023-11-07T05:31:56Z",
"Address": {
"Street": "<string>",
"City": "<string>",
"State": "<string>",
"ZipCode": "<string>",
"Country": "<string>"
},
"TripId": "<string>",
"Odometer": 123,
"OdometerReadingAt": "2023-11-07T05:31:56Z"
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json-patch+json'},
body: JSON.stringify({
Coordinates: {Latitude: '<string>', Longitude: '<string>'},
RecordedAt: '2023-11-07T05:31:56Z',
Address: {
Street: '<string>',
City: '<string>',
State: '<string>',
ZipCode: '<string>',
Country: '<string>'
},
TripId: '<string>',
Odometer: 123,
OdometerReadingAt: '2023-11-07T05:31:56Z'
})
};
fetch('https://integrations.alvys.com/api/p/v{version}/assets/{assetId}/locations', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://integrations.alvys.com/api/p/v{version}/assets/{assetId}/locations"
payload = {
"Coordinates": {
"Latitude": "<string>",
"Longitude": "<string>"
},
"RecordedAt": "2023-11-07T05:31:56Z",
"Address": {
"Street": "<string>",
"City": "<string>",
"State": "<string>",
"ZipCode": "<string>",
"Country": "<string>"
},
"TripId": "<string>",
"Odometer": 123,
"OdometerReadingAt": "2023-11-07T05:31:56Z"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json-patch+json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://integrations.alvys.com/api/p/v{version}/assets/{assetId}/locations",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'Coordinates' => [
'Latitude' => '<string>',
'Longitude' => '<string>'
],
'RecordedAt' => '2023-11-07T05:31:56Z',
'Address' => [
'Street' => '<string>',
'City' => '<string>',
'State' => '<string>',
'ZipCode' => '<string>',
'Country' => '<string>'
],
'TripId' => '<string>',
'Odometer' => 123,
'OdometerReadingAt' => '2023-11-07T05:31:56Z'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json-patch+json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://integrations.alvys.com/api/p/v{version}/assets/{assetId}/locations"
payload := strings.NewReader("{\n \"Coordinates\": {\n \"Latitude\": \"<string>\",\n \"Longitude\": \"<string>\"\n },\n \"RecordedAt\": \"2023-11-07T05:31:56Z\",\n \"Address\": {\n \"Street\": \"<string>\",\n \"City\": \"<string>\",\n \"State\": \"<string>\",\n \"ZipCode\": \"<string>\",\n \"Country\": \"<string>\"\n },\n \"TripId\": \"<string>\",\n \"Odometer\": 123,\n \"OdometerReadingAt\": \"2023-11-07T05:31:56Z\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json-patch+json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://integrations.alvys.com/api/p/v{version}/assets/{assetId}/locations")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json-patch+json")
.body("{\n \"Coordinates\": {\n \"Latitude\": \"<string>\",\n \"Longitude\": \"<string>\"\n },\n \"RecordedAt\": \"2023-11-07T05:31:56Z\",\n \"Address\": {\n \"Street\": \"<string>\",\n \"City\": \"<string>\",\n \"State\": \"<string>\",\n \"ZipCode\": \"<string>\",\n \"Country\": \"<string>\"\n },\n \"TripId\": \"<string>\",\n \"Odometer\": 123,\n \"OdometerReadingAt\": \"2023-11-07T05:31:56Z\"\n}")
.asString();{
"AssetId": "<string>",
"AssetType": "<string>",
"Source": "<string>",
"Coordinates": {
"Latitude": "<string>",
"Longitude": "<string>"
},
"RecordedAt": "2023-11-07T05:31:56Z",
"ReceivedAt": "2023-11-07T05:31:56Z",
"Address": {
"Street": "<string>",
"City": "<string>",
"State": "<string>",
"ZipCode": "<string>",
"Country": "<string>"
},
"FormattedAddress": "<string>",
"TripId": "<string>",
"TripNumber": "<string>",
"Odometer": 123,
"OdometerReadingAt": "2023-11-07T05:31:56Z"
}{
"Errors": {},
"Type": "<string>",
"Title": "<string>",
"Status": 123,
"Detail": "<string>",
"Instance": "<string>"
}{
"Type": "<string>",
"Title": "<string>",
"Status": 123,
"Detail": "<string>",
"Instance": "<string>"
}{
"Type": "<string>",
"Title": "<string>",
"Status": 123,
"Detail": "<string>",
"Instance": "<string>"
}{
"Type": "<string>",
"Title": "<string>",
"Status": 123,
"Detail": "<string>",
"Instance": "<string>"
}{
"Type": "<string>",
"Title": "<string>",
"Status": 123,
"Detail": "<string>",
"Instance": "<string>"
}{
"Type": "<string>",
"Title": "<string>",
"Status": 123,
"Detail": "<string>",
"Instance": "<string>"
}{
"Type": "<string>",
"Title": "<string>",
"Status": 123,
"Detail": "<string>",
"Instance": "<string>"
}