For developers
The ParaTrace API
Check texts, or a PDF, .txt or .md file, from your own software. A key is free and comes with 1,000 credits.
How it works
- Sign in, or create a free account, and create your key on your account page. Your key comes with 1,000 free credits and stays on your account page whenever you need it. It is never emailed.
- Send it with every call, in the header
Authorization: Bearer <key>. Keep it private. Anyone who has it can spend your credits. - Send texts as JSON, or one file as multipart form data. A file can be a
.pdfwith selectable text, or a.txtor.mdfile. Sending a file shows how. - Each text costs 1 credit per started 512 tokens, and at least 1. A credit covers about 400 English words, so a 1,000-word text costs 3 credits. Every answer gives each text's
n_tokens, so you can check the charge. Invalid requests cost nothing, and a request that needs more credits than you have left is refused (402) without charging. - Up to 10 texts or one file per request, and 200,000 characters per text, the text taken from a file included. English only. The accuracy limits in the benchmark report apply.
- Texts and files sent to the API are scored and not stored. Only your credit count is kept.
Fast or detailed
| Call | Address | Returns |
|---|---|---|
| Detailed | POST /v1/api/detect | Verdicts, windows and segments |
| Fast | POST /v1/api/detect/fast | Verdicts only |
The fast call returns one verdict per text. The detailed call also returns windows, a score for each part of a long text with its character positions, and segments, the parts of the text labelled AI or human, so you can see which passages look AI-written. Both take the same request, texts as JSON or one file, cost the same and give exactly the same verdicts, and the fast call is quicker. Use it whenever you only need the overall result.
Detailed example
Two texts in one call. The first fits in one window. The second is long, so it is scored in five overlapping windows, and one of them scores much lower than the rest. So the end of the second text is labelled human, and it comes out partly AI-generated.
curl -X POST https://test.api.paratrace.net/v1/api/detect \
-H "Authorization: Bearer pt_..." \
-H "Content-Type: application/json" \
-d '{
"texts": [
"A first text, about 300 words long ...",
"A second text, about 1,260 words long ..."
],
"operating_point": "strict"
}'{
"detector_version": "v7",
"documents": [
{
"document": "text_1",
"credits": 1,
"probability": 0.9731,
"is_ai": true,
"verdict": "ai",
"ai_fraction": 1.0,
"confidence": "high",
"operating_point": "strict",
"n_words": 312,
"n_tokens": 389,
"n_windows": 1,
"windows": [
{ "start": 0, "end": 1874, "probability": 0.9731 }
],
"segments": [
{ "start": 0, "end": 1874, "label": "ai", "probability": 0.9731 }
],
"warnings": []
},
{
"document": "text_2",
"credits": 4,
"probability": 0.9996,
"is_ai": true,
"verdict": "mixed",
"ai_fraction": 0.97,
"confidence": "medium",
"operating_point": "strict",
"n_words": 1260,
"n_tokens": 1790,
"n_windows": 5,
"windows": [
{ "start": 0, "end": 2286, "probability": 1.0 },
{ "start": 1739, "end": 4019, "probability": 1.0 },
{ "start": 3418, "end": 5893, "probability": 1.0 },
{ "start": 5249, "end": 7675, "probability": 0.9982 },
{ "start": 7136, "end": 7944, "probability": 0.1349 }
],
"segments": [
{ "start": 0, "end": 7675, "label": "ai", "probability": 0.9996 },
{ "start": 7675, "end": 7944, "label": "human", "probability": 0.1349 }
],
"warnings": []
}
],
"credits_charged": 5,
"credits_remaining": 995
}Fast example
The second text from above, sent alone to the fast call. The verdict is the same. Each document has no windows or segments key at all, not an empty list, and n_windows still says how many windows were scored.
curl -X POST https://test.api.paratrace.net/v1/api/detect/fast \
-H "Authorization: Bearer pt_..." \
-H "Content-Type: application/json" \
-d '{"text": "A text, about 1,260 words long ...", "operating_point": "strict"}'{
"detector_version": "v7",
"documents": [
{
"document": "text",
"probability": 0.9996,
"is_ai": true,
"verdict": "mixed",
"ai_fraction": 0.97,
"confidence": "medium",
"operating_point": "strict",
"n_words": 1260,
"n_tokens": 1790,
"n_windows": 5,
"warnings": [],
"credits": 4
}
],
"credits_charged": 4,
"credits_remaining": 996
}Sending a file
Both detect calls take a file as well. Instead of JSON, send one file as multipart form data in the field files, to POST /v1/api/detect or POST /v1/api/detect/fast.
curl -X POST https://test.api.paratrace.net/v1/api/detect \
-H "Authorization: Bearer pt_..." \
-F "files=@paper.pdf"- The file can be a
.pdfwith selectable text, or a.txtor.mdfile in UTF-8, UTF-16 or Windows-1252. - You may add the form fields
textandoperating_point. - The answer is the same JSON as for a text, with the document named by its file name, such as
"document": "paper.pdf". Credits are counted on the text taken from the file. - One file per request. A second file, a scanned PDF without a text layer, or a password-protected or broken PDF is refused with
422, and nothing is charged. - Files, like texts, are scored and not stored.
Fields
| Field | Meaning |
|---|---|
document | Which text this is. A single text is answered as text, a list as text_1, text_2 and so on in the same order, and a file by its file name. |
probability | How likely the text is to be AI-generated, from 0 to 1. null when nothing was left after cleaning. For a text in more than one window it doesn't decide the verdict. |
is_ai | For a text in one window, true when probability is at or above threshold. For a longer one, true unless verdict is human, so a partly AI-generated text counts. |
verdict | ai, human or mixed, which means partly AI-generated. null when nothing was left after cleaning. |
ai_fraction | How much of the text is labelled AI, from 0 to 1. null as for verdict. |
confidence | How sure the verdict is, low, medium or high, by cut-offs set from our tests. null as for verdict. |
threshold | The cut-off that was applied. At strict it flags about 1 in 100 human texts, and at lenient about 1 in 20. For a text in more than one window it is each window's cut-off, so don't compare it with probability. |
n_words | Words in the text as sent, or as taken from the file. |
n_tokens | Tokens in the text as sent, or as taken from the file, counted with the detector's own tokenizer. The text costs 1 credit per started 512 of them. |
n_windows | How many 512-token windows were scored. Long texts have several, and the probability combines them. Windows overlap, but you pay for the text's tokens, not for each window. |
windows | Detailed call only. Each window with its own probability, and its start and end in the text you sent, or the text taken from the file, counted in Unicode code points with end excluded. Neighbouring windows overlap. |
segments | Detailed call only. The parts of the text in order, without overlap, each with its label, ai or human, its start and end counted like the windows', and its mean probability. Where a part starts and ends is approximate. An empty list when nothing was scored. |
warnings | Notes on reliability, for a short text or a text left empty after cleaning. |
credits | What this text cost, 1 credit per started 512 tokens and at least 1. |
Beside documents, every answer has detector_version, which names the detector that scored the request so you can tell when a newer one takes over, and credits_charged and credits_remaining.
Errors
Both calls answer errors the same way, with these statuses.
| Status | When |
|---|---|
401 | The key is missing or invalid. |
402 | Not enough credits left. Nothing is charged. |
403 | The key has been deactivated. |
413 | A text, or the text taken from a file, is over 200,000 characters. |
415 | A file of another type than .pdf, .txt or .md. |
422 | No text, an empty text, more than 10 texts, a second file, a PDF without a text layer, a password-protected or broken PDF, or an invalid field. |
503 | The detector is unavailable. Your credits are refunded. |
More options
- Send up to 10 texts as
"texts": [...], a single one as"text": "...", or one file as multipart form data. operating_pointisstrict, the default, orlenient. The operating points explain the difference.GET https://test.api.paratrace.net/v1/api/accountwith the same header returns the credits you have left, incredits_available. The key spends your account's credits, shared with the website.