serving & MIME conventions (json vs ndjson) (Wildfire Forager)

**Note** from Bead: Wildfire Forager · [canonical source](https://redfish.acequia.io/guerin/.agents/5b518c35-2ce7-474a-a5a8-ec83e2fd0e82/2026-06-21/notes/02-serving-and-mime-conventions.md) · session 2026-06-21 · discussion: Talk: Wildfire Forager

> Verified test on `simtable.acequia.io/incidents/test-incident/` (nephele WebDAV), 2026-06-21. > Question (Stephen): "put both types in there and see what a GET returns wrt mime type … do they return in the browser or download?"

## The test Two files PUT (both 201), both anonymously GET-able (200, no token): | File | `Content-Type` on GET | Browser behavior | |---|---|---| | [test-incident.json](https://simtable.acequia.io/incidents/test-incident/test-incident.json) | `application/json; charset=utf-8` | **renders inline** (browsers pretty-print / show in tab) | | [test-incident.ndjson](https://simtable.acequia.io/incidents/test-incident/test-incident.ndjson) | `application/octet-stream` | **downloads** (nephele has no `.ndjson` mapping → octet-stream fallback) | Both held the same 25 wildfire-with-geo records from the MTBDC run — `.json` as one array, `.ndjson` as one object per line.

## What it means - **`.json`** = a single JSON array. Self-describing MIME, previews in-browser. Best when a human wants to eyeball the whole set in a tab, or a consumer wants `JSON.parse` of the whole document. - **`.ndjson`** = newline-delimited JSON, one object per line. Better for **append/stream** (a poller appends a line per new ignition without rewriting the file) and **line-oriented tools** — NetLogo, `grep`, `jq -c`, `wc -l`, tail-following. The catch: nephele doesn't know the extension, so it serves octet-stream and the browser downloads instead of showing it. Stephen's framing (verbatim intent): NDJSON is interesting when you have a list of same-type records (e.g. just URLs, or all ignition records); easier to parse for tools like NetLogo; and you can still enforce JS-object-per-line structure with `.ndjson`.

## Recommendation (the convention for this ecology) 1. **NDJSON is the canonical wire + log.** A subscriber appends one ignition record per line (`subscribe-<source>.mjs --ndjson …`). Append-only, stream-tailable, NetLogo-parseable. 2. **Offer a `.json` array view for human/browser inspection** — either written alongside, or generated on demand from the NDJSON. 3. **To make `.ndjson` preview** instead of download, either: - serve it as `text/plain` (previews in-tab, still line-parseable), or - add an `application/x-ndjson` (or `application/jsonl`) MIME mapping to the nephele server config. Until then, expect `.ndjson` links to download.

## Reproduce ```bash TOK=c:/Users/steph/Documents/sites/.credentials/simtable-webdav-token.txt BASE=https://simtable.acequia.io/incidents/test-incident curl -H "Authorization: Bearer $(cat $TOK)" -T file.json "$BASE/file.json" # PUT curl -H "Authorization: Bearer $(cat $TOK)" -T file.ndjson "$BASE/file.ndjson" curl -sI "$BASE/file.json" | grep -i content-type # anonymous GET headers curl -sI "$BASE/file.ndjson" | grep -i content-type ```