# ScanForAI HTTP API

Two public endpoints: `POST /api/scan` (detect AI-writing signals) and `POST /api/humanize` (light clean-up). Base URL `https://api.scanforai.com`. Anonymous works; an API key raises limits and saves history. The score is a signal, not a verdict.

- Interactive Swagger: https://api.scanforai.com/api/docs
- OpenAPI spec (import into Postman/Insomnia): https://api.scanforai.com/api/openapi.json

## Authentication

Send an API key (minted in the dashboard, https://app.scanforai.com/) as a bearer token:

```
Authorization: Bearer at_sk_your_key_here
```

Scripted/API calls need a key — registration is free (no card). Anonymous access is reserved for the web scanner and browser extension. Scopes: `full`, or `read`.

## POST /api/scan

Body can be JSON, a form field, or raw text.

```
curl -s --data-binary @draft.txt "https://api.scanforai.com/api/scan?format=text"

curl -s https://api.scanforai.com/api/scan \
  -H 'Authorization: Bearer at_sk_...' -H 'Content-Type: application/json' \
  -d '{"text": "...", "include_fixes": true}'
```

Parameters: `text` (required unless a `file` upload), `include_fixes` (bool), `genre` (`academic`/`expository`/`fiction`), `esl` (bool — the writer's first language isn't English; relaxes formality tells fairly, independent of `genre`), `deep` (bool, account only — run the deeper model on long text), `save` (bool, account only), `title`/`parent_scan_id` (account only).

Response fields: `score` (0–100, higher = more AI-like, NOT a probability), `band` (low/moderate/elevated/high), `label`, `model_used`, `word_count`, `coverage`, `signals[]` (name/score/weight/detail), `fixes[]`, `scan_id`, `disclaimer`.

Errors: `413` over char cap, `429` rate-limited, `402` monthly word quota, `422` empty text. If the model is briefly unavailable, the scan still succeeds heuristics-only (`model_used: false` + a `degraded` note).

## POST /api/humanize

Light clean-up: strips machine-typography artifacts and normalizes to plain text without rewriting a word. A deeper rewrite is coming.

```
curl -s https://api.scanforai.com/api/humanize \
  -H 'Content-Type: application/json' -d '{"text": "The results—truly—are “remarkable”…"}'
```

Parameters: `text` (required), `contractions` (bool, default false), account-only `title`/`save`.

Response: `mode`, `output_text`, `changes` (map of change → count), `total_changes`, `chars_in`, `chars_out`, `id`.

## Accounts & API keys

A free account raises the per-scan limit to 50,000 characters, adds a monthly word quota, saves scan + humanize history, and issues API keys. Authenticated calls are saved by default — pass `"save": false` to opt out. Anonymous scans/humanizes are never stored.

Source: https://scanforai.com/docs/api.html
