API Documentation

Score short-form videos programmatically. Upload, analyze, get results.

Pricing

Try It

Free
3 free analyses
No account needed

Starter

Free
Sign up, get 10 credits
API access included

Credits

$5+
500–10,000 credits
Buy anytime, no subscription

Your Account

Authentication

Pass your API key via the X-API-Key header, or a JWT via Authorization: Bearer <token>:

curl -H "X-API-Key: gl_xxxxxxxxxxxx" https://greenlit.live/api/health

Anonymous usage (no API key or JWT) uses IP-based rate limiting at 10/day. Authenticated requests deduct 1 credit per analysis.

Base URL

https://greenlit.live/api

Endpoints

POST /api/auth/signup Create account

Create a new account. Returns a JWT and 10 free credits.

Request

curl -X POST https://greenlit.live/api/auth/signup \
  -H "Content-Type: application/json" \
  -d '{"email": "[email protected]", "password": "12345678"}'

Response (201 Created)

{
  "token": "eyJ...",
  "user": { "id": 1, "email": "[email protected]", "credits": 10 }
}
POST /api/auth/login Sign in

Sign in with email and password. Returns a JWT (7-day expiry).

Request

curl -X POST https://greenlit.live/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email": "[email protected]", "password": "12345678"}'

Response (200 OK)

{
  "token": "eyJ...",
  "user": { "id": 1, "email": "[email protected]", "credits": 7 }
}
GET /api/auth/me Current user info

Returns current user profile, credits balance, and API keys. Requires JWT.

Request

curl https://greenlit.live/api/auth/me \
  -H "Authorization: Bearer eyJ..."

Response

{
  "user": { "id": 1, "email": "[email protected]", "credits": 7 },
  "keys": [{ "id": 1, "key_prefix": "gl_a1b2", "created_at": "..." }]
}
POST /api/keys Generate an API key

Generate a new API key linked to your account. Requires JWT. Max 3 keys per user.

Request

curl -X POST https://greenlit.live/api/keys \
  -H "Authorization: Bearer eyJ..."

Response (201 Created)

{
  "api_key": "gl_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
  "prefix": "gl_a1b2",
  "message": "Save this key now — it cannot be retrieved again."
}
POST /api/analyze Upload a video for analysis

Upload a video file as multipart form data. Deducts 1 credit. Returns a job ID for polling.

Request

ParameterTypeDescription
videorequiredfileVideo file (MP4, MOV, WebM). Max 100 MB, max 2 min.

Example

curl -X POST https://greenlit.live/api/analyze \
  -H "X-API-Key: gl_xxxxxxxxxxxx" \
  -F "video=@my_short.mp4"

Response (202 Accepted)

{
  "job_id": "abc123",
  "status": "processing",
  "poll_url": "/api/jobs/abc123"
}

Response Headers

HeaderExampleDescription
X-Credits-Remaining9Credits left after this request

Error: No Credits

// 402 Payment Required
{ "detail": "No credits remaining. Buy 100 credits for $1.", "credits": 0 }
GET /api/jobs/{job_id} Poll for analysis results

Poll this endpoint until status is "completed" or "failed". Recommended interval: 1.5s.

Example

curl https://greenlit.live/api/jobs/abc123 \
  -H "X-API-Key: gl_xxxxxxxxxxxx"

Response (completed)

{
  "job_id": "abc123",
  "status": "completed",
  "progress": 100,
  "result": {
    "score": 73,
    "dimensions": {
      "technical": { "score": 8.5, "max": 10, "breakdown": {...} },
      "audio":     { "score": 16, "max": 20, "breakdown": {...} },
      "visual":    { "score": 19, "max": 30, "breakdown": {...} },
      "content":   { "score": 29, "max": 40, "breakdown": {...} }
    },
    "issues": [
      { "severity": "warning", "message": "Audio loudness below target" }
    ],
    "transcript": { "text": "...", "language": "en" }
  }
}
GET /api/health Health check

Returns server status. No authentication required.

Response

{ "status": "ok" }

Scoring System

Each video is scored on a 0-100 scale across four weighted dimensions:

DimensionWeightWhat's Measured
Technical10 ptsResolution, FPS, codec, bitrate, duration, file size
Audio20 ptsLUFS loudness, true peak, silence gaps, clipping
Visual30 ptsBlack/frozen frames, keyframe quality (Gemini AI)
Content40 ptsHook clarity, pacing (WPS), narrative arc, info density (Gemini AI)

Verdicts

Rate Limits

MethodLimitHow
Anonymous (web)3 per browser + 10/day per IPlocalStorage + backend IP limit
Authenticated1 credit per analysisPrepaid credits, atomic deduction

When credits are exhausted, the API returns 402 Payment Required.

Errors

{
  "detail": "File too large: 150.0MB (max 100MB)"
}
StatusMeaningCommon Cause
400Bad RequestInvalid file type, too large, too long
401UnauthorizedMissing or invalid API key / JWT
402Payment RequiredNo credits remaining
404Not FoundJob ID doesn't exist
409ConflictEmail already registered / max keys
429Rate LimitedIP rate limit (anonymous)
500Server ErrorPipeline failure (check job status)