Initial import of zapier-user-docs from zapier monorepo
This commit is contained in:
commit
12b639ca61
16 changed files with 298 additions and 0 deletions
19
01-what-you-get.md
Normal file
19
01-what-you-get.md
Normal 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.
|
||||||
23
02-signup-zappier-portal.md
Normal file
23
02-signup-zappier-portal.md
Normal 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
19
03-connect-zapier.md
Normal 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
29
04-register-a-hash.md
Normal 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
22
05-wait-async-hooks.md
Normal 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).
|
||||||
24
06-lookup-central-chain.md
Normal file
24
06-lookup-central-chain.md
Normal 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 else’s **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.
|
||||||
16
07-attachments-and-metadata.md
Normal file
16
07-attachments-and-metadata.md
Normal 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.
|
||||||
17
08-bulk-merkle-summaries.md
Normal file
17
08-bulk-merkle-summaries.md
Normal 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 leaf’s **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
31
09-lookup-tree-nodes.md
Normal 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 **root’s** 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
28
10-reading-receipts.md
Normal 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.
|
||||||
14
11-errors-billing-retries.md
Normal file
14
11-errors-billing-retries.md
Normal 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 Zapier’s step timeout until chain poll interval and archive query window (`WAIT_ARCHIVE_MS`) are measured on NS1.
|
||||||
9
12-security.md
Normal file
9
12-security.md
Normal 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
5
NATS.md
Normal 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
27
README.md
Normal 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
9
SUMMARY.md
Normal 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
6
package.json
Normal 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"
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue