API documentation

Paraphrasing, grammar checking, summaries, translation and plagiarism checks in 56 languages. Simple REST, served from Cloudflare's edge.

Same-origin
The API currently serves requests from adeptwrite.com itself only (no CORS headers). External access with API keys is planned alongside the Pro plan. These docs are published early so the contract is open and you can prepare for it.
Summary

The AdeptWrite v1 API has three live endpoints. POST /api/v1/run takes JSON with task, mode, lang and text (up to 6,000 characters) and returns plain-text output from a Cloudflare Workers AI model chosen for the language; POST /api/v1/plagiarism compares a text with open sources and lists every source it searched; GET /api/v1/health returns the service status. Text is never stored or logged, and AI requests are limited to 30 per minute per IP.

Basics

  • Base URL: https://adeptwrite.com/api/v1
  • Format: requests and responses are JSON (Content-Type: application/json, UTF-8).
  • Authentication: none yet; requests must come from adeptwrite.com pages (same-origin). API keys arrive with Pro.
  • Privacy: the text field is never stored or logged; responses carry Cache-Control: no-store.
  • Versioning: the /v1/ path will not change incompatibly; breaking changes will use /v2/.

POST/api/v1/run

Runs one AI task on a text and returns the result as plain text (no preamble, no Markdown fences).

Request

FieldTypeRequiredNotes
taskstring✓Task name; see the task list below.
textstring✓Input text, 1–6,000 characters.
langstring✓Language of the result: one of the 56 site locale codes (en, id, ja, pt-pt, zh-hant…; BCP 47 tags such as pt-BR are mapped) or auto for "the same language as the input".
modestring—A mode available for that tool, e.g. Formal, Akademik, Ringkas, Poin-poin (mode names are the Indonesian registry labels). Ignored for tasks without modes.
optionsobject—Task-specific options: from / to for translate (any supported language to any other; from may be auto; sr-Cyrl asks for Serbian in Cyrillic), platform (instagram / tiktok / linkedin) for caption, and optional labelled fields for bio, coverletter and meta. Other keys are ignored.
POST /api/v1/run HTTP/1.1
Content-Type: application/json

{
  "task": "paraphrase",
  "mode": "Formal",
  "lang": "en",
  "text": "Good writing really matters for students.",
  "options": {}
}

Response

Status 200 with ok: true, the result in output, the model that actually answered in model (it differs when a fallback model stepped in) and the processing time in milliseconds. truncated: true is added when the answer hit its length budget or the time limit and was cut off.

{
  "ok": true,
  "output": "The quality of writing is essential for students.",
  "model": "@cf/aisingapore/gemma-sea-lion-v4-27b-it",
  "ms": 812
}

Example: curl

curl -X POST https://adeptwrite.com/api/v1/run \
  -H "Content-Type: application/json" \
  -d '{"task":"grammar","lang":"en","text":"Their going to the libary tomorow."}'

Example: JavaScript (fetch)

const res = await fetch('/api/v1/run', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ task: 'summarize', mode: 'Poin-poin', lang: 'en', text }),
});
const data = await res.json();
if (!data.ok) throw new Error(data.error.code + ': ' + data.error.message);
console.log(data.output);

POST/api/v1/plagiarism

Picks 4–8 distinctive phrases from the text, searches open sources in the text language (Wikipedia, Wikisource, Internet Archive full text, Europe PMC, DOAJ, arXiv; a web search provider only when configured and requested) and scores the overlap. Only those short phrases leave the server.

Request

FieldTypeRequiredNotes
textstring✓At least 30 words, at most 6,000 characters.
langstring✓A site locale code or auto.
optionsobject—web: true also queries the web search provider when the operator has configured one; webSearched in the response says whether it really answered.
POST /api/v1/plagiarism HTTP/1.1
Content-Type: application/json

{ "text": "…at least 30 words…", "lang": "en", "options": { "web": false } }

Response

Status 200 with score (matched words ÷ words, 0–1), matches per source with highlighted passages (character offsets into your text), sourcesSearched (exactly the sources whose answers are in the result), sourcesSkipped with a reason, and webSearched.

{
  "ok": true,
  "score": 0.42,
  "words": 52,
  "matchedWords": 22,
  "matches": [{ "source": "wikipedia", "title": "…", "url": "https://en.wikipedia.org/wiki/…",
                "matchedWords": 22, "passages": [{ "start": 0, "end": 131, "text": "…" }] }],
  "sourcesSearched": ["wikipedia", "wikisource", "internet-archive-fts", "europepmc", "doaj"],
  "sourcesSkipped": [],
  "webSearched": false,
  "ms": 2310
}

Example: curl

curl -X POST https://adeptwrite.com/api/v1/plagiarism \
  -H "Content-Type: application/json" \
  -d '{"lang":"en","text":"…at least 30 words…"}'

GET/api/v1/health

Reports which services are switched on. Takes no body and does not count towards the quota.

Response

Status 200. ai is false while the AI kill switch is on; plagiarism lists the sources the checker can query; aidetect describes the server-side deep analysis of the AI detector, which is not deployed yet (POST /api/v1/aidetect answers 503 disabled; the detector on the site runs in your browser).

{
  "ok": true,
  "ai": true,
  "plagiarism": { "enabled": true, "sources": ["wikipedia", "wikisource", "internet-archive-fts", "europepmc", "doaj", "arxiv"], "web": false },
  "aidetect": { "enabled": false, "judge": false }
}

Example: curl

curl https://adeptwrite.com/api/v1/health

Task list

taskWhat it does
paraphraseParaphrase; modes: Standar, Formal, Santai, Akademik, Kreatif, Ringkas, Panjangkan.
grammarGrammar and spelling correction (EYD V for Indonesian).
toneChange tone; modes: Formal, Kantor (office), Santai (casual).
rewriteFix stiff or awkward sentences; modes: Standar, Formal.
resizeShorten or expand sentences; modes: Ringkas, Panjangkan.
essayBuild paragraphs or an essay from bullet points; modes: Akademik, Kreatif, Panjangkan.
summarizeSummary; modes: Poin-poin (bullets), Paragraf, Satu kalimat (one sentence).
translateTranslation between any two supported languages; options.from (or auto) and options.to; modes: Alami (natural, default), Formal, Santai (casual).
thesisThesis title ideas and chapter outline.
abstractStructured abstract from a research summary.
captionSocial media captions; options.platform: instagram, tiktok, linkedin.
emailEmails and letters; modes: Lamaran kerja (job application), Surat resmi (formal letter), Follow-up.
headlineArticle titles and headlines; modes: Kreatif, Ringkas.
productProduct descriptions; modes: Marketplace, Toko online (online store).
synonymSynonym list for one word or phrase.
humanizeMake stiff, generic text read more naturally; modes: Alami, Pribadi (personal), Profesional.
metaThree meta title and description pairs; modes: Artikel, Produk, Halaman (any web page).
hashtagOne line of hashtags; modes: Instagram, TikTok, LinkedIn, X.
bioThree profile bios; modes: Instagram, LinkedIn, X, TikTok.
outlineNumbered outline with sub-points; modes: Artikel, Esai, Skripsi (thesis), Presentasi.
sloganTen slogan ideas; modes: Merek (brand), Kampanye (campaign), Produk.
paragraphOne paragraph from a topic; modes: Pembuka (opening), Isi (body), Penutup (closing).
coverletterCover letter draft; modes: Fresh graduate, Berpengalaman (experienced), Magang (internship).
poemShort poems; modes: Bebas (free verse), Berima (rhyming), Akrostik, Haiku.

Limits

Text length
At most 6,000 characters per request (413 too_long above that).
Per IP address
30 requests per minute.
Global
100 requests per minute across the whole service, plus a daily cap for AI features.
Plagiarism
5 checks per minute per IP and 60 per minute across the service; 30 words minimum.
Output
A per-task length budget, never more than 2,048 tokens; a cut-off answer carries truncated: true.
Model
Chosen per language: English and Indonesian run on @cf/aisingapore/gemma-sea-lion-v4-27b-it, every other language on @cf/qwen/qwen3-30b-a3b-fp8. When a model is busy, rate-limited, slow or fails, the request falls back to the next model in the chain (Qwen3-30B, then @cf/google/gemma-4-26b-a4b-it, then @cf/meta/llama-3.3-70b-instruct-fp8-fast). The model field always names the model that answered.

Error codes

StatusCodeWhen it happens
400invalid_requestInvalid JSON, a required field missing, or an unknown task or lang.
413too_longtext exceeds 6,000 characters.
403forbiddenThe request did not come from an adeptwrite.com page.
429rate_limitedThe per-IP or global per-minute limit was exceeded. Wait for the number of seconds in Retry-After.
429quota_exceededThe daily cap for AI features is used up. Try again the next day (UTC).
502upstreamEvery model in the chain failed to answer in time.
502empty_outputThe models answered, but with an empty result.
503disabledThe service has been switched off temporarily by the operator, or (for /api/v1/aidetect) is not deployed yet.

Error format

Every error is returned as JSON with the matching HTTP status code and the same shape:

{ "ok": false, "error": { "code": "rate_limited", "message": "Too many requests. Please try again shortly." } }

Check ok first, then read error.code for programmatic handling; error.message is safe to show to users.

  • Send text in parts (for example per paragraph) rather than one long document; results come back faster and are easier to review.
  • Handle 429 with exponential back-off, not immediate retries.
  • Do not send personal or confidential data you do not need to — even though we do not store it, data minimisation still applies.
  • AI output can be wrong; present it as a suggestion to review, not as a final truth.

Frequently asked questions

Can I call the API from my own app or domain?

Not yet. The Worker currently sends no CORS headers and only serves adeptwrite.com pages. External access with API keys is planned alongside the Pro plan; these docs will be updated when it is available.

Is text sent to the API stored?

No. The text is forwarded to the model to produce the answer and then discarded. Logs contain metadata only (status code, task, duration). See the privacy policy for all the details.

Why is the output plain text rather than structured JSON?

Each task produces one ready-to-use text without preamble or Markdown fences so it can be shown in the editor directly. Extra structure (for example a change list) is planned for a later version without changing v1.

How much does the API cost?

From adeptwrite.com it is free, limited to 30 AI requests per minute per IP. Pricing for external access will be announced with the Pro plan; nothing is charged before then.

Which model answers my request?

It depends on the language: English and Indonesian go to SEA-LION, the other languages to Qwen3-30B. If that model is busy or fails, the next model in the fallback chain answers instead, and the model field of the response names the one that did.