API reference
Endpoints
The CLI is a thin wrapper over these endpoints; you can call them directly. The API is in beta.
- Base URL
https://memprobe.dev - Auth
Authorization: Bearer mp_live_xxxxxxxx
What is metadata? The section and symbol table read from your ELF. The CLI builds it locally, you never write it by hand. Your binary is never uploaded.
metadata shape
{
"filename": "firmware.elf",
"binary": { "arch": "xtensa", "bitness": 32 },
"sections": [
{ "name": ".text", "size": 290816, "alloc": true }
],
"symbols": [
{ "name": "ui_render", "size": 8124, "section": ".text" }
]
}
POST/api/analyze
Size analysis. Saves a build.
Body
{ "metadata": { ... }, "project": "name" or null }POST/api/check
Budget gate. Budgets are in bytes.
Body
{ "metadata": { ... }, "budgets": { "flash": 524288, "ram": 131072 } }POST/api/diff
Size change between two builds.
Body
{ "base": { ... }, "head": { ... }, "fail_on": { "flash": 0 } }GET/api/account
Plan and this month's usage. No body.
Response formats
All responses are JSON; sizes are in bytes. On error you get { "error": "message" } with a 4xx status (401 bad key, 402 or 429 quota, 400 bad request).
analyze
{
"filename": "firmware.elf",
"total_flash": 412048,
"total_ram": 86320,
"section_count": 12,
"symbol_count": 1894,
"top_symbols": [
{ "name": "ui_render", "size": 8124, "section": ".flash.text" }
],
"warnings": [
{ "level": "warning", "message": "..." }
],
"build_id": 27
}
| total_flash | Bytes in flash (code and read-only data). |
| total_ram | Bytes in RAM at runtime. |
| top_symbols | Largest symbols, each with name, size, and section. |
| build_id | Id of the saved build, or null if it was not saved. |
check
{
"passed": false,
"total_flash": 540672,
"total_ram": 86320,
"violations": [
{ "kind": "flash", "label": "Flash", "budget": 524288, "actual": 540672, "overage": 16384 }
]
}
| passed | true when no budget was exceeded. |
| violations | One entry per breached budget. |
| overage | Bytes over the budget. |
diff
{
"flash_delta": 2048,
"ram_delta": -512,
"symbol_diffs": [
{ "name": "parse_json", "old_size": 1200, "new_size": 1712, "delta": 512 }
],
"regressions": [
{ "metric": "flash", "delta": 2048, "limit": 0 }
],
"passed": true
}
| flash_delta, ram_delta | Signed byte change, new build minus old. |
| symbol_diffs | Per-symbol old and new size, and the delta. |
| regressions | Present only when fail_on is set and a threshold is breached. |
| passed | false when a fail_on threshold was breached. |
account
{
"plan": "free",
"analyses": {
"used": 12,
"limit": 50,
"remaining": 38,
"period": "month",
"resets": "first of each month (UTC)"
},
"builds": { "used": 5, "limit": 10 },
"projects": { "used": 1, "limit": 2 }
}
| plan | "free" or "pro". |
| analyses.limit, analyses.remaining | null on Pro (unlimited, fair use). |
| analyses.resets | When the monthly counter resets. |
Privacy
Whether you use the CLI or call the API yourself, only section and symbol metadata is processed. Your compiled binary, source, and other file contents are never uploaded. The metadata is the same information readelf -S and nm print.
Analyze your own firmware
Drop in an ELF and see exactly where your flash and RAM go.