API Documentation
Everything you need to integrate Forensa's AI content detection into your application.
Overview
Forensa provides a REST API for detecting AI-generated content across text, images, audio, and video. All endpoints are served from a single base URL and return JSON responses.
Base URL: https://api.forensa.ai/api/v1 (production) or http://localhost:8000/api/v1 (local dev)
Authentication: Every request must include either a Bearer JWT token or an API key via the X-API-Key header. Anonymous scanning is available at /analyze/anonymous with a 3-scan limit per IP.
Authentication
Register a new account
POST /auth/register
Content-Type: application/json
{ "email": "you@example.com", "password": "securePass1" }
Returns: { access_token, token_type, plan, email, email_verified }
Log in
POST /auth/login
Content-Type: application/json
{ "email": "you@example.com", "password": "securePass1" }
Returns: { access_token, token_type, plan, email, email_verified }
Get profile
GET /auth/me Authorization: Bearer <token>
Create API key
POST /auth/api-key?name=MyApp Authorization: Bearer <token>
Returns the raw key once — store it securely.
Analyze (Authenticated)
Upload and analyze a file
POST /analyze Authorization: Bearer <token> Content-Type: multipart/form-data file: <binary> log_to_blockchain: false (optional query param)
Response:
{
"scan_id": "uuid",
"file_name": "photo.jpg",
"type": "image",
"ai_score": 0.87,
"ai_score_percent": 87,
"generated": true,
"verdict": "AI-Generated",
"model_used": "clip-probe",
"confidence": 0.92,
"forensics": { ... },
"blockchain": { "logged": false, "tx_hash": null },
"usage": { "scans_used": 3, "scans_remaining": 7 },
"timestamp": "2026-04-10T12:00:00Z"
}Supported media types: text (.txt, .md, .docx, .pdf), image (.jpg, .png, .webp, .gif), audio (.mp3, .wav, .ogg, .m4a, .flac), video (.mp4, .mov, .avi, .mkv, .webm)
Max file size: 50MB
Analyze (Anonymous)
Anonymous scan — no account required
POST /analyze/anonymous Content-Type: multipart/form-data file: <binary>
Limited to 3 scans per IP address per 30-day rolling window. No blockchain logging, no scan history.
Check remaining scans
GET /analyze/anonymous/remaining
Returns: { used, remaining, limit, window_days }
Scan History & Reports
Get scan history (paginated)
GET /analyze/history?page=1&per_page=20 Authorization: Bearer <token>
Get full forensic report
GET /analyze/report/{scan_id}
Authorization: Bearer <token>
Returns complete forensic detail including all signal scores, metadata, and blockchain proof if logged.
Error Codes
| Code | Meaning |
|---|---|
| 400 | Bad request — invalid input or missing fields |
| 401 | Authentication required or invalid credentials |
| 403 | Email verification required / insufficient permissions |
| 404 | Resource not found |
| 409 | Email already registered |
| 413 | File exceeds 50MB limit |
| 429 | Scan limit reached — upgrade plan or wait for reset |
| 500 | Internal server error |
| All error responses follow: `{ "detail": "Human-readable message" }` |
Rate Limits & Plans
| Plan | Scans/Month | Price | Features |
|---|---|---|---|
| Anonymous | 3 per 30 days | Free | Basic scan only |
| Free | 10 / month | $0 | Text + Image, forensic reports, API access |
| Pro | 500 / month | $19/mo | All media types, AI source ID, blockchain proof |
| Enterprise | Unlimited | $29/user/mo | All Pro + SLA, SSO, private endpoints |
| Scan counters reset every 30 days. Usage info is returned in every scan response under the `usage` key. | |||
| **Credit packs** are also available for one-time purchases: 25 ($5), 100 ($12), 500 ($40), 2000 ($100). |
Polygon Network
Forensa Blockchain Architecture
Two-contract verification system · Immutable · Tamper-proof
ContentAuditLog
Immutable forensic record
contentHash·bytes32aiScore·uint8mediaType·enumforensicHash·bytes32verifier·addressAppend-only · One record per content hash · Batch up to 50/tx
VerifiedHumanBadge
Soulbound ERC-721
contentHash·bytes32recipient·addressmintedAt·uint256revoked·boolrevokeReason·stringNon-transferable · One badge per content · Revocable with reason
Blockchain Contracts
Forensa deploys two smart contracts on Polygon to create an immutable, tamper-proof verification layer for AI content detection. Together they form a bidirectional trust system: one records what was analyzed, and the other certifies what was proven human. Both contracts are fully open-source, independently auditable, and designed around the principle that verification data — once written — can never be altered or deleted.
---
Contract 1: ContentAuditLog
Purpose: Immutable forensic audit log for every AI detection result produced by Forensa.
Problem it solves: In legal, journalistic, and regulatory settings, parties need to prove that a specific piece of content was analyzed at a specific point in time, and what the analysis concluded. Traditional databases can be edited, deleted, or backdated. ContentAuditLog makes that impossible — once a detection is recorded, it exists permanently on Polygon with a block-confirmed timestamp that no party (including Forensa) can alter.
How it works:
When a user runs a scan with blockchain logging enabled, Forensa's backend computes a SHA-256 hash of the analyzed content and a SHA-256 hash of the full forensic report JSON. These hashes, along with the AI probability score (0–100), the media type (TEXT, IMAGE, AUDIO, or VIDEO), and the binary AI/human classification, are submitted to the contract by an authorized verifier address.
The contract enforces strict immutability: each content hash can only be logged once. Attempting to re-log the same content reverts the transaction with a ContentAlreadyLogged error. This prevents anyone from overwriting a prior result with a different conclusion.
Key technical details:
Contract: ContentAuditLog Network: Polygon (PoS) Solidity: ^0.8.20 Inheritance: Ownable2Step, Pausable, ReentrancyGuard Storage per record: - contentHash (bytes32): SHA-256 of analyzed content - mediaType (enum): TEXT | IMAGE | AUDIO | VIDEO - isAI (bool): classification result - aiScore (uint8): 0–100 AI probability - timestamp (uint256): block.timestamp at submission - verifier (address): authorized address that submitted - forensicHash (bytes32): SHA-256 of full forensic report JSON
Batch processing: The contract supports batch logging of up to 50 detection records per transaction via logDetectionBatch(). This optimizes gas costs for high-volume users (Pro and Enterprise plans) who run hundreds of scans per month. Duplicate and invalid entries are silently skipped during batch operations, so callers don't need to pre-filter.
Access control: Only addresses in the authorizedVerifiers mapping (plus the contract owner) can submit records. This prevents unauthorized parties from polluting the audit log with fabricated detection results. Verifiers are managed by the contract owner via addVerifier() and removeVerifier().
Security features:
- Ownable2Step: two-step ownership transfer prevents accidental key loss (must accept on new address) - Pausable: emergency halt on all state-changing operations if a vulnerability is discovered post-deployment - ReentrancyGuard: defense-in-depth against state manipulation during function execution - Custom Solidity errors: ~50% gas savings vs require strings - bytes32 for all hashes: type-safe, gas-efficient storage
View functions:
getRecord(bytes32 contentHash) → Returns full DetectionRecord struct hasRecord(bytes32 contentHash) → Returns bool (existence check) hasRecords(bytes32[] contentHashes) → Returns bool[] (batch existence check) totalRecords → Returns uint256 (monotonically increasing counter)
Events emitted:
DetectionLogged(contentHash, verifier, mediaType, isAI, aiScore, timestamp) DetectionBatchLogged(verifier, count, timestamp) VerifierAdded(verifier, addedBy) VerifierRemoved(verifier, removedBy)
Use cases:
- Legal evidence: Lawyers can reference a Polygonscan transaction to prove content was flagged as AI-generated (or human) before a specific date
- Journalism: Newsrooms can verify that images or text were analyzed before publication, establishing a chain of custody
- Regulatory compliance: Organizations can demonstrate due diligence in screening content for AI generation
- Academic integrity: Institutions can create immutable records of submission analysis
- Insurance claims: Adjusters can prove when and how content authenticity was verified
---
Contract 2: VerifiedHumanBadge
Purpose: Soulbound ERC-721 NFT that certifies specific content as verified human-created.
Problem it solves: As AI-generated content proliferates, human creators need a way to prove their work is authentic. A database entry can be faked. A PDF certificate can be forged. A soulbound NFT on Polygon cannot. The VerifiedHumanBadge is permanently bound to the creator's wallet address — it cannot be transferred, sold, or traded — and is anchored to a specific content hash, creating a cryptographic link between a human identity and a verified piece of work.
How it works:
When Forensa's detection engine classifies content as human-created with high confidence, the content creator can request a VerifiedHumanBadge. An authorized minter address calls mintBadge() with the creator's wallet address, the SHA-256 content hash, and a metadata URI pointing to a JSON file (typically on IPFS) that describes the badge. The contract mints a non-transferable ERC-721 token to the creator's wallet.
The soulbound mechanism works by overriding ERC-721's _update() function: any transfer where both from and to are non-zero addresses is reverted with SoulboundTransferBlocked(). The approve() and setApprovalForAll() functions are also hard-blocked, preventing any approval-based transfer workarounds. Only minting (from = address(0)) and burning (to = address(0)) are permitted.
Key technical details:
Contract: VerifiedHumanBadge Network: Polygon (PoS) Solidity: ^0.8.20 Token Standard: ERC-721 (Soulbound) Token Name: "Forensa Verified Human Badge" Token Symbol: FVHB Inheritance: ERC721, ERC721URIStorage, Ownable2Step, Pausable, ReentrancyGuard Storage per badge: - contentHash (bytes32): SHA-256 of verified content - recipient (address): wallet of the human author - mintedAt (uint256): block.timestamp at minting - revoked (bool): true if badge was later revoked - revokeReason (string): on-chain reason for revocation
One badge per content: The contract enforces a strict one-to-one mapping between content hashes and badges via the _contentHashToToken mapping. If a content hash already has a badge (even if revoked), no new badge can be minted for it. This prevents duplicate certifications.
Revocation: If content is later determined to be AI-generated despite initial verification, the contract owner can call revokeBadge(tokenId, reason). This sets the revoked flag to true, stores the reason string on-chain for transparency, and burns the token from the holder's wallet. Revocation is irreversible — the Badge struct retains the full history (mint timestamp, original recipient, revocation reason) for auditability even after the token is burned.
Security features:
- Soulbound pattern: _update() override blocks all transfers between non-zero addresses - approve() and setApprovalForAll() hard-revert to prevent approval-based transfer workarounds - Ownable2Step: same two-step ownership as ContentAuditLog - Pausable: emergency halt on minting operations - ReentrancyGuard: defense-in-depth on mint and revoke - Custom errors: gas-efficient revert reasons
View functions:
getBadge(uint256 tokenId) → Returns full Badge struct getBadgeByContent(bytes32 contentHash) → Returns Badge struct by content hash lookup isVerified(bytes32 contentHash) → Returns bool (true if active, non-revoked badge exists) tokensOf(address holder) → Returns uint256[] of active (non-revoked) token IDs totalMinted() → Returns uint256 (all badges ever minted, including revoked)
Events emitted:
BadgeMinted(tokenId, recipient, contentHash, mintedAt) BadgeRevoked(tokenId, revokedBy, reason) MinterAdded(minter, addedBy) MinterRemoved(minter, removedBy)
Metadata format (ERC-721 tokenURI):
{
"name": "Forensa Verified Human Badge",
"description": "This content was verified as
human-created by Forensa.",
"image": "ipfs://...",
"attributes": [
{ "trait_type": "Content Hash", "value": "0x..." },
{ "trait_type": "Verified At", "value": "2026-04-10" }
]
}| **Use cases:** | |||
|---|---|---|---|
| - **Content creators:** Artists, writers, and musicians can prove their work is human-made in an era of AI-generated content | |||
| - **Social media verification:** Platforms can check whether content has an active VerifiedHumanBadge before applying AI-content labels | |||
| - **Portfolio authentication:** Professionals can link their wallet to verified badges as proof of original human work | |||
| - **Marketplace trust:** Content marketplaces can display badge status to buyers as a human-authenticity signal | |||
| - **Academic publishing:** Researchers can badge their papers to demonstrate human authorship | |||
| --- | |||
| **How the two contracts work together:** | |||
| ContentAuditLog and VerifiedHumanBadge form a complementary verification framework: | |||
| 1. **Content is uploaded** to Forensa for AI detection analysis | |||
| 2. **ContentAuditLog records the analysis** — the content hash, AI score, forensic report hash, and classification are permanently logged on Polygon | |||
| 3. **If the content is classified as human-created** with high confidence, the author can request a VerifiedHumanBadge | |||
| 4. **The badge is minted** as a soulbound NFT to the author's wallet, anchored to the same content hash that exists in the audit log | |||
| 5. **Anyone can verify** the chain: look up the content hash in ContentAuditLog to see what the analysis concluded, then check VerifiedHumanBadge to see if a human-authorship badge was issued | |||
| This creates a system where both negative results (AI-detected) and positive results (human-verified) are immutably recorded, and neither Forensa nor any third party can retroactively alter the record. | |||
| **Why Polygon:** | |||
| - **Low gas costs:** Polygon's PoS consensus provides transaction fees under $0.01, making it economically viable to log every scan on-chain | |||
| - **Fast finality:** ~2 second block times ensure detection records are confirmed almost instantly | |||
| - **EVM compatibility:** Full Solidity support with the same tooling, libraries (OpenZeppelin), and ecosystem as Ethereum mainnet | |||
| - **Ecosystem reach:** Polygon's widespread adoption means wallets, explorers (Polygonscan), and indexers already support the contracts natively | |||
| - **Environmental footprint:** PoS consensus uses ~99.9% less energy than proof-of-work chains | |||
| **Availability by plan:** | |||
| Feature | Free | Pro | Enterprise |
| ContentAuditLog (blockchain proof) | — | ✓ | ✓ |
| VerifiedHumanBadge (soulbound NFT) | — | ✓ | ✓ |
| Batch logging (up to 50/tx) | — | — | ✓ |
| View on Polygonscan | ✓ | ✓ | ✓ |