AmberPen Get started

SDK reference

@amber-pen/sdk exports a typed client, an error class, and the complete request and response contract of the HTTP API. Every public field has inline JSDoc, so your editor surfaces this documentation at the point of use.

createAmberPenClient(options)

Creates an AmberPenClient. Also available as new AmberPenClient(options).

import { createAmberPenClient } from "@amber-pen/sdk";

const amberPen = createAmberPenClient({ apiKey });
OptionTypeDescription
apiKeystringYour Amber Pen API key. Sent as a Bearer authorization header with every request.
fetchFetchA custom Fetch-compatible implementation. Defaults to globalThis.fetch.
incrementalTtlMsnumberHow long a textId's text and edits are kept in memory for incremental proofreading. Defaults to 24 hours.
incrementalChunkSizenumberApproximate characters of context included on each side of an incremental change before rounding to newline-delimited block boundaries. Defaults to 800.
const amberPen = createAmberPenClient({
	apiKey,
	// Any Fetch-compatible function works: retries, logging,
	// proxies, or a test double.
	fetch: (input, init) => myFetch(input, init),
});

client.proofread(request, options?)

Calls POST /proofread and returns a ProofreadResponse discriminated by its mode field. See the HTTP API reference for every request field and response shape. Pass a stable textId to enable incremental proofreading: the client keeps that text and its edits in memory and, on the next request for the same textId, sends only the chunks that changed while carrying the other edits over.

Narrowing on mode === "evaluate" gives you EvaluatedEdit[]: every edit adds possibleReplacements ranked by relevance, a category (spelling, grammar, style, or repetition), and a one-sentence explanation in the language of the submitted text.

const result = await amberPen.proofread(
	{
		text: "AmberPen are testing a cachebuster.",
		dictionary: ["cachebuster"],
		properNouns: ["AmberPen"],
		textId: "document-123",
		mode: "evaluate",
	},
	{
		signal: AbortSignal.timeout(10_000),
		headers: { "x-request-id": requestId },
	},
);

// Narrow on mode to reach the evaluate-only fields.
if (result.mode === "evaluate") {
	for (const edit of result.edits) {
		console.log(edit.category, edit.explanation, edit.possibleReplacements);
		// "grammar" "“AmberPen” is singular, so it takes “is”." ["is", "was"]
	}
}

client.proofreadStream(request, options?)

Streams complete TextEdit[] batches in document order. Every edit uses offsets into the full submitted text, so concatenate the batches and pass them to applyEdits. With mode: "evaluate", proposals are evaluated five at a time and the iterator yields complete EvaluatedEdit[] batches; proposals the evaluator rejects are dropped. Pass a stable textId to stream only changed chunks on later requests. A streamed snapshot enters the incremental cache only after successful completion.

const edits = [];
for await (const batch of amberPen.proofreadStream({
	text,
	textId: "document-123",
	mode: "correct",
})) {
	// Every batch contains complete edits with full-text offsets.
	edits.push(...batch);
}

const correctedText = applyEdits(text, edits);

client.health(options?)

Calls GET /health and resolves to { status: "ok" } when the API is ready.

const { status } = await amberPen.health();
// status === "ok"

applyEdits(text, edits)

Applies a response's edits to the text they were produced for and returns the corrected text. Edits are validated first — offsets and original substrings must match, or an Error is thrown. validateEdits(text, edits) is also exported on its own.

import { applyEdits } from "@amber-pen/sdk";

const result = await amberPen.proofread({ text });
const correctedText = applyEdits(text, result.edits);

Per-request options

Both methods accept an optional second argument:

OptionTypeDescription
signalAbortSignalCancels the request; the abort error from fetch is thrown unchanged.
headersHeadersInitMerged over the client-level headers for this request only.

AmberPenApiError

Thrown when the API responds with a non-2xx status, or with a body that is not valid JSON. Network and abort errors are passed through from fetch without wrapping.

PropertyTypeDescription
statusnumberThe HTTP status code returned by the API.
bodyunknownThe parsed JSON body, or undefined when empty or invalid.
responseResponseThe original Fetch response, for headers and other transport metadata.

Use isApiErrorResponse to narrow error.body to the API's structured error shape:

import { AmberPenApiError, isApiErrorResponse } from "@amber-pen/sdk";

try {
	await amberPen.proofread({ text });
} catch (error) {
	if (error instanceof AmberPenApiError && isApiErrorResponse(error.body)) {
		// error.body.code is a typed ProofreaderErrorCode
		console.error(error.body.code, error.body.error);
	}
}

Exports

  • RuntimecreateAmberPenClient, AmberPenClient, AmberPenApiError, isApiErrorResponse, applyEdits, validateEdits, DEFAULT_INCREMENTAL_CHUNK_SIZE, DEFAULT_INCREMENTAL_TTL_MS, and the constant arrays proofreadModes and proofreaderErrorCodes.
  • TypesProofreadRequest, ProofreadResponse (and its CorrectProofreadResponse / EvaluateProofreadResponse members), TextEdit, EvaluatedEdit, ProofreadStreamRequest, CorrectProofreadStreamRequest, EvaluateProofreadStreamRequest, HealthResponse, ApiErrorResponse, AmberPenClientOptions, AmberPenRequestOptions, and Fetch.