Quickstart
End-to-end pipeline in under five minutes using a free sandbox key. Three flavors — pick whichever fits your stack. Each one finishes at a verifiable certified PDF + JWS receipt.
Prerequisites
Two things, both free, both self-serve.
- A Verdacert account. Sign up here — magic-link auth, no password.
- A sandbox key minted in the agent portal. Sandbox keys run a deterministic state machine — no real translation, no charge, ideal for development.
created → paid → processing → in_review → ready in ~2 minutes for full translation, or created → paid → reviewing_draft → ready in ~90s for Review-and-Certify. The certified artifact you get back is a real Ed25519-signed receipt — verify it against the live JWKS exactly the same way you would in production.Path A · Plain REST
Any language with HTTP + JSON. Curl below; trivially portable.
1. Ground the agent on live enums
curl https://verdacert.com/api/v1/capabilities \
-H "Authorization: Bearer vc_sandbox_…"Returns supported languages, document types, speed tiers, add-ons (and whether each is currently available), and the USCIS acceptance guarantee URL. Cacheable for ~1h on your side.
2. Get a binding quote
curl -X POST https://verdacert.com/api/v1/quote \
-H "Authorization: Bearer vc_sandbox_…" \
-H "Content-Type: application/json" \
-d '{
"sourceLanguage": "fa",
"useCase": "uscis",
"pageCount": 2,
"speedTier": "standard"
}'Response carries quoteId, totalCents, an itemized breakdown, promisedDeliveryAt, and expiresAt (24h TTL). Show totalCents / 100 to your end-user; ask for confirmation; then submit.
3. Submit the job
curl -X POST https://verdacert.com/api/v1/submit \
-H "Authorization: Bearer vc_sandbox_…" \
-H "Content-Type: application/json" \
-d '{
"quoteId": "q_aabbccdd_1716480000000_x9k3",
"idempotencyKey": "demo-order-0001",
"echoedInput": {
"sourceLanguage": "fa",
"useCase": "uscis",
"pageCount": 2,
"speedTier": "standard"
},
"documents": [
{ "url": "https://example.com/birth-cert.pdf" }
]
}'Returns a jobId immediately. The idempotencyKey is yours to choose; reuse it to safely retry the same submit without creating a duplicate order.
quote is stateless — there is no quotes table. submit re-prices server-side using echoedInput and binds the quote id to the calling key so a stale or stolen quoteId can't change what gets ordered.4. Poll until ready
# Sandbox flips through states on a wall clock
# in ~2 minutes; recommend exponential backoff starting at 30s.
curl https://verdacert.com/api/v1/status/<jobId> \
-H "Authorization: Bearer vc_sandbox_…"Returns status, progressPercent (0–100), statusDescription, and an events array. Stop polling when status === "ready", or skip polling entirely and use webhooks.
5. Fetch the certified result
curl https://verdacert.com/api/v1/result/<jobId> \
-H "Authorization: Bearer vc_sandbox_…"Returns the certified PDF URL, the certificate metadata (issuer, translator, public verify URL), and a compact JWS you can verify against the live JWKS without calling us.
6. Verify the certificate (public, no auth)
curl https://verdacert.com/api/v1/verify/<certificateId>The verification endpoint never requires a key. That's the design: a USCIS reviewer, an opposing lawyer, or a university registrar can verify a Verdacert receipt with zero setup. Full walkthrough at /docs/certificates.
Path B · Vercel AI SDK
One import gives you all seven tools, typed, ready to drop into generateText / streamText / agent loops. Full reference at /docs/ai-sdk.
Install
pnpm add @verdacert/ai-sdk-tools ai zod
# or: npm i @verdacert/ai-sdk-tools ai zodUse
import { generateText, stepCountIs } from "ai";
import { createVerdacertTools } from "@verdacert/ai-sdk-tools";
const tools = createVerdacertTools({
apiKey: process.env.VERDACERT_API_KEY!,
});
const { text } = await generateText({
// Routes through Vercel AI Gateway automatically when
// AI_GATEWAY_API_KEY is present (auto-injected on Vercel).
model: "anthropic/claude-sonnet-4",
tools,
stopWhen: stepCountIs(20),
prompt:
"I have a 3-page Farsi birth certificate at " +
"https://example.com/cert.pdf that I need certified " +
"for USCIS. Quote it, submit it, poll until ready, " +
"and give me back the certified URL.",
});
console.log(text);AI_GATEWAY_API_KEY (auto-injected on Vercel) and the provider-string model (anthropic/claude-sonnet-4) does the routing automatically.Path C · MCP (Claude Desktop / Cursor / any MCP client)
Streamable HTTP MCP server at https://verdacert.com/api/mcp. Six tools. Stateless. Full reference at /docs/mcp.
Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json and restart Claude Desktop:
{
"mcpServers": {
"verdacert": {
"url": "https://verdacert.com/api/mcp",
"headers": {
"Authorization": "Bearer vc_sandbox_…"
}
}
}
}Cursor
Settings → MCP → Add new MCP server. Same JSON as above.
Any HTTP client (raw JSON-RPC)
curl https://verdacert.com/api/mcp \
-H 'Authorization: Bearer vc_sandbox_…' \
-H 'Accept: application/json, text/event-stream' \
-H 'Content-Type: application/json' \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {}
}'Going live
When you've validated against sandbox and want to make real orders.
- Open /portal/api, add a default payment method, and mint a live key (
vc_live_…). - Swap your sandbox token for the live token. Token is the only thing that changes — code paths are identical.
- Configure your webhook URL on the key (or pass
webhookUrlper-call onsubmit) so you can skip polling. See /docs/webhooks. - Set a spend cap in the portal if you want a safety rail (per-day, per-month, or both). Caps are enforced server-side and return
SPEND_LIMIT_EXCEEDEDwhen crossed.
submitcall on a live key triggers an off-session Stripe charge against your default payment method. There's no separate “approve charge” step. Test thoroughly on sandbox first; sandbox is byte-identical to live aside from the no-bill and synthetic-status behavior.