Guide,
for every workflow.
Reference guides for timestamping, ID, signing, and hosted Auth from quick start to production integration.
Reference guides for timestamping, ID, signing, and hosted Auth from quick start to production integration.
Learn how to use OTRUST for timestamping, document signing, browser-generated range proofs, and issuer-gated Auth flows.
Prove when data existed using blockchain anchoring via OpenTimestamps.
Multi-party document signing with Ed25519 cryptographic signatures.
Generate age and income range proofs locally, then verify them cryptographically.
Issuer-gated hosted Auth. Production challenges stay disabled until a trusted credential issuer is configured.
Timestamp hashing and private range-proof inputs stay in your browser. Signing uses local-first flows where possible.
Use this section as the web entrypoint. Detailed flows live in the dedicated sections: Timestamp, Proof Lab, Sign, and Auth.
Hash locally and anchor record metadata to Bitcoin via OpenTimestamps.
Create multi-party signing records around document hashes.
Generate range proofs locally without submitting the private input.
Integrate issuer-bound Auth after the trusted issuer capability is enabled.
Integrate OTRUST into your applications with official SDKs.
npm install @otrust/sdk
// Timestamp a file
import { timestamp, hashFile } from '@otrust/sdk'
const hash = await hashFile(file)
const result = await timestamp.create(hash)
console.log(result.id) // ot_xxx...
// Verify a timestamp
const verification = await timestamp.verify(hash)
console.log(verification.status) // 'confirmed'
pip install otrust
# Timestamp a file
from otrust import timestamp, hash_file
hash = hash_file("document.pdf")
result = timestamp.create(hash)
print(result.id) # ot_xxx...
# Verify
verification = timestamp.verify(hash)
print(verification.status) # 'confirmed'
| Module | Description |
|---|---|
timestamp | Create and verify blockchain timestamps |
sign | Multi-party document signing |
proof | Privacy-preserving ID packages |
auth | Hosted OTRUST Auth flows |
sha256, hashFile | Hashing utilities |
generateEd25519Keypair | Cryptographic key generation |
npm install @otrust/react
import { TimestampWidget, LoginButton, IDBadge } from '@otrust/react'
// Ready-to-use timestamp widget
<TimestampWidget onSuccess={(id) => console.log(id)} />
// Login with OTRUST button
<LoginButton onAuth={(user) => setUser(user)} />
// Display ID verification badge
<IDBadge id="id_xxx" />
Configure the SDK for custom deployments:
import { configure } from '@otrust/sdk'
configure({
baseUrl: 'https://your-otrust-instance.com',
timeout: 30000,
retries: 3
})
Verify when data existed using Bitcoin blockchain anchoring.
Your receipt list is stored in localStorage in the web tool and in chrome.storage.local in the extension. It is not uploaded to the server and cannot be listed by public key.
GET /receipts/:pubkey returns 410 Gone. Persist receipts client-side when you create them, or use individual /proof/:id URLs for verification.
Multi-party document signing with cryptographic evidence.
Choose local-hash mode or temporary encrypted upload when signers need a download link.
Enter email addresses. Choose parallel or sequential signing.
Each signer generates a keypair and signs the document hash.
The complete signature package is anchored to Bitcoin via OpenTimestamps.
| Mode | Description | Use Case |
|---|---|---|
| Parallel | All parties sign simultaneously | Simple agreements |
| Sequential | Must sign in order | Approval chains |
| Role | Action |
|---|---|
| Signer | Must cryptographically sign |
| Approver | Must approve (doesn't sign) |
| Viewer | Receives copy only |
Create signing requests without leaving your inbox:
Each party receives an email with Sign/Decline buttons.
Generate Groth16 range proofs locally and submit only the proof, public signals, and commitment.
Select an age or income range and enter the private value locally.
The browser uses the published circuit artifacts to create a Groth16 proof.
The result contains the proof, public signals, and commitment, never the private value.
The server verifies the proof before storing it and returning a public verification URL.
| Type | Public statement | Private input |
|---|---|---|
| Age range | The committed age is inside the selected range | Date of birth |
| Income range | The committed income is inside the selected range | Exact income |
The circuits and browser artifacts are reproducible and the server performs Groth16 verification. Production publishing remains fail-closed until the public trusted-setup ceremony is complete.
Until then, local generation and export remain available while the publish endpoint returns a service-unavailable response in production.
Use trusted issuer-bound credentials for challenge-bound partner Auth.
OTRUST Auth is an integration preview until a trusted credential issuer is configured. Production challenge creation fails closed before that capability is enabled.
Your app creates an authentication challenge.
The user is redirected to OTRUST to present an issuer-bound credential.
OTRUST verifies the current issuer binding, credential status, ownership, and challenge binding.
Your app receives a signed token and verifies it server-side before creating a session.
/health reports identity_auth as ready. This requires both a trusted issuer and an exact client redirect allowlist.
// Create hosted Auth challenge
import { auth } from '@otrust/sdk'
const state = auth.generateState()
const challenge = await auth.createChallenge({
clientId: 'my-app',
redirectUri: 'https://yourapp.com/auth/callback',
scope: ['identity'],
state
})
// Redirect user to OTRUST
window.location.href = challenge.loginUrl
// In your callback handler
const result = await auth.verify(token)
if (result.valid) {
console.log(result.proofId) // id_xxx for audit
}
Partners can attach an approved hosted-login theme to a client_id. The theme affects logo, colors, headline, spacing, radius, and footer copy on /auth/login?challenge=....
// Admin/dashboard save
PUT /admin/auth-branding/acme_prod
X-Admin-Key: <admin-key>
{
"logoUrl": "https://example.com/assets/logo.svg",
"backgroundColor": "#F8FAFC",
"primaryColor": "#12324A",
"textColor": "#0F1B2D",
"fontFamily": "Inter",
"borderRadius": 8,
"spacingScale": "default",
"headline": "Start Auth with Acme",
"subhead": "Issuer-bound verification with OTRUST",
"footerText": "Acme uses OTRUST as credential verifier",
"autoRedirectSeconds": 3
}
import { LoginButton } from '@otrust/react'
<LoginButton
scope={['identity']}
onSuccess={(user) => {
console.log(user.verified) // true
console.log(user.proofId) // id_xxx
}}
/>
| Claim | Description | Use Case |
|---|---|---|
identity | User controls a current trusted issuer-bound credential | Issuer-backed account access |
Timestamp any webpage with one click.
Available for Chrome, Chromium browsers (Edge, Brave), and Firefox (load unpacked).
Add to Chrome →chrome://extensions → Developer mode → Load unpackedabout:debugging#/runtime/this-firefox → Load Temporary Add-on → select manifest.jsonClick the OTRUST icon to:
Extension history is separate from the web tool — each browser profile keeps its own list.
Timestamp conversations directly in ChatGPT.
Timestamp emails by sending to timestamp@otrust.eu
Subject, sender, date, body text, and attachment hashes are included in the hash.
Timestamp messages in Telegram and WhatsApp.
Self-host the bot from addons/telegram-bot/ or use @OTRUSTbot when deployed.
/start or /help – Introduction/hash <sha256> – Timestamp a 64-char hash via POST /claim/simple/status – Live anchored stats from /stats/badges.jsonexport TELEGRAM_BOT_TOKEN=...
export OTRUST_API=https://www.otrust.eu
cd addons/telegram-bot && npm start
Enterprise feature requiring Meta Business verification.
Contact hello@otrust.eu for setup.
Command-line interface for automation and scripting.
# Clone and install
git clone https://github.com/otrust-eu/opensource.git
cd opensource
npm install
npm link # Makes 'otrust' command available
# Generate and save keypair
otrust keygen --save
# Timestamp a file or raw hash
otrust claim document.pdf
otrust claim a1b2c3...<64 hex>
# Verify a file or hash
otrust verify document.pdf
# Batch timestamp (max 100 files, one PoW)
otrust bulk ./docs/ --recursive
# Batch verify hashes
otrust verify-bulk ./docs/ -r --json
# Local CLI history (~/.otrust/history.json)
otrust history
otrust history --json
# Export IPFS-ready proof bundle
otrust ipfs-export ot_abc123xyz --out proof-bundle.json
Run otrust help for the full list. Email and webhook notifications are set via the API (notify_email, notify_webhook on POST /claim), not CLI flags.
| Variable | Description |
|---|---|
OTRUST_API | API endpoint (default: https://www.otrust.eu) |
OTRUST_KEY | Path to Ed25519 key file (default: ~/.otrust/key.json) |
OTRUST_HISTORY | Path to local receipt history JSON |
# Bash: timestamp all PDFs
for f in *.pdf; do otrust claim "$f"; done
# CI: batch timestamp release folder
otrust bulk dist/ --json
# Check proof metadata (curl)
curl -s "https://www.otrust.eu/proof/ot_abc123?format=json"
Trust badges, bookmarklets, and server callbacks for Bitcoin confirmation.
Show live anchored-record stats on your site:
<script src="https://www.otrust.eu/js/otrust-embed.js" data-otrust-badge></script>
See /embed for a preview. Data from /stats/badges.json.
<script src="https://www.otrust.eu/js/otrust-embed.js" data-otrust-badge data-otrust-theme="dark"></script>
Public ops view: /status (JSON: /status.json).
Compute HMAC signatures for test payloads: /webhook-test.
Verify the current page without installing an extension. Drag the link from /bookmarklet to your bookmarks bar.
Pass notify_webhook (HTTPS only) and optional notify_webhook_secret on POST /claim, POST /claim/bulk, or POST /claim/simple. When OpenTimestamps confirms on Bitcoin, OTRUST POSTs once and deletes the webhook URL.
{
"event": "bitcoin_confirmed",
"receipt_id": "ot_abc123",
"hash": "sha256-hex",
"block_height": 912345,
"proof_url": "https://www.otrust.eu/proof/ot_abc123",
"ots_url": "https://www.otrust.eu/proof/ot_abc123?format=ots",
"confirmed_at": "2026-07-04T14:00:00.000Z"
}
If notify_webhook_secret is set, verify header X-OTRUST-Signature: sha256=<hmac> (HMAC-SHA256 of the raw JSON body).
Alternatively use notify_email for a one-time confirmation email (deleted after send).
Run the open source OTRUST server, web UI, SDKs, CLI, and circuits from GitHub.
# Clone repository
git clone https://github.com/otrust-eu/opensource.git
cd opensource
# Install workspace dependencies
npm ci
The repository is self-hostable. Private OTRUST production infrastructure, partner themes, and service secrets are not included.
# Configure local environment
cp .env.example .env
# Start OTRUST with persistent SQLite storage
docker compose up -d --build
# Confirm storage and blockchain runtime status
curl -fsS http://localhost:3000/health
# Or run Node directly; data is stored in ./data
npm run dev
OTRUST stores application data in SQLite. OTRUST_DB_PATH defaults to ./data/otrust.sqlite. Docker Compose mounts the otrust_data volume at /app/data, so container rebuilds do not remove the database.
otrust.sqlite.migration.json manifest together after a MongoDB migrationOTRUST_BACKUP_ENABLED=true with private BUCKET_* credentials for automatic S3-compatible backupsVACUUM INTO, SQLite integrity checks, SHA-256 metadata, gzip compression, and configurable retentionstorage.backup in /health and periodically perform an independent restore drillOTRUST_ALLOW_EMPTY_DB=true only for a deliberate fresh production installationStop writes, export each MongoDB collection as Extended JSON, and run a dry run before creating the SQLite database. The destination database must not already exist.
# Validate the export without writing a database
npm run migrate:mongodb-export -- \
--source ./mongo-export \
--db ./data/otrust.sqlite \
--dry-run
# Create and verify the SQLite database
npm run migrate:mongodb-export -- \
--source ./mongo-export \
--db ./data/otrust.sqlite
The migration compares collection counts, record identities, canonical checksums, and SQLite integrity before writing the completion manifest. Follow the MongoDB migration guide for export, cutover, rollback, and backup steps.
The Docker image includes the pinned OpenTimestamps 0.7.2 client and the digest bridge used to timestamp existing SHA-256 hashes. Native Node installations require the ots command and its Python package on PATH.
ENABLE_BLOCKCHAIN=false disables blockchain submissionOTS_CLI_COMMAND and OTS_PYTHON_COMMAND override runtime command paths.env.example/health after startup to verify that the runtime is available# Core crypto tests
npm run test:core
# Build SDK packages
npm run build
# Use the CLI directly
node cli/otrust.js keygen
node cli/otrust.js verify 0000000000000000000000000000000000000000000000000000000000000000
| Package | Use | Default API |
|---|---|---|
sdk-js | Browser and server JavaScript integrations | https://otrust.eu |
sdk-python | Python automation and backend integrations | https://otrust.eu |
cli | Local hashing, signing, timestamping, and verification | https://www.otrust.eu |
The clean open source repository is maintained separately from private production infrastructure.
Open GitHub Technical Changelog