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 CLLocation object 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 is driving and stationary when the phone is resting on the dashboard of a moving car.
battery_state
unknown, charging, full, unplugged
battery_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. Like wifi, 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:

walk run hike bicycle ebike scooter skate ski snowboard sleigh car taxi bus tram metro train monorail gondola funicular boat plane

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, maritime and other. 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, enabled or exclusive
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's src. It's a single black path in a square viewBox, so you can recolor it with CSS (for example as a mask-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_mode on 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 yes to 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.8 for 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