OwnTracks is an open-source location app for Android and iOS that can publish your phone's position straight to an MQTT broker. With your own broker you decide who sees the data, how long it is stored and which other systems (Home Assistant, Node-RED, a database) consume it. Setup takes four values in the app (host, port, username, password), plus TLS and an ACL on the broker side.
This guide covers the app settings, the topics and payloads OwnTracks uses, broker ACLs for sharing with friends, the OwnTracks Recorder, and how to verify each step from a terminal.
What you need
| Item | Why | Notes |
|---|---|---|
| An MQTT broker reachable from the internet | Phones publish from mobile networks | Self-hosted or managed, MQTT 3.1.1 is enough |
| TLS on port 8883 | Locations are personal data | A publicly trusted certificate is easiest |
| One username per person | Topic and ACLs are derived from it | Never share one login between family members |
| OwnTracks app | Publishes location | Android (Google Play / F-Droid) or iOS |
| Optional: OwnTracks Recorder | Stores history, serves a web map | Docker image owntracks/recorder |
A public test broker is fine for checking that the app connects, but do not leave a real location stream on a shared endpoint: anyone who subscribes to owntracks/# there would see it.
Configure the app
In the app, open Preferences → Connection (Android) or Settings (iOS) and switch the mode from HTTP to MQTT. Field names differ slightly between platforms and versions, but the values are the same:
| Setting | Value |
|---|---|
| Mode | MQTT |
| Host | broker.connectmq.com (your broker's hostname) |
| Port | 8883 |
| TLS | On |
| Username / Password | The credentials of this person on your broker |
| Device ID | Short name for the phone, e.g. pixel or iphone |
| Tracker ID | Two characters shown on the map, e.g. AL |
| Client ID | Leave the default, it must be unique per device |
Save, then pull down on the map or tap the upload button to publish a location manually. The status screen should show the connection as connected. If you are not sure the broker accepts the credentials, test them first from your laptop with the online MQTT client — it isolates broker problems from app problems.
Topics and payloads
With username alice and device ID pixel, the app uses:
owntracks/alice/pixel location messages (_type: location), retained by default
owntracks/alice/pixel/event region enter/leave events (_type: transition)
owntracks/alice/pixel/info card with name and avatar (_type: card)
owntracks/alice/pixel/cmd commands TO the phone (_type: cmd)A location message looks like this (fields abbreviated; exact fields depend on platform and version):
{
"_type": "location",
"tid": "AL",
"lat": 48.856613,
"lon": 2.352222,
"acc": 12,
"alt": 35,
"batt": 78,
"conn": "m",
"t": "u",
"tst": 1792236000
}tst is the UTC time of the fix, acc the accuracy in metres, batt the battery level, conn the connection type (w Wi-Fi, m mobile) and t the trigger (u user, p ping, c region and others). The app also registers a Last Will message (_type: lwt) on the base topic, so a subscriber learns when the phone disconnects ungracefully.
The monitoring mode controls how often the phone reports: Significant (the default, battery-friendly, based on significant location changes), Move (frequent updates while moving, uses more battery), Manual and Quiet. Start with Significant.
If you build your own hardware tracker, publish the same JSON to the same topic layout and it shows up next to the phones. The GPS tracker tutorial builds one with an ESP32.
Verify from a terminal
Subscribe with the credentials of a user that may read Alice's topics:
mosquitto_sub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
-u "$MQTT_USER" -P "$MQTT_PASS" -t 'owntracks/#' -vTap publish in the app; the JSON appears within a second or two. To test the reverse direction, ask the phone for a location with a remote command. Remote commands must be enabled in the app's advanced settings, and on iOS background delivery is not guaranteed:
mosquitto_pub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
-u "$MQTT_USER" -P "$MQTT_PASS" \
-t 'owntracks/alice/pixel/cmd' -q 1 \
-m '{"_type":"cmd","action":"reportLocation"}'You can also impersonate a phone to test the Recorder or a dashboard without walking around:
mosquitto_pub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
-u "$MQTT_USER" -P "$MQTT_PASS" -t 'owntracks/alice/pixel' -q 1 -r \
-m "{\"_type\":\"location\",\"tid\":\"AL\",\"lat\":48.8584,\"lon\":2.2945,\"acc\":10,\"tst\":$(date +%s)}"ACLs: who sees whom
The app subscribes to owntracks/+/+ by default and draws every location it receives as a friend. That makes the broker's ACL the privacy control: a user sees exactly the topics they are allowed to read. In Mosquitto syntax:
# every user may publish and read under its own username
pattern readwrite owntracks/%u/#
# alice and bob share locations with each other
user alice
topic read owntracks/bob/#
user bob
topic read owntracks/alice/#
# the recorder reads everyone, publishes nothing
user recorder
topic read owntracks/#On a managed broker you express the same rules as per-user topic permissions. Two details to remember:
- The username in the app must match the second topic level, otherwise every publish is denied. Many brokers drop a denied publish without disconnecting the client, so the phone looks connected but nothing arrives. See ACL denied silently.
- Test the rules from the outside: log in as Bob and try to read someone who has not shared with him. A short script for this is in testing MQTT ACL permissions.
Store history with the Recorder
The OwnTracks Recorder subscribes to the broker, stores every location on disk and serves a web map and an HTTP API. The Docker image is configured with environment variables:
docker run -d --name ot-recorder -p 8083:8083 \
-e OTR_HOST=broker.connectmq.com \
-e OTR_PORT=8883 \
-e OTR_USER=recorder \
-e OTR_PASS="$MQTT_PASS" \
-e OTR_CAFILE=/etc/ssl/certs/ca-certificates.crt \
-v ot-store:/store \
owntracks/recorderOpen http://localhost:8083 for the Recorder's own web interface. Give the Recorder its own read-only user, as in the ACL above, and decide how long you keep history. Port 8083 here is the Recorder's HTTP port on your machine, unrelated to the broker's WebSocket port.
End-to-end encryption (optional)
OwnTracks can encrypt payloads with a shared secret key (libsodium). The broker then only sees {"_type":"encrypted","data":"…"} and every reader, including the Recorder, needs the key. It protects data from the broker operator, but you lose the ability to inspect messages in normal tools. TLS plus strict ACLs is enough for most setups; see MQTT payload encryption for the trade-offs.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| App shows an error right after connecting | Wrong username or password, or CONNACK "Not authorized" | Test the same credentials in the online client; look up the code with the reason code tool |
| TLS or certificate error | Self-signed or incomplete certificate chain | Use a publicly trusted certificate, or install your CA in the app |
Connected, but nothing in mosquitto_sub | ACL denies publish, or username ≠ topic user | Check broker logs and the ACL pattern |
| Friends missing on the map | No read permission for their topics | Add read rules, then reconnect the app |
| Updates stop after a while on Android | Battery optimisation kills the background service | Exclude OwnTracks from battery optimisation; see Android background disconnects |
OwnTracks on your own broker is one of the simplest useful MQTT deployments: a phone, one topic per device and a handful of ACL rules. Get TLS and the per-user permissions right first, verify each direction with mosquitto_sub and mosquitto_pub, and only then add the Recorder or home-automation integrations on top.
Frequently asked questions
Which topic does OwnTracks publish to?
By default the app publishes locations to owntracks/<username>/<deviceID>, where the username is the MQTT username and the device ID is set in the app. Events, info cards and commands use sub-topics such as /event, /info and /cmd.
Can OwnTracks use a self-signed certificate?
Yes, but the phone must trust it: install your CA certificate in the app's TLS settings (Android) or on the device (iOS). A certificate from a public CA such as Let's Encrypt avoids this step and works out of the box on port 8883.
How do friends see each other in OwnTracks?
The app subscribes to owntracks/+/+ by default and shows every location it receives. Which friends appear is therefore decided by the broker's ACLs: grant each user read access only to the people who should see them.


