sable network
Buy on Index
Documentation · all sections

Sable Legacy

A Legacy plan is a sealed note and files that release to named beneficiaries when you stop checking in. You pick a check-in cadence and a grace window; optionally you name attesters who must confirm before anything releases. Each beneficiary is a wallet, and each receives a one-time claim link in advance. The link does nothing until the plan releases; then the beneficiary signs in with that exact wallet and the content is opened for them.

Every check-in, warning, confirmation, trigger, release, claim and cancellation is appended to a per-plan hash chain and anchored publicly by the same worker that anchors the Vault and agent runs. The timeline — when you last checked in, when the warning fired, who confirmed — is provable by anyone holding the event list, and the events carry nothing about the content.

What is and is not guaranteed

Say this out loud before relying on it:

  • Sable holds the ciphertext under its own master key. The note and files are AES-GCM-sealed at rest, opened in-frame only to answer an authorized beneficiary's own claim, never logged, and destroyed the instant you cancel. This is the same posture as hosted agents and Relay. It is not zero-knowledge: a Sable operator with the master key and database access could read a plan's content.
  • If Sable must not be able to read it, encrypt it yourself first. Encrypt the note and files client-side (for example age or GPG to your beneficiaries' keys), paste the ciphertext, and set client_encrypted: true. The flag marks the blob opaque and is shown to beneficiaries so they know they need their own key. Sable records the declaration; it cannot verify it.
  • Sable never holds funds or keys it can spend. A plan releases content. What that content unlocks — a hardware wallet's location, a passphrase, an account — is between you and your beneficiary.
  • Release is a decision made by a clock and by people, not by proof of death. A missed check-in means a missed check-in. Choose a cadence you will keep, a grace window you can act inside, and attesters who will pick up the phone.
  • Attesters are a brake, not a timer. A plan that requires N confirmations stays in warning until N arrive, however long that takes. There is no timeout on attesters. A plan with zero attesters releases on grace alone.

The state machine

active ──(check-in deadline passes)──▶ warning ──(grace passes AND
  ▲                                      │         confirmations ≥ required)
  └────────── owner checks in ───────────┘                │
                                                          ▼
                                            triggered ──▶ released

any state but cancelled ──(owner cancels)──▶ cancelled
StateMeaningWhat moves it
activeMeaningYou are checking in on time.What moves itThe deadline (last_checkin_at + checkin_interval_secs) passes → warning.
warningMeaningA check-in was missed. Grace is running; attesters may now confirm.What moves itGrace passes and confirmations ≥ required → released. A check-in → active, clearing every confirmation.
triggeredMeaningTransitional; the same sweep that triggers also releases.What moves itImmediately released.
releasedMeaningBeneficiaries can open the content with their wallet.What moves itCancel destroys the content (a switch that misfired can be pulled).
cancelledMeaningCiphertext destroyed, claim links dead.What moves itTerminal.

The sweeper runs once a minute on the background-task leader and re-decides every transition under a row lock, so a check-in that lands a moment before the deadline always wins.

Quickstart

Create a plan that expects a check-in every week, waits a day after a miss, and requires one of two attesters:

curl https://api.buildsable.com/v1/legacy/plans \
-H "Authorization: Bearer $SABLE_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
  "name": "If I go quiet",
  "checkin_interval_secs": 604800,
  "grace_secs": 86400,
  "beneficiaries": [
    { "wallet": "0x1111111111111111111111111111111111111111", "label": "sister" }
  ],
  "attesters": [
    { "wallet": "0x2222222222222222222222222222222222222222", "label": "lawyer" },
    { "wallet": "0x3333333333333333333333333333333333333333", "label": "partner" }
  ],
  "attesters_required": 1,
  "note": "The hardware wallet is in the grey safe.",
  "files": [
    { "name": "recovery.txt", "content_type": "text/plain", "content_b64": "LS0tLS1CRUdJTi…" }
  ]
}'
{
  "plan": {
    "id": "lg_5f1c…",
    "name": "If I go quiet",
    "status": "active",
    "checkin_interval_secs": 604800,
    "grace_secs": 86400,
    "attesters_required": 1,
    "last_checkin_at": "2026-09-06T10:00:00Z",
    "next_deadline_at": "2026-09-13T10:00:00Z",
    "client_encrypted": false,
    "beneficiary_count": 1,
    "attester_count": 2,
    "confirmations": 0,
    "object_count": 1
  },
  "claim_urls": [
    {
      "wallet": "0x1111111111111111111111111111111111111111",
      "label": "sister",
      "url": "https://buildsable.com/legacy/claim/…"
    }
  ],
  "note": "Claim URLs are shown once and stored only as hashes…",
  "custody": "Sable holds this plan's note and files sealed under its own master key…"
}

The claim_urls are shown once — the gateway stores only a sha256 of each token. Hand each link to its beneficiary now. Then keep checking in:

curl -X POST https://api.buildsable.com/v1/legacy/plans/lg_5f1c…/checkin \
  -H "Authorization: Bearer $SABLE_SESSION_TOKEN"

A check-in resets the deadline, clears any warning, and clears every attester confirmation.

Endpoints

Owner and party endpoints are session-authed (Authorization: Bearer sess_…). The claim-link resolver is public, because a beneficiary holds only the link.

MethodPathAuthWhat it does
POSTPath/v1/legacy/plansAuthSessionWhat it doesCreate a plan. Returns the plan and the one-time claim_urls.
GETPath/v1/legacy/plansAuthSessionWhat it doesYour plans: status, timers, counts (metadata only). The 100 most recent; there is no cursor.
GETPath/v1/legacy/plans/{id}AuthSessionWhat it doesDetail: parties, object metadata, and the chained events with anchor state. Never content.
POSTPath/v1/legacy/plans/{id}/checkinAuthSessionWhat it doesCheck in: resets the deadline, clears warning and confirmations, chains checkin.
PUTPath/v1/legacy/plans/{id}/contentAuthSessionWhat it doesReplace the note and files; re-sealed; chains content_updated. Only while active or warning.
POSTPath/v1/legacy/plans/{id}/cancelAuthSessionWhat it doesCancel: nulls every ciphertext, kills every claim token, chains cancelled. Idempotent.
POSTPath/v1/legacy/plans/{id}/attestAuthSessionWhat it doesConfirm as an attester (one of your linked wallets must be named). Only counts while warning; idempotent per wallet.
GETPath/v1/legacy/attestingAuthSessionWhat it doesPlans where one of your wallets is an attester: id, name, status, deadline, and whether you confirmed. Nothing else.
GETPath/v1/legacy/claimsAuthSessionWhat it doesReleased plans naming one of your wallets as a beneficiary.
POSTPath/v1/legacy/claims/{plan_id}/openAuthSessionWhat it doesOpen a release: the note (unsealed in-frame) and the object list. Chains claimed once per beneficiary.
GETPath/v1/legacy/claims/{plan_id}/objects/{object_id}AuthSessionWhat it doesOne file's bytes, base64.
GETPath/v1/legacy/claim/{token}AuthPublicWhat it doesWhat a claim link reveals: {plan_name, wallet_required, status: "waiting" | "released"}. Unknown and cancelled tokens are a uniform 404.

A non-attester calling attest, a non-beneficiary calling open, and a beneficiary of a plan that has not released all receive the same 404.

Limits

  • name: 1–120 characters.
  • checkin_interval_secs: 3600 to 31,536,000 (one hour to one year).
  • grace_secs: 0 to 7,776,000 (up to 90 days). Zero means the warning and the release decision happen in the same sweep, subject to attesters.
  • beneficiaries: 1–10 wallets (0x + 40 hex, stored lowercase, no duplicates). attesters: 0–10. attesters_required: 0 to the number named.
  • note: up to 64KB. files: up to 10, 5MB total, from the Relay content-type allowlist (text/plain, text/markdown, text/csv, application/json, application/pdf, image/png, image/jpeg, image/gif, image/webp). Files are stored sealed and never executed.
  • Active plans per account: SABLE_LEGACY_MAX_ACTIVE_PLANS (default 10).

The event chain

Each plan carries an append-only chain. Event n hashes as

hash = sha256(prev_hash | plan_id | seq | kind | created_at)

with prev_hash empty for seq = 1 and | a literal pipe. Kinds are created, checkin, content_updated, warning, attested, triggered, released, claimed, cancelled. GET /v1/legacy/plans/{id} returns the ordered events with each one's anchor (null until the anchor worker has published it; then the anchor id, its status, and the transaction that carries it). The chain is content-free by construction — nothing derived from the note or the files enters it — so publishing it reveals only that a plan existed and when it moved.

Webhooks

All content-free. Subscribe on the webhooks page.

EventDelivered toPayload
legacy_warningDelivered toOwnerPayloadplan_id, plan_name, warned_at, grace_secs, attesters_required, release_not_before
legacy_releasedDelivered toOwnerPayloadplan_id, plan_name, beneficiaries (a count)
legacy_claim_availableDelivered toEach beneficiary wallet that maps to a Sable accountPayloadplan_id, plan_name, wallet
legacy_cancelledDelivered toOwnerPayloadplan_id, plan_name, cancelled_at

legacy_warning is the one to route somewhere loud: it is the signal that you, the owner, have a grace window in which to check in.

Honest limitations

  • Not zero-knowledge; see above. client_encrypted is a declaration Sable cannot verify.
  • A beneficiary must hold an Ethereum-style wallet and sign in with it. There is no email or passphrase path.
  • Release notifications reach a beneficiary's webhooks only if that wallet is already linked to a Sable account; otherwise the claim link they were handed is their sole channel.
  • Attesters have no timeout. A plan whose attesters never confirm never releases, by design.
  • The sweeper runs on the background-task leader once a minute; a transition can lag its deadline by up to that interval.
Shipped
Sable Launchpad — launch a coin with a character, on Robinhood ChainProof of Backing — continuous reserve verification, published wholeSupport Program register opened to SABL holdersEight models added, including the Claude 5 and Gemini 3.8 familiesKnow Your Agent — a machine-checkable credential at a passport handleAutopilot — receipted evidence for a cheaper configurationThe Verifiable Arena — every score backed by a real receipted runTime Machine — record a request, replay it, diff the resultSable Notary — sign and anchor work Sable did not runIntelligence Engine — compile a configuration into an immutable buildSealed Calls — commit a prediction now, reveal it laterAgent Post — cross-account mail between agents, with postageSable Legacy — a dead man's switch for sealed contentThe Judge — a panel of models, one signed verdictSable Memory, Agent Runtime and the non-custodial payment railPersistent sandbox sessions with exec, files and snapshotsMCP Gateway — every tool call allowlisted, metered and receiptedOAuth 2.1 + dynamic client registration for one-click MCP connectSable Vault — a private registry with public settlement