Generate and receive self-contained sharing links for user-owned data
Sharing links let you create self-contained, expiring URLs that give recipients access to specific data in your space — without requiring them to authenticate or have a TinyCloud account.
Under the hood, this string is a base64url-encoded JSON payload containing:
version: Link format version
key: The KV path that was shared
delegation: A signed UCAN delegation granting read access
spaceId: The owner’s space where the data lives
host: The TinyCloud node to contact
embedded private key: A session key for the recipient to authenticate the request
Sharing links contain an embedded private key that grants access to the shared data. Treat them like passwords. Anyone who has the link can read the shared data until the link expires.
import { TinyCloudWeb } from '@tinycloudlabs/web-sdk';const tc = new TinyCloudWeb({ host: 'https://node.tinycloud.xyz', prefix: 'my-app',});await tc.signIn();// Generate a sharing link for a specific keyconst link = await tc.sharing.generate({ key: 'my-document', expiresIn: '7d',});console.log(link);// tc1:eyJ2ZXJz...
// Simple: share a key for 7 daysconst link = await tc.sharing.generate({ key: 'my-document', expiresIn: '7d',});
Copy
const link = await tc.sharing.generate({ // The KV key to share // The recipient will be able to read the data at this key key: 'my-document', // How long the link remains valid // Formats: '1h', '12h', '7d', '30d' // The embedded delegation expires after this duration expiresIn: '7d',});
Recipients can access shared data using the static receiveShare method. This does not require the recipient to have a TinyCloud account or an active session.
import { TinyCloudWeb } from '@tinycloudlabs/web-sdk';const result = await TinyCloudWeb.receiveShare('tc1:eyJ2ZXJz...');if (result.ok) { console.log(result.data.data); // The shared data (parsed value) console.log(result.data.path); // Path that was shared, e.g. "my-document" console.log(result.data.spaceId); // Owner's space ID} else { console.error('Failed to receive share:', result.error);}
import { TinyCloudNode } from '@tinycloudlabs/node-sdk';const result = await TinyCloudNode.receiveShare('tc1:eyJ2ZXJz...');if (result.ok) { console.log(result.data.data); // The shared data console.log(result.data.path); // Shared path console.log(result.data.spaceId); // Owner's space ID}
receiveShare is a static method. You do not need to create a TinyCloud instance or call signIn() to use it. The link contains all the credentials needed to fetch the data.
Anyone who has the link can access the shared data. Do not post sharing links publicly unless you intend for the data to be publicly readable. Use secure channels (direct messages, encrypted email) to distribute links containing sensitive data.
Expiry is enforced server-side
The delegation embedded in the link has a cryptographically signed expiry. The TinyCloud node rejects requests with expired delegations. There is no way to extend the expiry of an existing link — you must generate a new one.
Links are read-only
Generated sharing links only grant read access to the specified key. Recipients cannot modify or delete the shared data through the link.
Links are scoped to a single key
Each link grants access to exactly one KV path. To share multiple keys, generate separate links for each one.
Sharing links respect the delegation expiry set at generation time. Once expired, the link stops working permanently.
Copy
// Short-lived link for sensitive dataconst sensitiveLink = await tc.sharing.generate({ key: 'credentials/api-key', expiresIn: '1h',});// Long-lived link for public contentconst publicLink = await tc.sharing.generate({ key: 'blog/latest-post', expiresIn: '30d',});
Choose expiry durations based on the sensitivity of the data and the use case. For one-time sharing, use short durations like '1h'. For persistent links embedded in documentation or wikis, use longer durations like '30d'.
Alice shares a document with Bob via a link, and Bob reads it without needing a TinyCloud account.
1
Alice stores data and generates a link
Copy
import { TinyCloudNode } from '@tinycloudlabs/node-sdk';const alice = new TinyCloudNode({ host: 'https://node.tinycloud.xyz', prefix: 'my-app', privateKey: process.env.ALICE_PRIVATE_KEY,});await alice.signIn();// Store the documentawait alice.kv.put('docs/meeting-notes', { title: 'Q4 Planning', content: 'We decided to...', date: '2026-01-15',});// Generate a sharing link (valid for 7 days)const link = await alice.sharing.generate({ key: 'docs/meeting-notes', expiresIn: '7d',});console.log('Share this link:', link);// tc1:eyJ2ZXJz...
2
Alice sends the link to Bob
Alice sends the tc1:... link to Bob through any channel — email, chat, or even a QR code.
3
Bob receives the shared data
Copy
import { TinyCloudNode } from '@tinycloudlabs/node-sdk';// Bob does NOT need to signIn or have a private keyconst result = await TinyCloudNode.receiveShare(link);if (result.ok) { console.log(result.data.data); // { title: 'Q4 Planning', content: 'We decided to...', date: '2026-01-15' } console.log(result.data.path); // 'docs/meeting-notes' console.log(result.data.spaceId); // '0xAlice...address-1-my-app'} else { console.error('Share failed:', result.error); // Possible reasons: link expired, data deleted, node unreachable}