Keep a report's AI text as it stands
const url = 'http://localhost:8000/api/solutions/runs/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/keep-ai/';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"fingerprint":"9f2b1c4e7a01d3f5b8c6e2a4d7f0b3c5"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url http://localhost:8000/api/solutions/runs/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/keep-ai/ \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "fingerprint": "9f2b1c4e7a01d3f5b8c6e2a4d7f0b3c5" }'The other half of refresh-ai (#1995). Re-stamps the run’s freshness baseline to the CURRENT inputs and regenerates nothing: no cached prose is dropped, no AiArtifact row is touched, no LLM call is made here or on the next load. The report’s meta.aiStale therefore reads false until the inputs move AGAIN, at which point the notice returns — this records that the coach accepted the text they have (typically because they edited it themselves), it does not disable staleness detection. Offered as the notice’s dismiss control, so a coach who does not want to spend a refresh is not left with a banner they cannot clear. Team-scoped; cross-team run ids are a 404. Compare-and-set: fingerprint must be the meta.aiFingerprint the report GET served, so a change landing while the report was open cannot be dismissed unseen (409). Deliberately NOT rate-limited — the throttle on refresh-ai caps paid-model spend, and this call has none.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”Request Bodyrequired
Section titled “Request Bodyrequired”POST /api/solutions/runs/<id>/keep-ai/ request — the coach keeps the AI
text they were shown (#1995).
fingerprint is the report GET’s own meta.aiFingerprint, echoed back. It
makes the dismiss a compare-and-set instead of a blind stamp: if the inputs
moved while the report was open, the server answers 409 and the notice comes
back describing the change nobody has seen yet, rather than silently
accepting it.
object
The meta.aiFingerprint served with the report being dismissed. A mismatch against the current inputs is a 409.
Examples
Echoes the report GET's own meta.aiFingerprint
{ "fingerprint": "9f2b1c4e7a01d3f5b8c6e2a4d7f0b3c5"}POST /api/solutions/runs/<id>/keep-ai/ request — the coach keeps the AI
text they were shown (#1995).
fingerprint is the report GET’s own meta.aiFingerprint, echoed back. It
makes the dismiss a compare-and-set instead of a blind stamp: if the inputs
moved while the report was open, the server answers 409 and the notice comes
back describing the change nobody has seen yet, rather than silently
accepting it.
object
The meta.aiFingerprint served with the report being dismissed. A mismatch against the current inputs is a 409.
Examplegenerated
fingerprint=examplePOST /api/solutions/runs/<id>/keep-ai/ request — the coach keeps the AI
text they were shown (#1995).
fingerprint is the report GET’s own meta.aiFingerprint, echoed back. It
makes the dismiss a compare-and-set instead of a blind stamp: if the inputs
moved while the report was open, the server answers 409 and the notice comes
back describing the change nobody has seen yet, rather than silently
accepting it.
object
The meta.aiFingerprint served with the report being dismissed. A mismatch against the current inputs is a 409.
Responses
Section titled “Responses”200 from POST /api/solutions/runs/<id>/keep-ai/ — the run’s freshness
baseline was re-stamped to the current inputs and nothing was regenerated,
so meta.aiStale reads false until the inputs move again (#1995).
object
Always true on a 200 — the AI text on the report is now the baseline. No prose was dropped and no LLM call was made.
Examples
Nothing regenerated; the notice stays down until the inputs move
{ "kept": true}object
Human-readable message, or a stable machine code for the cases a client branches on. The standard envelope for 400 (validation — a field-keyed object may appear instead), 401 (missing / invalid credentials), 403 (authenticated but not permitted), and 404 (absent — cross-team records are collapsed to 404 so the API never leaks the existence of another team’s data).
Examplegenerated
{ "detail": "example"}object
Human-readable message, or a stable machine code for the cases a client branches on. The standard envelope for 400 (validation — a field-keyed object may appear instead), 401 (missing / invalid credentials), 403 (authenticated but not permitted), and 404 (absent — cross-team records are collapsed to 404 so the API never leaks the existence of another team’s data).
Examplegenerated
{ "detail": "example"}No active team on the requesting account.
object
Human-readable message, or a stable machine code for the cases a client branches on. The standard envelope for 400 (validation — a field-keyed object may appear instead), 401 (missing / invalid credentials), 403 (authenticated but not permitted), and 404 (absent — cross-team records are collapsed to 404 so the API never leaks the existence of another team’s data).
Examplegenerated
{ "detail": "example"}object
Human-readable message, or a stable machine code for the cases a client branches on. The standard envelope for 400 (validation — a field-keyed object may appear instead), 401 (missing / invalid credentials), 403 (authenticated but not permitted), and 404 (absent — cross-team records are collapsed to 404 so the API never leaks the existence of another team’s data).
Examplegenerated
{ "detail": "example"}The inputs moved between the report GET and this call, so the notice being dismissed is not the one that is now true. Re-read the report: the staleness it reports is a change the coach has not seen yet.
object
Human-readable message, or a stable machine code for the cases a client branches on. The standard envelope for 400 (validation — a field-keyed object may appear instead), 401 (missing / invalid credentials), 403 (authenticated but not permitted), and 404 (absent — cross-team records are collapsed to 404 so the API never leaks the existence of another team’s data).
Examplegenerated
{ "detail": "example"}