ThemysThemys/Docs

API Overview

Integrate Themys into your own applications with the REST API.

Base URL

EnvironmentURL
Productionhttps://themys.ca/api
Local developmenthttp://localhost:3000/api

Authentication

The Themys API supports two authentication methods. Pick whichever fits your integration model:

Long-lived tmys_* keys scoped to specific permissions. Generate one in the Developer Portal and use it as a Bearer token:

code
Authorization: Bearer tmys_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6

Get the full reference — scopes, rotation, security best practices — in API Keys.

Option B: Clerk session token (browser use only)

Your Clerk session JWT works directly against the API. Tokens are tied to your user account and expire with your session.

code
Authorization: Bearer <clerk-session-jwt>

The Clerk path is supported for browser users (the in-app scanner on /dashboard/new-scan) but API Keys are the documented way for programmatic integrations.


Rate Limits

Two separate rate limit pools. Per-key quotas are isolated from the parent user's browser quota so API callers can bulk-scan without burning free-tier scans.

PlanDaily Scans (per key / browser pool)Monthly AI (per key / browser pool)
Free55
Base2530
Advanced100unlimited

When you exceed your limit, the API returns:

  • 402 Payment Required for browser (Clerk) callers — you can consume credits to bypass.
  • 429 Too Many Requests for API key callers — no credits apply; the per-key daily budget has been spent. Wait for reset.

Per-key usage is surfaced live in Developer Portal → Usage and via GET /api/developer/usage/per-key.

Error Format

All errors follow a consistent JSON structure:

json
{
  "error": "Daily scan limit reached for this API key"
}

Common status codes:

CodeMeaning
200Success
400Bad request (missing or invalid parameters)
401Unauthorized (no/invalid auth)
402Browser-user scan limit reached (use credits)
403API key missing required scope (e.g. need analyze to call /api/analyze)
429API key rate limit reached (daily quota spent)
500Internal server error
502Extraction failed (could not retrieve text from URL)

Endpoints

POST /api/extract

Extracts and structures the raw text from a Terms of Service URL.

Required scope (API key): extract

json
{
  "url": "https://example.com/terms"
}

Reference: API Keys → Scopes

POST /api/analyze

Analyzes a ToS URL or pasted text, returning flagged clauses, attention guidance, and the backward-compatible riskScore field.

Required scope (API key): analyze

json
{
  "url": "https://example.com/terms",
  "domain": "example.com",
  "bypassCache": false
}

Reference: API Keys → Scopes

riskScore remains in API responses for compatibility. Treat it as an internal ranking signal for sorting and grouping, not legal advice or an authoritative legal risk determination.

POST /api/analyze/batch

Analyzes up to 5 ToS items (URLs or text) in one call.

Required scope (API key): analyze

See the full reference: API Reference → Batch Endpoint

POST /api/extension/limit-check

Checks whether the authenticated Clerk user has remaining scans for the day. Used by the Chrome extension before initiating a scan.

json
{
  "clerkId": "user_abc123",
  "consume": "scan"
}

Browser-only — does not accept API keys.

GET /api/developer/usage

Aggregate usage over the past 30 days (default, configurable via ?days=N up to 90).

GET /api/developer/usage/per-key

Per-key rate limit snapshot for every active key under the authenticated user.

Code Example

cURL with an API key:

bash
curl -X POST https://themys.ca/api/analyze \
  -H "Authorization: Bearer *** \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/terms"}'

JavaScript with an API key:

javascript
const response = await fetch("https://themys.ca/api/analyze", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: `Bearer ${THEMYS_API_KEY}`,
  },
  body: JSON.stringify({ url: "https://example.com/terms" }),
})

const data = await response.json()

if (!response.ok) {
  console.error(`Error: ${data.error}`)
} else {
  console.log("Attention guidance:", data.riskScore)
  console.log("Flags:", data.flags)
}

Python with an API key:

python
import os
import requests

response = requests.post(
    "https://themys.ca/api/analyze",
    headers={"Authorization": f"Bearer {os.environ['THEMYS_API_KEY']}"},
    json={"url": "https://example.com/terms"},
)
response.raise_for_status()
data = response.json()
print("Attention guidance:", data["riskScore"])

See the API Keys reference for how to obtain and rotate your key, and the Batch Endpoint reference for multi-URL workflows.

Was this page helpful?

Try it live

Paste a URL or text to see Themys in action