Streaming mode
Streaming returns proofreading edits as soon as complete sections of a document are ready. Unlike token streaming, every value is a complete, validated edit array with offsets into the full text you submitted. You never need to reconstruct partial JSON or partial replacements.
Stream corrections
Use proofreadStream as an async iterator. Correct mode yields complete TextEdit[] batches in document order. Without a cached textId snapshot, the
complete document is sent in one model request; stable prefixes of its streamed response are diffed
as they arrive. Accumulating every batch produces the same edits as a regular correct-mode request.
import { applyEdits, createAmberPenClient } from "@amber-pen/sdk";
const amberPen = createAmberPenClient({ apiKey });
const edits = [];
for await (const batch of amberPen.proofreadStream({
text,
textId: "chapter-1",
mode: "correct",
})) {
// Each batch is a complete TextEdit[].
edits.push(...batch);
}
// All offsets refer to the original text.
const correctedText = applyEdits(text, edits); Keep the original text unchanged while consuming the stream. Every start and end offset refers to that original text; applying one batch immediately would shift
the offsets needed by later batches. Accumulate the edits and apply them together, or represent
them as editor decorations anchored to the original document.
Stream evaluated edits
With mode: "evaluate", AmberPen streams correction proposals from the same whole-document
request. As soon as five proposals are available, they are sent through the high-reasoning
evaluation pass and the complete EvaluatedEdit[] result is streamed back. The final
group is evaluated even when it contains fewer than five edits. Evaluate mode is billed at twice
the character usage of correct mode.
const evaluations = [];
for await (const batch of amberPen.proofreadStream({
text,
mode: "evaluate",
})) {
// Each batch is a complete EvaluatedEdit[]: rejected proposals
// are already dropped, so every edit is worth applying.
for (const edit of batch) {
console.log(edit.category, edit.explanation, edit.possibleReplacements);
}
evaluations.push(...batch);
}
const correctedText = applyEdits(text, evaluations); Each evaluated edit lists its valid replacements in possibleReplacements, ranked by
relevance, along with its category and a one-sentence explanation in the
language of the submitted text. Proposals the evaluator rejects are left out of the stream
entirely.
Ordering and batching
- Correct mode sends the entire source text on a non-incremental request.
- Incomplete response tokens remain buffered until the diff prefix is stable.
- Evaluate mode consumes the same stable correction edits in groups of five.
- Edit batches are still emitted in document order with globally sequential IDs.
- Evaluation requests run concurrently, while completed results are emitted in proposal order.
- Batches with no edits are omitted from the public iterator.
Cancel a stream
Pass an AbortSignal in the request options. Aborting stops the response and propagates
cancellation to pending correction or evaluation requests. When a textId is present, an
aborted stream does not replace the last successfully completed cached snapshot.
const controller = new AbortController();
cancelButton.addEventListener("click", () => controller.abort());
for await (const edits of amberPen.proofreadStream(
{ text, textId: "chapter-1", mode: "correct" },
{ signal: controller.signal },
)) {
consume(edits);
} Stream incremental updates
Pass a stable textId to combine streaming with incremental proofreading. The first
request streams the whole text. Later requests stream only changed chunks and carry edits from
untouched text into the result, still in document order with full-text offsets. The SDK caches the
new snapshot only after every required chunk reaches its terminal [] marker; failed,
cancelled, and partially consumed streams are never cached.
Use the HTTP API directly
Set stream: true and request application/x-ndjson. Every non-empty line is
a complete edit array. A final empty array, [], marks successful completion and lets
clients detect a truncated connection. Errors that occur after streaming starts are sent as a
structured error object instead of an edit array.
curl -N https://api.amberpen.dev/proofread \
-H "authorization: Bearer $AMBER_PEN_API_KEY" \
-H "content-type: application/json" \
-H "accept: application/x-ndjson" \
-d '{ "text": "This are a sentnce.", "mode": "correct", "stream": true }'
[{"id":0,"start":5,"end":8,"original":"are","replacement":"is"}]
[{"id":1,"start":11,"end":18,"original":"sentnce","replacement":"sentence"}]
[]