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

CodeMeaning
400Bad request — invalid input or missing fields
401Authentication required or invalid credentials
403Email verification required / insufficient permissions
404Resource not found
409Email already registered
413File exceeds 50MB limit
429Scan limit reached — upgrade plan or wait for reset
500Internal server error
All error responses follow: `{ "detail": "Human-readable message" }`

Rate Limits & Plans

PlanScans/MonthPriceFeatures
Anonymous3 per 30 daysFreeBasic scan only
Free10 / month$0Text + Image, forensic reports, API access
Pro500 / month$19/moAll media types, AI source ID, blockchain proof
EnterpriseUnlimited$29/user/moAll 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

Solidity ^0.8.20
contentHash·bytes32
aiScore·uint8
mediaType·enum
forensicHash·bytes32
verifier·address

Append-only · One record per content hash · Batch up to 50/tx

VerifiedHumanBadge

Soulbound ERC-721

FVHB Token
contentHash·bytes32
recipient·address
mintedAt·uint256
revoked·bool
revokeReason·string

Non-transferable · One badge per content · Revocable with reason

⛓️Polygon PoS·< $0.01 gas
🔒OpenZeppelin v5·Audited libs
~2s Finality·Near-instant
🌱99.9% Less Energy·vs PoW chains

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:**
FeatureFreeProEnterprise
ContentAuditLog (blockchain proof)
VerifiedHumanBadge (soulbound NFT)
Batch logging (up to 50/tx)
View on Polygonscan