Authentication
Certivu uses two separate credential types that serve different purposes:
| Credential | Used for | How to get it |
|---|---|---|
| Session JWT | Dashboard access | Returned on POST /v1/auth/login |
API key (ctv_key_…) | SDK & programmatic signing | Created in the dashboard → Generators page |
These are intentionally separate. Your API key is a long-lived secret for server-side use. Session tokens are short-lived (24h) browser credentials.
1. Register an account
Section titled “1. Register an account”curl -X POST https://api.certivu.ai/v1/auth/register \ -H "Content-Type: application/json" \{ "user": { "user_id": "usr_abc123", "email_verified": false, "org_id": "org_xyz789" }}A verification email is sent immediately. Click the link before signing content — the free tier works without verification but all features require it.
2. Verify your email
Section titled “2. Verify your email”The email contains a link to:
https://certivu.ai/verify-email?token=<token>Or confirm via API:
curl -X POST https://api.certivu.ai/v1/auth/verify-email \ -H "Content-Type: application/json" \ -d '{ "token": "<token-from-email>" }'3. Log in
Section titled “3. Log in”curl -X POST https://api.certivu.ai/v1/auth/login \ -H "Content-Type: application/json" \Without 2FA — returns a session token immediately:
{ "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",}With 2FA enabled — returns a challenge token instead:
{ "requires_2fa": true, "challenge_token": "ch_7f3kx9mq..." }Then submit the OTP from your authenticator app:
curl -X POST https://api.certivu.ai/v1/auth/verify-2fa \ -H "Content-Type: application/json" \ -d '{ "challenge_token": "ch_7f3kx9mq...", "otp": "123456" }'# → { "token": "eyJ...", "user": { ... } }Challenge tokens are single-use and burned on first submission.
The JWT is valid for 24 hours. Use it as a Bearer token for dashboard API calls:
curl https://api.certivu.ai/v1/auth/me \ -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."4. Get an API key
Section titled “4. Get an API key”Your ctv_key_… org API key is shown in the dashboard under Settings → API Keys. Store it securely — it is shown once and cannot be recovered.
Generators support two keypair modes. Choose one when registering a generator:
Server-managed keypair (recommended)
Section titled “Server-managed keypair (recommended)”Certivu generates and stores the ML-DSA keypair. You don’t handle private key material. Use POST /v1/sign to sign content — upload the file, get it back watermarked and signed.
In the dashboard: Generators → Add generator → leave the public key field blank. The server keypair is created automatically.
Client-managed keypair (advanced)
Section titled “Client-managed keypair (advanced)”You generate the ML-DSA keypair locally and register only the public key. Private key material never leaves your server. Sign payloads yourself and submit records via POST /v1/records.
import { generateKeypair } from '@certivu/sdk'
const { publicKey, privateKey } = generateKeypair()// Store privateKey securely — never share it, never upload it// Register publicKey in the dashboardIn the dashboard: Generators → Add generator → paste your public key.
5. Use the API key in the SDK
Section titled “5. Use the API key in the SDK”import { CertivuClient } from '@certivu/sdk'
const certivu = new CertivuClient({ apiKey: process.env.CERTIVU_API_KEY, // ctv_key_… generatorId: process.env.CERTIVU_GENERATOR_ID,})
const { token } = await certivu.sign({ content: imageBuffer, model: 'stable-diffusion-xl',})Password reset
Section titled “Password reset”# 1. Request a reset linkcurl -X POST https://api.certivu.ai/v1/auth/forgot-password \ -H "Content-Type: application/json" \
# 2. Reset with the token from the emailcurl -X POST https://api.certivu.ai/v1/auth/reset-password \ -H "Content-Type: application/json" \ -d '{ "token": "<token-from-email>", "password": "new-password" }'The reset token is valid for 1 hour and is single-use.
Rate limits by plan
Section titled “Rate limits by plan”Session-authenticated dashboard calls use the same plan-based limits as API key calls:
| Plan | Requests / min |
|---|---|
| Free | 100 |
| Starter | 500 |
| Growth | 1,000 |
| Scale | 2,000 |
| Enterprise | Unlimited |
Verification (POST /v1/verify) is always free and not subject to signing quotas.