API
Same-origin JSON under /api. Anything the page can do, a script can do. Unknown fields and unknown query parameters are rejected with 400 unknown_field, never ignored. Errors look like {"error":{"code","message"}}.
POST /api/scan
No account needed (5 scans an hour per visitor; signed in, 60 a month).
curl -s https://leanbump.grain64.com/api/scan \
-H 'content-type: application/json' \
-d '{"repo_url":"https://github.com/b-mehta/PrimeCert","ref":"f699a3e5"}'
repo_url- required. A public GitHub address; a
/tree/<ref>URL works. ref- optional. Branch, tag or commit. Default: the default branch.
from- optional, like
v4.20.0. Default: detected fromlean-toolchainand the Lake manifest. to- optional. Default: newest release in the map.
Returns id, repo_url, ref, commit_sha, from, to, pin, line (the totals sentence), totals (occurrences, files, safe_renames, check_renames, removed_no_alias, will_break, warn_only), per_file, path (release by release), hits (each: file, line, col, token, old, new, label, certainty, confidence, module, since, breaks), files_scanned, truncated. Results of the same repository, ref and target are reused for 10 minutes.
GET /api/scans/:id
A saved result by id, the same body as the scan.
GET /api/rename
Query: name (required: an old name, or a whole unknown identifier line), from, to (optional releases). Returns query, matches (each: old, new, module, deprecated_since, deprecated_in, removed_in, last_present_in, type_changed, source, confidence, source_url, match) and coverage.
curl -s 'https://leanbump.grain64.com/api/rename?name=mul_right_eq_self'
GET /api/deprecations
Query: from (required), to, module_prefix, cursor, limit (1 to 200, default 50). Returns items and next_cursor.
GET /api/rename-map
Query: from (required), to. The whole slice as compact rows with columns: old, new, confidence, module, deprecated_since, first_idx, last_idx, removed.
GET /api/benchmark
The benchmark results behind /benchmark as JSON, no parameters.
POST /api/waitlist and POST /api/contact
Waitlist body: email, plan (Pro), both required. Contact body: message required; topic (feedback, correction, remove_project, bug, other), email, page, honeypot optional.
Account routes
POST /api/auth/request {email} sends a one-time link; POST /api/auth/verify {token} opens a session cookie; POST /api/auth/logout; GET /api/me; GET /api/projects; POST /api/projects {repo_url, name?}; POST /api/projects/:id/scan {from?, to?, ref?}; GET /api/projects/:id/scans; DELETE /api/projects/:id; GET /api/export; DELETE /api/account {confirm: your email}; POST /api/survey {answer}.
What a scan means
The scan reads names. certainty is exact (the full name), by-open (a short name resolved through an open) or possible (a bare word or short suffix also in the map; never counted in the totals). confidence below 0.8 means the replacement was taken from the deprecation message text: check it. breaks is true when the name is gone at the target and false when it is deprecated but still present.