ZeroLLM

API reference

Check text for AI writing and rewrite drafts in your own voice over HTTP. Both endpoints take and return JSON, and use the same models as the website.

ZeroLLM is in beta. Scores are estimates, and response fields may grow. We won't remove fields without notice.

Authentication

Every request needs an API key. Sign in with Google, then create a key on your API keys page. Keys start with zl_live_ and are shown once, so store them somewhere safe. Send the key as a bearer token:

header
Authorization: Bearer zl_live_…

Keep keys on your server. Anyone with a key can spend your allowance, and you can revoke one at any time from the API keys page.

Limits and headers

API calls count against the same monthly allowance as the website. Allowances reset on the first of the month (UTC).

PlanCheckingRewritingRequests
Free300,000 words a month10,000 words a month20 a minute
Pro (coming soon)3,000,000 words a month200,000 words a month120 a minute

Every metered response carries these headers:

HeaderMeaning
x-planYour plan: free or pro.
x-ratelimit-limitRequests allowed per minute.
x-quota-limitWords in this period's allowance for the endpoint.
x-quota-remainingWords left after this request.
x-quota-resetWhen the allowance resets, as an ISO 8601 timestamp.
retry-afterSeconds to wait, sent with a 429 when you hit the per-minute limit.

Check text

POST https://zerollm.app/api/v1/detect

Send { "text": string } with at least 30 words and at most 20,000 characters. The response scores the whole text and every sentence. score runs from 0 (reads as human) to 1 (reads as AI); sentences scoring 0.5 or more are the ones the website marks. start and end are character offsets into the text you sent.

request.sh
curl https://zerollm.app/api/v1/detect \
  -H "Authorization: Bearer zl_live_…" \
  -H "Content-Type: application/json" \
  -d '{"text": "Paste at least 30 words of the text you want checked."}'
response.json
{
  "score": 0.82,
  "label": "ai",
  "confidence": "high",
  "ai_fraction": 0.6,
  "signals": {
    "classifier": { "probability": 0.84, "logit": 1.66 },
    "binoculars": { "score": null, "threshold": 0.9 },
    "style": { "aiism_per_100w": 1.4, "contractions_per_100w": 0.2 }
  },
  "contributions": { "classifier_logit": 2.1, "aiism_per_100w": 0.6 },
  "reasons": [
    { "signal": "classifier", "leans": "ai", "text": "The classifier recognizes patterns common in model output." }
  ],
  "sentences": [
    { "start": 0, "end": 118, "score": 0.91 },
    { "start": 119, "end": 204, "score": 0.34 }
  ],
  "phrases": [
    { "start": 0, "end": 8, "text": "Moreover", "category": "transition" }
  ],
  "stats": { "words": 212, "sentences": 9, "ms": 640, "calibration": "v3" }
}
FieldTypeDescription
scorenumberOverall likelihood the text is AI-written, 0 to 1.
label"ai" | "mixed" | "human"The verdict the score falls into.
confidence"high" | "medium" | "low"How firm the verdict is. Short texts are low.
ai_fractionnumberShare of the text in sentences that read as AI.
sentencesarrayEach sentence's start, end and score.
phrasesarrayStock phrases models overuse, with their offsets and category.
reasonsarrayPlain-language reasons, each leaning ai, human or neutral.
contributionsobjectHow much each signal moved the score. Keys appear only for signals that ran.
signalsobjectRaw signal values behind the score.
statsobjectWord and sentence counts and processing time in milliseconds.
detect.ts
const res = await fetch("https://zerollm.app/api/v1/detect", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.ZEROLLM_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ text }),
});
if (!res.ok) throw new Error((await res.json()).error);
const detection = await res.json();

Rewrite text

POST https://zerollm.app/api/v1/humanize

Rewrites a draft so it reads like your own writing, keeping every fact, name and number. With refine on, the result is checked and sentences that still read as AI are reworked, up to twice. The call returns once the rewrite is finished.

ParameterTypeDefaultDescription
textstringrequiredThe draft, up to 20,000 characters.
modestringstandardThe voice to write in. See the list below.
strengthstringbalancedHow much to change.
refinebooleantrueRecheck and rework flagged sentences.
request.sh
curl https://zerollm.app/api/v1/humanize \
  -H "Authorization: Bearer zl_live_…" \
  -H "Content-Type: application/json" \
  -d '{"text": "Your draft here.", "mode": "professional", "strength": "balanced", "refine": true}'
response.json
{
  "text": "The rewritten draft, in the voice you asked for.",
  "score": 0.21,
  "label": "human",
  "refine_passes": 1,
  "detection": { "score": 0.21, "label": "human", "sentences": [] },
  "notices": []
}

detection is the full check of the final text, in the same shape as the detect response. notices lists anything worth knowing, such as the detector being unavailable for the final check.

Errors

Errors come back with a JSON body of { "error": string } written to be shown to a person as is.

StatusWhen
400Unknown mode or strength.
401The API key is missing, invalid or revoked.
413The text is over 20,000 characters.
422Not enough text: detect needs 30 words, humanize a few sentences.
429Per-minute limit (with retry-after) or the period's allowance is used up.
502The rewrite model returned an error. Safe to retry.
503The detector is briefly unavailable. Safe to retry.

Voices and strengths

modeVoice
standardClear, natural, everyday voice
academicMeasured and precise, for papers
professionalDirect and concise, for work
casualRelaxed, like talking to a friend
simpleShort sentences and everyday words
creativeMore voice and rhythm
strengthChange
lightKeep most of your wording
balancedRebuild sentences, keep the order
strongRewrite from scratch, keep every point