HTTP API reference
The API speaks JSON over HTTPS. All the shapes on this page ship as TypeScript types in @amber-pen/sdk, which also handles serialization and error
mapping for you.
Authentication and key types
Send either key type as Authorization: Bearer <api-key>. Live ap_live_v1 keys require an active subscription. Verified accounts can create one ap_test_v1 key for free; it calls the same endpoint and returns the same response
shapes.
Test-key allowance is shared across the account:
- 20 requests per minute
- 1,000 weighted input characters per request, including dictionary and proper-noun entries
- 200 request units and 50,000 weighted input characters per UTC day
An evaluate request consumes two request units and twice its weighted input length.
Successful responses expose minute limits in RateLimit-* headers and daily allowance
in X-Test-Daily-* headers. See Testing for free for the
complete setup and quota guide.
POST /proofread
Proofreads text and returns the edits needed to construct the corrected version.
curl https://api.amberpen.dev/proofread \
-H "authorization: Bearer $AMBER_PEN_API_KEY" \
-H "content-type: application/json" \
-d '{ "text": "This are a sentnce by AmberPen and cachebuster.", "dictionary": ["cachebuster"], "properNouns": ["AmberPen"] }' Request body
| Field | Type | Description |
|---|---|---|
text | string | Required. The complete text to proofread. Empty text is accepted and produces no edits. |
dictionary | string[] | Words the correction pass should recognize and preserve. |
properNouns | string[] | Names the correction pass should recognize and preserve. |
mode | "correct" | "evaluate" | The strategy; defaults to correct. evaluate adds a second pass that reviews each proposed edit and is billed at twice the character usage. |
stream | boolean | Set to true to stream complete edit batches as NDJSON. |
textId is not a request field: incremental proofreading is handled by the SDK for both proofread and proofreadStream. The SDK diffs the text in your process,
strips the identifier, and sends only the chunks that changed. A direct HTTP request body containing textId is rejected with a 400.
Response
Both modes return an edits array. Correct mode returns plain edits:
{
"mode": "correct",
"processingTimeMs": 217,
"edits": [
{ "id": 0, "start": 5, "end": 8, "original": "are", "replacement": "is" },
{ "id": 1, "start": 11, "end": 18, "original": "sentnce", "replacement": "sentence" }
]
} In evaluate mode the second pass has already reviewed each proposed edit, so the array
only contains edits worth applying, and every edit adds three fields: possibleReplacements ranked by relevance, a category, and a one-sentence explanation written in the language of the submitted text.
{
"mode": "evaluate",
"processingTimeMs": 434,
"edits": [
{
"id": 0,
"start": 5,
"end": 8,
"original": "are",
"replacement": "is",
"possibleReplacements": ["is"],
"category": "grammar",
"explanation": "The singular subject “This” takes “is”."
},
{
"id": 1,
"start": 11,
"end": 18,
"original": "sentnce",
"replacement": "sentence",
"possibleReplacements": ["sentence", "sentience"],
"category": "spelling",
"explanation": "“sentnce” is misspelled."
}
]
} | Field | Description |
|---|---|
mode | The strategy that produced the response: "correct" or "evaluate". |
processingTimeMs | Cumulative time spent waiting for inference-provider responses, in milliseconds. Evaluate mode includes both passes. |
edits | Sorted, non-overlapping edits that transform the submitted text into the corrected text. |
Streaming response
With stream: true, the response uses application/x-ndjson. Every non-empty
line is a complete edit array with offsets into the full submitted text. Correct mode emits TextEdit[]. Evaluate mode collects correction proposals in document order, evaluates them
five at a time, and emits complete EvaluatedEdit[] batches. A final empty array marks
successful completion. Use the SDK's proofreadStream method to parse transport fragments, validate batches, and detect
truncated streams.
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"}]
[] Edits
| Field | Description |
|---|---|
id | Identifier unique within the containing edit list. |
start / end | Inclusive start and exclusive end offsets, in UTF-16 code units — pass them directly to String.prototype.slice. |
original | The exact source substring between start and end. |
replacement | The text to insert in place of original. |
possibleReplacements | Evaluation mode only. Valid replacements in descending order of relevance. The first value equals replacement. |
category | Evaluation mode only. spelling, grammar, style, or repetition. |
explanation | Evaluation mode only. A one-sentence explanation of the issue, in the language of the submitted text. |
The SDK's applyEdits(text, edits) reconstructs the corrected
text from a response's edits.
GET /health
Returns { "status": "ok" } when the API is ready to receive requests. No
authentication required.
Errors
Failures return a JSON body with a human-readable message:
{
"error": "Field 'text' must be a string"
} | Status | When |
|---|---|
400 | Invalid JSON, missing text, or an unrecognized mode / model value. |
401 | The Bearer API key is missing, invalid, expired, or revoked. |
413 | The request body or test-key weighted input limit was exceeded. |
429 | A test key exceeded its minute or daily allowance. Inspect Retry-After and the rate-limit headers. |
404 | Unknown method or path. |
503 | Proofreading failed upstream, or test quota enforcement or another required service is temporarily unavailable. |
A failure that interrupts a stream is delivered as a JSON object on its own NDJSON line rather than
as an HTTP status, and that object carries a stable code. The terminal empty array is
not sent, so a stream that ends without one has failed.
{"error":"Service unavailable, please try again later or contact our support at contact@amberpen.dev","code":"provider_error"} | Code | Meaning |
|---|---|
configuration_error | The server is misconfigured for the requested pass. |
provider_error | The inference provider returned an error. |
invalid_provider_response | The provider's output could not be parsed. |
invalid_edit | A generated edit did not match the source text. |