How to integrate an AI detector API

Send an image, text or code to the isGenAI API and get a result with every check behind it. This working Node.js example runs in minutes with private inputs, a request timeout and a small, predictable output.

What is an AI detector API?

An AI detector API is a web endpoint your application calls to check content for signs of AI use. With isGenAI, you send an image, text, code or public URL to POST /v1/check and get JSON back: a headline, the basis for it, such as a public label, saved prompt or signed record, and the status of each check. Every finding is evidence you can show your users, with its source attached.

1. Run a check

Install Node.js 22 or newer, then download check-content.mjs. The example needs no package installation and no API key for the public endpoint. Service limits keep it fast for everyone.

node check-content.mjs
node check-content.mjs --text "This summary was drafted with Claude."
node check-content.mjs --code "// This function was coded using GitHub Copilot."
node check-content.mjs --file picture.png

The command without arguments checks a clearly labelled demonstration sentence. Use --text, --code or --file to supply your own input. Each command sends one check.

2. Read the result and its basis

The default sentence states that ChatGPT was used, so the response headline is AI DETECTED with Public label as its basis: a stated AI use, with the sentence to prove it.

For images, results also come from saved prompts, signed records and matching copies. Read adapter_runs to see which checks completed and which were unavailable. NO AI SIGNAL DETECTED means the completed checks found no AI evidence in that copy: a verified clean copy, reported as exactly that rather than as a human certificate.

The downloadable example prints the headline, basis and check statuses, and keeps submitted text, filenames and feedback tokens out of its console output.

3. Use the complete example

// isGenAI public API example. CC0-1.0. Requires Node.js 22 or newer.
// Checks one explicitly supplied file/text or the clearly labelled default example.
import { readFile, stat } from "node:fs/promises";
import { extname } from "node:path";

const [mode, value, extra] = process.argv.slice(2);
if (extra || (mode && (!["--text", "--code", "--file"].includes(mode) || !value))) {
  throw new Error('Usage: node check-content.mjs [--text "words" | --code "code" | --file picture.png]');
}
const base = new URL(process.env.ISGENAI_BASE_URL || "https://isgenai.com");
if (base.username || base.password || (base.protocol !== "https:" && !(base.protocol === "http:" && ["localhost", "127.0.0.1"].includes(base.hostname)))) {
  throw new Error("Use HTTPS, or HTTP localhost for a local test.");
}
let body;
let headers;
if (mode === "--file") {
  const type = { ".png": "image/png", ".jpg": "image/jpeg", ".jpeg": "image/jpeg", ".webp": "image/webp", ".avif": "image/avif" }[extname(value).toLowerCase()];
  if (!type || (await stat(value)).size > 20 * 1024 * 1024) throw new Error("Use a PNG, JPEG, WebP or AVIF file up to 20 MB.");
  body = new FormData();
  body.set("file", new Blob([await readFile(value)], { type }), `image${extname(value).toLowerCase()}`);
  body.set("privacy", "private");
  body.set("source_context", "isgenai-api-example");
} else {
  const text = value || "This demonstration caption was generated with ChatGPT.";
  if (!text.trim() || text.length > 16000) throw new Error("Use 1 to 16,000 characters.");
  body = JSON.stringify({ text, kind: mode === "--code" ? "code" : "text", privacy: "private", source_context: "isgenai-api-example" });
  headers = { "content-type": "application/json" };
}
const response = await fetch(new URL("/v1/check", base), { method: "POST", headers, body, signal: AbortSignal.timeout(30000) });
if (!response.ok) throw new Error(`Check returned HTTP ${response.status}. For 429, wait before retrying; do not loop requests.`);
const result = await response.json();
if (!result.public_result?.headline || !Array.isArray(result.adapter_runs)) throw new Error("Unexpected check response.");
// Print the headline and check statuses only: no submitted content, filenames or feedback tokens.
console.log(JSON.stringify({
  headline: result.public_result.headline,
  basis: result.public_result.basis,
  checks: result.adapter_runs.map(({ adapter, status }) => ({ adapter, status })),
}, null, 2));

4. Add the check to a review workflow

  1. Send one input after the user asks to check it. Set privacy: "private" explicitly.
  2. Show the result together with its basis and completed checks.
  3. Handle non-success HTTP responses separately. On 429, wait before retrying; skip automatic request loops.
  4. Offer a report or review action. A check gives a person evidence to examine; build the flow around that.

Text and code go up to 16,000 characters; images are PNG, JPEG, WebP and AVIF up to 20 MiB (20,971,520 bytes). The script never executes submitted code. The endpoint also checks public URLs; set their privacy explicitly because public-link defaults differ from uploads.

For a local server, set ISGENAI_BASE_URL=http://localhost:3000. For another hosted deployment, use HTTPS. The default is https://isgenai.com.

Read the full API reference, try the AI image detector or open the text and code checker. The example code is CC0-1.0, so adapt it freely in your app.

5. Extract a saved image prompt without an AI model

For an image library or review tool, use mode=saved_only with POST /v1/prompt. It reads the saved instructions from the supplied file, word for word, and never falls back to generating a new prompt.

Download extract-saved-prompt.mjs, then run it with an original image. Node.js 22 or newer, no package installation, no API key.

node extract-saved-prompt.mjs picture.png

The command sends one image to isGenAI and prints the saved prompt, optional negative prompt and recorded model name. Keep that output out of shared logs when it contains private material. This endpoint never adds the image or prompt to a public report.

When a copy contains no saved prompt, the API returns HTTP 422 with no_saved_prompt and the example prints status: "not_found". No model request is made, even when reconstruction is enabled on the server. Both outcomes describe the file’s records, cleanly separated from any verdict on whether the image is real.

Supported records include AUTOMATIC1111 settings in PNG, JPEG and WebP, ComfyUI and Flux workflows in PNG, and InvokeAI PNG records. Use the two downloadable demonstration images to compare identical pixels with and without saved instructions. Service and upload limits apply.

6. Extract saved prompts from a small batch

Download extract-saved-prompts.mjs to check 1–10 explicitly selected files with Node.js 22 or newer. Each file goes up to 20 MiB, with 40 MiB across the batch. File types, byte limits and readability are checked before the first upload. Files are then sent one at a time with generic upload filenames. Every request uses mode=saved_only: no AI model calls, no automatic retries.

node extract-saved-prompts.mjs --output saved-prompts.json -- first.png second.png

Use --output to create a new JSON file with owner-only permissions on macOS and Linux (0600); an existing output path is refused, never overwritten. On Windows, choose a folder with appropriate access permissions. The terminal prints a summary. Without --output, the full JSON goes to standard output and can contain private prompts. Reports identify files by their 1-based input order and omit their filenames; extracted record text itself can still hold sensitive information, so handle it accordingly.

  • saved: saved prompt data was read. not_found: this copy holds no saved prompt.
  • error: a file could not be checked. An individual rejected input is followed by the next file.
  • skipped: a remaining file was not uploaded after the batch stopped. Network failures, server failures, HTTP 429, authorization failures and malformed responses stop further requests.

Try two controlled files first

Download the PNG with saved parameters and the same pixels without records, then run:

node extract-saved-prompts.mjs --output example-prompts.json -- parameters-tEXt.png without-records.png

The expected statuses are saved for input 1 and not_found for input 2. These files exercise saved-record handling end to end. Public endpoint service limits apply.

7. Verify your integration with known files

Run the saved-only example against the controlled parameters PNG. The result contains the paper-boat prompt, seed "42", 20 steps and CFG scale 7. Seeds are strings so large integer values keep their precision.

Then use the same pixels without records. Treat no_saved_prompt as a result your application explains to the user, separately from network or server failures. In saved-only mode this endpoint never generates replacement text.

For workflow JSON, compare the two saved graph types. For before/after files, read the metadata comparison states. The three PNG encoding examples give you another controlled fixture set.

Ready to build? Read the AI detector API reference for every endpoint, field and limit.

AI detector API questions

What does an AI detector API return?

The isGenAI API returns a result headline, the basis for it (such as a public label, saved prompt or signed record) and adapter_runs showing exactly which checks completed or were unavailable. “NO AI SIGNAL DETECTED” means the completed checks found no AI evidence in that copy, reported as a verified clean copy rather than a human certificate.

Do I need an API key to try it?

No. The documented public endpoints used in this guide need no API key and no package installation. Service limits keep it fast for everyone, so handle HTTP 429 by waiting before retrying instead of looping.

Read the API reference

What inputs can I send to POST /v1/check?

Text or code up to 16,000 characters, a PNG, JPEG, WebP or AVIF image up to 20 MiB, or a public URL. Set privacy to private explicitly; public URL checks default to public with signed receipts. Submitted code is read as text and never executed.

Does the API give an AI probability score for text?

No, by design. Text and code checks report disclosed AI use and tool mentions with the exact matching words, so every finding is traceable. A result without a disclosure tells you the text declares no AI use, which is the honest answer rather than a style guess.

How do I extract saved prompts through the API?

Send the original image to POST /v1/prompt with mode=saved_only. It reads AUTOMATIC1111, ComfyUI and InvokeAI records with no AI model call and returns a clean HTTP 422 with no_saved_prompt when the file holds none.

See the saved-only request