Initial import of zapier-user-docs from zapier monorepo

This commit is contained in:
George Lambert 2026-09-11 15:00:04 -04:00
commit e14b047938
16 changed files with 298 additions and 0 deletions

19
01-what-you-get.md Normal file
View file

@ -0,0 +1,19 @@
# 1. What you get
Verae Time proves that a SHA-256 existed at a given time. Zapier lets you do that from the tools you already use (Drive, email, CRM, forms) without writing HTTP clients.
Three kinds of proof:
| Proof | Where it lives | Zapier search |
|-------|----------------|---------------|
| **Itemized seal** | Main Verae chain (`api.veraetime.net`) | Find Timestamp by SHA256 |
| **Bulk Merkle root** | Main chain, one seal for many items | Create Batch Timestamps |
| **Leaf inclusion** | External tree-node archives (NATS, never Zapier) | Find Hash (tree nodes + central chain) |
You also get:
- A **zappier** customer portal: account, API key, usage, invoices, prepaid balance.
- A **Zapier** integration: creates, searches, and a “timestamp completed” trigger.
- Optional **public metadata**, **encrypted private metadata**, and **file attachments** stored on WORM archives — not on the blockchain.
Zapier talks **HTTPS only** to zappier-edge. zappier meters the call and forwards to Verae middleware. Middleware talks to the chain and, when asked, to archive/tree-node NATS servers. You never configure NATS in Zapier.

View file

@ -0,0 +1,23 @@
# 2. Sign up for a Verae / zappier account
You need an API key **before** you can connect Zapier.
1. Open the customer portal (`/portal` on the zappier host your operator gave you).
2. Choose **Create an account**.
3. Enter name, email, and a password of at least 8 characters.
4. You start on the **Free** plan and receive an **API key immediately**.
5. Copy the key. It is sent as `x-api-key` on every Zapier request.
If your company already created an account (you received a key by email), sign up with the **same email**. The existing plan and key are kept; your password is attached to that account.
## After signup
- **Dashboard** — usage this month, included credit, billable overage, prepaid balance.
- **API & pricing** — live rate card (free / fixed / variable per operation, including batch).
- **Invoices** — draft / issued / paid.
- **Billing** — reload $1$10,000; prepaid is drawn down automatically.
- **Security** — optional 2FA.
Regenerating the API key **invalidates the old one immediately**. Update the Zapier authentication field or every Zap step will 401.
Simulator: action **Sign up (zappier portal)** then **Connect Zapier app**.

19
03-connect-zapier.md Normal file
View file

@ -0,0 +1,19 @@
# 3. Connect the Zapier app
1. Sign in at [zapier.com](https://zapier.com) (or your Zapier workspace).
2. Create a Zap → add **Verae Time** (or **Verae Activate** while the full app is in private invite).
3. When Zapier asks for authentication, paste:
- **API key** from the zappier portal.
- **API base URL** if the operator asked you to (hosted edge). Leave blank only for local-mock Activate steps that do not hit the chain.
4. Click **Test**. Zapier calls zappier-edge over HTTPS (`whoami` / a cheap GET). You should see your email and plan. A 401 means the key was regenerated or mistyped.
You do **not** enter NATS URLs, Verae JWT, or `api.veraetime.net` credentials. Those stay on middleware.
## Plans
| Plan | Typical access |
|------|----------------|
| Free | Single timestamp, lookup, Add Numbers / Echo / SHA256 helpers |
| Paid | Batch timestamps, wait-for-certificate, attached metadata, tree-node lookup |
A 403 `PLAN_UPGRADE_REQUIRED` means that Zap step is paid-only. A 402 means you exhausted included credit — reload in the portal (the error should include an upgrade URL).

29
04-register-a-hash.md Normal file
View file

@ -0,0 +1,29 @@
# 4. Register a SHA-256 (create timestamp)
Two Zapier **creates**:
| Action | What happens | What you get back |
|--------|----------------|-------------------|
| **Create Timestamp (async)** | Submit hash, return immediately | `jobId`, `sha256`, `existing` |
| **Create Timestamp and Wait** | Submit hash, hold the Zap step until the certificate exists (or timeout) | `status`, `receipts[]`, `completedAt` |
## Inputs
- **Data** — raw text/bytes. Middleware hashes it with SHA-256. Prefer this when the previous Zap step has the document contents.
- **SHA256** — 64 hex characters if you already hashed the file outside Zapier (recommended for large files: hash locally, send only the digest).
- **Hash algorithm**`SHA256` (default).
Do not send the whole PDF to the blockchain. Only the digest is sealed.
## Already registered
If that SHA-256 was sealed before, you get the **original** `jobId` and certificate. A second chain write is not created. `existing: true`.
## Example Zap
1. Trigger: “New file in Google Drive”.
2. Action (optional): compute SHA-256 in a Code step, or pass file contents as **Data**.
3. Action: **Create Timestamp and Wait**.
4. Action: store `jobId`, `sha256`, and certificate in your sheet/CRM.
Simulator: scenario **Register** (wait + `includeAttached`).

22
05-wait-async-hooks.md Normal file
View file

@ -0,0 +1,22 @@
# 5. Wait, async, and completed hooks
Timestamping is not always instant. Middleware publishes `verae.zapier.jobs.watch`; a poller waits on the chain; then `verae.zapier.jobs.events` fires. Zapier never sees those subjects.
## Choose a pattern
| Pattern | Use when |
|---------|----------|
| **Wait** | The next Zap step needs the certificate now (Slack message, PDF receipt). |
| **Async + Find Job Status** | You stored `jobId` and will poll later. |
| **Timestamp Completed trigger** | You want a second Zap to run when the seal exists (REST Hook). |
If **Wait** returns `status: pending`, the chain or NATS event did not finish inside `WAIT_TIMEOUT_MS`. Pair async creates with the **Timestamp Completed** trigger instead of raising the timeout blindly.
## Trigger setup
1. New Zap → Verae Time → **Timestamp Completed**.
2. Zapier registers a REST Hook URL with middleware (`/zapier/v1/webhooks/subscribe`).
3. When `jobs.events` says `timestamp.completed`, middleware HTTPS POSTs that URL.
4. Turning the Zap off unsubscribes the hook.
The hook payload is the same completed-job JSON as wait (seal receipt, optional attached metadata).

View file

@ -0,0 +1,24 @@
# 6. Look up a hash on the central Verae chain
Zapier search: **Find Timestamp by SHA256**.
Middleware: `GET /zapier/v1/hashes/{sha256}`.
This asks the **main Verae chain** (or its mock) whether that digest was **itemized** as its own seal.
| Result | Meaning |
|--------|---------|
| One record, `exists: true`, `itemizedOnMainChain: true` | This hash has its own certificate. Use `jobId` / `receipts[0]`. |
| Empty / `exists: false` | Not itemized on the main chain. It may still exist as a **leaf** of a bulk summary — use [tree-node lookup](09-lookup-tree-nodes.md). |
Searches in Zapier must return a list. Zero hits is a miss (the Zap can follow the “not found” path). Errors other than 404 fail the step.
## When central lookup is the right tool
- You registered with **Create Timestamp** (single item).
- You stored the `sha256` from that Zap and want to confirm the seal later.
- You are verifying someone elses **itemized** hash (they gave you 64 hex chars that they sealed individually).
## When it is the wrong tool
- The hash was submitted in **Create Batch Timestamps**. The chain stored the Merkle **root**, not this leaf. Central lookup will miss. Continue to tree nodes.

View file

@ -0,0 +1,16 @@
# 7. Attachments and metadata (not on chain)
The blockchain stores hash + time + certificate. Everything else is **off-chain WORM**:
| Field | Chain | Archive (`verae.archive.put`) |
|-------|-------|-------------------------------|
| SHA-256 | yes | key |
| Public metadata JSON | no | `kind: publicMeta` |
| Encrypted private metadata | no | `kind: privateMeta` |
| File bytes | no | `kind: file` + `contentSha256` |
Set **includeAttached** on wait/lookup when you need those records back. Middleware then broadcasts `verae.archive.query`. Each archive uses a bloom filter: **if it does not have the hash, it sends nothing**. Archives that have data reply; the aggregator merges them into `receipts[]` and `files[]`.
Bloom false positives are possible (empty reply after a maybe). False negatives must be rare.
Private metadata is only returned on authenticated archive replies. Zapier still never talks to NATS; it only sees the JSON middleware built.

View file

@ -0,0 +1,17 @@
# 8. Bulk Merkle summaries
**Create Batch Timestamps** takes one payload per line (or an `items[]` array).
Middleware:
1. SHA-256 each item (leaf).
2. Build a Merkle tree.
3. Seal **only the root** on the main Verae chain (one certificate, one `jobId`).
4. Put each leafs **inclusion proof** on a sharded **tree-node** archive (`kind: tree`).
5. Return `jobId`, `merkleRoot`, `leafCount`, and the leaf hashes.
Those member hashes are **not individually itemized** on the main chain. Looking them up with **Find Timestamp by SHA256** returns empty. That is expected.
Why batch: one chain write for thousands of documents, cheaper and faster, while each document can still prove inclusion later via its proof + the root certificate.
Simulator: scenario **Batch Merkle**, then copy the first leaf into the SHA256 field.

31
09-lookup-tree-nodes.md Normal file
View file

@ -0,0 +1,31 @@
# 9. Look up a hash on tree-node archives
Zapier search: **Find Hash (tree nodes + central chain)**.
Middleware: `GET /zapier/v1/hashes/{sha256}?includeAttached=true&includeTree=true`.
## Sequence (you never configure this)
1. Central chain lookup (same as chapter 6).
2. If itemized, return that seal (and attached metadata if requested).
3. If miss, middleware broadcasts `verae.archive.query` with `kinds: ["tree", …]` to **every** tree-node NATS server.
4. A node whose bloom filter does not contain the hash **stays silent**.
5. A node that holds the leaf replies on `verae.archive.reply.<correlationId>` with `{ merkleRoot, proof, leafIndex, chainSealJobId }`.
6. Middleware checks the proof against the root, loads the **roots** chain seal, and returns both receipts.
## Reading the result in a Zap
- `exists: true` and `itemizedOnMainChain: false` — this hash was in a bulk summary.
- `proofOk: true` — the leaf really is under `merkleRoot`.
- `receipts` includes `kind: seal` (of the root) and `kind: tree-leaf` (the proof).
- `archiveId` tells you which tree node answered (for support).
If every node is silent, the hash is unknown **or** the archive fleet is down. The simulator flags “all archives silent” when puts were known to exist; operators should treat that as an outage, not a miss.
## Zap pattern
1. Search: Find Hash (tree nodes + central chain).
2. Filter / Paths:
- Found + itemized → treat as a first-class seal.
- Found + not itemized → store Merkle proof + root certificate.
- Not found → optionally **Create Timestamp** to itemize it now.

28
10-reading-receipts.md Normal file
View file

@ -0,0 +1,28 @@
# 10. Reading receipts
Completed JSON (wait, hook, or lookup):
```json
{
"jobId": "…",
"status": "completed",
"sha256": "…",
"receipts": [
{ "kind": "seal", "timestamp": "…", "certificate": "…", "blockIndex": 42 },
{ "kind": "metadata-attach", "attachedAt": "…", "publicMetadata": {} },
{ "kind": "tree-leaf", "merkleRoot": "…", "proof": [], "itemizedOnMainChain": false }
],
"files": [{ "id": "invoice.pdf", "sha256": "…", "archiveId": "archive-b" }],
"archivesQueried": true,
"archiveReplies": 2
}
```
| `kind` | Meaning |
|--------|---------|
| `seal` | Chain certificate. If `of: merkleRoot`, this seal covers a batch, not the leaf itself. |
| `metadata-attach` | Public or private metadata added later. |
| `file-attach` | Off-chain file (content hash in the record). |
| `tree-leaf` | Inclusion proof for a hash that is not itemized on the main chain. |
**Verify Timestamp** takes a `certificate` string and returns `{ valid, timestamp, blockIndex }`. For a bulk leaf, verify the **root** certificate, then trust the leaf only if `proofOk` is true.

View file

@ -0,0 +1,14 @@
# 11. Errors, billing, retries
| HTTP | Zapier mapping | What you should do |
|------|----------------|--------------------|
| 400 | validation | SHA-256 must be 64 hex chars; supply Data or SHA256. |
| 401 | auth | Re-paste API key; it may have been regenerated. |
| 402 | QuotaExceeded | Reload prepaid credit in the portal (`upgradeUrl` in the error). |
| 403 | PlanUpgradeRequired | Batch / wait / tree lookup may be paid-only. |
| 404 | empty search | Not itemized — try tree-node search before creating a new seal. |
| 504 / pending | timeout | Use the Completed trigger; do not loop wait in the same step. |
Middleware retries `jobs.watch` / `jobs.events` once when NATS drops (simulator: enable **recover**). Zapier itself retries failed HTTP according to your Zap settings — keep creates **idempotent** (re-registering the same hash returns the original seal).
Delays: if the simulator flags hops over 200ms, do not raise Zapiers step timeout until chain poll interval and archive query window (`WAIT_ARCHIVE_MS`) are measured on NS1.

9
12-security.md Normal file
View file

@ -0,0 +1,9 @@
# 12. Security: what Zapier never sees
- Zapier **never** connects to NATS, tree nodes, WORM archives, or `api.veraetime.net`.
- NS1 `nats-server` stays on **127.0.0.1:4222**. Operators use `scripts/nats-tunnel.sh`; it is not a public bind.
- File bytes and private metadata never go on chain. Private metadata is only on authenticated archive replies.
- API keys are `x-api-key` / Bearer tokens on HTTPS. Treat them like passwords; regenerating kills old Zaps.
- Bloom filters are **not** an access-control list. On a hit, middleware still checks tenant/share before returning private records.
If a trace (simulator or `DEBUG_VERAE`) ever shows a `zapier-platform-app` hop with a `verae.*` subject, that is a bug — do not push the app.

5
NATS.md Normal file
View file

@ -0,0 +1,5 @@
# NATS — zapier-user-docs
This documentation repo does **not** subscribe to NATS. It describes what middleware and tree nodes do so users can choose the right Zapier search.
Users never set NATS URLs in Zapier.

27
README.md Normal file
View file

@ -0,0 +1,27 @@
# Verae Time for Zapier — user guide
How to go from **zero account** to **registering SHA-256 hashes**, **looking them up on the central Verae chain**, and **finding hashes that were only sealed as part of a bulk Merkle summary** on external tree-node archives.
This is the customer-facing guide (signup → Zaps). Developers: see [zapier-docs-master](https://git.georgelambert.org/marchon/zapier-docs-master) and the simulator at [verae-zapier-simulator](https://git.georgelambert.org/marchon/verae-zapier-simulator).
**Live catalog:** https://zapier.georgelambert.org/
**Clone:** `ssh://git@git.georgelambert.org:2223/marchon/zapier-user-docs.git`
## Contents
1. [What you get](01-what-you-get.md)
2. [Sign up for a Verae / zappier account](02-signup-zappier-portal.md)
3. [Connect the Zapier app](03-connect-zapier.md)
4. [Register a SHA-256 (create timestamp)](04-register-a-hash.md)
5. [Wait, async, and completed hooks](05-wait-async-hooks.md)
6. [Look up a hash on the central Verae chain](06-lookup-central-chain.md)
7. [Attachments and metadata (not on chain)](07-attachments-and-metadata.md)
8. [Bulk Merkle summaries](08-bulk-merkle-summaries.md)
9. [Look up a hash on tree-node archives](09-lookup-tree-nodes.md)
10. [Reading receipts](10-reading-receipts.md)
11. [Errors, billing, retries](11-errors-billing-retries.md)
12. [Security: what Zapier never sees](12-security.md)
## Try it without going live
The [interface simulator](https://git.georgelambert.org/marchon/verae-zapier-simulator) is a Zapier-like form plus a trace console. Run **Batch Merkle**, copy a leaf SHA-256, then **Find Timestamp by SHA256** (miss) vs **Find Hash (tree nodes)** (proof).

9
SUMMARY.md Normal file
View file

@ -0,0 +1,9 @@
# zapier-user-docs
**Job:** Teach a customer to sign up, connect Zapier, register SHA-256s, look them up on the central Verae chain, and query tree-node archives for hashes only present in a bulk Merkle summary.
**Expects messages from:** none (static docs).
**Sends messages to:** none.
**Published on:** https://zapier.georgelambert.org/user-docs/

6
package.json Normal file
View file

@ -0,0 +1,6 @@
{
"name": "zapier-user-docs",
"version": "0.1.0",
"private": true,
"description": "Verae Time × Zapier user documentation from signup through hash register, central lookup, and tree-node queries"
}