API Overview
Integrate Themys into your own applications with the REST API.
Base URL
https://themys.ca/apihttp://localhost:3000/apiAuthentication
The Themys API supports two authentication methods. Pick whichever fits your integration model:
Option A: API key (recommended for non-browser callers)
Long-lived tmys_* keys scoped to specific permissions. Generate one in the Developer Portal and use it as a Bearer token:
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.
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.
When you exceed your limit, the API returns:
402 Payment Requiredfor browser (Clerk) callers — you can consume credits to bypass.429 Too Many Requestsfor 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:
{
"error": "Daily scan limit reached for this API key"
}
Common status codes:
200400401402403analyze to call /api/analyze)429500502Endpoints
POST /api/extract
Extracts and structures the raw text from a Terms of Service URL.
Required scope (API key): extract
{
"url": "https://example.com/terms"
}
Reference: API Keys → Scopes
POST /api/analyze
Analyzes a ToS URL or pasted text, returning a risk score and flagged clauses.
Required scope (API key): analyze
{
"url": "https://example.com/terms",
"domain": "example.com",
"bypassCache": false
}
Reference: API Keys → Scopes
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.
{
"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:
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:
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("Risk Score:", data.riskScore)
console.log("Flags:", data.flags)
}
Python with an API key:
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("Risk Score:", 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