IDENTIF.Ai API Docs

IDENTIF.Ai Text Detection API

Zero‑shot AI text detection via lightweight perplexity analysis. This service exposes HTTP endpoints for single and batch detection, health, and Prometheus metrics.

Base URL
https://api.identif.ai/
Version 1.0.0
Auth
Send API key via Authorization: Bearer <key> or X-API-Key: <key>
Model
Default HF model: gpt2 (configurable)
Content Type
application/json

Quickstart

cURL

curl -s -X POST "https://<host>/api/v1/detect" \ 
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "This is a sample paragraph...",
    "threshold": 0.9
  }'

JavaScript (fetch)

const res = await fetch("https://<host>/api/v1/detect", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${API_KEY}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({ text: inputText, threshold: 0.9 })
});
const data = await res.json();

Python

import requests
r = requests.post(
  "https://<host>/api/v1/detect",
  headers={"Authorization": f"Bearer {API_KEY}"},
  json={"text": "...", "threshold": 0.9}
)
print(r.json())
Heads‑up: The detector treats lower scores as more likely AI. A threshold closer to 1.0 is stricter; default is 0.9.

Authentication

Provide a static API key using either header. If both are present, Authorization takes precedence.

HeaderExampleNotes
AuthorizationBearer dev-key-12345Preferred
X-API-Keydev-key-12345Alternative

Default/dev key is dev-key-12345 unless API_KEY env var is set.

Rate Limits

Simple in‑memory limiter keyed by client IP.

SettingEnvDefault
Max requestsRATE_LIMIT_REQUESTS100
Window (seconds)RATE_LIMIT_WINDOW60

Exceeding the limit returns 429 Too Many Requests.

Endpoints

GET

/

Root info.

Response

{
  "service": "IDENTIF.Ai Text Detection API",
  "version": "1.0.0",
  "status": "running"
}
GET

/health

Health and readiness.

FieldTypeDescription
statusstringhealthy | unhealthy
model_loadedbooleanTrue when model is in cache
devicestringcuda | cpu
uptime_secondsnumberProcess uptime
versionstringAPI version
GET

/metrics

Prometheus exposition format.

Content type: text/plain; version=0.0.4

POST

/api/v1/detect

Detect whether a single text is AI‑generated.

Auth

Requires API key & passes rate limit.

Request Body

{
  "text": "string (1..50000 chars)",
  "threshold": 0.9,         // optional, 0.0..1.0 (lower score = AI)
  "return_probabilities": false // optional (reserved)
}

Success Response 200

{
  "verdict": "ai_generated" | "human_written",
  "confidence": 0.42,
  "score": 0.37,            // lower = more likely AI
  "is_ai_generated": true,
  "model_used": "IDENTIF.Ai",
  "processing_time_ms": 12.8,
  "metadata": {
    "text_length": 1234,
    "word_count": 215,
    "threshold": 0.9
  }
}

Errors

  • 401 Missing/invalid API key
  • 429 Rate limit exceeded
  • 503 Model not loaded
  • 500 Detection failed
POST

/api/v1/detect/batch

Batch detection for multiple texts.

Request Body

{
  "texts": ["...", "..."], // 1..100 items, non‑empty strings
  "threshold": 0.9,
  "return_probabilities": false
}

Success Response 200

{
  "results": [
    {
      "verdict": "ai_generated",
      "confidence": 0.31,
      "score": 0.25,
      "is_ai_generated": true,
      "model_used": "IDENTIF.Ai",
      "processing_time_ms": 10.1,
      "metadata": { "text_length": 141, "word_count": 25, "threshold": 0.9 }
    },
    { /* ... */ }
  ],
  "total_items": 2,
  "processing_time_ms": 21.5,
  "summary": {
    "ai_generated_count": 1,
    "human_written_count": 1,
    "error_count": 0,
    "ai_percentage": 50.0
  }
}

Errors

  • 401 Missing/invalid API key
  • 429 Rate limit exceeded
  • 503 Model not loaded
  • 500 Batch detection failed

Schemas

TextDetectionRequest

textstring (required, 1..50000)
thresholdnumber (0..1, default 0.9)
return_probabilitiesboolean (default false)

BatchTextDetectionRequest

textsarray<string> (1..100, trimmed)
thresholdnumber (0..1, default 0.9)
return_probabilitiesboolean (default false)

DetectionResult

verdictai_generated | human_written
confidencenumber (0..1)
scorenumber (0..1, lower = AI)
is_ai_generatedboolean
model_usedstring ("IDENTIF.Ai")
processing_time_msnumber
metadataobject (length, words, threshold)

BatchDetectionResult

resultsarray<DetectionResult | error>
total_itemsinteger
processing_time_msnumber
summaryobject (counts & percentage)

HealthResponse

statusstring
model_loadedboolean
devicestring
uptime_secondsnumber
versionstring

Error Format

Errors use a consistent JSON envelope:

{
  "error": "message",
  "status_code": 401,
  "timestamp": "2025-01-01T12:34:56.789Z"
}
StatusWhen
400Validation errors (e.g., empty text)
401Missing/invalid API key
429Rate limit exceeded
500Unhandled server error
503Model not loaded

Prometheus Metrics

MetricTypeLabelsDescription
IDENTIF.Ai_requests_total counter endpoint, status Total number of requests per endpoint (success/error)
IDENTIF.Ai_request_duration_seconds histogram endpoint Request duration
IDENTIF.Ai_detections_total counter verdict Count of detection outcomes

Scrape /metrics with your Prometheus server.

Deploy & Configuration

Environment Variables

API_KEYStatic auth key (default dev-key-12345)
MODEL_NAMEHF model id (default gpt2)
DEVICEcuda | cpu (auto if unset)
CORS_ORIGINSComma‑separated list (default *)
PORTDefault 5002
HOSTDefault 0.0.0.0
RELOADtrue | false (dev hot reload)
WORKERSUvicorn workers (default 1)
LOG_LEVELcritical|error|warning|info|debug|trace
RATE_LIMIT_REQUESTSDefault 100
RATE_LIMIT_WINDOWDefault 60

Run Locally

python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
export API_KEY=dev-key-12345
uvicorn main:app --host 0.0.0.0 --port 5002 --reload

Health & Startup

On startup the app loads the tokenizer/model and caches them globally. /health returns model_loaded=true when ready.

Implementation note: The code uses a single cached model across requests; ensure your container has sufficient VRAM/Memory when setting MODEL_NAME to larger LMs.

Changelog