API,
for verifiable trust.
Reference endpoints for timestamping, signature verification, range-proof verification, and issuer-gated partner Auth.
Reference endpoints for timestamping, signature verification, range-proof verification, and issuer-gated partner Auth.
Integrate timestamping, browser-generated proofs, signing, and issuer-gated partner Auth. Public timestamp endpoints remain account-free.
Public timestamp endpoints do not require accounts or API keys. Claim creation requires an Ed25519 signature plus a challenge proof-of-work, and rate limits apply. Production Auth challenge creation is unavailable until a trusted issuer and an exact client redirect allowlist are configured.
Receipt lists are client-side. Persist receipts in your app (localStorage, extension storage, or your database). GET /receipts/:pubkey returns 410 Gone. Use GET /proof/:receiptId for individual verification.
Create a short-lived hosted Auth challenge after trusted issuer support and the client are configured. redirectUri must exactly match the client's server-side allowlist. Redirect only to the loginUrl returned by this endpoint.
{
"clientId": "hemsted_prod",
"redirectUri": "https://hemsted.se/auth/callback",
"scope": ["identity"],
"state": "opaque-csrf-state"
}
GET /api/v1/auth/challenge/:id, POST /api/v1/auth/prove, POST /api/v1/auth/verify, and GET /api/v1/auth/userinfo.
Get a challenge nonce and difficulty for claim proof-of-work. Challenges are single-use and expire server-side.
{
"challenge": "a1b2c3d4e5f6...",
"difficulty": 16,
"expires": "2026-05-19T12:15:00.000Z"
}
Submit a signed hash for timestamping.
{
"hash": "sha256-hex-of-content",
"signature": "ed25519-signature-hex",
"pubkey": "ed25519-public-key-hex",
"pow": {
"challenge": "challenge-from-/challenge",
"nonce": "nonce-that-meets-difficulty"
},
"filename": "optional-display-name.pdf",
"notify_email": "[email protected]",
"notify_webhook": "https://your.app/hooks/otrust",
"notify_webhook_secret": "optional-hmac-secret"
}
notify_email triggers a one-time Bitcoin confirmation email (stored separately, deleted after send). notify_webhook must be HTTPS; OTRUST POSTs once on confirm with optional X-OTRUST-Signature HMAC. See webhook docs.
{
"status": "ok",
"timestamp": "2026-05-19T12:00:00.000Z",
"receipt_id": "ot_abc123xyz",
"blockchain_status": "submitted",
"ots_proof": true
}
Submit up to 100 signed hashes with one proof-of-work challenge.
{
"pow": { "challenge": "...", "nonce": "..." },
"claims": [
{
"hash": "sha256-hex",
"signature": "ed25519-signature-hex",
"pubkey": "ed25519-public-key-hex"
}
],
"notify_email": "[email protected]",
"notify_webhook": "https://your.app/hooks/otrust"
}
One notify_email / notify_webhook applies to all newly created receipts in the batch.
Check whether a SHA-256 hash has timestamp claims in OTRUST.
{
"hash": "sha256-hex-of-content"
}
{
"status": "found",
"hash": "sha256-hex",
"claims": [
{
"receipt_id": "ot_abc123xyz",
"pubkey": "ed25519-public-key-hex",
"timestamp": "2026-05-19T12:00:00.000Z",
"blockchain_confirmed": false,
"proof_url": "/proof/ot_abc123xyz"
}
]
}
Verify up to 100 hashes in one request.
{
"hashes": ["sha256-hex-1", "sha256-hex-2"]
}
{
"status": "ok",
"results": [
{ "hash": "...", "status": "found", "claims": [] },
{ "hash": "...", "status": "not_found" }
]
}
Public transparency metrics: records, anchored claims, activity counters, latest Bitcoin block. See also Trust Log.
Compact stats for embed widgets (/embed). Cached 5 minutes.
{
"service": "OTRUST",
"anchored_records": 1234,
"latest_block": 912345,
"updated_at": "2026-07-04T12:00:00.000Z"
}
Browser-friendly lookup for a SHA-256 hash. Prefer POST /verify when you want to keep hashes out of URLs and logs.
{
"status": "found",
"claims": []
}
Removed. Always returns 410 Gone with error: "local_history_only". Store receipt IDs client-side when you create timestamps.
Return a human-readable timestamp record page by default. Add ?format=json for metadata or ?format=ots to download the raw OpenTimestamps receipt.
{
"status": "pending",
"receipt_id": "ot_abc123xyz",
"hash": "sha256-hex",
"download_url": "/proof/ot_abc123xyz?format=ots"
}
Verify that an Ed25519 signature matches a hash and public key.
{
"hash": "sha256-hex-of-content",
"signature": "ed25519-signature-hex",
"pubkey": "ed25519-public-key-hex"
}
Verify a SHA-256 hash against a base64 OpenTimestamps receipt payload.
{
"hash": "sha256-hex-of-content",
"ots_proof": "base64-encoded-ots-file"
}
Complete example using curl:
# 1. Hash your file locally
HASH=$(sha256sum document.pdf | cut -d' ' -f1)
# 2. Sign the hash with your Ed25519 key
# 3. Submit the claim
curl -X POST https://www.otrust.eu/claim \
-H "Content-Type: application/json" \
-d '{"hash":"'$HASH'","signature":"...","pubkey":"...","pow":{"challenge":"...","nonce":"..."}}'
# 4. Check status
curl https://www.otrust.eu/proof/ot_abc123xyz?format=json
# 5. Download OTS receipt
curl https://www.otrust.eu/proof/ot_abc123xyz?format=ots \
-o document.pdf.ots
When using /sign/upload, certain file types are blocked for security reasons.
Server-executable files that could pose security risks:
| Category | Extensions |
|---|---|
| Windows Executables | .exe .dll .bat .cmd .com .msi .scr |
| Shell Scripts | .sh .bash .zsh .csh |
| PHP | .php .php3 .php4 .php5 .phtml .phar |
| ASP.NET | .asp .aspx .ashx .asmx .ascx |
| Java Server | .jsp .jspx .jsf .jspa .jar .war .ear |
| CGI/Config | .cgi .htaccess .htpasswd |
| Legacy | .swf .fla |
All other file types are allowed, including:
| Category | Extensions |
|---|---|
| Documents | .pdf .doc .docx .odt .txt .rtf .md |
| Images | .png .jpg .jpeg .gif .webp .svg .bmp .tiff |
| Source Code | .js .ts .py .rb .go .rs .c .cpp .java .cs |
| Data Files | .json .xml .yaml .yml .csv .toml |
| Archives | .zip .tar .gz .7z .rar |