API
Overland posts GeoJSON to an HTTP endpoint of your choosing. This page describes what the app sends, how your server should reply, and how your server can configure the app.
Request
The app will post the location data to the endpoint configured in Settings. The POST request body is a JSON object containing a property locations which is an array of GeoJSON objects. The default batch size is 200 but can be set in the settings. The request will look something like the following:
POST /api HTTP/1.1
Authorization: Bearer xxxxxx
Content-Type: application/json
{
"locations": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-122.030581,
37.331800
]
},
"properties": {
"timestamp": "2015-10-01T08:00:00-0700",
"altitude": 0,
"speed": 4,
"horizontal_accuracy": 30,
"vertical_accuracy": -1,
"motion": ["driving","stationary"],
"pauses": false,
"activity": "other_navigation",
"desired_accuracy": 100,
"deferred": 1000,
"significant_change": "disabled",
"locations_in_payload": 1,
"battery_state": "charging",
"battery_level": 0.80,
"device_id": "",
"wifi": ""
}
}
],
"current": { ... }, (optional)
"trip": { ... } (optional)
}
If you've configured an access token, it will be sent in the HTTP Authorization header preceded by the text Bearer.
Location properties
The properties on the location objects are as follows:
timestamp- The ISO8601 timestamp of the
CLLocationobject recorded altitude- The altitude of the location in meters
speed- Meters per second
course- Direction of travel in degrees
horizontal_accuracy- Accuracy of the position in meters
vertical_accuracy- Accuracy of the altitude in meters
speed_accuracy- Accuracy of the speed in meters per second, or -1 if speed is unknown
course_accuracy- Accuracy of the course in degrees, or -1 if speed is unknown
motion- An array of motion states detected by the motion coprocessor. Possible values are:
driving,walking,running,cycling,stationary. A common combination isdrivingandstationarywhen the phone is resting on the dashboard of a moving car. battery_stateunknown,charging,full,unpluggedbattery_level- A value from 0 to 1 indicating the percent battery remaining
wifi- If the device is connected to a wifi hotspot, the name of the SSID will be included
wifi_bssid- If the device is connected to a wifi hotspot, the address (BSSID) of the access point, such as
3c:22:fb:1a:00:11, or an empty string. Likewifi, this needs Precise Location access. device_id- The device ID configured in the settings, or an empty string
unique_id- If "Unique ID" is enabled, the device's Unique ID as set by Apple
During a trip
The following properties are included only while a trip is in progress:
trip_id- The ISO8601 timestamp of when the trip started, which is the same for every point in the trip
trip_mode-
The server value of the trip mode when this point was recorded. By default this is the mode's ID, or the ID of a mode the user added, such as
kayak, but the user can change it in Trip Modes. If the mode is changed during a trip, later points have the new mode. The built-in modes' IDs are:walkrunhikebicycleebikescooterskateskisnowboardsleighcartaxibustrammetrotrainmonorailgondolafunicularboatplane
Tracking stats
The following properties are included only if the "Include Tracking Stats" option is selected:
pauses- Boolean, whether the "pause updates automatically" preference is checked
activity- A string denoting the type of activity as indicated by the setting. Possible values are
automotive_navigation,fitness,other_navigation,airborne,maritimeandother. This can be set on the settings screen. desired_accuracy- The requested accuracy in meters as configured on the settings screen
deferred- The distance in meters to defer location updates, configured on the settings screen
significant_change- A string indicating the significant change mode,
disabled,enabledorexclusive locations_in_payload- The number of locations that were sent in the batch along with this location
Trip records
When a trip ends, a trip record is added to the locations array along with the points. It's a GeoJSON Feature at the trip's last location, and its properties include "type": "trip", the trip's mode (the mode's server value), start and end (ISO8601), duration (seconds), distance (meters), start_location and end_location (location Features), steps, and stopped_automatically, along with the same device properties as a location, such as battery_level and wifi.
The trip record also has the mode's icon, so you can show it the way the app does:
icon- For the built-in modes, and any mode using one of Overland's own icons: the icon as an SVG data URI, such as
data:image/svg+xml;base64,PHN2Zy..., which you can use as an image'ssrc. It's a single black path in a square viewBox, so you can recolor it with CSS (for example as amask-image). These are about 0.5 to 1.6 KB. sf_symbol- For a mode the user gave an SF Symbol: the symbol's name, such as
figure.kayaking. SF Symbols' license doesn't allow sending the image itself, so map the name to an icon of your own.
Current location
If the number of locations in the queue is more than twice the batch size, then the request will also contain a property current with the most recent location point stored by the device. (This point will not be one of the ones in the batch.) If you need your backend to be aware of the current location, this allows you to ignore the batch being uploaded and instead use just that point.
Current trip
If a trip is active, an object called trip will be included in the request as well, with information about the current trip. This object will contain the following properties:
distance- Current trip distance in meters as calculated by the device
mode- The trip mode's server value, the same as
trip_modeon points current_location- A location record that represents the most recent location of the device
start_location- A location record that represents the location at the start of the trip
start- An ISO8601 timestamp representing the time the trip was started. This may be slightly different from the timestamp in the start location.
Response
Your server must reply with a JSON response containing:
{
"result": "ok"
}
This indicates to the app that the batch was received, and it will delete those points from the local cache. If the app receives any other response, it will keep the data locally and try to send it again at the next interval.
If you are unable to return this JSON, you can turn on "Consider HTTP 2XX Successful" in the iOS Settings app, and then any HTTP 2xx response will be considered successful.
Configuration by server response
You can configure all of the settings in the app by having your server return new settings in the JSON response when it uploads data. The JSON structure and all possible config values are below.
{
"result": "ok",
"set": {
"send_interval": "1s|5s|10s|15s|30s|1m|2m|5m|10m|30m|off",
"trip_mode": "walk|run|hike|bicycle|ebike|scooter|skate|ski|snowboard|sleigh|car|taxi|bus|tram|metro|train|monorail|gondola|funicular|boat|plane|<a mode's server value or ID>",
"main": {
"tracking_mode": "off|standard|significant|both",
"visit_tracking": true|false,
"desired_accuracy": "nav|best|10m|100m|1km|3km",
"activity_type": "other|car|fitness|nav|air|boat",
"background_indicator": true|false,
"pause_automatically": true|false,
"logging_mode": "all|latest|owntracks",
"batch_size": 50|100|200|500|1000,
"resume_with_geofence": "off|100m|200m|500m|1km|2km",
"min_distance": "off|1m|10m|50m|100m|500m",
"min_time": "1s|5s|10s|30s|1m|5m",
"discard_without_gps": true|false,
"discard_stationary": true|false,
},
"trip": {
"desired_accuracy": "nav|best|10m|100m|1km|3km",
"activity_type": "other|car|fitness|nav|air|boat",
"background_indicator": true|false,
"prevent_screen_lock": true|false,
"logging_mode": "all|latest|owntracks",
"batch_size": 50|100|200|500|1000,
"min_distance": "off|1m|10m|50m|100m|500m",
"min_time": "1s|5s|10s|30s|1m|5m",
"discard_without_gps": true|false,
"discard_stationary": true|false,
}
}
}
Note that most values are strings, with the exception of some that are numbers or boolean.
The settings under main correspond to the settings in the main settings screen in the UI, and the settings under trip correspond to the settings when a trip is in progress.
Important: It is very possible to send a setting to the phone that will disable logging completely, which creates a dead end, since the phone will then never check back with the server for updated settings! The main setting that can cause this to happen is send_interval=off. Setting tracking_mode=off means only "visits" will be tracked, which will be received extremely infrequently, so you won't have a chance to change the setting to something else until after the phone checks in after that.
It is best to only send properties in the response that you want to change at that moment, rather than always sending the values on every response. Treat it like pressing the button in the UI, only send the response when you want to press the button.
Configuration by custom URL
You can send people a custom URL that will configure the app by clicking on it. Create a URL with your endpoint, token and device ID like the following:
overland://setup?url=https%3A%2F%2Fexample.com%2Fapi&token=1234&device_id=1&unique_id=yes
Tapping that URL on a device with the app installed will launch the app and save the values in the configuration. This is a quick way to configure many devices since it bypasses the need to enter the values in the settings screen.
Query parameters:
url- The server URL to post data to
token- The access token to use in requests
device_id- Set the user-defined device ID here
unique_id=yes- Set this to
yesto toggle the "Unique ID" setting
Endpoint URL templates
If the endpoint URL has any template parameters, they will be replaced with the value of the most recent location update. The template parameters you can use are below:
%TS- Timestamp (ISO 8601, e.g.
2023-12-05T16:50:25Z) %LAT- Latitude
%LON- Longitude
%SPD- Speed in meters per second (negative means invalid)
%ACC- Accuracy (horizontal) of location in meters
%ALT- Altitude in meters
%BAT- Battery percent (e.g.
0.8for 80%)
For example, you can use the URL below to receive all the data in the query string. Use this with the "Only Latest" logging mode.
https://example.com/input?ts=%TS&lat=%LAT&lon=%LON&acc=%ACC&spd=%SPD&bat=%BAT&alt=%ALT