Projects, favorites and alerts
Save and share analyses as projects, keep a watchlist of favorite places and set visit alerts through the API.
These endpoints manage your organization’s working state: projects (saved analyses), favorites (a watchlist of places) and alerts (week-over-baseline change notifications). All require authentication; paths are relative to https://api.mapdove.com/api/v1.
| Method | Path | Purpose |
|---|---|---|
| GET | /projects |
List projects |
| POST | /projects |
Create a project |
| GET | /projects/:id |
Get a project |
| PATCH | /projects/:id |
Update a project |
| DELETE | /projects/:id |
Delete a project |
| GET | /favorites |
List favorite places |
| PUT | /favorites/:place_id |
Add a favorite |
| DELETE | /favorites/:place_id |
Remove a favorite |
| GET | /alerts |
List alerts with evaluation |
| POST | /alerts |
Create an alert |
| DELETE | /alerts/:id |
Delete an alert |
Projects
A project stores an analysis — its kind, city, parameters and result — plus notes, so the team can reopen and reproduce it. Projects are visible to everyone in the organization.
{
"id": "6f1c2a8e-3d4b-4f0a-9a51-0b7e2c9d1f33",
"name": "Austin café #12 — shortlist",
"kind": "compare",
"city_slug": "austin",
"params": { "category": "coffee", "sites": ["…"], "weights": { "daytime": 8, "gap": 7 } },
"result": { "sites": ["…"] },
"notes": "Mueller preferred; check landlord TI allowance.",
"created_at": "2026-11-04T15:22:10Z",
"updated_at": "2026-11-05T09:01:44Z",
"created_by_name": "Ada Park"
}
kind is one of site_selection, huff, catchment, compare, trade_area. params and result are free-form JSON — store the request body you sent and the response you received.
List projects
curl https://api.mapdove.com/api/v1/projects \
-H "Authorization: Bearer $MAPDOVE_KEY"
Returns Project[].
Create a project
POST /projects — body { name, kind, city_slug, params, result?, notes? }. Returns 201 with the project.
curl -X POST https://api.mapdove.com/api/v1/projects \
-H "Authorization: Bearer $MAPDOVE_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Mueller coffee forecast",
"kind": "huff",
"city_slug": "austin",
"params": { "category": "coffee", "lng": -97.7046, "lat": 30.2981, "sqft": 2200, "brand_strength": 1.1 },
"result": { "predicted_daily_visits": 397, "total_cannibalized_daily": 212 },
"notes": "Base case."
}'
// Run a model, then save it as a project
const params = { city: 'austin', category: 'coffee', lng: -97.7046, lat: 30.2981 };
const headers = { Authorization: `Bearer ${key}`, 'Content-Type': 'application/json' };
const result = await fetch(`${BASE}/sdss/huff`, { method: 'POST', headers, body: JSON.stringify(params) }).then((r) => r.json());
const project = await fetch(`${BASE}/projects`, {
method: 'POST',
headers,
body: JSON.stringify({ name: 'Mueller coffee forecast', kind: 'huff', city_slug: 'austin', params, result }),
}).then((r) => r.json());
params = {"city": "austin", "category": "coffee", "lng": -97.7046, "lat": 30.2981}
result = requests.post(f"{BASE}/sdss/huff", headers=H, json=params, timeout=120).json()
project = requests.post(f"{BASE}/projects", headers=H, timeout=30, json={
"name": "Mueller coffee forecast", "kind": "huff", "city_slug": "austin",
"params": params, "result": result,
}).json()
print(project["id"])
Saving a project does not count as an analysis; only the model run does.
Get, update, delete
# Get
curl https://api.mapdove.com/api/v1/projects/6f1c2a8e-3d4b-4f0a-9a51-0b7e2c9d1f33 \
-H "Authorization: Bearer $MAPDOVE_KEY"
# Update notes (any of name, params, result, notes)
curl -X PATCH https://api.mapdove.com/api/v1/projects/6f1c2a8e-3d4b-4f0a-9a51-0b7e2c9d1f33 \
-H "Authorization: Bearer $MAPDOVE_KEY" -H "Content-Type: application/json" \
-d '{ "notes": "Approved for LOI." }'
# Delete → 204
curl -X DELETE https://api.mapdove.com/api/v1/projects/6f1c2a8e-3d4b-4f0a-9a51-0b7e2c9d1f33 \
-H "Authorization: Bearer $MAPDOVE_KEY"
PATCH returns the updated project and bumps updated_at.
Favorites
Favorites are a watchlist of places. GET /favorites returns them as PlaceSummary[] computed over the last 30 days of data.
# Add place 42 → 204
curl -X PUT https://api.mapdove.com/api/v1/favorites/42 \
-H "Authorization: Bearer $MAPDOVE_KEY"
# List
curl https://api.mapdove.com/api/v1/favorites \
-H "Authorization: Bearer $MAPDOVE_KEY"
# Remove → 204
curl -X DELETE https://api.mapdove.com/api/v1/favorites/42 \
-H "Authorization: Bearer $MAPDOVE_KEY"
[
{ "id": 42, "name": "Bean Republic · Downtown", "visits": 11520, "visits_prev": 11208, "change_pct": 2.8, "avg_daily_visits": 384, "…": "…" }
]
PUT is idempotent — adding an existing favorite is not an error.
Alerts
An alert watches one metric of one place and reports whether the latest week moved more than a threshold. Alerts are evaluated whenever you list them:
change_pct = 100 · (current_week − baseline_week) / baseline_week
current_week— the latest 7 days of data (sum of visits or visitors; average dwell).baseline_week— the weekly average of the 4 weeks before that.
An alert is triggered when it is active and the change passes the threshold in the chosen direction.
| Field | Values |
|---|---|
place_id |
integer |
metric |
visits (default), visitors or dwell |
direction |
up (change ≥ threshold), down (change ≤ −threshold) or either (absolute change ≥ threshold) |
threshold_pct |
percentage, e.g. 10 |
Alert counts are limited by plan: Free 0, Pro 10, Business 100, Enterprise unlimited. Creating one beyond the limit returns 402 plan_limit.
Create an alert
curl -X POST https://api.mapdove.com/api/v1/alerts \
-H "Authorization: Bearer $MAPDOVE_KEY" \
-H "Content-Type: application/json" \
-d '{ "place_id": 42, "metric": "visits", "direction": "down", "threshold_pct": 10 }'
alert = requests.post(f"{BASE}/alerts", headers=H, timeout=30, json={
"place_id": 42, "metric": "visits", "direction": "down", "threshold_pct": 10,
}).json()
Response 201:
{
"id": "0d9b5f3e-1c7a-4e2b-8f6d-5a4c3b2a1e0f",
"place_id": 42, "place_name": "Bean Republic · Downtown",
"metric": "visits", "direction": "down", "threshold_pct": 10,
"active": true, "created_at": "2026-11-06T10:12:03Z",
"triggered": false, "last_change_pct": -3.4
}
List and delete
curl https://api.mapdove.com/api/v1/alerts -H "Authorization: Bearer $MAPDOVE_KEY"
curl -X DELETE https://api.mapdove.com/api/v1/alerts/0d9b5f3e-1c7a-4e2b-8f6d-5a4c3b2a1e0f \
-H "Authorization: Bearer $MAPDOVE_KEY"
To build notifications, poll GET /alerts on a schedule (once a day is plenty — the data is daily) and act on items whose triggered is true.