[Epic] M2M API — keyed third-party data API + guest throttling
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 8/100
- Issue type
- Feature
- Clarity
- Needs clarification
- Activity status
- Quiet
- Domain
- api, authorization, backend
Research direction
This is an epic with no code change of its own; the design lives in docs/features/m2m-api/README.md on the branch named in the body. Read that doc first, then the linked child issues, starting with pskillen/meshflow-api#417 (guest endpoint throttling), which the epic says ships independently. Done means the child issues close and the epic's listed deliverables exist, so a newcomer should pick up one child issue rather than this epic.
Written by the indexing model from the issue text.
Description
Summary
A read-only, versioned machine-to-machine API at /api/m2m/v1/ for third-party dashboards and analytics. It is separate from the bot ingest API (NodeAPIKey) and the web UI API (JWT).
- Approved users (Django group
m2m_api) mint their own API keys, several per user, after accepting versioned terms: acceptable use, good faith, non-commercial, attribution. Data is licensed CC BY-NC 4.0. - Data is aggregates first (packets today, nodes heard, role mix, feeder counts, time series), plus infrastructure nodes with health metrics. Meshtastic and MeshCore are strictly split. No positions.
- This epic also adds throttling to the existing guest-readable endpoints, which are currently unthrottled, so the M2M terms can't be bypassed by scraping.
Motivating request: a scotmesh-style dashboard (cf. https://meshcore.scotmesh.net/) for the Meshtastic side, linking back to Meshflow node pages.
Design doc: docs/features/m2m-api/README.md (on branch claude/elegant-ramanujan-llmcka until merged)
Key decisions
| Topic | Decision |
|---|---|
| Path | /api/m2m/v1/ on the existing domain; key management at /api/m2m/keys/ (JWT) |
| Mint permission | Django group m2m_api (or staff), checked only when minting |
| Request auth | API key only: exists, hash matches, not revoked, owner.is_active. No group check per request. |
| Disabling a user | Kills all their keys immediately and stamps them revoked |
| Group removal | Stops new mints only; existing keys keep working |
| Withdraw | One staff operation: remove from group and revoke all keys |
| Terms bump | 90-day grace period, then 403 until re-accepted |
| "Today" | UTC calendar day, documented in feature docs and OpenAPI |
| Infra roles (MT) | nodes.constants.INFRASTRUCTURE_ROLES (ROUTER, ROUTER_CLIENT, REPEATER, ROUTER_LATE). Not CLIENT_BASE. |
| Infra types (MC) | adv_type repeater, room |
| Feeders | Aggregate counts only |
| Positions | Omitted |
| Opt-out | ObservedNode.m2m_opt_out, settable by claimant, managed-node owner or staff. Excluded from per-node output, still counted in aggregates. |
| Ingress | Prod reaches Django only via Cloudflare Tunnel, so CF-Connecting-IP is trusted in prod (behind a setting) |
| Initial rates | Guest 120/min/IP · guest expensive 10/min/IP · JWT user 600/min · M2M 60/min + 5000/day per key, same ceiling per owner |
Breakdown (delivery order)
API (meshflow-api)
- pskillen/meshflow-api#417 Guest endpoint throttling. Ships independently.
- pskillen/meshflow-api#418 API keys: model, auth, terms, CRUD, throttles
- pskillen/meshflow-api#419 Staff "withdraw M2M access" (needs #418)
- pskillen/meshflow-api#420 Node opt-out flag
- pskillen/meshflow-api#421 v1 Meshtastic data endpoints (needs #418, #420). Unblocks the requester.
- pskillen/meshflow-api#422 Usage metering (needs #418)
- pskillen/meshflow-api#423 v1 MeshCore endpoints (needs #421)
- pskillen/meshflow-api#424 History: role-mix snapshots, infra health (later)
UI (meshflow-ui)
- pskillen/meshflow-ui#362 Developer / API access page (with #418)
- pskillen/meshflow-ui#363 Opt-out toggle (with #420)
Done when
- Guest endpoints are throttled in prod with CF-aware client IPs, and ingest is untouched.
- An approved user can mint a key in the UI, and the scotmesh-style dashboard can be built against
/api/m2m/v1/meshtastic/*. - MeshCore endpoints reach parity.
openapi-m2m.yamlis published, andENV_VARS.md,REDIS.mdandpermissions/README.mdare updated.
- Dominant language
- Python
- Stars
- 1
- Forks
- 0
- Avg merge
- 1d 20h
- Merged PRs (30d)
- 5
Getting set up
- Ships a Dockerfile or Docker Compose file
- Has a pull request template
- No contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from pskillen/meshflow-api
-
enhancement meshtastic-2.8
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
pskillen/meshflow-api#459 ·
-
enhancement meshtastic-2.8
Difficulty 3/5 1-2 days Newbie friendliness 35/100
pskillen/meshflow-api#465 ·
-
enhancement meshtastic-2.8
Difficulty 4/5 3-5 days Newbie friendliness 22/100
pskillen/meshflow-api#464 ·
-
enhancement meshtastic-2.8
Difficulty 4/5 3-5 days Newbie friendliness 35/100
pskillen/meshflow-api#463 ·
-
enhancement meshtastic-2.8
Difficulty 3/5 1-2 days Newbie friendliness 45/100
pskillen/meshflow-api#462 ·
All issues in pskillen/meshflow-api
Similar issues
-
Import errors are swallowed: PerthImplicitWatermarker silently becomes NonePossibly taken @JonRC claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
resemble-ai/Perth#23 ·
-
correction metadata
Difficulty 2/5 Under an hour Newbie friendliness 65/100
acl-org/acl-anthology#10753 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
earthtojake/text-to-cad#758 ·
Maintainers usually reply within 1 day
-
Difficulty 1/5 1-3 hours Newbie friendliness 70/100
DataTalksClub/faq#545 ·
Maintainers usually reply within 2 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
Maintainers usually reply within 1 day