LoseIt CLI
Nutrition data out of Lose It!, no official API.
the project
LoseIt CLI pulls your nutrition data out of Lose It! and emits standardized per-day nutrition JSON — calories and macros, ready for an agent or script to reason over. It does one thing and stays dumb on purpose: extraction only, no storage, no interpretation. What the numbers meanis the consumer's job.
The catch: Lose It! has no public API. This is the tool that gets the data out anyway — shipped as a static Go binary and an OpenClaw / ClawHub skill.
the hard problem: no official API
There is no documented endpoint to call. So the work was reverse-engineering the real ones: the OAuth password-grant login (api.loseit.com/account/login) and the private data-export endpoint (loseit.com/export/data) — and discovering that the web form's reCAPTCHA isn't actually enforced on the API itself, so a clean authenticated POST works.
That makes the integration inherently fragile — a Lose It! change can break it overnight. The repo treats that as a known operating condition: endpoints are compiled-in constants (not overridable at runtime), and a “When auth breaks” playbook is written down in advance — check for a new captcha, renamed cookies, moved endpoints — so recovery is a known procedure, not a forensic dig.
the engineering
- Self-healing session cache. Tokens expire roughly every 14 days. Rather than make you re-login, the tool detects the expiry, re-authenticates from stored credentials, and retries — no human in the loop. The cached token is written owner-only (
0600). - Credential safety as a hard rule.Login and export requests assert they're going to a first-party host (
*.loseit.com, HTTPS) so a hostile env var or config file can't redirect credentials elsewhere. Secrets are gitignored and never printed. - Data minimization by design. The Lose It! export ZIP also contains bodyweight, exercise, steps, and photos. The tool reads onlythe two nutrition CSVs and discards the rest in memory — enforced as a regression test. Widening that scope would require a separate, security-reviewed, opt-in change; it's never on by default.
- Go 1.24 + cobra, single static binary, cross-compiled to GitHub Releases and auto-published to ClawHub on skill-doc changes.
lessons learned
Mocks lie; the live endpoint is the source of truth.Because the API is undocumented and reverse-engineered, the repo mandates a real end-to-end test against the actual Lose It! service — with real credentials — before any PR is opened. A green mock proves nothing when the thing you're integrating with can change its login form without telling you. The other rule is restraint: the tool deliberately owns no business logic, which keeps its attack surface and its maintenance burden small.
what this demonstrates
- Pragmatic integration against a hostile surface— getting useful data out of a closed system, cleanly, without pretending it's stable.
- Security and privacy treated as invariants — first-party assertions, minimization-as-a-test, secrets handled correctly.
- Honest operations. The failure modes are documented before they happen, because fragile dependencies are a fact, not a surprise.