Inspect a native app's processing stages, timings and decisions without uploading the user's content or treating successful work as a crash
Last updated October 24, 2026
Native Processing Reports
Processing reports explain how an app handled one operation. They carry a random report UUID, ordered stages, elapsed milliseconds, numeric counts, fixed decisions and the app release. A run can succeed, fail, be cancelled or be interrupted. These reports create no error issue or release session and do not affect crash-free rates, browser visits or hidden-origin totals. Native crash stacks still belong in Error Tracking and Issues.
The initial version supports floorplan-import. It intentionally cannot carry image bytes, OCR strings, addresses, filenames, room names, coordinates, user identifiers or arbitrary log messages. Use the enum and numeric fields below to explain processing decisions. A count is diagnostic context, not proof that a reconstruction is accurate.
Send a report
Post JSON to https://flaggr.dev/api/ingest/mobile-processing with the app's public Site ID. No secret belongs in a mobile binary. Ingest uses the same Site ownership and optional SDK/project-key checks as mobile errors. These are client-reported, unauthenticated-device observations; knowing a Site ID does not establish which device sent a run.
{
"siteId": "site_your_app",
"reports": [{
"schemaVersion": 1,
"reportId": "407259a8-9093-4399-a669-97a4996f335b",
"sessionId": "507259a8-9093-4399-a669-97a4996f335b",
"operation": "floorplan-import",
"sourceKind": "photo",
"startedAt": "2026-10-24T05:00:00.000Z",
"timestamp": "2026-10-24T05:00:01.000Z",
"release": "com.example.app@1.0.0+3",
"appVersion": "1.0.0",
"buildNumber": "3",
"osVersion": "26.0",
"deviceModel": "iPhone18,1",
"platform": "ios",
"outcome": "succeeded",
"submission": "automatic",
"durationMs": 1000,
"stages": [
{ "sequence": 1, "stage": "started", "elapsedMs": 0, "counts": { "sources": 1 } },
{ "sequence": 2, "stage": "selectingRegions", "elapsedMs": 500,
"counts": { "candidateRegions": 2, "excludedOverviewRegions": 1 }, "decision": "overviewRemoved" },
{ "sequence": 3, "stage": "completed", "elapsedMs": 1000, "counts": { "rooms": 5 } }
],
"summary": { "rooms": 5, "excludedOverviewRegions": 1 },
"truncated": false
}]
}Use actual timestamps and random UUIDs. The request contains exactly one report and is at most 64 KiB. The report contains 1–40 stages with increasing sequences (1–40) and non-decreasing elapsed times no greater than durationMs. All counts and times are non-negative integers up to 604,800,000. Reports must start within the last seven days and finish no more than one minute into the future. Clients should expire pending reports earlier so retries can still arrive within that window.
A successful durable write returns HTTP 202 with {"accepted":1,"rejected":0,"throttled":0}. Invalid schema returns 202 with accepted:0,rejected:1; do not call that delivered. Oversized bodies return 413; IP or Site quotas return 429. The Site quota is 60 requests per minute. HTTP 5xx means retry later. Delivery is at least once: a lost response may leave duplicate stored rows. Reads collapse duplicates by Site/report UUID and show the latest received copy, so keep a report's UUID and contents stable across retries. There is no database migration for this feature.
Version 1 fields
| Field | Values |
|---|---|
sourceKind | file, photo, scan, sample |
outcome | succeeded, failed, cancelled, interrupted |
submission | automatic, manual |
stage | started, downloading, reading, preparing, findingWalls, straightening, readingLabels, selectingRegions, findingOpenings, buildingRooms, reviewReady, saving, completed |
Optional decision | preserved, overviewRemoved, annotationsRemoved, ambiguousPreserved |
Optional failure | unreadable, encrypted, tooSmall, noPlanLikePage, noWalls, inkOutOfRange, cancelled, saveFailed, interrupted; not allowed for a successful run |
Count keys, in counts and summary | sources, pages, candidateRegions, excludedOverviewRegions, excludedAnnotationRegions, removedTextObservations, removedForegroundPixels, textObservations, walls, rooms, levels, issues, scaleCandidates |
The five release/device metadata fields are required and bounded to 200 token-like characters; email addresses and credentials are rejected. Unknown fields and count keys are discarded, and invalid enum values reject the report. The server sets trust marks itself and never accepts a client-supplied service ID.
Inspect a run
Use the read-only MCP tool list_mobile_processing_reports with siteId and optionally reportId, outcome, range (1h, 24h, 7d, 30d) and limit (default 20, maximum 100). It returns the complete bounded stage trace and current authoritative Site-to-service association. The initial default is seven days. The hosted tool ships with this change; published @flaggr/mcp-server 0.4.0 predates it.
The same data is available to project members through:
GET /api/analytics/mobile-processing?siteId=site_your_app&range=7d&reportId=<uuid>The read checks the Site's actual owning project, service-scoped credential restrictions and Site integrity. A caller-supplied project ID cannot grant access to another Site. Public showcase access does not expose reports or report-existence lookups. Responses are private and not cached. Trust marks and network-origin hashes are not returned. Access controls protect reading; the public ingest Site ID cannot authenticate an individual device.
An interrupted run only says the app recovered an unfinished operation. It is not a native crash classification. A successful report confirms the stages that ran, not a person's approval of the resulting floor plan.