Halton Meter Docs
Docs /Halton Meter Cloud /Prompt & response bodies
HALTON METER CLOUD Stable

Prompt & response bodies

How Cloud handles request and response bodies: stored only when the workspace opts in, redacted daemon-side, off by default.

macOS · Linux · Windows ·5 min read ·Updated Jun 8, 2026

With the default off, no prompt text leaves the machine.

Captured request and response bodies are the highest-leak data the daemon holds: a request body carries the full prompt you sent, a response body carries the model's full completion. Cloud can store them, but only when the workspace has explicitly turned that on. The switch is store_prompt_content, and it defaults to OFF. When it is off the ordinary metadata sync carries no prompt or completion text at all. This page documents the mechanism end to end: the wire shape, the auth, the opt-in gate, and what the default protects.

1. What syncs when bodies are off

The default metadata sync (POST /v1/requests/batch) never carries prompt or completion text. With store_prompt_content off, the only thing that leaves the machine per request is metadata:

  • Token counts (prompt, completion, cache-read, cache-write).
  • Model and provider.
  • Cost (recomputed cloud-side from seeded pricing rates).
  • Latency and HTTP status / error class.
  • Project attribution and prompt_hash (a SHA-256 fingerprint, not the prompt).

That list is structurally complete: with the gate off, the body endpoint persists nothing, so there is no path by which prompt text reaches the cloud database. See Data sync & retention for the full per-field table.

Plain-English placeholder: when body storage is off, we do not store the text of your prompts or the model's replies, only the metadata listed above. (Exact lawful-basis wording under UK GDPR Art.5(1)(c)/25 is pending legal review.)

2. The body endpoint

Bodies sync on a separate endpoint from the metadata batch, live since daemon v0.2.2:

POST /v1/requests/{id}/body
Authorization: Bearer hm_sync_…

The token must carry the sync or admin scope. The wire shape is BodyEnvelopeV021. The daemon sends two POSTs per captured request, one with direction=request and one with direction=response. Both upsert into a single request_bodies row keyed on request_id. It is last-write-wins per direction: there is no content dedup, and a re-send of the same direction overwrites the prior value.

The envelope fields:

FieldWhat it is
request_idUUID of the captured request the body belongs to
directionrequest or response
content_typeMIME type of the body (e.g. application/json)
body_b64Base64 of the post-redaction body bytes
redaction_appliedBoolean: did any redaction rule fire
redaction_summaryList of rule names that fired, e.g. ["email", "aws-access-key"]
original_size_bytesSize of the body before base64 encoding

Redaction happens daemon-side, before upload. The bytes in body_b64 are already redacted; the cloud never sees the pre-redaction body, and redaction_summary reports which rules ran so the result is auditable.

Cloud decodes body_b64 from base64 to UTF-8 and stores the text. Input that is not valid base64, or that does not decode to UTF-8, is rejected with a 400.

3. The opt-in gate

Persistence is gated on the workspace flag store_prompt_content, which defaults to FALSE. The endpoint's behaviour depends entirely on it:

  • Off (default). The endpoint returns 200 with {stored: false, reason: "store_prompt_content_disabled"} and persists nothing. The body is discarded and unrecoverable.
  • On. The endpoint persists the decoded body and returns 204.

Because the default is off, the privacy promise holds cloud-side, not just by daemon convention: the database has no row to read because the endpoint refused to write one.

When redaction_summary is non-empty the cloud OR-merges redaction_applied across the two directions, so a row reads as redacted if either the request or the response had a rule fire.

4. Daemon-side body sync

On the daemon, body sync is its own switch, off by default and independent of the cloud-side store_prompt_content flag. Inspect the current policy:

$ halton-meter cloud privacy show

Enabling daemon body upload is documented in Data sync & retention. Both gates must be on for a body to be stored: the daemon must be configured to upload it, and the workspace must have store_prompt_content on. If the daemon uploads while the workspace gate is off, the endpoint returns 200 and discards the payload.

~: body endpoint, gate off
$ halton-meter cloud sync
 POST /v1/requests/<id>/body  →  200  {stored: false, reason: store_prompt_content_disabled}
# Gate off: the cloud discarded the body. Metadata still synced.

Plain-English placeholder: who on a team may view a stored body, and the audit logging around that access, is governed by a separate policy. (Exact teammate prompt-visibility wording is pending legal review; the live access rule is a role check, documented under Consent.)

See also