API documentation

Authentication

Every call to the v1 API (and the MCP endpoint) authenticates with a single Bearer token. The public verification endpoints (/api/v1/verify/{certificateId} and /.well-known/jwks.json) require no auth — by design, so any party can verify a Verdacert certificate.

Token format

Token strings are self-describing — you can tell sandbox from live at a glance.

TokenMeaning
vc_sandbox_p7q8r…Sandbox key. Free. Synthetic state machine. No real translation, no Stripe charge. Use during development.
vc_live_abc123…Live key. Real orders, real translators, real Stripe charges on submit.

Both share the same shape: prefix vc_, environment tag (live or sandbox), and a high-entropy base32 body. Tokens are hashed at rest — once minted, you see the raw value once in the portal and we can no longer recover it. Save it somewhere safe.

Treat tokens like passwords
A leaked live key can place orders that bill your default payment method. Tokens live in your secret manager, never in source control, and never in a URL query string (URLs end up in access logs, browser histories, and shoulder-surf range). Rotate immediately if a key may have been exposed — portal/api→ revoke → mint.

Environments

Sandbox and live share endpoints. The environment is determined by the token prefix — no hostnames to swap.

BehaviorSandboxLive
BillingNever chargesCharges default payment method on submit
submit responseJob goes to a wall-clock state machine; no real translators touch itJob enters the production review queue; documents are ingested into R2
status lifecyclecreated → paid → processing → in_review → ready in ~2 min (full) / ~90s (R&C)Driven by real review workflow + AI pipeline events
result artifactFixed demo PDF + a real Ed25519 certificate with isSandbox=true claimReal certified PDF + production certificate
verify endpointReturns acceptanceGuarantee = null, isSandbox = trueReturns USCIS acceptance guarantee
Webhook signingSame HMAC scheme; identical signature verification pathSame HMAC scheme; identical signature verification path
Rate limit300 req/min per key300 req/min per key
Sandbox certs are real certificates
The JWS receipt returned by sandbox is real — same Ed25519 key, same JWKS endpoint, same compact JWS encoding. The only difference is the isSandbox: trueclaim in the payload. Your verification code path doesn't branch for sandbox vs live.

Key lifecycle

Mint, use, rotate, revoke. All self-serve from the portal.

Minting

From the agent portal:

  1. Click Mint key. Choose env (sandbox or live) and an optional label.
  2. Copy the token. This is the only time the raw value is shown.
  3. Set spend caps + webhook URL if applicable (see below).

Rotation

Mint a new key, deploy it to your runtime, then revoke the old one. Revoked keys reject all requests with REVOKED_KEY immediately — no grace period — so sequence the swap from your side first.

Revocation

In the portal, click Revoke on the key row. Revocation is irreversible. Pending in-flight requests already in our handler complete; subsequent requests fail with REVOKED_KEY.

Spend caps

Optional per-key safety rails — set a maximum cents/day and/or cents/month. Enforced server-side at submit time against the rolling window. Exceeding the cap returns SPEND_LIMIT_EXCEEDED (HTTP 402) and no order is created. Caps apply to live keys only; sandbox is free by design.

Security checklist

If you'd ask 'is this the right way?' — the answer is in here.

  • Server-side only. Keys are bearer credentials. Never expose one in a browser bundle, mobile app binary, or anything else a user can extract. If your end-user needs to interact with us directly, surface publicVerifyUrl from getResult instead.
  • Use a secret manager. Vercel Project Environment Variables, Doppler, 1Password Secrets Automation, AWS Secrets Manager — anything but .env in source control.
  • Distinct keys per environment.Production, staging, and CI each get their own key so revoking one doesn't take the others down.
  • Mint one key per platform tenant if you multi-tenant on top of Verdacert. Per-tenant keys are the unit of revocation and spend-cap.
  • Webhook secrets are sensitive too. Each key gets its own webhook signing secret; treat it as a credential (see /docs/webhooks).
  • TLS only. All endpoints are HTTPS. Plain HTTP requests are rejected.
  • Watch x-vc-request-id. Every response carries one. Log it alongside your own request id so we can correlate when you ask support to investigate.

Local development setup

Drop-in patterns for the three most common stacks.

Node / TypeScript (.env)

# .env (NEVER commit)
VERDACERT_API_KEY=vc_sandbox_…
import "dotenv/config";
import { createVerdacertTools } from "@verdacert/ai-sdk-tools";

const tools = createVerdacertTools({
  apiKey: process.env.VERDACERT_API_KEY!,
});

Next.js on Vercel

# Local
vercel env pull .env.local

# CI / preview / production
vercel env add VERDACERT_API_KEY

Server-side only — never expose the key with NEXT_PUBLIC_. Use Route Handlers or Server Actions on the server and stream the result to the client.

Python

import os, requests

resp = requests.post(
    "https://verdacert.com/api/v1/quote",
    headers={
        "Authorization": f"Bearer {os.environ['VERDACERT_API_KEY']}",
        "Content-Type":  "application/json",
    },
    json={
        "sourceLanguage": "fa",
        "useCase":        "uscis",
        "pageCount":      2,
        "speedTier":      "standard",
    },
    timeout=30,
)
resp.raise_for_status()
print(resp.json())

Where to next

Get instant quotePricing