PetTracer exposes an (unofficial) web portal API used by their apps/website. This skill gives a reliable, low-drama workflow for:
Current location
(latest known point)
Recent route/history
(time-windowed points)
Near-real-time updates
(WebSocket push, optional)
It is designed to minimise API load (be respectful) and to produce
consistent, copy/paste-friendly outputs
.
Quick start
Snapshot location (recommended default)
Set credentials (prefer env vars, not CLI args):
export
PETTRACER_USERNAME
=
"you@example.com"
export
PETTRACER_PASSWORD
=
"••••••••"
List devices:
python scripts/pettracer_cli.py list
--format
json
--pretty
Locate a pet:
By name:
python scripts/pettracer_cli.py
locate
--pet
"Fluffy"
--format
json
--pretty
By id:
python scripts/pettracer_cli.py
locate
--device-id
12345
--format
json
--pretty
If the account has
exactly one collar
, you can omit
--pet/--device-id
:
python scripts/pettracer_cli.py
locate
--format
json
--pretty
Get location history (last 6 hours)
python scripts/pettracer_cli.py
history
--pet
"Fluffy"
--hours
6
--format
json
--pretty
Core workflow the agent should follow
1) Decide: snapshot vs history vs live updates
Snapshot
user asks “where is X right now?” → use
locate
.
History
user asks “where has X been today/last hour?” → use
history
.
Live
user wants continuous updates → use WebSocket (see
references/websocket.md
).
Default to
snapshot
unless the user explicitly wants a route or live tracking.
2) Authenticate safely
Preferred order:
Use
PETTRACER_TOKEN
if already available.
Else login with
PETTRACER_USERNAME
+
PETTRACER_PASSWORD
(or
PETTRACER_EMAIL
).
Never
ask the user to paste tokens into chat. Ask them to set env vars or store secrets in their vault.
Optional overrides (useful for debugging / future-proofing):
PETTRACER_API_BASE
(REST base; default
https://portal.pettracer.com/api
)
PETTRACER_WS_BASE
(WebSocket base; default
wss://pt.pettracer.com/sc
)
3) Identify the right device
Fetch devices via
GET /api/map/getccs
(wrapped by
pettracer_cli.py list
).
Match by
details.name
case-insensitively.
If multiple matches: show a disambiguation list (id + name) and ask the user which one.
If no match: show available device names.
If the account has exactly one collar, you can default to it.
4) Fetch location data
Current location
comes from
device.lastPos
(collars) or top-level
posLat/posLong
(HomeStations):
posLat
,
posLong
timeMeasure
(timestamp)
acc
(accuracy, metres) or
horiPrec
(fallback)
History
uses
POST /api/map/getccpositions
with:
devId
,
filterTime
(ms),
toTime
(ms)
See
references/endpoints.md
and
references/data-model.md
.
5) Present results consistently
When reporting location, include:
Pet name + device id
Coordinates (lat, lon)
Last update time
Accuracy (if present)
How old the fix is (seconds/minutes since last fix), if possible
Optional: a map link (Google Maps + OpenStreetMap)
Preferred JSON shape (for tool-to-tool handoff):
{
"pet"
:
{
"id"
:
12345
,
"name"
:
"Fluffy"
}
,
"last_fix"
:
{
"lat"
:
48.137154
,
"lon"
:
11.576124
,
"time"
:
"2026-02-25T12:34:56+00:00"
,
"accuracy_m"
:
12
}
,
"last_fix_age_s"
:
90
,
"battery_mv"
:
4012
,
"battery_percent_est"
:
78
,
"home"
:
false
,
"links"
:
{
"google_maps"
:
"https://www.google.com/maps?q=48.137154,11.576124"
,
"openstreetmap"
:
"https://www.openstreetmap.org/?mlat=48.137154&mlon=11.576124#map=18/48.137154/11.576124"
}
}
Notes:
battery_percent_est
is an
estimate
derived from voltage (PetTracer reports millivolts, not %).
If there’s no GPS fix, report
error=no_recent_fix
and include
last_contact
.
Live tracking (optional, avoid aggressive polling)
If you need frequent updates:
Prefer WebSocket push (avoid aggressive polling).
Only fall back to polling if WebSocket is not possible; keep polling ≥ 60s by default.
Install dependency:
pip
install
aiohttp
Then run:
python scripts/pettracer_watch.py
--pet
"Fluffy"
See:
references/websocket.md
scripts/pettracer_watch.py
for a working SockJS/STOMP implementation.
Troubleshooting playbook
No location /
lastPos
is missing
Common reasons:
Collar hasn’t reported a GPS fix recently (indoors, low signal).
Battery low / collar off.
Subscription expired.
Action:
Report “no recent fix” and show
lastContact
if available.
Suggest switching to a higher-frequency mode (Fast/Live) in the PetTracer app/portal
only if the user asks
(see
references/modes.md
).
Auth failures (401 / invalid_auth)
Re-login to obtain a fresh
access_token
.
Confirm the login payload uses keys
login
+
password
(not
username
).
Rate limiting / service respect
Avoid tight loops against
/map/getccs
.
Prefer WebSocket for near-real-time tracking.
THE EXACT PROMPT — Location response format
Use this when the user wants a human-readable answer:
Give the pet’s latest known PetTracer location.
Include:
- Pet name + device id
- Time of last fix (and last contact if different)
- Coordinates + map link(s)
- Accuracy (metres) if present
- One-line assessment: “recent fix” vs “stale fix” (use last_fix_age_s if available; interpret in the context of the current tracking mode)