Skip to main content

API docs → Migrate from Copyleaks

Migrate from Copyleaks

Copyleaks uses an async submit-then-webhook flow. We're synchronous — answer in the HTTP response. The migration is mostly about deleting webhook plumbing.

Why switch

  • Synchronous answer. 80ms warm latency vs Copyleaks' 30-90 second scan queue. Drop ~150 lines of webhook plumbing.
  • Single API key. Bearer token vs Copyleaks' email + key + access-token-exchange dance.
  • Per-passage breakdown. Plus tier ships paragraph + sentence highlights with the fired rule ids. Copyleaks shows match-only.
  • Lower cost. $0.0003/word or $0.50/call vs Copyleaks' $0.15-$0.36 per page.
  • Hidden multilingual. 20+ languages — no per-language quota or flag.
  • Privacy default. Plaintext NOT retained.

Side-by-side

Before — Copyleaks (async)
// Before: Copyleaks (async — submit + wait for webhook)
// 1. Get a token
const token = await fetch('https://id.copyleaks.com/v3/account/login/api', {
  method: 'POST',
  body: JSON.stringify({ email: process.env.CL_EMAIL, key: process.env.CL_KEY }),
});

// 2. Submit a scan with a callback URL
await fetch('https://api.copyleaks.com/v3/businesses/submit/file/SCAN_ID', {
  method: 'PUT',
  headers: { Authorization: 'Bearer ' + token.access_token },
  body: JSON.stringify({
    base64: Buffer.from(text).toString('base64'),
    filename: 'doc.txt',
    properties: {
      webhooks: { status: 'https://your.app/cl-webhook' },
      sandbox: false,
    },
  }),
});

// 3. Wait for webhook callback. Receive results in a separate handler.
// (50-200 lines of webhook plumbing to actually get the answer.)
After — Deep AI Detector (sync)
// After: deepaidetector (synchronous — answer in the response)
import { createClient } from '@deepaidetector/client';
const client = createClient({ apiKey: process.env.DEEPAIDETECTOR_KEY });

const data = await client.detect({ text });
const aiScore = data.score;          // 0-1
const verdict = data.band;           // categorical
// You can still subscribe to webhooks (for fan-out to other systems),
// but the synchronous answer is right here.

Field mapping

CopyleaksDeep AI DetectorNotes
summary.aiscoreAI score 0-1. Same semantics.
summary.ai_writing_likelihood_classbandCategorical verdict. Their {AI, Human, Unsure} maps to our 7-band scale.
results.score.aggregatedScoreplagiarism.report.overallPercentPlagiarism overall percent (different endpoint).
results.internet[].urlplagiarism.report.sources[].urlPer-source URL.
results.score.identicalWordsplagiarism.report.diagnostics.ngramsCheckedWe expose n-gram matches in diagnostics.
developerPayloaddocument_idOur document_id is a UUID — use that for correlation.

Behaviour differences to know

  • Authentication is one step. No token-exchange — bearer auth directly. Save your dad_live_ key as a secret, that's it.
  • Synchronous. The answer is in the response body. You can still wire webhooks for fan-out, but they're not required for the primary flow.
  • Base64 not needed. Send the text as a UTF-8 string in the JSON body.
  • Detection + plagiarism are separate endpoints. Call both in parallel for the bundled equivalent.
  • 80-word minimum. Below 80 words on /v1/detect we return 422 insufficient_text.
  • Different units for plagiarism overall. Copyleaks: 0-100 integer. Us: 0-100 float (overallPercent).

Migration checklist

  1. Generate a Deep AI Detector API key in your dashboard.
  2. Delete the Copyleaks token-exchange step entirely.
  3. Delete the Copyleaks webhook handler (or leave it for fan-out — your call).
  4. Replace the submit + wait flow with a synchronous client.detect() call.
  5. Replace base64 + filename body with plain JSON containing text.
  6. Update response parsing per the field map.
  7. Add 422 handling for short text.
  8. If you still need plagiarism, add a parallel client.plagiarism() call.

Want a hand?

Email [email protected] with your Copyleaks integration — we'll write the migration patch on Plus tier and above.

Sign up