{"openapi":"3.1.0","info":{"title":"Verafirma","version":"v1","description":"eSignature API for AI agents and developers. $0.10 per envelope, no subscription. Wraps Documenso (envelope content) + Relaystation (billing).","contact":{"url":"https://verafirma.com"},"license":{"name":"Proprietary"}},"servers":[{"url":"https://api.verafirma.com","description":"production"},{"url":"https://i67x9gp3ib.execute-api.us-east-1.amazonaws.com","description":"dev"}],"tags":[{"name":"envelopes","description":"Envelope CRUD + lifecycle"},{"name":"verifications","description":"Identity verification CRUD + lifecycle"},{"name":"templates","description":"Saved envelope definitions"},{"name":"webhooks","description":"Outbound webhook registrations"},{"name":"auth","description":"Wallet-JWT challenge/verify"},{"name":"account","description":"Customer account + history"},{"name":"discovery","description":"OpenAPI / llms.txt / MCP advertisement"}],"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","bearerFormat":"vf_live_<32-hex> | vf_test_<32-hex>","description":"API key minted at app.verafirma.com after OAuth signup."},"walletJwt":{"type":"http","scheme":"bearer","bearerFormat":"JWT (HS256)","description":"Issued by POST /v1/auth/verify after EIP-191 wallet signature. Used for read paths."},"x402":{"type":"apiKey","in":"header","name":"PAYMENT-SIGNATURE","description":"Base64-encoded EIP-3009 PaymentPayload (USDC v2 on Base Sepolia/mainnet). One call = one payment."}},"schemas":{"V1Recipient":{"type":"object","required":["email","name","role"],"properties":{"email":{"type":"string","format":"email"},"name":{"type":"string"},"role":{"type":"string","enum":["SIGNER","APPROVER","VIEWER","CC","ASSISTANT"]}}},"V1RecipientStatus":{"allOf":[{"$ref":"#/components/schemas/V1Recipient"},{"type":"object","properties":{"signingUrl":{"type":"string","format":"uri"},"signingStatus":{"type":"string"},"readStatus":{"type":"string"},"sendStatus":{"type":"string"},"signedAt":{"type":"string","format":"date-time"},"rejectionReason":{"type":"string"}}}]},"V1Field":{"type":"object","required":["type","recipientEmail"],"properties":{"id":{"type":"string"},"type":{"type":"string","enum":["SIGNATURE","INITIALS","NAME","EMAIL","DATE","TEXT","NUMBER","CHECKBOX","RADIO","DROPDOWN"]},"recipientEmail":{"type":"string","format":"email"},"page":{"type":"integer","minimum":1},"positionXPercent":{"type":"number","minimum":0,"maximum":100},"positionYPercent":{"type":"number","minimum":0,"maximum":100},"widthPercent":{"type":"number","minimum":0,"maximum":100},"heightPercent":{"type":"number","minimum":0,"maximum":100}}},"V1Envelope":{"type":"object","required":["envelopeId","documensoEnvelopeId","status","createdAt"],"properties":{"envelopeId":{"type":"string","format":"uuid"},"documensoEnvelopeId":{"type":"string"},"status":{"type":"string","enum":["DRAFT","PENDING","SENT","PARTIALLY_SIGNED","COMPLETED","REJECTED","EXPIRED","CANCELLED"]},"title":{"type":"string","nullable":true},"recipients":{"type":"array","items":{"$ref":"#/components/schemas/V1RecipientStatus"}},"storageExpiresAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"}}},"V1Webhook":{"type":"object","required":["id","url","events","active","createdAt"],"properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string"}},"description":{"type":"string","nullable":true},"active":{"type":"boolean"},"consecutiveFailures":{"type":"integer"},"secret":{"type":"string","description":"Returned ONCE on POST /v1/webhooks. Subsequent reads omit."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"V1WebhookDelivery":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"webhookId":{"type":"string","format":"uuid"},"event":{"type":"string"},"envelopeId":{"type":"string","format":"uuid","nullable":true},"status":{"type":"string","enum":["PENDING","SUCCESS","FAILED"]},"attempts":{"type":"integer"},"responseCode":{"type":"integer","nullable":true},"errorMessage":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"}}},"Error":{"type":"object","required":["error","code"],"properties":{"error":{"type":"string"},"code":{"type":"string"}}}},"responses":{"Unauthorized":{"description":"Missing or invalid auth.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"Resource not found or not owned by the customer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"ValidationError":{"description":"Invalid request body or parameters.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/health":{"get":{"tags":["discovery"],"summary":"Health check.","security":[],"responses":{"200":{"description":"OK"}}}},"/openapi.json":{"get":{"tags":["discovery"],"summary":"This OpenAPI 3.1 spec.","security":[],"responses":{"200":{"description":"OpenAPI document."}}}},"/llms.txt":{"get":{"tags":["discovery"],"summary":"Plain-text capability summary for LLM agent discovery.","security":[],"responses":{"200":{"description":"Capability summary.","content":{"text/plain":{"schema":{"type":"string"}}}}}}},"/.well-known/mcp.json":{"get":{"tags":["discovery"],"summary":"MCP-server advertisement.","security":[],"responses":{"200":{"description":"MCP advertisement."},"404":{"description":"MCP disabled (`verafirma.feature.mcp_enabled = false`)."}}}},"/mcp":{"post":{"tags":["discovery"],"summary":"MCP transport — JSON-RPC over HTTP.","description":"Streamable-HTTP MCP server. Methods: `initialize`, `tools/list`, `tools/call`. Auth flows through the same modes as /v1/*: API key, x402, wallet JWT.","security":[{"apiKey":[]},{"walletJwt":[]},{"x402":[]}],"responses":{"200":{"description":"JSON-RPC result."},"503":{"description":"MCP disabled."}}}},"/v1/auth/challenge":{"get":{"tags":["auth"],"summary":"Issue a wallet-sign-in nonce + EIP-191 message.","security":[],"parameters":[{"name":"wallet","in":"query","required":true,"schema":{"type":"string","pattern":"^0x[a-fA-F0-9]{40}$"}}],"responses":{"200":{"description":"Challenge."}}}},"/v1/auth/verify":{"post":{"tags":["auth"],"summary":"Verify EIP-191 signature and mint a wallet JWT.","security":[],"responses":{"200":{"description":"JWT minted."}}}},"/v1/envelopes":{"post":{"tags":["envelopes"],"description":"Create + send (or DRAFT) an envelope. **Billable: $0.10**","summary":"Create envelope.","security":[{"apiKey":[]},{"walletJwt":[]},{"x402":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["pdf","payload"],"properties":{"pdf":{"type":"string","format":"binary"},"payload":{"type":"string","description":"JSON-encoded { title, recipients, fields?, storageExpiryDays?, meta? }."}}}}}},"responses":{"201":{"description":"Envelope created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Envelope"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"description":"INSUFFICIENT_BALANCE."}}},"get":{"tags":["envelopes"],"summary":"List envelopes.","security":[{"apiKey":[]},{"walletJwt":[]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0}},{"name":"status","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Page of envelopes."}}}},"/v1/envelopes/{id}":{"get":{"tags":["envelopes"],"summary":"Cached envelope detail.","security":[{"apiKey":[]},{"walletJwt":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Envelope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Envelope"}}}},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"tags":["envelopes"],"summary":"Cancel envelope; refund-on-terminal triggers.","security":[{"apiKey":[]},{"walletJwt":[]},{"x402":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Cancelled."},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/envelopes/{id}/status":{"get":{"tags":["envelopes"],"summary":"Live status (Documenso authoritative; reconciles cache).","security":[{"apiKey":[]},{"walletJwt":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Live status."},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/envelopes/{id}/send":{"post":{"tags":["envelopes"],"description":"Distribute a DRAFT envelope. **Billable: $0.10**","summary":"Send a draft.","security":[{"apiKey":[]},{"walletJwt":[]},{"x402":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Distributed."}}}},"/v1/envelopes/{id}/resend":{"post":{"tags":["envelopes"],"summary":"Chase unsigned recipients.","security":[{"apiKey":[]},{"walletJwt":[]},{"x402":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Resent."}}}},"/v1/envelopes/{id}/download":{"get":{"tags":["envelopes"],"summary":"Stream the signed PDF.","security":[{"apiKey":[]},{"walletJwt":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"PDF stream.","content":{"application/pdf":{}}}}}},"/v1/envelopes/{id}/fields":{"post":{"tags":["envelopes"],"summary":"Add fields to a DRAFT envelope.","security":[{"apiKey":[]},{"walletJwt":[]},{"x402":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Fields added."}}}},"/v1/envelopes/{id}/fields/{fid}":{"delete":{"tags":["envelopes"],"summary":"Remove a field from a DRAFT envelope.","security":[{"apiKey":[]},{"walletJwt":[]},{"x402":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"fid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Removed."}}}},"/v1/verifications":{"post":{"tags":["verifications"],"description":"Create an identity verification (idswyft-backed). **Billable: $0.50**","summary":"Create a verification.","security":[{"apiKey":[]},{"walletJwt":[]},{"x402":[]}],"responses":{"201":{"description":"Verification created."}}},"get":{"tags":["verifications"],"summary":"List verifications.","security":[{"apiKey":[]},{"walletJwt":[]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0}},{"name":"status","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Page of verifications."}}}},"/v1/verifications/{id}":{"get":{"tags":["verifications"],"summary":"Cached verification detail.","security":[{"apiKey":[]},{"walletJwt":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Verification detail."},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/verifications/{id}/status":{"get":{"tags":["verifications"],"summary":"Live status (idswyft authoritative; reconciles cache).","security":[{"apiKey":[]},{"walletJwt":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Live status."},"404":{"$ref":"#/components/responses/NotFound"}}}},"/v1/templates":{"post":{"tags":["templates"],"summary":"Create a template.","security":[{"apiKey":[]},{"walletJwt":[]},{"x402":[]}],"responses":{"201":{"description":"Template created."}}},"get":{"tags":["templates"],"summary":"List templates.","security":[{"apiKey":[]},{"walletJwt":[]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Page of templates."}}}},"/v1/templates/{id}":{"get":{"tags":["templates"],"summary":"Template detail.","security":[{"apiKey":[]},{"walletJwt":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Template."}}},"put":{"tags":["templates"],"summary":"Update template title or meta.","security":[{"apiKey":[]},{"walletJwt":[]},{"x402":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Updated."}}},"delete":{"tags":["templates"],"summary":"Delete a template.","security":[{"apiKey":[]},{"walletJwt":[]},{"x402":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Deleted."}}}},"/v1/templates/{id}/from-template":{"post":{"tags":["templates"],"description":"Instantiate an envelope from a template. **Billable: $0.10**","summary":"Instantiate envelope from template.","security":[{"apiKey":[]},{"walletJwt":[]},{"x402":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"201":{"description":"Envelope created from template."}}}},"/v1/webhooks":{"post":{"tags":["webhooks"],"summary":"Register a webhook (returns secret ONCE).","security":[{"apiKey":[]},{"walletJwt":[]},{"x402":[]}],"responses":{"201":{"description":"Webhook registered.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Webhook"}}}}}},"get":{"tags":["webhooks"],"summary":"List webhook registrations.","security":[{"apiKey":[]},{"walletJwt":[]}],"responses":{"200":{"description":"Webhook list."}}}},"/v1/webhooks/{id}":{"get":{"tags":["webhooks"],"summary":"Webhook detail (no secret).","security":[{"apiKey":[]},{"walletJwt":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Webhook."}}},"put":{"tags":["webhooks"],"summary":"Update webhook (active / events / url / description).","security":[{"apiKey":[]},{"walletJwt":[]},{"x402":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Updated."}}},"delete":{"tags":["webhooks"],"summary":"Delete webhook (deliveries kept for audit).","security":[{"apiKey":[]},{"walletJwt":[]},{"x402":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Deleted."}}}},"/v1/webhooks/{id}/deliveries":{"get":{"tags":["webhooks"],"summary":"Paginated delivery history.","security":[{"apiKey":[]},{"walletJwt":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0}},{"name":"status","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Delivery page."}}}},"/v1/account":{"get":{"tags":["account"],"summary":"Customer profile + balance.","security":[{"apiKey":[]},{"walletJwt":[]}],"responses":{"200":{"description":"Account info."}}}},"/v1/account/usage":{"get":{"tags":["account"],"summary":"Usage history (proxy ledger).","security":[{"apiKey":[]},{"walletJwt":[]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Usage entries."}}}},"/v1/account/summary":{"get":{"tags":["account"],"summary":"Spending aggregates (wallet JWT only).","security":[{"walletJwt":[]}],"responses":{"200":{"description":"Summary."},"403":{"description":"WALLET_JWT_REQUIRED."}}}},"/v1/account/envelopes":{"get":{"tags":["account"],"summary":"Envelope history.","security":[{"apiKey":[]},{"walletJwt":[]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0}},{"name":"status","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Envelope page."}}}},"/v1/account/products/{product}/enable":{"post":{"tags":["account"],"summary":"Enable a Verafirma-family product for the calling customer.","description":"Dashboard-only action (vf_session cookie OR wallet-JWT). Rejects API-key + x402. Idempotent — repeated enables return the same shape.","security":[{"walletJwt":[]}],"parameters":[{"name":"product","in":"path","required":true,"schema":{"type":"string","enum":["verafirma_id"]}}],"responses":{"200":{"description":"Product enabled."}}}},"/v1/account/products":{"get":{"tags":["account"],"summary":"Enrollment list for the calling customer.","description":"Returns the products this customer is enrolled in. Accepts API-key, vf_session, or wallet-JWT. Rejects x402 with X402_NOT_APPLICABLE (lodestone callers per D43 never enroll).","security":[{"apiKey":[]},{"walletJwt":[]}],"responses":{"200":{"description":"Enrollment list (may be empty)."},"400":{"description":"X402_NOT_APPLICABLE."},"401":{"description":"MISSING_AUTH."}}}}}}