Developers

Clex API
without the mess

Sign in, create a key, copy a command. The API controls rooms and receipts; file bytes still move directly between browsers over WebRTC.

1. Sign in with Google 2. Create API key 3. Send Bearer key

Create your API key

Use the same Firebase Google login as Clex AI to create a Clex API key. Send it as Authorization: Bearer <key> for protected Clex API routes.

Sign in to create an API key Ready

Simple API,
ready to paste

Copy these in order. The key command updates automatically after you create a key.

01

Save your key

export CLEX_API_KEY='<YOUR_API_KEY>'
02

Check the API

curl https://api.clex.in/api/health
03

Send an authenticated request

curl -X POST https://clex.in/vault/api/uploads \
  -H "Authorization: Bearer <YOUR_API_KEY>" \
  -H "X-Filename: report.pdf" \
  --data-binary @report.pdf

Programmatic uploads
with per-key limits

Sign in once with Google, mint a key on your account page, then upload files with a single HTTP call. Each account can keep five active unlimited keys; revoke old keys before creating new ones.

Get a key → Up to 5 active keys per account Hash-only storage; plaintext shown once
POST /vault/api/uploads Stable

Upload a file using a Bearer API key. Returns a share URL, an internal id, and rate-limit headers (X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset). The body is the raw file bytes; metadata travels in headers (X-Filename, optional X-Expires-In).

# curl
curl -X POST https://clex.in/vault/api/uploads \
  -H "Authorization: Bearer clex_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "X-Filename: report.pdf" \
  -H "X-Expires-In: 86400" \
  --data-binary @report.pdf

{
  "id": "ap_…",
  "shareToken": "K9M3JX72A8DR",
  "shareUrl": "https://clex.in/share/K9M3JX72A8DR",
  "downloadUrl": "https://…signed-supabase-url…",
  "size": 524288,
  "expiresAt": 1714972800
}
POST /vault/api/uploads Python
import os, requests

with open("report.pdf", "rb") as f:
    r = requests.post(
        "https://clex.in/vault/api/uploads",
        headers={
            "Authorization": f"Bearer {os.environ['CLEX_API_KEY']}",
            "X-Filename": "report.pdf",
            "X-Expires-In": "86400",
        },
        data=f,
    )

r.raise_for_status()
print(r.json()["shareUrl"])
POST /vault/api/uploads Node / fetch
import { readFile } from 'node:fs/promises'

const body = await readFile('report.pdf')
const res = await fetch('https://clex.in/vault/api/uploads', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.CLEX_API_KEY}`,
    'X-Filename': 'report.pdf',
    'X-Expires-In': '86400',
  },
  body,
})

if (!res.ok) throw new Error(`upload failed: ${res.status}`)
const { shareUrl } = await res.json()
console.log(shareUrl)
GET /vault/api/uploads Stable

List uploads owned by the authenticated user. Authenticate via Bearer key (returns only that key's uploads) or X-Vault-UID (returns everything).

DELETE /vault/api/uploads/:id Stable

Revoke an upload. Subsequent share-link hits return 410.

Limits cheat-sheet

  • File size per key: 10 MB · 100 MB · 1 GB · unlimited (5 GB hard ceiling per upload).
  • Rate per key: 10 · 30 · 100 · 1000 req/min · unlimited.
  • Expiry: 5 minutes – 7 days. Default 24 hours. Pass X-Expires-In in seconds.
  • Plaintext key: shown exactly once at creation. Only the SHA-256 hash is stored.

API controls metadata.
WebRTC moves files.

API

Health checks, auth, transfer metadata, receipts, and future room controls.

WebSocket

Connects two peers by relaying offer, answer, and ICE messages.

WebRTC

Sends file chunks directly between devices. Clex does not receive raw file bytes.

The token shown here is a Google Firebase ID token. It is meant for protected API calls and expires automatically; create a fresh one when needed.

Test the transfer flow

Open the workspace, send a file, then use the API page for developer access.