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 a risk score and flagged clauses.

Required scope (API key): analyze

json
{

"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.

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("Risk Score:", 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("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