Run reference

Create and
manage rewrites

A run is one rewrite request. It processes in the background. Creating a run reserves funds and queues the work; retrieve the result when it finishes.

Asynchronous runsText & Markdown
On this page
POST

/v1/runs

Creates a run and returns 202 Accepted. Limited to 6 requests per minute per key. A 429 includes a Retry-After header.

Request bodyJSON
{
  "text": "Your draft, in plain text or Markdown.",
  "quality": "standard",
  "options": {
    "persona": "freelance journalist filing a feature",
    "tone": "warm and plain-spoken",
    "formality": 2,
    "typos_enabled": true,
    "typos_per_100_words": 1.0,
    "common_words_enabled": true,
    "min_zipf": 4.0
  }
}
FieldDescription
textRequired. Longer than restrictions.max_chars_per_run from GET /v1/me returns 400 text_too_long. Text with no prose words returns 400.
qualitylow, standard, or high. An unknown name is 400.
optionsOptional. See below. Omit it to let each run pick a voice.
Queued responseJSON
{
  "id": "run_01J9ABCDEF",
  "status": "queued",
  "quality": "standard",
  "word_count": 11,
  "prose_word_count": 11,
  "estimated_cost_usd": "0.050000",
  "held_usd": "0.050000",
  "is_estimate": true,
  "events_url": "/api/v1/runs/run_01J9ABCDEF/events"
}

held_usd is reserved until the run settles. estimated_cost_usd is not the price. The amount you pay is billing.charged_usd on the finished run. If the available balance cannot cover the hold, the response is 402 and nothing is queued.

Options

Omitted voice settings are selected for each run. Rewriting the same text twice may produce different styles. GET /v1/presets returns the lists the sampler draws from.

FieldDescription
personaWho is writing. A concrete description works better than a label like “professional”.
toneHow it should sound.
formalityInteger from 1 (conversational) to 5 (formal).
typos_enabledDefaults to true. Drafts under 100 words receive no added typos.
typos_per_100_wordsRate used when typos are on. The default in the app is 1.0.
common_words_enabledPrefer everyday wording. Defaults to true.
min_zipfHow common a replacement word should be. The app default is 4.0.
random_planWhen true, voice options in the same object are ignored and all settings are selected for the run.

Statuses

StatusDescription
queuedAccepted, not started.
runningIn progress. The hold is still reserved.
succeededRewrite is in output_text.
rejectedFinished, and our checks did not pass. You are still charged for the work. Read scores.reasons.
failedThe run stopped on an error. You are charged for work already done.
canceledYou canceled it. Unused hold is released. Work already done is charged.
GET

/v1/runs/{id}

The run, including both texts. A run that belongs to someone else is 404.

Completed runJSON
{
  "id": "run_01J9ABCDEF",
  "status": "succeeded",
  "quality": "standard",
  "prose_word_count": 11,
  "input_text": "Artificial intelligence has fundamentally transformed the landscape of modern software development.",
  "output_text": "Artificial intelligence has changed modern software development.",
  "text_deleted_at": null,
  "scores": {
    "validation_passed": true,
    "reasons": []
  },
  "billing": {
    "charged_usd": "0.050000",
    "estimated_cost_usd": "0.050000",
    "held_usd": "0.050000",
    "charge_exceeded_hold": false
  },
  "created_at": "2026-10-05T18:00:00+00:00",
  "finished_at": "2026-10-05T18:00:40+00:00"
}

charge_exceeded_hold is true when the final charge was higher than the amount reserved up front. scores.validation_passed is the check result. A few extra fields may be present; you do not need them to read the rewrite or the charge.

GET

/v1/runs

Your runs, newest first. limit defaults to 50 and caps at 100. List items omit input_text and output_text and include input_preview, the first 160 characters of the draft.

List responseJSON
{ "data": [ /* run objects */ ], "next_cursor": null }
POST

/v1/runs/{id}/cancel

Cancels a queued or running run and returns the run. Canceling a finished run returns it unchanged.

DELETE

/v1/runs/{id}

Erases the draft and the rewrite. The billing record stays, so the charge still appears in the ledger. Cancel an in-progress run first; otherwise the response is 409 run_in_progress.

Delete responseJSON
{ "id": "run_01J9ABCDEF", "text_deleted": true, "deleted_at": "2026-10-05T19:00:00+00:00" }
DELETE

/v1/runs?confirm=true

Erases the text of every finished run. Without confirm=true the response is 400 confirmation_required. Runs that are still queued or running are skipped.

Clear responseJSON
{ "deleted": 12, "skipped_in_progress": 0 }