API reference

Spondeo API

Hand-written contract for the Spondeo e-signature API.

The Spondeo API is the wedge against DocuSign — the same primitives, but designed for developers instead of integrations consultants.

Conventions

  • Authentication. Every request carries Authorization: Bearer sk_…. Secret keys are workspace-scoped and minted in the Spondeo dashboard.
  • Versioning. The API is date-pinned via the Spondeo-Version header (e.g. 2026-05-01). A version stays supported for at least 12 months after deprecation. There is no URL-versioning besides the /v1/ prefix.
  • IDs. Every resource is prefixed (env_…, rcp_…, doc_…, tpl_…, evt_…, whe_…) so log lines disambiguate at a glance.
  • Timestamps. RFC 3339 / ISO 8601 with Z suffix.
  • Pagination. Cursor-based via limit + starting_after. Responses include has_more and next_cursor.
  • Idempotency. Any POST may carry Idempotency-Key; replays within 24h return the original response without re-executing the side effects.
  • Errors. Always JSON { error: { type, code, message, param?, request_id } }. Every response includes Spondeo-Request-Id in headers regardless of status.
  • Rate limits. Two buckets apply to every request: per-API-key (100/sec sustained, burst 200; test keys get 10×) and per-workspace (500/sec sustained, burst 1000). Every 2xx and 4xx response carries X-RateLimit-{Limit,Remaining,Reset,Bucket} reflecting the more-constrained bucket (see components/headers/RateLimit*); 429 responses also include Retry-After (seconds). Individual operations omit these from their per-response schemas to avoid noise — they apply uniformly. Call GET /v1/rate_limits to introspect current bucket state without consuming a token. The official SDKs retry 429s automatically with exponential backoff.
  • Webhooks. Signed with HMAC-SHA256 in Spondeo-Signature: t=<ts>,v1=<hex>. Verify with Spondeo.webhooks.constructEvent() in the official SDKs.
  • Server-to-server only. The API is intentionally not CORS-enabled. Secret keys (sk_live_…, sk_test_…) must never leave a server — a browser preflight will fail, by design. Browser-side embedded signing flows mint a signing_url on your backend and load the resulting JWT-secured iframe; the browser never calls /v1 directly.
  • Modes & scope. Every secret key is one of two modes: sk_test_… (sandbox — no email delivery, no legal weight) or sk_live_… (production). Every envelope, document, template, and webhook endpoint is tagged with the mode of the key that created it, and cross-mode access returns `404 not_found` — not `403` — by design. We never confirm the existence of a resource a caller is not authorized to see. The same rule applies cross-workspace: a key from workspace A asking for env_xxx in workspace B gets a 404, not a leaky 403. Use test-mode keys to prototype freely; promote to live only when you're ready for real emails and real audit trails.