curl --request POST \
--url https://api.catenatelematics.com/v2/notifications/geofence-monitors \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"destination": {
"latitude": 39.9612,
"longitude": -82.9988,
"radius_meters": 800
},
"origin": {
"latitude": 40.7484,
"longitude": -73.9857,
"radius_meters": 200
},
"starts_at": "2026-08-14T12:00:00Z",
"webhook_group_id": "0198c1f2-3a4b-7c5d-8e6f-0a1b2c3d4e5f"
}
'import requests
url = "https://api.catenatelematics.com/v2/notifications/geofence-monitors"
payload = {
"destination": {
"latitude": 39.9612,
"longitude": -82.9988,
"radius_meters": 800
},
"origin": {
"latitude": 40.7484,
"longitude": -73.9857,
"radius_meters": 200
},
"starts_at": "2026-08-14T12:00:00Z",
"webhook_group_id": "0198c1f2-3a4b-7c5d-8e6f-0a1b2c3d4e5f"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
destination: {latitude: 39.9612, longitude: -82.9988, radius_meters: 800},
origin: {latitude: 40.7484, longitude: -73.9857, radius_meters: 200},
starts_at: '2026-08-14T12:00:00Z',
webhook_group_id: '0198c1f2-3a4b-7c5d-8e6f-0a1b2c3d4e5f'
})
};
fetch('https://api.catenatelematics.com/v2/notifications/geofence-monitors', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.catenatelematics.com/v2/notifications/geofence-monitors"
payload := strings.NewReader("{\n \"destination\": {\n \"latitude\": 39.9612,\n \"longitude\": -82.9988,\n \"radius_meters\": 800\n },\n \"origin\": {\n \"latitude\": 40.7484,\n \"longitude\": -73.9857,\n \"radius_meters\": 200\n },\n \"starts_at\": \"2026-08-14T12:00:00Z\",\n \"webhook_group_id\": \"0198c1f2-3a4b-7c5d-8e6f-0a1b2c3d4e5f\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}require 'uri'
require 'net/http'
url = URI("https://api.catenatelematics.com/v2/notifications/geofence-monitors")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"destination\": {\n \"latitude\": 39.9612,\n \"longitude\": -82.9988,\n \"radius_meters\": 800\n },\n \"origin\": {\n \"latitude\": 40.7484,\n \"longitude\": -73.9857,\n \"radius_meters\": 200\n },\n \"starts_at\": \"2026-08-14T12:00:00Z\",\n \"webhook_group_id\": \"0198c1f2-3a4b-7c5d-8e6f-0a1b2c3d4e5f\"\n}"
response = http.request(request)
puts response.read_bodyHttpResponse<String> response = Unirest.post("https://api.catenatelematics.com/v2/notifications/geofence-monitors")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"destination\": {\n \"latitude\": 39.9612,\n \"longitude\": -82.9988,\n \"radius_meters\": 800\n },\n \"origin\": {\n \"latitude\": 40.7484,\n \"longitude\": -73.9857,\n \"radius_meters\": 200\n },\n \"starts_at\": \"2026-08-14T12:00:00Z\",\n \"webhook_group_id\": \"0198c1f2-3a4b-7c5d-8e6f-0a1b2c3d4e5f\"\n}")
.asString();using RestSharp;
var options = new RestClientOptions("https://api.catenatelematics.com/v2/notifications/geofence-monitors");
var client = new RestClient(options);
var request = new RestRequest("");
request.AddHeader("Authorization", "Bearer <token>");
request.AddJsonBody("{\n \"destination\": {\n \"latitude\": 39.9612,\n \"longitude\": -82.9988,\n \"radius_meters\": 800\n },\n \"origin\": {\n \"latitude\": 40.7484,\n \"longitude\": -73.9857,\n \"radius_meters\": 200\n },\n \"starts_at\": \"2026-08-14T12:00:00Z\",\n \"webhook_group_id\": \"0198c1f2-3a4b-7c5d-8e6f-0a1b2c3d4e5f\"\n}", false);
var response = await client.PostAsync(request);
Console.WriteLine("{0}", response.Content);
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.catenatelematics.com/v2/notifications/geofence-monitors",
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([
'destination' => [
'latitude' => 39.9612,
'longitude' => -82.9988,
'radius_meters' => 800
],
'origin' => [
'latitude' => 40.7484,
'longitude' => -73.9857,
'radius_meters' => 200
],
'starts_at' => '2026-08-14T12:00:00Z',
'webhook_group_id' => '0198c1f2-3a4b-7c5d-8e6f-0a1b2c3d4e5f'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"webhook_group_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"fleet_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"vehicle_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"status": "active",
"current_stop_sequence": 123,
"starts_at": "2023-11-07T05:31:56Z",
"expires_at": "2023-11-07T05:31:56Z",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"name": "<string>",
"fleet_ref": "<string>",
"vin": "<string>",
"license_plate_number": "<string>",
"license_plate_region": "<string>",
"license_plate_country": "<string>",
"stops": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"sequence": 123,
"point": {
"type": "Point",
"coordinates": {
"[0]": 123,
"[1]": 123
},
"bbox": {
"[0]": 123,
"[1]": 123,
"[2]": 123,
"[3]": 123
}
},
"radius_meters": 123,
"name": "<string>",
"arrived_at": "2023-11-07T05:31:56Z",
"departed_at": "2023-11-07T05:31:56Z"
}
],
"cancelled_at": "2023-11-07T05:31:56Z",
"completed_at": "2023-11-07T05:31:56Z"
}{
"code": 400,
"message": "Bad Request",
"detail": "<string>"
}{
"code": 401,
"message": "Unauthorized",
"detail": "<string>"
}{
"code": 403,
"message": "Forbidden",
"detail": "<string>"
}{
"code": 404,
"message": "Not Found",
"detail": "<string>"
}{
"code": 405,
"message": "Method Not Allowed",
"detail": "<string>"
}{
"code": 409,
"message": "Conflict",
"detail": "<string>"
}{
"code": 422,
"message": "Invalid Request Body",
"detail": [
{
"path": "<string>",
"input": "<string>",
"message": "<string>",
"error_type": "<string>"
}
]
}{
"code": 429,
"message": "Too Many Requests",
"detail": {
"retry_after_seconds": 123,
"message": "<string>"
}
}{
"message": "Internal Server Error"
}Create Geofence Monitor
Create a geofence monitor for one vehicle, watched from its origin to its destination.
curl --request POST \
--url https://api.catenatelematics.com/v2/notifications/geofence-monitors \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"destination": {
"latitude": 39.9612,
"longitude": -82.9988,
"radius_meters": 800
},
"origin": {
"latitude": 40.7484,
"longitude": -73.9857,
"radius_meters": 200
},
"starts_at": "2026-08-14T12:00:00Z",
"webhook_group_id": "0198c1f2-3a4b-7c5d-8e6f-0a1b2c3d4e5f"
}
'import requests
url = "https://api.catenatelematics.com/v2/notifications/geofence-monitors"
payload = {
"destination": {
"latitude": 39.9612,
"longitude": -82.9988,
"radius_meters": 800
},
"origin": {
"latitude": 40.7484,
"longitude": -73.9857,
"radius_meters": 200
},
"starts_at": "2026-08-14T12:00:00Z",
"webhook_group_id": "0198c1f2-3a4b-7c5d-8e6f-0a1b2c3d4e5f"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
destination: {latitude: 39.9612, longitude: -82.9988, radius_meters: 800},
origin: {latitude: 40.7484, longitude: -73.9857, radius_meters: 200},
starts_at: '2026-08-14T12:00:00Z',
webhook_group_id: '0198c1f2-3a4b-7c5d-8e6f-0a1b2c3d4e5f'
})
};
fetch('https://api.catenatelematics.com/v2/notifications/geofence-monitors', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.catenatelematics.com/v2/notifications/geofence-monitors"
payload := strings.NewReader("{\n \"destination\": {\n \"latitude\": 39.9612,\n \"longitude\": -82.9988,\n \"radius_meters\": 800\n },\n \"origin\": {\n \"latitude\": 40.7484,\n \"longitude\": -73.9857,\n \"radius_meters\": 200\n },\n \"starts_at\": \"2026-08-14T12:00:00Z\",\n \"webhook_group_id\": \"0198c1f2-3a4b-7c5d-8e6f-0a1b2c3d4e5f\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}require 'uri'
require 'net/http'
url = URI("https://api.catenatelematics.com/v2/notifications/geofence-monitors")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"destination\": {\n \"latitude\": 39.9612,\n \"longitude\": -82.9988,\n \"radius_meters\": 800\n },\n \"origin\": {\n \"latitude\": 40.7484,\n \"longitude\": -73.9857,\n \"radius_meters\": 200\n },\n \"starts_at\": \"2026-08-14T12:00:00Z\",\n \"webhook_group_id\": \"0198c1f2-3a4b-7c5d-8e6f-0a1b2c3d4e5f\"\n}"
response = http.request(request)
puts response.read_bodyHttpResponse<String> response = Unirest.post("https://api.catenatelematics.com/v2/notifications/geofence-monitors")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"destination\": {\n \"latitude\": 39.9612,\n \"longitude\": -82.9988,\n \"radius_meters\": 800\n },\n \"origin\": {\n \"latitude\": 40.7484,\n \"longitude\": -73.9857,\n \"radius_meters\": 200\n },\n \"starts_at\": \"2026-08-14T12:00:00Z\",\n \"webhook_group_id\": \"0198c1f2-3a4b-7c5d-8e6f-0a1b2c3d4e5f\"\n}")
.asString();using RestSharp;
var options = new RestClientOptions("https://api.catenatelematics.com/v2/notifications/geofence-monitors");
var client = new RestClient(options);
var request = new RestRequest("");
request.AddHeader("Authorization", "Bearer <token>");
request.AddJsonBody("{\n \"destination\": {\n \"latitude\": 39.9612,\n \"longitude\": -82.9988,\n \"radius_meters\": 800\n },\n \"origin\": {\n \"latitude\": 40.7484,\n \"longitude\": -73.9857,\n \"radius_meters\": 200\n },\n \"starts_at\": \"2026-08-14T12:00:00Z\",\n \"webhook_group_id\": \"0198c1f2-3a4b-7c5d-8e6f-0a1b2c3d4e5f\"\n}", false);
var response = await client.PostAsync(request);
Console.WriteLine("{0}", response.Content);
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.catenatelematics.com/v2/notifications/geofence-monitors",
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([
'destination' => [
'latitude' => 39.9612,
'longitude' => -82.9988,
'radius_meters' => 800
],
'origin' => [
'latitude' => 40.7484,
'longitude' => -73.9857,
'radius_meters' => 200
],
'starts_at' => '2026-08-14T12:00:00Z',
'webhook_group_id' => '0198c1f2-3a4b-7c5d-8e6f-0a1b2c3d4e5f'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"webhook_group_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"fleet_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"vehicle_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"status": "active",
"current_stop_sequence": 123,
"starts_at": "2023-11-07T05:31:56Z",
"expires_at": "2023-11-07T05:31:56Z",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"name": "<string>",
"fleet_ref": "<string>",
"vin": "<string>",
"license_plate_number": "<string>",
"license_plate_region": "<string>",
"license_plate_country": "<string>",
"stops": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"sequence": 123,
"point": {
"type": "Point",
"coordinates": {
"[0]": 123,
"[1]": 123
},
"bbox": {
"[0]": 123,
"[1]": 123,
"[2]": 123,
"[3]": 123
}
},
"radius_meters": 123,
"name": "<string>",
"arrived_at": "2023-11-07T05:31:56Z",
"departed_at": "2023-11-07T05:31:56Z"
}
],
"cancelled_at": "2023-11-07T05:31:56Z",
"completed_at": "2023-11-07T05:31:56Z"
}{
"code": 400,
"message": "Bad Request",
"detail": "<string>"
}{
"code": 401,
"message": "Unauthorized",
"detail": "<string>"
}{
"code": 403,
"message": "Forbidden",
"detail": "<string>"
}{
"code": 404,
"message": "Not Found",
"detail": "<string>"
}{
"code": 405,
"message": "Method Not Allowed",
"detail": "<string>"
}{
"code": 409,
"message": "Conflict",
"detail": "<string>"
}{
"code": 422,
"message": "Invalid Request Body",
"detail": [
{
"path": "<string>",
"input": "<string>",
"message": "<string>",
"error_type": "<string>"
}
]
}{
"code": 429,
"message": "Too Many Requests",
"detail": {
"retry_after_seconds": 123,
"message": "<string>"
}
}{
"message": "Internal Server Error"
}vehicle_id if you have it, otherwise vin or the full license plate. Creating a monitor requires an active share agreement granting you vehicle_location access to that vehicle’s fleet.Authorizations
The access token received from the authorization server in the OAuth 2.0 flow.
Body
Geofence monitor create model.
The geofence_monitor.* subscription to deliver this monitor's events to. Returned when you create the subscription.
Where the journey starts. Departure is detected on leaving this circle.
Show child attributes
Show child attributes
{
"latitude": 39.9612,
"longitude": -82.9988,
"radius_meters": 200
}
Where the journey ends. Arriving here is the delivery; the monitor completes once the vehicle leaves destination, so the dwell can be measured.
Show child attributes
Show child attributes
{
"latitude": 39.9612,
"longitude": -82.9988,
"radius_meters": 200
}
When the journey is expected to start. Pings before this are ignored, so set it close to dispatch -- a monitor watching a truck still parked in the origin yard will record that as the origin arrival. Must include a UTC offset.
Your own label for this journey, for example a load or BOL number. Echoed on every event.
255The Catena vehicle identifier.
Vehicle Identification Number. 17 characters, A-Z excluding I, O and Q, and 0-9.
Must be sent together with the region and country.
Two letter state or province abbreviation, e.g. 'OH' or 'ON'.
Plate country code (ISO-3166-1 alpha-3, e.g., 'USA', 'CAN')
Planned stops between origin and destination, in travel order. Each one gets its own arrival and departure events.
Show child attributes
Show child attributes
When to stop watching. Must include a UTC offset. Both the default and the maximum are measured from starts_at, not from now, so booking a monitor early does not eat into the journey's window. Defaults to 3 days after starts_at, up to a maximum of 14 days.
Response
Successful Response
Geofence monitor read model
The geofence_monitor.* subscription this monitor's events are delivered to
The Catena fleet whose vehicle is being watched
The Catena vehicle being watched
The monitor's lifecycle status. Non-terminal means still being watched.
active, completed, expired, cancelled Which stop is currently being watched
Pings before this are ignored.
When the watch ends. A monitor still ACTIVE past this is marked EXPIRED.
When the monitor was created
When the monitor last changed, including each stop transition
Your own reference for the fleet
The journey, in travel order
Show child attributes
Show child attributes
When the partner cancelled the monitor
When the vehicle departed the final stop, ending the watch
Was this page helpful?