Submit a feedback report
POST/api/feedback
submitFeedback
Files a pre-alpha feedback report from the in-app launcher: what the reporter typed, the page they were on, and the console/request diagnostics the client buffered, plus an optional pasted screenshot as base64. Session-authenticated only — a scoped service token is refused. Diagnostics are capped server-side (body 4000 characters; the newest 200 console entries and 100 request entries) and over-cap payloads are TRUNCATED rather than rejected: the `truncated` object in the response says exactly what was dropped. The screenshot is the exception — it is refused with 415 if its type is not an allowlisted raster image (SVG is never accepted), 413 if it decodes to more than 4 MiB, and 400 if the bytes do not sniff as the type they declare. An accepted screenshot is METADATA-STRIPPED (EXIF/GPS included) and capped at 4096 pixels on its long edge before it is stored, so the raw upload never exists at rest. The stored content type is therefore what was actually WRITTEN, not what was declared — a downscaled WebP is stored as JPEG (or PNG when it has alpha) — and `size_bytes` is the size of the stored object. The 4 MiB limit is enforced on that stored object as well as on the upload, because a re-encode can be larger than its input.
Requires authentication using a session cookie — see tokens and scopes.
curl
curl -X POST 'https://neosource.dev/api/feedback' \
-b 'ns_session=$NEOSOURCE_SESSION' \
-H 'Content-Type: application/json' \
-d '{"kind":"string","body":"string"}'fetch
fetch("https://neosource.dev/api/feedback", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
credentials: "include",
body: JSON.stringify({"kind":"string","body":"string"}),
});Request bodyrequired
application/json
Responses
201Report filed
application/json
403Forbidden — one of: forbidden, needs_scope
application/json
413The screenshot decodes to more than the server's per-image limit, NORMALISES to more than that limit, or the whole request body exceeded the route's limit. Nothing else on this route is size-rejected — it is truncated.
415The screenshot's content type is not an allowlisted raster image. SVG is deliberately never accepted.
503The process-global upload pool is full. Held for the whole handler, ahead of the image decode, so a flood is shed here rather than queueing on a decode permit while holding a buffered body. Retry after the `Retry-After` header.
Standard errors
Bodies documented once for the whole API — see standard errors.
- 400Bad Request — one of: invalid_input
- 401Authentication required
- 404Not Found — one of: not_found
- 429Rate limited — retry after the `Retry-After` header
- 500Internal server error
- 504Gateway timeout — the request exceeded the server's handling budget