Verafirma logo Verafirma

Quickstart

Two products, full feature set on both: envelope signing at $0.10 per envelope and ID verification starting at $0.08 (with à la carte add-ons per /pricing). This page gets you from “I have a Verafirma URL” to “my first envelope landed in a recipient’s inbox” in about 10 minutes.

If you’re an autonomous agent (no human in the loop), skip to §5 — x402 path. The first four sections are for developers with a browser handy.

1. Sign in (2 min)

Open app.verafirma.comSign in with Google.

On first sign-in, your vf_test_* API key appears once as a URL fragment after the OAuth redirect. Copy it now — it is shown once, then never again. If you miss it, regenerate via the API Keys page in the dashboard (the previous key is invalidated; pin the regenerated one in your secrets manager immediately).

2. Top up your balance (2 min)

In the dashboard, click Top up. Stripe Checkout opens. $5 minimum (Stripe’s per-transaction fee is $0.30 + 2.9%, which is why we collect a balance rather than charging $0.10 directly per call; $5 ≈ 50 calls’ worth, $20 ≈ 200, and so on).

You can also skip the dashboard entirely and pay per-call via x402 on the wire — see §5 below.

3. Your first envelope (3 min)

The simple workflow places fields and distributes in one call only when you pass a non-empty fields array in the payload (or when the source PDF carries placeholder markers Documenso auto-detects). If you don’t have either, use the three-step draft workflow — that’s the recommended path for most beta-tester scenarios.

export VF_API_KEY='vf_test_<your-key>'
export VF_API_URL='https://api.verafirma.com'

# Step 1 — create a draft envelope (no charge yet).
DRAFT=$(curl -sS -X POST "$VF_API_URL/v1/envelopes" \
  -H "Authorization: Bearer $VF_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -F "pdf=@your-pdf.pdf" \
  -F 'payload={"title":"My first envelope","recipients":[{"role":"SIGNER","name":"Recipient","email":"recipient@example.com"}],"storageExpiryDays":30}')
ENVELOPE_ID=$(echo "$DRAFT" | jq -r '.envelopeId')

# Step 2 — place a signature field (positions are percentages of the page).
curl -sS -X POST "$VF_API_URL/v1/envelopes/$ENVELOPE_ID/fields" \
  -H "Authorization: Bearer $VF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"fields":[{"type":"SIGNATURE","recipientEmail":"recipient@example.com","page":1,"positionX":10,"positionY":75,"width":30,"height":8}]}'

# Step 3 — send. Charge fires here ($0.10).
curl -i -X POST "$VF_API_URL/v1/envelopes/$ENVELOPE_ID/send" \
  -H "Authorization: Bearer $VF_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{}'

Expect HTTP/2 200 with status: "SENT". The recipient receives a signing-link email within ~60-90 seconds.

Tip — single-call simple workflow. If you pre-embed PDF placeholder markers like {{signature, r1}} in the PDF, the simple workflow places fields automatically; you can collapse the three steps into one POST /v1/envelopes with a non-empty fields: [{...}] array. See /docs/envelopes for both approaches.

4. Your first verification (2 min)

curl -X POST "$VF_API_URL/v1/verifications" \
  -H "Authorization: Bearer $VF_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"type":"document"}'

Expect HTTP/2 201 with a hostedUrl. Open that URL in a browser (or send it to whoever you need verified). They upload an ID + selfie; you receive a webhook callback when the check completes. The V1 wire API charges a flat $0.10 per /v1/verifications call today; the granular per-check pricing ($0.08 ID + $0.04 face + add-ons) on /pricing reflects where the API surface is heading.

Webhooks for verification events land on registered URLs subscribed to the relevant event types — see /docs/webhooks for registration and signature-verification details.

5. x402 path (for agents)

If you’re building an autonomous agent that has no human, no email, and no dashboard signin: skip §§1-2 entirely. Sign an EIP-3009 USDC transferWithAuthorization for $0.10 on Base Sepolia (or Base mainnet for prod), attach it as a base64-encoded PAYMENT-SIGNATURE header, and POST in one shot:

curl -X POST https://api.verafirma.com/v1/envelopes \
  -H "PAYMENT-SIGNATURE: $(cat payment.b64)" \
  -F 'pdf=@contract.pdf' \
  -F 'payload={"title":"NDA","recipients":[{"email":"counterparty@example.com","name":"Counterparty","role":"SIGNER"}]}'

Full wire format: /docs/x402. The wallet that signs the payment is the identity for any later history reads — same wallet → same balance → same history across both products.

The agent path is the lodestone — the simplest version of the API surface, single HTTPS call, no signup.

6. Where to find things

7. Reporting bugs + feedback

We’re in private beta. Send feedback to service@verafirma.com. Include:

  • What you tried — request URL + method + (redacted) headers.
  • What you expected — the response shape per the spec or per intuition.
  • What happened — actual status code + body.
  • Your customerId or envelopeId / verificationId if applicable — helps us trace through the ledger and webhook chain.

Thanks for kicking the tires.