Spondeo — Pricing
Model: freemium. The consumer C2C proof-link path is free forever (it's the funnel). The developer API is free to start and metered as you grow. This page is committed product policy and is rendered at /pricing. Prices are USD, exclusive of tax.
Price ladder
| Tier | Price / mo | Included verifications | Overage | What's included |
|---|---|---|---|---|
| Developer (Free) | $0 | 500 / mo | Hard stop (429 → /pricing) | Test + live keys, sandbox, webhooks, TypeScript SDK, MCP server, OpenAPI, community support |
| Startup | $49 | 5,000 | $0.015 / verify | Everything in Free + email support, usage dashboard, 1 production webhook fleet |
| Growth | $249 | 50,000 | $0.008 / verify | Everything in Startup + audit-log export, multiple webhooks, higher rate limits, priority support |
| Scale | from $999 (contact) | 500,000+ | negotiated (~$0.004) | Everything in Growth + SLA, DPA + security review, custom claim schemas, dedicated issuer subdomain, SSO |
Consumer C2C — verify once, mint shareable proof links, view per-link analytics: free forever. No account upgrade, no metering. It exists to show the privacy model publicly and feed the developer funnel.
Billing details
- Annual billing = 2 months free (~17% off) on Startup and Growth.
- Only successful verifications count toward the included quota and overage. A
valid:false
response (or an invalid/expired presentation) is not billed.
- Metering is per account, not per key —
sk_test_sandbox calls are never billed. - Overage applies on Startup and above. Free tier hard-stops at 500/mo (returns
429 quota_exceeded, links to /pricing) — no surprise bills, ever.
- Quota resets at the UTC month boundary.
Rationale
- Near-zero COGS. A verification is an email-domain lookup against vendored, redistributable data
(MIT/ISC/CC0/US-public-domain) plus a signature check. The only real variable cost is the verification email at issuance time, not per /v1/verify. This is what lets the consumer path be free forever and the free dev tier be generous.
- Free 500/mo matches the market floor. Didit's free identity tier set the expectation that a
meaningful free allowance is table stakes; we match it so a builder can ship and dogfood before paying anything.
- Overage priced to undercut identity verification by an order of magnitude. Stripe Identity is
~$1.50/check and Persona ~$0.30–0.50/check — those are document + selfie identity checks. Spondeo verifies affiliation with no PII custody, so even Startup overage ($0.015) is ~20–100× cheaper, and Scale (~$0.004) is cheaper still. We compete on both price and liability.
- Hard-stop only on Free; meter above it. New builders get a predictable, zero-risk free tier;
paying customers get elastic capacity without hitting a wall mid-launch.
- Scale is contact-sales because it carries non-self-serve commitments (SLA, DPA, security review,
custom schemas, SSO, dedicated subdomain) that warrant a conversation.
Upgrade path
A Free-tier key that hits 500/mo returns 429 quota_exceeded with a link to /pricing. Upgrading is self-serve (Stripe Checkout) for Startup and Growth; Scale is a "Contact sales" form that captures the lead. Downgrades and cancellations take effect at the end of the paid period (see docs/legal/refunds.md).
Billing implementation notes (when wiring real Stripe)
The current build ships a deterministic checkout stub (src/billing/index.ts, no live charges) with a drop-in seam for Stripe Billing. When connecting real Stripe:
- Create test-mode Products/Prices for Startup/Growth + a metered usage price; gate
plan.limitoff the
active subscription.
- Emit a metered usage event from
recordUsage()for paid accounts. - The inbound Stripe webhook handler MUST be idempotent — dedupe on Stripe's
event.id(Stripe
delivers each event at-least-once and retries). Without it, a duplicate checkout.session.completed / customer.subscription.updated can double-provision or double-count. Persist processed event.ids and no-op on repeats. (Spondeo's own OUTBOUND webhooks already carry a dedupe id for the same reason.)
- Verify end-to-end with a Stripe test clock + test cards (
4242…); assert the 429→checkout→200 transition.