docs: current-state product pages (sign/dataroom/captable) + plugin-platform architecture

Product pages — corrected to what each app actually does today:
- sign: esign.hanzo.ai (not sign.hanzo.ai); image ghcr.io/hanzoai/esign; IAM_URL;
  real FieldType enum; /api/v1 (ts-rest, stable) + /api/v2 (tRPC) surfaces;
  framed as the AGPLv3 open-source e-signature app it is.
- dataroom: Papermark fork; embedded SQLite default (not Postgres); drop the
  fabricated LinkedIn OAuth and invented clean-REST contract; add real features
  (conversations, AI Q&A, file requests, SCIM, Hanko passkeys, BoxyHQ SAML);
  honest unversioned /api surface.
- captable: drop fabricated 409A history / waterfall / round-modeling and the
  invented REST endpoints; document the real tRPC + Hono /api/v1 API
  (OpenAPI at /v1/docs); IAM_URL; note incorporation is WIP.

Architecture section (new) — explicitly direction, not shipped:
- content/docs/architecture/{index,plugin-platform}.mdx + meta.json, wired into
  the root nav after Proof of AI. Documents the consensus-backed plugin platform
  (HIP-0116, Draft): plugins as the unit (cloud.Register, HIP-0105); a small
  post-quantum BFT (Quasar) control plane holding the placement map + writer
  leases, with the data plane reusing existing S3/ZapDB replication (HIP-0107);
  5 voters + N data nodes, pinned writers, per-connection pinning, per-tenant
  sharding; ZAP-native authoring (HIP-0114). Every code sample is labeled
  proposed / not-yet-available; consensus-off-the-data-path is called out.

The services nav derives from @hanzo/products (gen-services-nav.ts); sign,
dataroom and captable remain under the generated "More" group until they are
added to the commerce catalog + snapshot — a registry change out of scope for a
docs-only PR.
This commit is contained in:
2026-07-07 16:49:22 -07:00
parent 330bf79d70
commit 9eb525b137
7 changed files with 281 additions and 306 deletions
@@ -0,0 +1,29 @@
---
title: Architecture
description: How Hanzo Cloud is built today, and the plugin-platform direction it is evolving toward.
index: true
---
# Architecture
This section explains how Hanzo Cloud is put together — what runs today, and where the platform is headed. We keep the two clearly separated: the product pages elsewhere in these docs describe shipped behavior, while the platform direction here is design work being ratified through the [Hanzo Improvement Proposals (HIPs)](https://hips.hanzo.ai).
## Today
Hanzo Cloud is a family of services behind one front door. A single API key at `api.hanzo.ai` reaches every service — AI inference, identity, secrets, storage, commerce, and more — grouped into ten categories: AI, Compute, Data, Network, Security, Observe, Platform, Web3, Apps, and Commerce. See [Platform & Services](/docs/services) for the full catalog.
Each product is its own repository and its own container image, deployed and reconciled independently. Some products run as standalone applications on their own domains — for example [Sign](/docs/services/sign) (`esign.hanzo.ai`), [Dataroom](/docs/services/dataroom) (`dataroom.hanzo.ai`), and [Cap Table](/docs/services/captable) (`captable.hanzo.ai`). They authenticate through Hanzo IAM, but each runs as its own application rather than inside a single shared runtime.
## Direction
The platform is converging on one model for running these services: a **consensus-backed plugin platform**, where each service is a *plugin* registered into a single cloud runtime, and a small consensus control plane decides where each plugin's writers live. This is a design direction — specified as a draft proposal, not yet a shipped runtime.
<Cards>
<Card title="Consensus-Backed Plugin Platform" href="/docs/architecture/plugin-platform" description="The HIP-0116 direction: plugins as the unit, consensus over placement, ZAP-native authoring." />
<Card title="ZAP Protocol" href="/docs/zap" description="Zero-Copy App Proto — the high-performance transport plugins default to." />
<Card title="Hanzo Improvement Proposals" href="https://hips.hanzo.ai" description="Where platform architecture is specified and ratified." />
</Cards>
<Callout type="info">
The plugin platform is described in **HIP-0116 (Draft)**. It builds on a set of related proposals — the in-process extension runtime (HIP-0105), the unified cloud binary (HIP-0106), streaming replication (HIP-0107), and the ZAP transport (HIP-0114). Draft proposals may change; nothing on the [plugin-platform page](/docs/architecture/plugin-platform) is a shipped user feature.
</Callout>
@@ -0,0 +1,9 @@
{
"title": "Architecture",
"description": "How Hanzo Cloud is built today, and the plugin-platform direction it is evolving toward",
"icon": "Blocks",
"pages": [
"index",
"plugin-platform"
]
}
@@ -0,0 +1,102 @@
---
title: Consensus-Backed Plugin Platform
description: The architecture direction for Hanzo Cloud — plugins as the unit of deployment, a small consensus control plane over placement, and ZAP-native authoring. Specified in HIP-0116 (Draft).
---
# Consensus-Backed Plugin Platform
<Callout type="warn">
This page describes a **design direction**, not a shipped feature. The runtime it describes is specified in **HIP-0116 (Draft)** and is **not yet built**. It is published so the design can be reviewed. For what runs today, see the product pages under [Platform & Services](/docs/services); this page is about where the platform is headed and why.
</Callout>
Hanzo Cloud today is many services, each its own repository, image, and deployment. The direction is to run them as **plugins** inside one cloud runtime, and to let a **small consensus control plane** decide where each plugin's write side lives. The goal is that a service author writes almost none of the hard parts — placement, failover, replication, high availability — and inherits them from the platform.
The design rests on one principle: **consensus orders decisions, not bytes.**
## The unit is a plugin
In the proposed model (HIP-0105, *In-Process Extension Runtime Standard*), a service registers itself with a single call:
```go
// Proposed API (HIP-0105) — not yet available.
func init() {
cloud.Register("kms", 500, mount)
}
```
A plugin is the unit the platform places and scales. The `cloud` binary loads a set of registered plugins; **nodes specialize** by running a dynamic subset of them rather than every node running everything. That makes the runtime one deployable artifact whose behavior on each node is data — the placement decision — rather than a per-service build.
Existing subsystems — KMS, IAM, Base, Gateway, Commerce, tasks, pubsub — are exactly the kind of thing that becomes a plugin under this model. They are **not** plugins today; this is the target.
## Consensus orders decisions, not bytes
The platform splits into two planes that are deliberately kept separate.
**Control plane — a small, fixed quorum.** Five voter nodes run a post-quantum BFT consensus engine (the **Quasar** engine from Lux, with a post-quantum certificate profile). Its replicated log orders only tiny metadata:
- cluster membership,
- the **placement map** — which node holds the writer for each `(plugin, shard)`, and its followers,
- **writer leases** with fencing epochs, so there is exactly one writer per shard per epoch.
**Data plane — reuse what exists.** The bytes do not go through consensus. The data plane reuses the existing streaming replication (HIP-0107) that already backs the platform's storage — the S3 / ZapDB log-ship. The only change is the write fence: instead of asking "do I hold a Kubernetes lease?", a writer asks "does the control plane grant this shard's lease at the current epoch?"
The consequence is the important part:
<Callout type="info">
**Consensus sits off the data path.** If the control-plane quorum is lost, placement and failover freeze — but serving does not stop. Every current writer keeps its lease and keeps writing; readers keep reading. Losing quorum degrades **failover**, not availability. This is the Chubby / etcd shape applied to the Hanzo runtime.
</Callout>
## Scaling to N nodes
The two planes scale independently:
- **5 voters** run the control plane. The quorum is small and fixed, so adding capacity never slows consensus.
- **N data nodes** host plugin shards and each follow a read-only copy of the placement map. `N` grows without bound.
Within that topology:
- **Pinned writers** — each shard has one writer node, assigned by the placement map, so writes have a single owner and never conflict.
- **Per-connection pinning** — a client's connection is routed to the node that currently owns the shard it is talking to, so reads and writes land on the right replica.
- **Per-tenant sharding** — the write side can be split by tenant, down to a `(plugin, org)` shard, so a single busy organization gets its own writer. Fine per-tenant sharding is a **later stage** of the proposal; the earlier stages run one writer per plugin.
## ZAP-native, easy plugin authoring
The payoff is the developer experience. Under HIP-0105 and HIP-0114, a plugin author implements one small interface and calls `cloud.Register`. In return the platform supplies placement, per-tenant scale, replication, per-connection pinning, and high availability — none of which the author writes.
```go
// Proposed authoring model (HIP-0105 / HIP-0116) — illustrative, not yet available.
// The author writes the handler; the platform supplies placement + replication + HA.
func mount(deps cloud.Deps) http.Handler {
db := deps.OpenShard("kms") // the placement-assigned shard for this node
return newHandler(db) // ...just serve requests
}
func init() { cloud.Register("kms", 500, mount) }
```
The default wire is **ZAP** (Zero-Copy App Proto, HIP-0114) — the same high-performance, post-quantum transport documented in the [ZAP section](/docs/zap). Every plugin registered through `cloud.Register` speaks ZAP with no extra work, so cross-plugin and inter-node calls get zero-copy performance by default rather than as an opt-in.
<Callout type="warn">
The snippets above show the **proposed** shape of the API to illustrate the direction. They are not a tutorial for a runtime that exists today — there is no `cloud.Register` plugin runtime to deploy against yet. Treat them as design, pending ratification of HIP-0116.
</Callout>
## Where this is specified
The plugin platform is defined across a set of Hanzo Improvement Proposals. Statuses are as of writing and may change — track them at [hips.hanzo.ai](https://hips.hanzo.ai) and [github.com/hanzoai/hips](https://github.com/hanzoai/hips).
| HIP | Title | Status |
|-----|-------|--------|
| HIP-0116 | Consensus-Backed Plugin-Placement Platform | Draft |
| HIP-0105 | In-Process Extension Runtime Standard | Draft |
| HIP-0106 | Unified Hanzo Cloud Binary | Draft |
| HIP-0107 | Streaming Replication over VFS | Draft |
| HIP-0112 | Cloud Infrastructure Topology Standard | Active |
| HIP-0114 | ZAP — Inter-VM Cognitive Transport | Draft |
## Next Steps
<Cards>
<Card title="Architecture Overview" href="/docs/architecture" description="How Hanzo Cloud is built today, and the direction it is evolving toward." />
<Card title="ZAP Protocol" href="/docs/zap" description="The zero-copy transport plugins default to." />
<Card title="Platform & Services" href="/docs/services" description="The services that run today, behind one api.hanzo.ai." />
</Cards>
+2
View File
@@ -22,6 +22,8 @@
"commerce",
"---Proof of AI---",
"proof-of-ai",
"---Architecture---",
"architecture",
"---Infrastructure---",
"tasks",
"functions",
+49 -152
View File
@@ -5,19 +5,24 @@ description: Equity management and cap table platform
# Hanzo Cap Table
Hanzo Cap Table is an equity management platform for startups and growth-stage companies. Manage share classes, stock options, SAFEs, convertible notes, and equity plans with full audit trails and built-in e-signing.
Hanzo Cap Table is an open-source equity-management platform for startups and growth-stage companies — a self-hostable alternative to Carta, Pulley, and AngelList. Manage share classes, stock options, SAFEs, and convertible notes; run fundraising rounds; share documents in a data room; and collect signatures — all with a full audit trail. It runs as a standalone Next.js application at `captable.hanzo.ai` and signs in through Hanzo IAM.
> The equity, fundraising, document, data-room, e-signing, and investor-update workflows are production features today. Company incorporation is still under active development and is marked as a work in progress inside the app.
## Features
- **Share Classes**: Common, preferred, and custom share classes
- **Stock Options**: ISO and NSO option grants with vesting schedules
- **SAFEs**: Y Combinator SAFE management with conversion modeling
- **Convertible Notes**: Track notes with interest, caps, and discounts
- **Share Classes**: Common and preferred classes with customizable terms
- **Securities**: Shares, stock options (ISO / NSO / RSU), SAFEs, and convertible notes
- **SAFEs**: The six standard Y Combinator SAFE templates plus custom terms — valuation cap, discount, MFN, and pro-rata rights
- **Convertible Notes**: CCD, OCD, and NOTE instruments with interest accrual
- **Equity Plans**: Option pools and equity incentive plans
- **Vesting Schedules**: Cliff, linear, and custom vesting
- **409A Valuations**: Track fair market value history
- **E-Signing**: Built-in document signing for equity grants
- **Data Rooms**: Integrated document management
- **Vesting Schedules**: Cliff plus multi-year vesting on shares and option grants
- **Stakeholders**: Individuals and institutions with relationship types (founder, employee, investor, advisor, and more)
- **Fundraising**: Track investments, issue securities, and manage round participants
- **Documents & Data Rooms**: Upload to S3-compatible storage and share through access-controlled data rooms
- **E-Signing**: Built-in PDF signing workflows for equity grants and agreements
- **Investor Updates**: Rich-text updates with public/private visibility and recipient tracking
- **Roles & Permissions**: Role-based access control with a full activity audit log
- **Hanzo IAM SSO**: Single sign-on via Hanzo identity
## Endpoints
@@ -25,12 +30,14 @@ Hanzo Cap Table is an equity management platform for startups and growth-stage c
| Environment | URL |
|-------------|-----|
| Production | `https://captable.hanzo.ai` |
| REST API | `https://captable.hanzo.ai/api/v1` |
| API reference | `https://captable.hanzo.ai/v1/docs` |
## Architecture
```
+---------------------------------------------------------------+
| HANZO CAP TABLE |
| HANZO CAP TABLE |
+---------------------------------------------------------------+
| |
| +-----------------------+ +-------------------------------+ |
@@ -41,106 +48,34 @@ Hanzo Cap Table is an equity management platform for startups and growth-stage c
| +-----------------------+ +-------------------------------+ |
| |
| +-----------------------+ +-------------------------------+ |
| | Instruments | | Compliance | |
| | Instruments | | Governance | |
| | +------+ +-------+ | | +--------+ +-------------+ | |
| | | SAFE | | Notes | | | | 409A | | Audit Log | | |
| | | SAFE | | Notes | | | | RBAC | | Audit Log | | |
| | +------+ +-------+ | | +--------+ +-------------+ | |
| +-----------------------+ +-------------------------------+ |
| |
+---------------------------------------------------------------+
```
## Quick Start
## How It Works
### 1. Create a Company
Cap-table operations are carried out in the dashboard and recorded in the audit log.
Set up your company profile with incorporation details:
### 1. Set Up the Company
```typescript
const company = await fetch('https://captable.hanzo.ai/api/company', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'Acme Corp',
incorporationDate: '2024-01-15',
incorporationState: 'DE',
incorporationCountry: 'US'
})
})
```
Create the company profile with its incorporation details, then invite team members and assign roles.
### 2. Create Share Classes
### 2. Define Share Classes
```typescript
// Common stock
await fetch('https://captable.hanzo.ai/api/share-classes', {
method: 'POST',
headers: { 'Authorization': `Bearer ${apiToken}` },
body: JSON.stringify({
name: 'Common Stock',
classType: 'COMMON',
authorizedShares: 10000000,
parValue: 0.0001,
votesPerShare: 1
})
})
Add common and preferred share classes — each with authorized shares, par value, and voting rights, plus liquidation preferences and conversion terms for preferred classes.
// Preferred stock
await fetch('https://captable.hanzo.ai/api/share-classes', {
method: 'POST',
headers: { 'Authorization': `Bearer ${apiToken}` },
body: JSON.stringify({
name: 'Series Seed Preferred',
classType: 'PREFERRED',
authorizedShares: 2000000,
parValue: 0.0001,
liquidationPreference: 1.0,
conversionRatio: 1.0
})
})
```
### 3. Issue Securities
### 3. Issue Shares
Issue shares and grant options (ISO / NSO / RSU) to stakeholders, attaching vesting schedules where applicable.
```typescript
await fetch('https://captable.hanzo.ai/api/shares/issue', {
method: 'POST',
headers: { 'Authorization': `Bearer ${apiToken}` },
body: JSON.stringify({
stakeholderId: 'founder-1',
shareClassId: 'common-stock-id',
quantity: 5000000,
pricePerShare: 0.0001,
vestingSchedule: {
type: 'CLIFF_LINEAR',
cliffMonths: 12,
totalMonths: 48,
startDate: '2024-01-15'
}
})
})
```
### 4. Run Fundraising
### 4. Create a SAFE
```typescript
await fetch('https://captable.hanzo.ai/api/safes', {
method: 'POST',
headers: { 'Authorization': `Bearer ${apiToken}` },
body: JSON.stringify({
investorId: 'investor-1',
investmentAmount: 500000,
valuationCap: 10000000,
discount: 0.20,
proRata: true,
mfn: true,
safeType: 'POST_MONEY'
})
})
```
Model SAFEs and convertible notes — valuation caps, discounts, MFN, and pro-rata rights — and track investments through the round.
## Securities Types
@@ -151,56 +86,38 @@ await fetch('https://captable.hanzo.ai/api/safes', {
| Stock Options (ISO) | Incentive stock options (tax-advantaged) |
| Stock Options (NSO) | Non-qualified stock options |
| RSUs | Restricted stock units |
| SAFEs | Simple Agreement for Future Equity |
| Convertible Notes | Debt instruments convertible to equity |
| Warrants | Right to purchase shares at a set price |
| SAFEs | Simple Agreement for Future Equity (six YC templates + custom) |
| Convertible Notes | Debt instruments convertible to equity (CCD / OCD / NOTE) |
## Vesting Schedules
## Vesting
| Schedule | Description |
|----------|-------------|
| `CLIFF_LINEAR` | Cliff period then monthly vesting |
| `LINEAR` | Equal monthly vesting from start |
| `BACK_WEIGHTED` | Accelerating vesting over time |
| `CUSTOM` | Custom milestone-based vesting |
| `IMMEDIATE` | Fully vested on grant |
### Standard 4-Year with 1-Year Cliff
Shares and option grants support a cliff followed by multi-year vesting. The most common schedule is four-year vesting with a one-year cliff:
```
Year 1: 0% → 25% (cliff)
Year 2: 25% → 50% (monthly)
Year 3: 50% → 75% (monthly)
Year 4: 75% → 100% (monthly)
Year 2: 25% → 50%
Year 3: 50% → 75%
Year 4: 75% → 100%
```
## Cap Table Reports
## Ownership View
### Ownership Summary
View current ownership percentages across all stakeholders, including fully-diluted calculations.
### Waterfall Analysis
Model liquidation scenarios to understand payout distributions at various exit valuations.
### Round Modeling
Project dilution and ownership changes for future financing rounds.
The cap table shows current ownership across all stakeholders, including fully-diluted figures that account for the option pool and outstanding convertible instruments.
## Authentication
Hanzo Cap Table supports multiple authentication methods:
Hanzo Cap Table signs users in through Hanzo IAM and supports:
- **Hanzo IAM**: SSO via `https://hanzo.id` (recommended)
- **Google OAuth**: Sign in with Google
- **Hanzo IAM**: SSO via `https://hanzo.id` (required for production)
- **Email & Password**: Native NextAuth accounts
- **Passkeys**: WebAuthn/FIDO2 authentication
- **Google OAuth**: Optional legacy provider
### IAM Integration
```bash
# Environment variables
IAM_ENDPOINT=https://hanzo.id
IAM_URL=https://hanzo.id
IAM_CLIENT_ID=app-captable
IAM_CLIENT_SECRET=<from-kms>
```
@@ -215,7 +132,7 @@ docker run -d \
-p 3000:3000 \
-e DATABASE_URL=postgres://... \
-e NEXTAUTH_URL=https://captable.yourdomain.com \
-e IAM_ENDPOINT=https://hanzo.id \
-e IAM_URL=https://hanzo.id \
-e IAM_CLIENT_ID=app-captable \
ghcr.io/hanzoai/captable:latest
```
@@ -227,38 +144,18 @@ docker run -d \
| `DATABASE_URL` | PostgreSQL connection string |
| `NEXTAUTH_URL` | Public URL of the application |
| `NEXTAUTH_SECRET` | NextAuth encryption secret |
| `IAM_ENDPOINT` | Hanzo IAM server URL |
| `IAM_URL` | Hanzo IAM server URL |
| `IAM_CLIENT_ID` | IAM application client ID |
| `IAM_CLIENT_SECRET` | IAM application client secret |
| `S3_*` | S3-compatible object storage credentials (S3, MinIO, or R2) |
| `SMTP_HOST` | Email server host |
| `STRIPE_SECRET_KEY` | Stripe billing key |
## API Reference
## API
### Share Classes
Hanzo Cap Table is built on **tRPC** for type-safe internal calls, with a **REST API** exposed under `/api/v1` (built on Hono) and an interactive **OpenAPI reference at `/v1/docs`**. Programmatic access uses scoped API tokens; token types include API access, signature, data-room, and investor-update tokens.
- `POST /api/share-classes` - Create share class
- `GET /api/share-classes` - List share classes
- `PATCH /api/share-classes/:id` - Update share class
### Stakeholders
- `POST /api/stakeholders` - Add stakeholder
- `GET /api/stakeholders` - List stakeholders
- `GET /api/stakeholders/:id` - Get stakeholder details
### Securities
- `POST /api/shares/issue` - Issue shares
- `POST /api/options/grant` - Grant options
- `POST /api/safes` - Create SAFE
- `POST /api/convertible-notes` - Create convertible note
### Reports
- `GET /api/reports/captable` - Current cap table
- `GET /api/reports/waterfall` - Waterfall analysis
- `GET /api/reports/409a` - 409A valuation history
The API covers the same resources as the dashboard — companies and members, stakeholders, share classes and equity plans, securities (shares, options, SAFEs, convertible notes), documents and data rooms, and investor updates. See `/v1/docs` on your instance for the exact request and response shapes.
## Next Steps
+52 -133
View File
@@ -5,16 +5,23 @@ description: Secure document sharing with analytics and access controls
# Hanzo Dataroom
Hanzo Dataroom is a secure document sharing platform with real-time analytics, granular access controls, and custom branding. Share pitch decks, fundraising materials, legal documents, and more with full visibility into how recipients engage.
Hanzo Dataroom is an open-source secure document-sharing platform — a self-hostable fork of Papermark (AGPLv3) — with real-time analytics, granular access controls, and custom branding. Share pitch decks, fundraising materials, and legal documents through controlled links, and organize due-diligence material into structured data rooms with full visibility into how recipients engage. It runs as a standalone Next.js application at `dataroom.hanzo.ai` and signs in through Hanzo IAM.
## Features
- **Secure Sharing**: Password protection, email verification, NDA agreements
- **Real-Time Analytics**: Page-by-page view tracking, time spent, completion rates
- **Custom Branding**: Per-team logos, colors, and custom domains
- **Data Rooms**: Organized folder structures for due diligence and fundraising
- **Access Controls**: Expiration dates, download restrictions, watermarking
- **SAML SSO**: Enterprise single sign-on via BoxyHQ Jackson
- **Shareable Links**: Per-link expiration, password protection, email verification, and allow/deny lists
- **Watermarking**: Dynamic watermarks stamped with viewer information
- **Screenshot Protection**: Discourage capture of sensitive material
- **Custom Domains & Branding**: Per-team logos and colors, custom domains, and custom link metatags
- **Data Rooms**: Multi-document collections with folders, viewer groups, and granular permissions
- **Real-Time Analytics**: Page-by-page view tracking, time spent, downloads, and per-page reactions
- **Conversations**: Comment threads on documents and data rooms
- **AI Q&A**: Chat over documents and data rooms (optional; requires a model-provider key)
- **File Requests**: Collect document uploads from visitors through a link
- **Link Presets & Tags**: Reusable link configurations and labels across links, documents, and data rooms
- **NDA & Agreements**: Require acceptance before viewing
- **Enterprise SSO**: SAML via BoxyHQ Jackson, plus SCIM directory sync
- **Passkeys**: WebAuthn authentication via Hanko
- **Hanzo IAM SSO**: Single sign-on via Hanzo identity
## Endpoints
@@ -28,7 +35,7 @@ Hanzo Dataroom is a secure document sharing platform with real-time analytics, g
```
+---------------------------------------------------------------+
| HANZO DATAROOM |
| HANZO DATAROOM |
+---------------------------------------------------------------+
| |
| +-----------------------+ +-------------------------------+ |
@@ -48,113 +55,38 @@ Hanzo Dataroom is a secure document sharing platform with real-time analytics, g
+---------------------------------------------------------------+
```
## Quick Start
## How It Works
The full workflow runs in the dashboard.
### 1. Upload a Document
```typescript
const formData = new FormData()
formData.append('file', pdfFile)
const response = await fetch('https://dataroom.hanzo.ai/api/documents', {
method: 'POST',
headers: { 'Authorization': `Bearer ${apiToken}` },
body: formData
})
const { id: documentId } = await response.json()
```
Upload a PDF (or other supported file) to your team's library. Uploads go to S3-compatible object storage or Vercel Blob, depending on the configured transport, with resumable upload support.
### 2. Create a Sharing Link
```typescript
const link = await fetch('https://dataroom.hanzo.ai/api/links', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
documentId,
name: 'Investor Deck - Series A',
password: 'optional-password',
expiresAt: '2026-04-01T00:00:00Z',
emailProtected: true,
allowDownload: false,
enableWatermark: true
})
})
Generate a link and attach controls — a name, optional password, expiration date, email verification, allow/deny lists, download permission, and watermarking. Share the resulting `/view/...` URL with recipients.
// Share this URL with recipients
console.log(link.url) // https://dataroom.hanzo.ai/view/abc123
```
### 3. Track Engagement
### 3. View Analytics
```typescript
const analytics = await fetch(
`https://dataroom.hanzo.ai/api/links/${linkId}/analytics`,
{ headers: { 'Authorization': `Bearer ${apiToken}` } }
).then(r => r.json())
// Per-viewer engagement data
analytics.views.forEach(view => {
console.log(`${view.email}: ${view.totalDuration}s, ${view.completionRate}%`)
view.pages.forEach(page => {
console.log(` Page ${page.number}: ${page.duration}s`)
})
})
```
Watch views arrive in real time: who opened the link, how long they spent on each page, which pages they revisited, and what they downloaded.
## Data Rooms
Organize documents into structured data rooms for due diligence, fundraising, or any multi-document workflow.
### Create a Data Room
```typescript
const dataroom = await fetch('https://dataroom.hanzo.ai/api/datarooms', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'Series A Due Diligence',
folders: [
{ name: 'Financials' },
{ name: 'Legal' },
{ name: 'Product' },
{ name: 'Team' }
]
})
})
```
### Add Documents to Folders
```typescript
await fetch(`https://dataroom.hanzo.ai/api/datarooms/${dataroomId}/documents`, {
method: 'POST',
headers: { 'Authorization': `Bearer ${apiToken}` },
body: JSON.stringify({
documentId,
folderId: 'financials-folder-id'
})
})
```
Organize documents into structured data rooms for due diligence, fundraising, or any multi-document workflow. Each data room supports nested folders, viewer groups, and permission groups so different recipients see different subsets, with an optional introduction page and per-room change notifications.
## Access Controls
| Feature | Description |
|---------|-------------|
| Password Protection | Require password to view |
| Email Verification | Require verified email |
| NDA Agreement | Accept NDA before viewing |
| Password Protection | Require a password to view |
| Email Verification | Require a verified email |
| NDA Agreement | Accept an NDA before viewing |
| Expiration Date | Auto-expire links |
| Download Restriction | Prevent PDF downloads |
| Download Restriction | Prevent file downloads |
| Watermarking | Dynamic watermarks with viewer info |
| Allow List | Restrict to specific email domains |
| Screenshot Protection | Discourage screen capture |
| Allow / Deny Lists | Restrict to (or block) specific emails or domains |
## Analytics
@@ -174,40 +106,41 @@ Track engagement at the page level to understand which sections resonate:
- Time spent per page
- Page revisits
- Scroll depth
- Download attempts
- Per-page reactions
- Download activity
## Authentication
Hanzo Dataroom supports multiple authentication methods:
Hanzo Dataroom signs users in through Hanzo IAM and supports:
- **Hanzo IAM**: SSO via `https://hanzo.id` (recommended)
- **Google OAuth**: Sign in with Google
- **LinkedIn OAuth**: Sign in with LinkedIn
- **Hanzo IAM**: SSO via `https://hanzo.id` (default, recommended)
- **Email Magic Link**: Passwordless email login
- **Passkeys**: WebAuthn/FIDO2 authentication
- **SAML SSO**: Enterprise SSO via BoxyHQ Jackson
- **Passkeys**: WebAuthn/FIDO2 authentication via Hanko
- **SAML SSO**: Enterprise SSO via BoxyHQ Jackson, with SCIM directory sync
- **Google OAuth**: Optional legacy provider
### IAM Integration
```bash
# Environment variables
IAM_ENDPOINT=https://hanzo.id
IAM_URL=https://hanzo.id
IAM_CLIENT_ID=app-dataroom
IAM_CLIENT_SECRET=<from-kms>
```
## Self-Hosting
Hanzo Dataroom ships as a Next.js standalone application with an embedded SQLite database by default (single-replica), so a basic deployment needs only a persistent volume and object storage.
### Docker
```bash
docker run -d \
--name hanzo-dataroom \
-p 3000:3000 \
-e DATABASE_URL=postgres://... \
-v dataroom-data:/app/data \
-e NEXTAUTH_URL=https://dataroom.yourdomain.com \
-e IAM_ENDPOINT=https://hanzo.id \
-e IAM_URL=https://hanzo.id \
-e IAM_CLIENT_ID=app-dataroom \
ghcr.io/hanzoai/dataroom:latest
```
@@ -216,40 +149,26 @@ docker run -d \
| Variable | Description |
|----------|-------------|
| `DATABASE_URL` | PostgreSQL connection string |
| `DATABASE_URL` | Database connection (embedded SQLite by default) |
| `NEXTAUTH_URL` | Public URL of the application |
| `NEXTAUTH_SECRET` | NextAuth encryption secret |
| `IAM_ENDPOINT` | Hanzo IAM server URL |
| `IAM_URL` | Hanzo IAM server URL |
| `IAM_CLIENT_ID` | IAM application client ID |
| `IAM_CLIENT_SECRET` | IAM application client secret |
| `NEXT_PUBLIC_BASE_URL` | Public base URL |
| `NEXT_PUBLIC_UPLOAD_TRANSPORT` | Storage backend — `s3` or `vercel` |
| `S3_*` | S3-compatible object storage credentials |
| `SMTP_HOST` | Email server host |
| `STRIPE_SECRET_KEY` | Stripe billing key |
## API Reference
## Integrations & API
### Documents
Hanzo Dataroom is primarily a dashboard-driven product: documents are uploaded, links are created, and analytics are viewed in the app. Programmatic surfaces include:
- `POST /api/documents` - Upload document
- `GET /api/documents` - List documents
- `GET /api/documents/:id` - Get document
- `DELETE /api/documents/:id` - Delete document
- **Next.js API routes** under `/api` (unversioned) — links, views, teams, verification, and file handling used by the app and its share pages.
- **SAML SSO & SCIM** for enterprise identity and directory sync.
- **Incoming webhooks** and **Slack notifications** for view and download events.
- **AI Q&A** endpoints for chat over documents and data rooms.
### Links
- `POST /api/links` - Create sharing link
- `GET /api/links` - List links
- `GET /api/links/:id` - Get link details
- `GET /api/links/:id/analytics` - Get link analytics
- `PATCH /api/links/:id` - Update link settings
- `DELETE /api/links/:id` - Delete link
### Data Rooms
- `POST /api/datarooms` - Create data room
- `GET /api/datarooms` - List data rooms
- `POST /api/datarooms/:id/documents` - Add document
- `DELETE /api/datarooms/:id` - Delete data room
Refer to your instance and the self-hosting configuration for the exact route set.
## Next Steps
+38 -21
View File
@@ -5,15 +5,21 @@ description: Document signing and e-signature platform
# Hanzo Sign
Hanzo Sign is a document signing platform for creating, sending, and managing legally binding electronic signatures. Built for teams that need secure, compliant e-signatures integrated with the Hanzo ecosystem.
Hanzo Sign (also called Hanzo eSign) is an open-source document signing platform — an AGPLv3 alternative to DocuSign — for creating, sending, and managing legally binding electronic signatures. It runs as a standalone Next.js/React Router application at `esign.hanzo.ai`, integrates with Hanzo IAM for SSO, and can be self-hosted.
Documents are signed cryptographically: the completed PDF is sealed with a signing certificate (a P12 certificate or Google Cloud HSM key), and every action is captured in an audit trail.
## Features
- **PDF Signing**: Upload and sign PDF documents with legally binding e-signatures
- **Templates**: Create reusable document templates with pre-defined signing fields
- **Signing Fields**: Text, signature, initials, date, checkbox, dropdown, and more
- **Teams & Organizations**: Multi-tenant workspace management
- **Webhooks**: Real-time notifications for signing events
- **PDF Signing**: Upload and sign PDF documents with legally binding, cryptographically sealed signatures
- **Envelopes**: Group multiple documents and attachments into a single signing transaction
- **Templates**: Create reusable document templates with pre-defined fields and bulk send
- **Signing Fields**: Signature, initials, name, email, date, text, number, radio, checkbox, and dropdown fields
- **Recipients & Signing Order**: Assign roles (signer, CC, viewer) and sequential signing workflows
- **Direct Links**: Tokenized public signing links, no account required for signers
- **Folders & Audit Trail**: Organize documents; every action recorded for compliance
- **Teams & Organizations**: Multi-tenant workspaces with role-based access and invites
- **Webhooks**: Real-time notifications for document lifecycle events
- **Per-Org OIDC**: Organization-scoped SSO portals
- **Hanzo IAM SSO**: Single sign-on via Hanzo identity
@@ -21,8 +27,9 @@ Hanzo Sign is a document signing platform for creating, sending, and managing le
| Environment | URL |
|-------------|-----|
| Production | `https://sign.hanzo.ai` |
| API | `https://sign.hanzo.ai/api/v1` |
| Production | `https://esign.hanzo.ai` |
| API (stable) | `https://eesign.hanzo.ai/api/v1` |
| API (v2, tRPC) | `https://esign.hanzo.ai/api/v2` |
## Architecture
@@ -55,7 +62,7 @@ Hanzo Sign is a document signing platform for creating, sending, and managing le
Upload a PDF and add recipients:
```typescript
const response = await fetch('https://sign.hanzo.ai/api/v1/documents', {
const response = await fetch('https://esign.hanzo.ai/api/v1/documents', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiToken}`,
@@ -74,7 +81,7 @@ const response = await fetch('https://sign.hanzo.ai/api/v1/documents', {
### 2. Add Signing Fields
```typescript
await fetch(`https://sign.hanzo.ai/api/v1/documents/${docId}/fields`, {
await fetch(`https://esign.hanzo.ai/api/v1/documents/${docId}/fields`, {
method: 'POST',
headers: { 'Authorization': `Bearer ${apiToken}` },
body: JSON.stringify({
@@ -90,7 +97,7 @@ await fetch(`https://sign.hanzo.ai/api/v1/documents/${docId}/fields`, {
### 3. Send for Signing
```typescript
await fetch(`https://sign.hanzo.ai/api/v1/documents/${docId}/send`, {
await fetch(`https://esign.hanzo.ai/api/v1/documents/${docId}/send`, {
method: 'POST',
headers: { 'Authorization': `Bearer ${apiToken}` }
})
@@ -101,20 +108,23 @@ await fetch(`https://sign.hanzo.ai/api/v1/documents/${docId}/send`, {
| Type | Description |
|------|-------------|
| `SIGNATURE` | Electronic signature |
| `FREE_SIGNATURE` | Free-form drawn signature |
| `INITIALS` | Signer initials |
| `TEXT` | Free text input |
| `NAME` | Signer name |
| `EMAIL` | Signer email |
| `DATE` | Date picker |
| `CHECKBOX` | Boolean checkbox |
| `DROPDOWN` | Select from options |
| `TEXT` | Free text input |
| `NUMBER` | Numeric input |
| `RADIO` | Radio button group |
| `CHECKBOX` | Boolean checkbox |
| `DROPDOWN` | Select from options |
## Webhooks
### Configure Webhook
```typescript
await fetch('https://sign.hanzo.ai/api/v1/webhooks', {
await fetch('https://esign.hanzo.ai/api/v1/webhooks', {
method: 'POST',
headers: { 'Authorization': `Bearer ${apiToken}` },
body: JSON.stringify({
@@ -145,14 +155,16 @@ Hanzo Sign supports multiple authentication methods:
- **Hanzo IAM**: SSO via `https://hanzo.id` (recommended)
- **Google OAuth**: Sign in with Google
- **Email Magic Link**: Passwordless email login
- **Passkeys**: WebAuthn/FIDO2 authentication
- **Microsoft OAuth**: Sign in with Microsoft / Azure AD
- **Generic OIDC**: Any OpenID Connect provider
- **Email & Password**: Native accounts (signup can be disabled for closed deployments)
- **Passkeys**: WebAuthn/FIDO2 authentication, plus optional 2FA
### IAM Integration
```bash
# Environment variables
IAM_ENDPOINT=https://hanzo.id
IAM_URL=https://hanzo.id
IAM_CLIENT_ID=app-sign
IAM_CLIENT_SECRET=<from-kms>
```
@@ -166,9 +178,9 @@ docker run -d \
--name hanzo-sign \
-p 3000:3000 \
-e DATABASE_URL=postgres://... \
-e IAM_ENDPOINT=https://hanzo.id \
-e IAM_URL=https://hanzo.id \
-e IAM_CLIENT_ID=app-sign \
ghcr.io/hanzoai/sign:latest
ghcr.io/hanzoai/esign:latest
```
### Environment Variables
@@ -177,7 +189,7 @@ docker run -d \
|----------|-------------|
| `DATABASE_URL` | PostgreSQL connection string |
| `NEXT_PUBLIC_WEBAPP_URL` | Public URL of the application |
| `IAM_ENDPOINT` | Hanzo IAM server URL |
| `IAM_URL` | Hanzo IAM server URL |
| `IAM_CLIENT_ID` | IAM application client ID |
| `IAM_CLIENT_SECRET` | IAM application client secret |
| `NEXT_PRIVATE_ENCRYPTION_KEY` | Document encryption key |
@@ -187,6 +199,11 @@ docker run -d \
## API Reference
Hanzo Sign exposes two API surfaces:
- **`/api/v1`** — the stable REST API (contract-based), authenticated with a Bearer API token. The endpoints below are on this surface.
- **`/api/v2`** and **`/api/v2-beta`** — the current tRPC API with an auto-generated OpenAPI schema at `/api/v2/openapi.json`. This surface is evolving and covers newer capabilities (envelopes, folders, embedding).
### Documents
- `POST /api/v1/documents` - Create document