Skip to content

Authentication

Certivu uses two separate credential types that serve different purposes:

CredentialUsed forHow to get it
Session JWTDashboard accessReturned on POST /v1/auth/login
API key (ctv_key_…)SDK & programmatic signingCreated 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.


Terminal window
curl -X POST https://api.certivu.ai/v1/auth/register \
-H "Content-Type: application/json" \
-d '{ "org_name": "Acme AI", "email": "you@acme.com", "password": "••••••••" }'
{
"user": {
"user_id": "usr_abc123",
"email": "you@acme.com",
"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.


The email contains a link to:

https://certivu.ai/verify-email?token=<token>

Or confirm via API:

Terminal window
curl -X POST https://api.certivu.ai/v1/auth/verify-email \
-H "Content-Type: application/json" \
-d '{ "token": "<token-from-email>" }'

Terminal window
curl -X POST https://api.certivu.ai/v1/auth/login \
-H "Content-Type: application/json" \
-d '{ "email": "you@acme.com", "password": "••••••••" }'
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"user_id": "usr_abc123",
"email": "you@acme.com",
"email_verified": true,
"org_id": "org_xyz789"
}
}

The JWT is valid for 24 hours. Use it as a Bearer token for dashboard API calls:

Terminal window
curl https://api.certivu.ai/v1/auth/me \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

API keys are created via the dashboard generators page or CLI.

Each generator has its own ML-DSA keypair. Generate one:

Terminal window
bun run infra/scripts/gen-keys.ts --name "stable-diffusion-xl"

This prints a public key you register in the dashboard. The private key never leaves your server.

Once registered, your ctv_key_… API key is shown in the dashboard. Store it securely — it cannot be recovered after leaving the page.


import { CertivuClient } from '@certivu/sdk'
const certivu = new CertivuClient({
apiKey: process.env.CERTIVU_API_KEY, // ctv_key_…
generatorId: process.env.CERTIVU_GENERATOR_ID,
privateKey: process.env.CERTIVU_PRIVATE_KEY,
})
const { token } = await certivu.sign({
content: imageBuffer,
model: 'stable-diffusion-xl',
})

Terminal window
# 1. Request a reset link
curl -X POST https://api.certivu.ai/v1/auth/forgot-password \
-H "Content-Type: application/json" \
-d '{ "email": "you@acme.com" }'
# 2. Reset with the token from the email
curl -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.


Session-authenticated dashboard calls use the same plan-based limits as API key calls:

PlanRequests / min
Free100
Starter500
Growth1,000
Scale2,000
EnterpriseUnlimited

Verification (POST /v1/verify) is always free and not subject to signing quotas.