What a report contains
A report is a single JSON object describing a file from its bytes. Here is every field, how it is bounded, and the endpoint that produces it.
Upload the file first with POST /api/files, then analyze it by id. Analysis is owner-scoped — a file that is not yours answers 404 — and it runs on stored bytes, so no re-upload is needed.
# Analyze a file you have already uploaded (POST /api/files)
curl -X POST "$BASE/api/files/$FILE_ID/sandbox" \
-H "Authorization: Bearer $API_KEY"
# Fetch the most recent report without re-analyzing
curl "$BASE/api/files/$FILE_ID/sandbox" \
-H "Authorization: Bearer $API_KEY"A POST writes a new report (append-only history); a GET returns the most recent one, or 404 when the file has not been analyzed yet.
identitySHA-256, size in bytes, MIME type, and the file kind.formatThe format read from magic bytes, with header facts. Real parsers for PE/COFF (machine, DLL vs EXE, link timestamp, sections), ELF, Mach-O (labelled), and PDF (counts of /JavaScript, /OpenAction, /Launch, /EmbeddedFile). Archives are labelled, never expanded.sectionsPer-section name, size, flags and Shannon entropy (PE and ELF section tables). A high-entropy section carries a packed_likely flag.entropyOverall Shannon entropy and a packed_likely flag — surfaced as a fact, never a trigger to unpack.stringsPrintable ASCII and UTF-16 runs extracted from the bytes.iocs / ioc_totalURLs, IPv4 addresses, domains, emails, hashes and registry keys, grouped and counted.re_staticReverse-engineering facts: architecture, bit width, and the import table (PE import directory / ELF dynamic symbols). radare2 enriches this when present; otherwise a dependency-free parser recovers the same imports.captureFor a pcap/pcapng: a summary of the record/block structure. Payloads are counted, never inspected.safety / partial / duration_msThe never-executed guarantee as a string, a partial flag when an analyzer could not finish, and how long the pass took.
{
"schema": "sandbox.report/1",
"analyzer_version": "1",
"identity": {
"sha256": "d3b07384d113edec49eaa6238ad5ff00…",
"size_bytes": 214016,
"mime": "application/x-dosexec",
"kind": "artifact"
},
"format": {
"label": "PE (Windows executable)",
"machine": "x86-64",
"is_dll": false,
"link_timestamp": "2024-03-28T00:00:00Z"
},
"sections": [
{ "name": ".text", "size": 96256, "entropy": 6.41 },
{ "name": ".rdata", "size": 41984, "entropy": 5.02 },
{ "name": ".rsrc", "size": 61440, "entropy": 7.73, "packed_likely": true }
],
"entropy": { "overall": 6.88, "packed_likely": false },
"re_static": {
"arch": "x86-64", "bits": 64,
"imports": ["kernel32!CreateFileW", "ws2_32!connect", "advapi32!RegSetValueExW"]
},
"iocs": {
"url": ["http://example-c2.test/gate.php"],
"ipv4": ["203.0.113.14"],
"registry_key": ["HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"]
},
"ioc_total": 3,
"strings": ["GetProcAddress", "cmd.exe /c", "%APPDATA%"],
"partial": false,
"duration_ms": 74,
"safety": "Static analysis only. The sample was never executed, unpacked, decompressed, or detonated; only bytes at rest were read."
}The whole pass runs against a short wall-clock budget with byte and count caps, so a huge or awkward file can never hang the analysis. Any analyzer that cannot make sense of its bytes is caught and the report is marked partial — you get the facts that were recovered, never a 500 and never a fabricated field.
The report says what it is at the bottom, every time: static analysis only, the sample was never executed, unpacked, decompressed, or detonated.
When you analyze a clean file and keep chatting, the report travels with it into the model’s context — fenced and labelled as untrusted external data, so a hostile string inside the sample is evidence to reason about, never an instruction. That is what lets you ask “what stands out here?” and get an answer grounded in the file’s actual bytes. Which models are built for this →