API Reference

LegitV API Documentation

Authenticate products programmatically. Send images, get detailed verdicts with confidence scores in seconds.

Base URL: https://api.legitv.ioFormat: JSON

Quick Start

Get your first authentication result in 3 API calls. All requests require a JWT bearer token obtained via Supabase Auth, or a business API key for B2B integrations.

1. Create a verification

POST /api/verify/create
curl -X POST https://api.legitv.io/api/verify/create \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "itemType": "nike_dunk_low",
    "listingUrl": "https://vinted.fr/items/123456",
    "userDescription": "Nike Dunk Low Panda, size 42"
  }'

# Response
{
  "id": "ver_abc123",
  "status": "draft",
  "itemType": "nike_dunk_low",
  "createdAt": "2026-03-31T10:00:00Z"
}

2. Trigger analysis

POST /api/verify/:id/analyze
curl -X POST https://api.legitv.io/api/verify/ver_abc123/analyze \
  -H "Authorization: Bearer <token>"

# Response
{
  "status": "queued",
  "jobId": "job_xyz789",
  "estimatedWait": "~30s"
}

3. Get the result

GET /api/verify/:id
curl https://api.legitv.io/api/verify/ver_abc123 \
  -H "Authorization: Bearer <token>"

# Response
{
  "id": "ver_abc123",
  "status": "completed",
  "verdict": "authentic",
  "confidenceScore": 0.94,
  "criteriaResults": [
    {
      "name": "Label typography",
      "score": 0.97,
      "status": "pass",
      "details": "Font weight and spacing match authentic samples"
    },
    {
      "name": "Stitching pattern",
      "score": 0.91,
      "status": "pass",
      "details": "Stitch density consistent with Nike QC standards"
    }
  ],
  "proofHash": "sha256:a1b2c3d4...",
  "reportUrl": "/api/verify/ver_abc123/report"
}

Authentication

Bearer Token (B2C)

For end-user authentication via Supabase Auth. Include the JWT in every request.

Authorization: Bearer <supabase_jwt_token>

API Key (B2B)

For business integrations. Contact [email protected] to get your key.

X-API-Key: <your_business_api_key>

Endpoints Reference

Verification

POST/api/verify/create
Create a draft verificationauth
POST/api/verify/:id/analyze
Queue AI analysisauth
GET/api/verify/:id
Get verification resultauth
GET/api/verify/list
List user verificationsauth
DELETE/api/verify/:id
Delete a verificationauth
GET/api/verify/:id/queue
Get queue positionauth
GET/api/verify/:id/report
Download PDF reportauth

Proof & Sharing

GET/api/verify/:id/proof
Get proof data (public)
POST/api/verify/proof/check
Verify proof with images (public)
GET/api/share
Get shareable verification

Templates

GET/api/templates
List active product templates
GET/api/templates/:id
Get template with criteria
GET/api/templates/by-type/:itemType
Get template by item type
GET/api/templates/categories
List categories
GET/api/templates/criteria-options
Zones and photo types

Credits & Billing

GET/api/credits/balance
Get credit balanceauth
GET/api/credits/packages
List credit packages
GET/api/credits/history
Transaction historyauth
POST/api/credits/redeem
Redeem promo codeauth
POST/api/credits/checkout
Create Stripe checkoutauth

Feedback

GET/api/feedback
Get user feedbackauth

System

GET/health
Health check
GET/api/verify/providers
List AI providers
GET/api/verify/queue/status
Queue statisticsauth

Request & Response Format

Create Verification — Request Body

POST /api/verify/create
{
  "itemType": "string",        // Required — template slug (e.g. "nike_dunk_low")
  "listingUrl": "string",      // Optional — marketplace listing URL
  "images": ["string"],        // Optional — array of image URLs or base64
  "userDescription": "string"  // Optional — item description
}

Verification Result — Response

GET /api/verify/:id (completed)
{
  "id": "string",
  "status": "draft" | "queued" | "processing" | "completed" | "failed",
  "verdict": "authentic" | "suspect" | "inconclusive",
  "confidenceScore": 0.0 - 1.0,
  "criteriaResults": [
    {
      "criterionId": "string",
      "name": "string",
      "zone": "label" | "hardware" | "stitching" | "material" | "overall",
      "score": 0.0 - 1.0,
      "status": "pass" | "fail" | "inconclusive",
      "isDealbreaker": false,
      "details": "string"
    }
  ],
  "proofHash": "sha256:...",
  "itemType": "string",
  "createdAt": "ISO 8601",
  "completedAt": "ISO 8601"
}

Webhooks

For async workflows, configure a webhook URL in your business dashboard. We send a POST request when verification completes.

Webhook payload
POST https://your-app.com/webhooks/legitv
Content-Type: application/json
X-LegitV-Signature: sha256=...

{
  "event": "verification.completed",
  "verificationId": "ver_abc123",
  "verdict": "authentic",
  "confidenceScore": 0.94,
  "completedAt": "2026-03-31T10:00:30Z"
}

Rate Limits & SLA

PlanRate LimitAvg. ResponseSLA
Free / B2C10 req/min< 30sBest effort
Starter60 req/min< 20s99%
Growth200 req/min< 15s99.5%
EnterpriseCustom< 10s99.9%

Error Codes

CodeMeaningResolution
401UnauthorizedCheck your token or API key
402Insufficient creditsPurchase more credits or upgrade plan
404Not foundCheck resource ID
422Validation errorCheck request body format
429Rate limitedReduce request frequency

SDK Examples

Python

python
import requests

API_URL = "https://api.legitv.io"
API_KEY = "your_api_key"

headers = {"X-API-Key": API_KEY}

# Create verification
resp = requests.post(f"{API_URL}/api/verify/create", headers=headers, json={
    "itemType": "chanel_classic_flap",
    "listingUrl": "https://vestiairecollective.com/items/..."
})
verification = resp.json()

# Trigger analysis
requests.post(f"{API_URL}/api/verify/{verification['id']}/analyze", headers=headers)

# Poll for result (or use webhook)
import time
while True:
    result = requests.get(f"{API_URL}/api/verify/{verification['id']}", headers=headers).json()
    if result["status"] == "completed":
        print(f"Verdict: {result['verdict']} ({result['confidenceScore']:.0%})")
        break
    time.sleep(5)

Node.js

javascript
const API_URL = "https://api.legitv.io";
const headers = { "X-API-Key": "your_api_key", "Content-Type": "application/json" };

// Create and analyze
const { id } = await fetch(`${API_URL}/api/verify/create`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    itemType: "louis_vuitton_neverfull",
    listingUrl: "https://vinted.fr/items/789"
  })
}).then(r => r.json());

await fetch(`${API_URL}/api/verify/${id}/analyze`, { method: "POST", headers });

// Get result (after webhook or polling)
const result = await fetch(`${API_URL}/api/verify/${id}`, { headers }).then(r => r.json());
console.log(`Verdict: ${result.verdict} (${Math.round(result.confidenceScore * 100)}%)`);

Ready to integrate?

Get a free business API key and start your pilot with 100 free verifications.