Choose your recipe
Both languages implement the same single and bulk modes. Pick one implementation; do not run both against the same work queue.
Prepare your drafts and API token
- Get your token from the Stealth API dashboard. The examples send it in the
api-tokenheader on every create and status request. - Download the sample drafts and save them as
review-drafts.json. Replace theirtextwith source drafts only—no “humanize this” instructions. - Give every document revision a stable, unique
id, such aspricing-guide-v3. The scripts use it as the idempotency key and review filename. Keep an ID and its request settings unchanged when retrying. Use a new revision ID for deliberately changed content or a fresh attempt after a failed run.
Recipe 1: async humanization → editorial review
Copy one implementation below toreview.ts or review.py. Both send rephrase: true, explicitly select model: "super", and request plain text. A run returns 202 with a runId and statusUrl; the script saves that association before polling.
The scripts retry network failures, 429, and 5xx with the same body and keys, with a bounded number of attempts. Bulk mode also waits and retries 409. A terminal failed or cancelled result becomes a blocked review file; it is never silently resubmitted as a new paid run.
- TypeScript · Node.js 24
- Python · 3.10+
Save this as
review.ts. It uses Node’s built-in TypeScript support and has no package dependencies.review.ts
review-output/<document-id>.review.json per draft, plus a manifest.json mapping your IDs to API runs and a hash of each intended request. On restart, known runs are polled directly without another create call; only drafts absent from the manifest are submitted. A changed draft, model setting or callback configuration under an existing ID is rejected before submission. Run one worker per output directory; use a transactional database or job store when multiple workers share a queue.
The API does not expose a caller-controlled idempotency expiry. Durable run IDs are your resume mechanism, rather than an assumption that a provider key remains valid indefinitely. If a saved run returns 404, investigate that record; these clients do not silently create a replacement.
Make review a publishing gate
Open each review file and comparesourceText with candidateText. Check names, numbers, claims and citations; test links; inspect headings, tables, lists and brand voice in the destination renderer. Then record the reviewer, time and decision in editorialReview. A downstream CMS integration should require an approved decision and the reviewed version of the text before creating a publication.
The examples never set approved. They publish each completed JSON file through a temporary file and an atomic hard link, so overlapping polls and callbacks see complete reviews and keep existing editorial notes. Use a local filesystem that supports hard links. For a new paid attempt, use a new document revision ID and keep the old record.
Recipe 2: bulk humanization → collect every result → review
Use the same script and draft format withbulk:
idempotencyKey on every item. The response’s runs[i] corresponds to items[i]; the scripts save this mapping and poll each statusUrl. They wait until the current batch is terminal before submitting the next one. Failed items are saved with editorialReview.decision: "blocked", and the scripts stop before sending another batch.
- The platform caps the request body at 4.5 MB. These examples use a conservative 4,000,000-byte client check; long drafts may need fewer than 100 items.
- A different batch submitted while a previous bulk batch is active can return 409. A resend covering those same active items with unchanged keys and inputs can recover the existing runs.
429or500can occur after keyed items were already created. Resend the same complete request; do not generate new keys for a transport retry.- A failed run remains failed under the same key and request. Inspect its
error.code; correct the cause and deliberately choose a new revision ID for a new attempt.
Optional: signed webhooks with polling reconciliation
Set these before creating runs if you have an HTTPS callback endpoint:review.ts functions above. Mount POST in your existing backend and give it the same durable review directory and secret as the worker. It performs local persistence only, so it can acknowledge promptly within the API’s 10-second delivery timeout. For serverless deployments, replace local files with a shared durable store; an ephemeral filesystem is not a delivery queue.
webhook.ts
429 and 5xx. Other 4xx responses stop delivery retries. Keep polling or schedule status reconciliation from the saved manifest; a missing callback does not mean the run failed. These scripts continue polling even when webhooks are enabled, making callback delivery an acceleration path rather than the only record of completion.
Billing, model controls and recovery
Humanization bills input plus output billable words, rounded up. Standard and Lite use a 1× multiplier; Super uses 2.5×. For example, 1,000 input words plus 900 output words is 1,900 plan words for Standard/Lite or 4,750 for Super. The examples store the API’s actualwordsSpent, creditsSpent, billingMode and meteredChargedCredits fields; use those values for reconciliation rather than estimating final output length. Preserved spans can affect billable word counts.
Creating runs checks estimated billing access and can reserve prepaid credits. Each run is billed when it finishes. A bulk estimate is checked as a whole, and a later billing problem can still end an individual run as failed. REST calls use the API balance; MCP can follow a different account billing setting. See API pricing for current plan economics.
qualityMode: "quality" is a model control, not editorial approval. Standard uses its quality-check pipeline; Super’s quality mode enables em-dash cleanup, and Lite uses its lightweight path. Choose the model for your workload and review the resulting draft. For format-sensitive content, use Text Preservation and verify the reconstructed document; selecting Markdown alone does not establish that every table, link or layout survives.
Using n8n
You can build the same review handoff with the n8n integration or HTTP Request nodes. Check your installed node version before importing a workflow: the publishedn8n-nodes-stealthgpt 0.1.2 schema exposes heavy and lite for humanization (heavy maps to Standard), and has no bulk operation. Use the REST contract directly for an explicit Super selection or bulk submission. Store API tokens in n8n credentials, and send results to a draft/review destination before any publish node.
Related references
- Async create, status and webhook contract
- Bulk limits and idempotency
- Workflow patterns
- Codex MCP setup