Now Live

Your run, your API.

DotDot is the first GPS tracking platform built for LLM agents. Manage followers, react to run events, send cheers, all programmatic — over a hosted MCP server or plain REST.

webhook — run.started
// your agent receives this
{
"event": "run.started",
"runner": "sarah",
"run_id": "a1b2c3d4",
"tracking_url": "dotdot.sivoov.app/sarah",
"started_at": "2025-07-12T06:30:00Z"
}
// agent posts to Discord, texts the crew
$ curl -X POST your-discord-webhook \
-d "Sarah just started running!"

Model Context Protocol

One URL. Your agent runs with you.

DotDot ships a hosted MCP server with OAuth built in. Point Claude, Cursor, or anything else that speaks MCP at one URL, approve the scopes it asks for, and it discovers every tool on its own. No client to write, nothing to install, no token to copy.

add a connector
https://dotdot.sivoov.app/api/mcp
// that's the whole setup — your agent registers
// itself, sends you to DotDot, and you approve.

No browser to approve in? Scripts and CI can use a scoped API token instead:

terminal
$ claude mcp add --transport http dotdot \
https://dotdot.sivoov.app/api/mcp \
--header "Authorization: Bearer dotdot_pat_..."
Added MCP server dotdot

Scoped by what you approve

The server lists only the tools the grant covers. Approve read:runs and the agent cannot see — let alone call — a tool that invites people or changes your privacy. Disconnect it and its access ends immediately.

get_current_run

read:runs

list_runs

read:runs

get_activity

read:profile

invite_followers

write:followers

approve_follower

write:followers

send_cheer

write:cheers

update_privacy

write:privacy

create_webhook

write:events

19 tools in total, covering profile, runs, followers, privacy, cheers, and webhooks.

What that looks like

“I’m running Chamonix on Saturday. Invite my crew, only notify people that day, and message me when someone new asks to follow.”

Your agent works out which tools to call. You didn’t write any of them.

What agents do with DotDot

Real use cases, real endpoints. Your agent handles the logistics. You handle the elevation.

🏁

Race-day crew coordinator

Before a 100-miler, your agent bulk-invites your crew, sets privacy to friends-only, and schedules notification days. During the race, it relays cheers to your Discord.

POST /api/me/followers/bulk-invite
Authorization: Bearer dotdot_pat_k8x...
{
"invites": [
{ "email": "[email protected]" },
{ "email": "[email protected]" },
{ "email": "[email protected]" }
]
}
🔀

Cross-platform bridge

Your agent watches for run events and posts updates to Slack, Discord, Strava clubs, or your blog. Real-time, zero manual effort.

// webhook: run.finished
{
"event": "run.finished",
"runner": "arthur",
"distance_meters": 80467,
"duration_seconds": 51840,
"moving_seconds": 48120,
"paused_seconds": 3720,
"spectator_count": 247
}
// "Arthur finished 50mi in 14:24"
🛡️

Smart follower manager

Auto-approve anyone from your running club's email domain. Deny the rest. Get a Telegram ping for edge cases.

// webhook: follower.requested
{
"event": "follower.requested",
"follower_id": "f9e8d7c6",
"email": "[email protected]",
"nickname": "Jamie"
}
// agent checks domain → approve
POST /api/me/followers/f9e8d7c6/approve

Autonomous hype bot

Your agent sends personalized cheers based on progress. It knows when you've been climbing for an hour and sends the right words.

// agent reads live position
GET /api/runners/sarah/current
// detects big climb, sends cheer
POST /api/runs/a1b2c3d4/cheers
{
"nickname": "Coach Bot",
"message": "8hrs in, summit done."
}

Getting started

Three steps. No SDK.

01

Sign up

That is genuinely it for MCP — OAuth handles the rest. For scripts and CI, create a scoped API token in the dashboard instead.

read:runs · write:followers · write:events

02

Connect the MCP server

Paste one URL into your agent and approve the scopes it asks for. It discovers the tools it is allowed to use, and nothing else.

https://dotdot.sivoov.app/api/mcp

03

Register a webhook

Optional, and how you stop polling. Events arrive as signed POSTs; your agent calls back through MCP or REST.

run.started · run.finished · follower.approved

Reference

API at a glance

Standard REST. Authorization: Bearer dotdot_pat_...

GET/api/runners/:username
Runner profilepublic
GET/api/runners/:username/current
Live run + trackpointspublic
GET/api/runners/:username/runs
Run historypublic
POST/api/runs/:runId/cheers
Send a cheerpublic
GET/api/me
Your profileread:profile
GET/api/me/followers
List followersread:followers
POST/api/me/followers/invite
Invite a followerwrite:followers
POST/api/me/followers/bulk-invite
Bulk invite (max 50)write:followers
POST/api/me/followers/:id/approve
Approve requestwrite:followers
POST/api/me/followers/:id/deny
Deny requestwrite:followers
DELETE/api/me/followers/:id
Remove followerwrite:followers
GET/api/me/privacy
Privacy settingsread:profile
PUT/api/me/privacy
Update privacywrite:privacy
POST/api/me/shared-days
Schedule notification daywrite:privacy
POST/api/me/cheers/send
Cheer own active runwrite:cheers
GET/api/me/tokens
List API tokensClerk JWT
POST/api/me/tokens
Create API tokenClerk JWT
DELETE/api/me/tokens/:id
Revoke tokenClerk JWT
GET/api/me/webhooks
List webhooksread:events
POST/api/me/webhooks
Create webhookwrite:events
PATCH/api/me/webhooks/:id
Update webhookwrite:events
DELETE/api/me/webhooks/:id
Delete webhookwrite:events
GET/api/me/activity
Activity feedread:profile
GET/api/me/garmin/status
Garmin connectionread:profile

Full OpenAPI 3.1 spec at /api/openapi.json

Real-time

Events, not polling

Register a webhook URL. We POST signed JSON payloads when things happen. HMAC-SHA256 on every request. Retry with exponential backoff. Your agent reacts in real time.

run.started

Runner begins a GPS-tracked run

run.finished

Run completed with summary stats

cheer.received

Someone cheered during a run

follower.requested

New follow request incoming

follower.approved

Follow request was approved

spectator.milestone

3, 5, 10, 25, 50, 100 watchers

trackpoints.batch

New GPS data (configurable)

incoming webhook
1POST https://your-agent.dev/webhook
2X-DotDot-Signature: sha256=a8f5f1...
3Content-Type: application/json
4
5{
6 "event": "spectator.milestone",
7 "timestamp": "2025-07-12T09:45:00Z",
8 "data": {
9 "run_id": "a1b2c3d4",
10 "runner": "sarah",
11 "threshold": 50,
12 "count": 53,
13 "top_followers": [
14 "Coach Mike",
15 "Alex",
16 "Sam"
17 ]
18 }
19}

Verify the signature. Parse the JSON. Do your thing.

.well-known/agent.json
1GET /.well-known/agent.json
2
3{
4 "name": "DotDot",
5 "description": "Live GPS run tracking for ultra runners, with a programmable API for agents",
6 "url": "https://dotdot.sivoov.app",
7 "openapi": "https://dotdot.sivoov.app/api/openapi.json",
8 "auth": {
9 "type": "bearer",
10 "instructions": "Create a Personal Access Token at /dashboard?tab=integrations"
11 },
12 "mcp": {
13 "url": "https://dotdot.sivoov.app/api/mcp",
14 "transport": "streamable-http"
15 },
16 "webhook_events": [
17 "run.started",
18 "run.finished",
19 "cheer.received",
20 "follower.requested",
21 "follower.approved",
22 "spectator.milestone",
23 "trackpoints.batch"
24 ]
25}

Standards-first

Auto-discovery built in

DotDot publishes a standard discovery file at /.well-known/agent.json. It points at both the MCP endpoint and the OpenAPI spec, so an agent can pick whichever it speaks. No SDK to install. No vendor lock-in. Just HTTPS and JSON.

MCP (streamable HTTP)OpenAPI 3.1HMAC-signed webhooksScoped tokens

The one human step

Your Garmin watch starts LiveTrack, which emails DotDot. The only manual setup is adding [email protected] as a LiveTrack recipient in Garmin Connect, a one-time step. After that, every run is automatically tracked, broadcast, and available via the API.

Working on full automation. Community recipes for agent-driven setup coming soon.

Your next ultra, fully orchestrated.

Create an account. Generate a token. Let your agent handle the rest.