[{"data":1,"prerenderedAt":2134},["ShallowReactive",2],{"docs:\u002Fdocs\u002Fquickstart":3,"docs:nav":2095},{"id":4,"title":5,"badge":6,"body":7,"description":54,"extension":2088,"meta":2089,"navigation":266,"order":61,"path":2090,"section":2091,"seo":2092,"stem":2093,"__hash__":2094},"docs\u002Fdocs\u002Fquickstart.md","Quickstart",null,{"type":8,"value":9,"toc":2076},"minimark",[10,14,28,43,48,119,128,131,135,138,171,175,188,217,225,229,241,773,776,804,808,867,1019,1031,1035,1038,1537,1548,1552,1555,1641,1644,1648,1773,1780,1784,1988,1991,1995,2058,2065,2072],[11,12,13],"p",{},"By the end of this page you will have stored an object as 30 encrypted shards on 30 independent\nproviders and read it back from 10 of them.",[11,15,16,17,21,22,27],{},"The path today is the CLI. ",[18,19,20],"code",{},"tessera signup"," creates the account, for an agent or a human. Browser\nsignup is not available. Every new account starts at $0.00 with one upload of up to 40 MiB and one\ndownload — a technical validation. Tessera covers the hosts for that validation. After it, top up\nto continue. Rates and rails are on ",[23,24,26],"a",{"href":25},"\u002Fdocs\u002Faccounts","Accounts & billing",".",[11,29,30,31,34,35,38,39,27],{},"Your network must let the client reach storage providers directly over TCP (siamux, on the port\neach provider announces, usually 9984). HTTPS to ",[18,32,33],{},"tessera.storage"," and ",[18,36,37],{},"index.tessera.storage"," is\nnot enough. Each upload needs 30 reachable providers; each download needs 10 of the providers\nholding the file. See ",[23,40,42],{"href":41},"\u002Fdocs\u002Ferrors#transfer-errors-from-the-cli","Transfer errors",[44,45,47],"h2",{"id":46},"cli","CLI",[49,50,55],"pre",{"className":51,"code":52,"language":53,"meta":54,"style":54},"language-bash shiki shiki-themes github-dark-default github-dark-default","# install — see https:\u002F\u002Ftessera.storage\u002Finstall.sh\ntessera signup --name \"my-agent\"\ntessera upload .\u002Fhello.txt\ntessera download \u003Cobject-id> .\u002Fhello.txt\n","bash","",[18,56,57,66,84,95],{"__ignoreMap":54},[58,59,62],"span",{"class":60,"line":61},"line",1,[58,63,65],{"class":64},"sI3U9","# install — see https:\u002F\u002Ftessera.storage\u002Finstall.sh\n",[58,67,69,73,77,81],{"class":60,"line":68},2,[58,70,72],{"class":71},"sAxfE","tessera",[58,74,76],{"class":75},"skZ57"," signup",[58,78,80],{"class":79},"sEQcL"," --name",[58,82,83],{"class":75}," \"my-agent\"\n",[58,85,87,89,92],{"class":60,"line":86},3,[58,88,72],{"class":71},[58,90,91],{"class":75}," upload",[58,93,94],{"class":75}," .\u002Fhello.txt\n",[58,96,98,100,103,107,110,114,117],{"class":60,"line":97},4,[58,99,72],{"class":71},[58,101,102],{"class":75}," download",[58,104,106],{"class":105},"srH4v"," \u003C",[58,108,109],{"class":75},"object-i",[58,111,113],{"class":112},"sb7RM","d",[58,115,116],{"class":105},">",[58,118,94],{"class":75},[11,120,121,123,124,127],{},[18,122,20],{}," prints a recovery phrase and an API key once. Keep both. On a new machine,\n",[18,125,126],{},"tessera login \"\u003C12 words>\""," restores the same account. Tessera cannot recover a lost phrase.",[11,129,130],{},"The CLI is the supported path. The walkthrough below is the same calls the CLI makes, if you are\nwriting your own client.",[44,132,134],{"id":133},"before-you-start","Before you start",[11,136,137],{},"The raw API needs a runtime that can speak the storage transfer protocol to providers directly.\nTessera does not proxy object bytes. That means a server-side runtime — Bun, Node, Go, or Python —\nnot a browser.",[49,139,141],{"className":51,"code":140,"language":53,"meta":54,"style":54},"bun add @noble\u002Fhashes @noble\u002Fcurves\nexport TESSERA_API=\"https:\u002F\u002Findex.tessera.storage\"\n",[18,142,143,157],{"__ignoreMap":54},[58,144,145,148,151,154],{"class":60,"line":61},[58,146,147],{"class":71},"bun",[58,149,150],{"class":75}," add",[58,152,153],{"class":75}," @noble\u002Fhashes",[58,155,156],{"class":75}," @noble\u002Fcurves\n",[58,158,159,162,165,168],{"class":60,"line":68},[58,160,161],{"class":105},"export",[58,163,164],{"class":112}," TESSERA_API",[58,166,167],{"class":105},"=",[58,169,170],{"class":75},"\"https:\u002F\u002Findex.tessera.storage\"\n",[44,172,174],{"id":173},"_1-get-a-credential","1 — Get a credential",[11,176,177,178,180,181,34,184,187],{},"Use ",[18,179,20],{}," (above) to obtain ",[18,182,183],{},"app_id",[18,185,186],{},"app_key"," — there is no separate provisioning\nendpoint for the raw API; it uses the same credential your CLI config.json holds.",[49,189,191],{"className":51,"code":190,"language":53,"meta":54,"style":54},"export TESSERA_APPKEY=\"\u003Cyour 128-hex app_key>\"\nexport TESSERA_CREDENTIAL=\"\u003Cyour app_id>\"\n",[18,192,193,205],{"__ignoreMap":54},[58,194,195,197,200,202],{"class":60,"line":61},[58,196,161],{"class":105},[58,198,199],{"class":112}," TESSERA_APPKEY",[58,201,167],{"class":105},[58,203,204],{"class":75},"\"\u003Cyour 128-hex app_key>\"\n",[58,206,207,209,212,214],{"class":60,"line":68},[58,208,161],{"class":105},[58,210,211],{"class":112}," TESSERA_CREDENTIAL",[58,213,167],{"class":105},[58,215,216],{"class":75},"\"\u003Cyour app_id>\"\n",[218,219,222],"app-callout",{"title":220,"tone":221},"`app_key` is yours alone","warn",[11,223,224],{},"It is your ed25519 private key. We do not store a recoverable copy, so if you lose it, everything\nstored under it is unreachable — by you and by us. Put it in a secret manager now, before you write\nany data.",[44,226,228],{"id":227},"_2-sign-a-request","2 — Sign a request",[11,230,231,232,235,236,240],{},"Every other endpoint needs three signed query parameters. Copy ",[18,233,234],{},"signRequest"," from\n",[23,237,239],{"href":238},"\u002Fdocs\u002Fauthentication","Authentication"," — the construction has enough sharp edges that reading that\npage is genuinely faster than guessing.",[49,242,246],{"className":243,"code":244,"language":245,"meta":54,"style":54},"language-ts shiki shiki-themes github-dark-default github-dark-default","import { signRequest } from '.\u002Fsign'\n\nconst API = new URL(process.env.TESSERA_API!)\nconst cred = {\n  appKey: process.env.TESSERA_APPKEY!,\n  credential: process.env.TESSERA_CREDENTIAL!,\n}\n\nasync function call(method: string, path: string, body?: unknown) {\n  const raw = body === undefined ? null : new TextEncoder().encode(JSON.stringify(body))\n  const params = signRequest(cred, method, API.host, path, raw)\n\n  const res = await fetch(`${API.origin}${path}?${params}`, {\n    method,\n    headers: raw ? { 'content-type': 'application\u002Fjson' } : undefined,\n    body: raw,\n  })\n\n  const text = await res.text()\n  if (!res.ok) throw new Error(`${method} ${path} → ${res.status}: ${text}`)\n  \u002F\u002F Some endpoints answer 200 with a JSON error object rather than an error status.\n  const parsed = text ? JSON.parse(text) : null\n  if (parsed && typeof parsed === 'object' && 'error' in parsed) {\n    throw new Error(`${method} ${path} → ${parsed.error}`)\n  }\n  return parsed\n}\n","ts",[18,247,248,262,268,298,310,324,337,343,348,396,449,471,476,521,527,557,563,569,574,595,648,654,685,719,753,759,768],{"__ignoreMap":54},[58,249,250,253,256,259],{"class":60,"line":61},[58,251,252],{"class":105},"import",[58,254,255],{"class":112}," { signRequest } ",[58,257,258],{"class":105},"from",[58,260,261],{"class":75}," '.\u002Fsign'\n",[58,263,264],{"class":60,"line":68},[58,265,267],{"emptyLinePlaceholder":266},true,"\n",[58,269,270,273,276,279,282,286,289,292,295],{"class":60,"line":86},[58,271,272],{"class":105},"const",[58,274,275],{"class":79}," API",[58,277,278],{"class":105}," =",[58,280,281],{"class":105}," new",[58,283,285],{"class":284},"sYGIp"," URL",[58,287,288],{"class":112},"(process.env.",[58,290,291],{"class":79},"TESSERA_API",[58,293,294],{"class":105},"!",[58,296,297],{"class":112},")\n",[58,299,300,302,305,307],{"class":60,"line":97},[58,301,272],{"class":105},[58,303,304],{"class":79}," cred",[58,306,278],{"class":105},[58,308,309],{"class":112}," {\n",[58,311,313,316,319,321],{"class":60,"line":312},5,[58,314,315],{"class":112},"  appKey: process.env.",[58,317,318],{"class":79},"TESSERA_APPKEY",[58,320,294],{"class":105},[58,322,323],{"class":112},",\n",[58,325,327,330,333,335],{"class":60,"line":326},6,[58,328,329],{"class":112},"  credential: process.env.",[58,331,332],{"class":79},"TESSERA_CREDENTIAL",[58,334,294],{"class":105},[58,336,323],{"class":112},[58,338,340],{"class":60,"line":339},7,[58,341,342],{"class":112},"}\n",[58,344,346],{"class":60,"line":345},8,[58,347,267],{"emptyLinePlaceholder":266},[58,349,351,354,357,360,363,366,369,372,375,378,380,382,384,387,390,393],{"class":60,"line":350},9,[58,352,353],{"class":105},"async",[58,355,356],{"class":105}," function",[58,358,359],{"class":284}," call",[58,361,362],{"class":112},"(",[58,364,365],{"class":71},"method",[58,367,368],{"class":105},":",[58,370,371],{"class":79}," string",[58,373,374],{"class":112},", ",[58,376,377],{"class":71},"path",[58,379,368],{"class":105},[58,381,371],{"class":79},[58,383,374],{"class":112},[58,385,386],{"class":71},"body",[58,388,389],{"class":105},"?:",[58,391,392],{"class":79}," unknown",[58,394,395],{"class":112},") {\n",[58,397,399,402,405,407,410,413,416,419,422,425,427,430,433,436,438,441,443,446],{"class":60,"line":398},10,[58,400,401],{"class":105},"  const",[58,403,404],{"class":79}," raw",[58,406,278],{"class":105},[58,408,409],{"class":112}," body ",[58,411,412],{"class":105},"===",[58,414,415],{"class":79}," undefined",[58,417,418],{"class":105}," ?",[58,420,421],{"class":79}," null",[58,423,424],{"class":105}," :",[58,426,281],{"class":105},[58,428,429],{"class":284}," TextEncoder",[58,431,432],{"class":112},"().",[58,434,435],{"class":284},"encode",[58,437,362],{"class":112},[58,439,440],{"class":79},"JSON",[58,442,27],{"class":112},[58,444,445],{"class":284},"stringify",[58,447,448],{"class":112},"(body))\n",[58,450,452,454,457,459,462,465,468],{"class":60,"line":451},11,[58,453,401],{"class":105},[58,455,456],{"class":79}," params",[58,458,278],{"class":105},[58,460,461],{"class":284}," signRequest",[58,463,464],{"class":112},"(cred, method, ",[58,466,467],{"class":79},"API",[58,469,470],{"class":112},".host, path, raw)\n",[58,472,474],{"class":60,"line":473},12,[58,475,267],{"emptyLinePlaceholder":266},[58,477,479,481,484,486,489,492,494,497,499,501,504,507,509,512,515,518],{"class":60,"line":478},13,[58,480,401],{"class":105},[58,482,483],{"class":79}," res",[58,485,278],{"class":105},[58,487,488],{"class":105}," await",[58,490,491],{"class":284}," fetch",[58,493,362],{"class":112},[58,495,496],{"class":75},"`${",[58,498,467],{"class":79},[58,500,27],{"class":75},[58,502,503],{"class":112},"origin",[58,505,506],{"class":75},"}${",[58,508,377],{"class":112},[58,510,511],{"class":75},"}?${",[58,513,514],{"class":112},"params",[58,516,517],{"class":75},"}`",[58,519,520],{"class":112},", {\n",[58,522,524],{"class":60,"line":523},14,[58,525,526],{"class":112},"    method,\n",[58,528,530,533,536,539,542,545,548,551,553,555],{"class":60,"line":529},15,[58,531,532],{"class":112},"    headers: raw ",[58,534,535],{"class":105},"?",[58,537,538],{"class":112}," { ",[58,540,541],{"class":75},"'content-type'",[58,543,544],{"class":112},": ",[58,546,547],{"class":75},"'application\u002Fjson'",[58,549,550],{"class":112}," } ",[58,552,368],{"class":105},[58,554,415],{"class":79},[58,556,323],{"class":112},[58,558,560],{"class":60,"line":559},16,[58,561,562],{"class":112},"    body: raw,\n",[58,564,566],{"class":60,"line":565},17,[58,567,568],{"class":112},"  })\n",[58,570,572],{"class":60,"line":571},18,[58,573,267],{"emptyLinePlaceholder":266},[58,575,577,579,582,584,586,589,592],{"class":60,"line":576},19,[58,578,401],{"class":105},[58,580,581],{"class":79}," text",[58,583,278],{"class":105},[58,585,488],{"class":105},[58,587,588],{"class":112}," res.",[58,590,591],{"class":284},"text",[58,593,594],{"class":112},"()\n",[58,596,598,601,604,606,609,612,614,617,619,621,623,626,628,631,634,636,639,642,644,646],{"class":60,"line":597},20,[58,599,600],{"class":105},"  if",[58,602,603],{"class":112}," (",[58,605,294],{"class":105},[58,607,608],{"class":112},"res.ok) ",[58,610,611],{"class":105},"throw",[58,613,281],{"class":105},[58,615,616],{"class":284}," Error",[58,618,362],{"class":112},[58,620,496],{"class":75},[58,622,365],{"class":112},[58,624,625],{"class":75},"} ${",[58,627,377],{"class":112},[58,629,630],{"class":75},"} → ${",[58,632,633],{"class":112},"res",[58,635,27],{"class":75},[58,637,638],{"class":112},"status",[58,640,641],{"class":75},"}: ${",[58,643,591],{"class":112},[58,645,517],{"class":75},[58,647,297],{"class":112},[58,649,651],{"class":60,"line":650},21,[58,652,653],{"class":64},"  \u002F\u002F Some endpoints answer 200 with a JSON error object rather than an error status.\n",[58,655,657,659,662,664,667,669,672,674,677,680,682],{"class":60,"line":656},22,[58,658,401],{"class":105},[58,660,661],{"class":79}," parsed",[58,663,278],{"class":105},[58,665,666],{"class":112}," text ",[58,668,535],{"class":105},[58,670,671],{"class":79}," JSON",[58,673,27],{"class":112},[58,675,676],{"class":284},"parse",[58,678,679],{"class":112},"(text) ",[58,681,368],{"class":105},[58,683,684],{"class":79}," null\n",[58,686,688,690,693,696,699,702,704,707,710,713,716],{"class":60,"line":687},23,[58,689,600],{"class":105},[58,691,692],{"class":112}," (parsed ",[58,694,695],{"class":105},"&&",[58,697,698],{"class":105}," typeof",[58,700,701],{"class":112}," parsed ",[58,703,412],{"class":105},[58,705,706],{"class":75}," 'object'",[58,708,709],{"class":105}," &&",[58,711,712],{"class":75}," 'error'",[58,714,715],{"class":105}," in",[58,717,718],{"class":112}," parsed) {\n",[58,720,722,725,727,729,731,733,735,737,739,741,744,746,749,751],{"class":60,"line":721},24,[58,723,724],{"class":105},"    throw",[58,726,281],{"class":105},[58,728,616],{"class":284},[58,730,362],{"class":112},[58,732,496],{"class":75},[58,734,365],{"class":112},[58,736,625],{"class":75},[58,738,377],{"class":112},[58,740,630],{"class":75},[58,742,743],{"class":112},"parsed",[58,745,27],{"class":75},[58,747,748],{"class":112},"error",[58,750,517],{"class":75},[58,752,297],{"class":112},[58,754,756],{"class":60,"line":755},25,[58,757,758],{"class":112},"  }\n",[58,760,762,765],{"class":60,"line":761},26,[58,763,764],{"class":105},"  return",[58,766,767],{"class":112}," parsed\n",[58,769,771],{"class":60,"line":770},27,[58,772,342],{"class":112},[11,774,775],{},"Confirm it works before going further:",[49,777,779],{"className":243,"code":778,"language":245,"meta":54,"style":54},"await call('GET', '\u002Fauth\u002Fcheck') \u002F\u002F resolves on 204, throws on 401\n",[18,780,781],{"__ignoreMap":54},[58,782,783,786,788,790,793,795,798,801],{"class":60,"line":61},[58,784,785],{"class":105},"await",[58,787,359],{"class":284},[58,789,362],{"class":112},[58,791,792],{"class":75},"'GET'",[58,794,374],{"class":112},[58,796,797],{"class":75},"'\u002Fauth\u002Fcheck'",[58,799,800],{"class":112},") ",[58,802,803],{"class":64},"\u002F\u002F resolves on 204, throws on 401\n",[44,805,807],{"id":806},"_3-ask-where-to-write","3 — Ask where to write",[49,809,811],{"className":243,"code":810,"language":245,"meta":54,"style":54},"const { hosts } = await call('POST', '\u002Fprepare-write', {\n  totalShards: 30,\n  minShards: 10,\n})\n",[18,812,813,842,852,862],{"__ignoreMap":54},[58,814,815,817,819,822,824,826,828,830,832,835,837,840],{"class":60,"line":61},[58,816,272],{"class":105},[58,818,538],{"class":112},[58,820,821],{"class":79},"hosts",[58,823,550],{"class":112},[58,825,167],{"class":105},[58,827,488],{"class":105},[58,829,359],{"class":284},[58,831,362],{"class":112},[58,833,834],{"class":75},"'POST'",[58,836,374],{"class":112},[58,838,839],{"class":75},"'\u002Fprepare-write'",[58,841,520],{"class":112},[58,843,844,847,850],{"class":60,"line":68},[58,845,846],{"class":112},"  totalShards: ",[58,848,849],{"class":79},"30",[58,851,323],{"class":112},[58,853,854,857,860],{"class":60,"line":86},[58,855,856],{"class":112},"  minShards: ",[58,858,859],{"class":79},"10",[58,861,323],{"class":112},[58,863,864],{"class":60,"line":97},[58,865,866],{"class":112},"})\n",[49,868,872],{"className":869,"code":870,"language":871,"meta":54,"style":54},"language-json shiki shiki-themes github-dark-default github-dark-default","{\n  \"hosts\": [\n    {\n      \"publicKey\": \"ed25519:9f3c1a...\",\n      \"address\": \"provider-1.example:9984\",\n      \"accountToken\": \"{\\\"hostKey\\\":\\\"ed25519:9f3c…\\\",\\\"account\\\":\\\"…\\\",\\\"validUntil\\\":…,\\\"signature\\\":\\\"…\\\"}\",\n      \"contractID\": \"a1b2c3...\"\n    }\n  ]\n}\n","json",[18,873,874,879,888,893,905,917,995,1005,1010,1015],{"__ignoreMap":54},[58,875,876],{"class":60,"line":61},[58,877,878],{"class":112},"{\n",[58,880,881,885],{"class":60,"line":68},[58,882,884],{"class":883},"sV7Mv","  \"hosts\"",[58,886,887],{"class":112},": [\n",[58,889,890],{"class":60,"line":86},[58,891,892],{"class":112},"    {\n",[58,894,895,898,900,903],{"class":60,"line":97},[58,896,897],{"class":883},"      \"publicKey\"",[58,899,544],{"class":112},[58,901,902],{"class":75},"\"ed25519:9f3c1a...\"",[58,904,323],{"class":112},[58,906,907,910,912,915],{"class":60,"line":312},[58,908,909],{"class":883},"      \"address\"",[58,911,544],{"class":112},[58,913,914],{"class":75},"\"provider-1.example:9984\"",[58,916,323],{"class":112},[58,918,919,922,924,927,930,933,935,937,939,942,944,947,949,952,954,956,958,961,963,965,967,970,972,975,977,980,982,984,986,988,990,993],{"class":60,"line":326},[58,920,921],{"class":883},"      \"accountToken\"",[58,923,544],{"class":112},[58,925,926],{"class":75},"\"{",[58,928,929],{"class":105},"\\\"",[58,931,932],{"class":75},"hostKey",[58,934,929],{"class":105},[58,936,368],{"class":75},[58,938,929],{"class":105},[58,940,941],{"class":75},"ed25519:9f3c…",[58,943,929],{"class":105},[58,945,946],{"class":75},",",[58,948,929],{"class":105},[58,950,951],{"class":75},"account",[58,953,929],{"class":105},[58,955,368],{"class":75},[58,957,929],{"class":105},[58,959,960],{"class":75},"…",[58,962,929],{"class":105},[58,964,946],{"class":75},[58,966,929],{"class":105},[58,968,969],{"class":75},"validUntil",[58,971,929],{"class":105},[58,973,974],{"class":75},":…,",[58,976,929],{"class":105},[58,978,979],{"class":75},"signature",[58,981,929],{"class":105},[58,983,368],{"class":75},[58,985,929],{"class":105},[58,987,960],{"class":75},[58,989,929],{"class":105},[58,991,992],{"class":75},"}\"",[58,994,323],{"class":112},[58,996,997,1000,1002],{"class":60,"line":339},[58,998,999],{"class":883},"      \"contractID\"",[58,1001,544],{"class":112},[58,1003,1004],{"class":75},"\"a1b2c3...\"\n",[58,1006,1007],{"class":60,"line":345},[58,1008,1009],{"class":112},"    }\n",[58,1011,1012],{"class":60,"line":350},[58,1013,1014],{"class":112},"  ]\n",[58,1016,1017],{"class":60,"line":398},[58,1018,342],{"class":112},[11,1020,1021,1022,1026,1027,1030],{},"You get 30 entries, each a ",[1023,1024,1025],"strong",{},"different"," provider, with a funded contract and an ",[18,1028,1029],{},"accountToken","\nthat authorises your writes. Treat the token as opaque and hand it to the transfer protocol\nunmodified.",[44,1032,1034],{"id":1033},"_4-encrypt-split-and-write","4 — Encrypt, split, and write",[11,1036,1037],{},"Encryption first, then erasure coding. In that order — coding ciphertext means a provider holds a\nfragment of ciphertext; coding first and encrypting after would defeat the point.",[49,1039,1041],{"className":243,"code":1040,"language":245,"meta":54,"style":54},"import { createCipheriv, randomBytes } from 'node:crypto'\nimport { ReedSolomon } from 'your-rs-library'\n\nconst MIN_SHARDS = 10\nconst TOTAL_SHARDS = 30\n\n\u002F\u002F 4a — encrypt\nconst dataKey = randomBytes(32)\nconst iv = randomBytes(16)\nconst cipher = createCipheriv('aes-256-ctr', dataKey, iv)\nconst ciphertext = Buffer.concat([cipher.update(plaintext), cipher.final()])\n\n\u002F\u002F 4b — erasure code: 10 data shards + 20 parity\nconst shardSize = Math.ceil(ciphertext.length \u002F MIN_SHARDS)\nconst shards: Uint8Array[] = []\nfor (let i = 0; i \u003C MIN_SHARDS; i++) {\n  const shard = new Uint8Array(shardSize)\n  shard.set(ciphertext.subarray(i * shardSize, (i + 1) * shardSize))\n  shards.push(shard)\n}\nfor (let i = 0; i \u003C TOTAL_SHARDS - MIN_SHARDS; i++) shards.push(new Uint8Array(shardSize))\n\nconst rs = new ReedSolomon(MIN_SHARDS, TOTAL_SHARDS - MIN_SHARDS)\nrs.encode(shards)\n\n\u002F\u002F 4c — write shard i directly to provider i, and keep the sector root it returns\nconst sectors = await Promise.all(\n  shards.map(async (shard, i) => ({\n    host: hosts[i].publicKey,\n    root: await writeSectorToProvider(hosts[i], shard), \u002F\u002F your transfer client\n    contractID: hosts[i].contractID,\n  })),\n)\n",[18,1042,1043,1055,1067,1071,1083,1095,1099,1104,1123,1141,1161,1191,1195,1200,1228,1248,1282,1298,1333,1344,1348,1392,1396,1426,1436,1440,1445,1467,1497,1503,1520,1526,1532],{"__ignoreMap":54},[58,1044,1045,1047,1050,1052],{"class":60,"line":61},[58,1046,252],{"class":105},[58,1048,1049],{"class":112}," { createCipheriv, randomBytes } ",[58,1051,258],{"class":105},[58,1053,1054],{"class":75}," 'node:crypto'\n",[58,1056,1057,1059,1062,1064],{"class":60,"line":68},[58,1058,252],{"class":105},[58,1060,1061],{"class":112}," { ReedSolomon } ",[58,1063,258],{"class":105},[58,1065,1066],{"class":75}," 'your-rs-library'\n",[58,1068,1069],{"class":60,"line":86},[58,1070,267],{"emptyLinePlaceholder":266},[58,1072,1073,1075,1078,1080],{"class":60,"line":97},[58,1074,272],{"class":105},[58,1076,1077],{"class":79}," MIN_SHARDS",[58,1079,278],{"class":105},[58,1081,1082],{"class":79}," 10\n",[58,1084,1085,1087,1090,1092],{"class":60,"line":312},[58,1086,272],{"class":105},[58,1088,1089],{"class":79}," TOTAL_SHARDS",[58,1091,278],{"class":105},[58,1093,1094],{"class":79}," 30\n",[58,1096,1097],{"class":60,"line":326},[58,1098,267],{"emptyLinePlaceholder":266},[58,1100,1101],{"class":60,"line":339},[58,1102,1103],{"class":64},"\u002F\u002F 4a — encrypt\n",[58,1105,1106,1108,1111,1113,1116,1118,1121],{"class":60,"line":345},[58,1107,272],{"class":105},[58,1109,1110],{"class":79}," dataKey",[58,1112,278],{"class":105},[58,1114,1115],{"class":284}," randomBytes",[58,1117,362],{"class":112},[58,1119,1120],{"class":79},"32",[58,1122,297],{"class":112},[58,1124,1125,1127,1130,1132,1134,1136,1139],{"class":60,"line":350},[58,1126,272],{"class":105},[58,1128,1129],{"class":79}," iv",[58,1131,278],{"class":105},[58,1133,1115],{"class":284},[58,1135,362],{"class":112},[58,1137,1138],{"class":79},"16",[58,1140,297],{"class":112},[58,1142,1143,1145,1148,1150,1153,1155,1158],{"class":60,"line":398},[58,1144,272],{"class":105},[58,1146,1147],{"class":79}," cipher",[58,1149,278],{"class":105},[58,1151,1152],{"class":284}," createCipheriv",[58,1154,362],{"class":112},[58,1156,1157],{"class":75},"'aes-256-ctr'",[58,1159,1160],{"class":112},", dataKey, iv)\n",[58,1162,1163,1165,1168,1170,1173,1176,1179,1182,1185,1188],{"class":60,"line":451},[58,1164,272],{"class":105},[58,1166,1167],{"class":79}," ciphertext",[58,1169,278],{"class":105},[58,1171,1172],{"class":112}," Buffer.",[58,1174,1175],{"class":284},"concat",[58,1177,1178],{"class":112},"([cipher.",[58,1180,1181],{"class":284},"update",[58,1183,1184],{"class":112},"(plaintext), cipher.",[58,1186,1187],{"class":284},"final",[58,1189,1190],{"class":112},"()])\n",[58,1192,1193],{"class":60,"line":473},[58,1194,267],{"emptyLinePlaceholder":266},[58,1196,1197],{"class":60,"line":478},[58,1198,1199],{"class":64},"\u002F\u002F 4b — erasure code: 10 data shards + 20 parity\n",[58,1201,1202,1204,1207,1209,1212,1215,1218,1221,1224,1226],{"class":60,"line":523},[58,1203,272],{"class":105},[58,1205,1206],{"class":79}," shardSize",[58,1208,278],{"class":105},[58,1210,1211],{"class":112}," Math.",[58,1213,1214],{"class":284},"ceil",[58,1216,1217],{"class":112},"(ciphertext.",[58,1219,1220],{"class":79},"length",[58,1222,1223],{"class":105}," \u002F",[58,1225,1077],{"class":79},[58,1227,297],{"class":112},[58,1229,1230,1232,1235,1237,1240,1243,1245],{"class":60,"line":529},[58,1231,272],{"class":105},[58,1233,1234],{"class":79}," shards",[58,1236,368],{"class":105},[58,1238,1239],{"class":71}," Uint8Array",[58,1241,1242],{"class":112},"[] ",[58,1244,167],{"class":105},[58,1246,1247],{"class":112}," []\n",[58,1249,1250,1253,1255,1258,1261,1263,1266,1269,1272,1274,1277,1280],{"class":60,"line":559},[58,1251,1252],{"class":105},"for",[58,1254,603],{"class":112},[58,1256,1257],{"class":105},"let",[58,1259,1260],{"class":112}," i ",[58,1262,167],{"class":105},[58,1264,1265],{"class":79}," 0",[58,1267,1268],{"class":112},"; i ",[58,1270,1271],{"class":105},"\u003C",[58,1273,1077],{"class":79},[58,1275,1276],{"class":112},"; i",[58,1278,1279],{"class":105},"++",[58,1281,395],{"class":112},[58,1283,1284,1286,1289,1291,1293,1295],{"class":60,"line":565},[58,1285,401],{"class":105},[58,1287,1288],{"class":79}," shard",[58,1290,278],{"class":105},[58,1292,281],{"class":105},[58,1294,1239],{"class":284},[58,1296,1297],{"class":112},"(shardSize)\n",[58,1299,1300,1303,1306,1308,1311,1314,1317,1320,1323,1326,1328,1330],{"class":60,"line":571},[58,1301,1302],{"class":112},"  shard.",[58,1304,1305],{"class":284},"set",[58,1307,1217],{"class":112},[58,1309,1310],{"class":284},"subarray",[58,1312,1313],{"class":112},"(i ",[58,1315,1316],{"class":105},"*",[58,1318,1319],{"class":112}," shardSize, (i ",[58,1321,1322],{"class":105},"+",[58,1324,1325],{"class":79}," 1",[58,1327,800],{"class":112},[58,1329,1316],{"class":105},[58,1331,1332],{"class":112}," shardSize))\n",[58,1334,1335,1338,1341],{"class":60,"line":576},[58,1336,1337],{"class":112},"  shards.",[58,1339,1340],{"class":284},"push",[58,1342,1343],{"class":112},"(shard)\n",[58,1345,1346],{"class":60,"line":597},[58,1347,342],{"class":112},[58,1349,1350,1352,1354,1356,1358,1360,1362,1364,1366,1368,1371,1373,1375,1377,1380,1382,1384,1387,1389],{"class":60,"line":650},[58,1351,1252],{"class":105},[58,1353,603],{"class":112},[58,1355,1257],{"class":105},[58,1357,1260],{"class":112},[58,1359,167],{"class":105},[58,1361,1265],{"class":79},[58,1363,1268],{"class":112},[58,1365,1271],{"class":105},[58,1367,1089],{"class":79},[58,1369,1370],{"class":105}," -",[58,1372,1077],{"class":79},[58,1374,1276],{"class":112},[58,1376,1279],{"class":105},[58,1378,1379],{"class":112},") shards.",[58,1381,1340],{"class":284},[58,1383,362],{"class":112},[58,1385,1386],{"class":105},"new",[58,1388,1239],{"class":284},[58,1390,1391],{"class":112},"(shardSize))\n",[58,1393,1394],{"class":60,"line":656},[58,1395,267],{"emptyLinePlaceholder":266},[58,1397,1398,1400,1403,1405,1407,1410,1412,1415,1417,1420,1422,1424],{"class":60,"line":687},[58,1399,272],{"class":105},[58,1401,1402],{"class":79}," rs",[58,1404,278],{"class":105},[58,1406,281],{"class":105},[58,1408,1409],{"class":284}," ReedSolomon",[58,1411,362],{"class":112},[58,1413,1414],{"class":79},"MIN_SHARDS",[58,1416,374],{"class":112},[58,1418,1419],{"class":79},"TOTAL_SHARDS",[58,1421,1370],{"class":105},[58,1423,1077],{"class":79},[58,1425,297],{"class":112},[58,1427,1428,1431,1433],{"class":60,"line":721},[58,1429,1430],{"class":112},"rs.",[58,1432,435],{"class":284},[58,1434,1435],{"class":112},"(shards)\n",[58,1437,1438],{"class":60,"line":755},[58,1439,267],{"emptyLinePlaceholder":266},[58,1441,1442],{"class":60,"line":761},[58,1443,1444],{"class":64},"\u002F\u002F 4c — write shard i directly to provider i, and keep the sector root it returns\n",[58,1446,1447,1449,1452,1454,1456,1459,1461,1464],{"class":60,"line":770},[58,1448,272],{"class":105},[58,1450,1451],{"class":79}," sectors",[58,1453,278],{"class":105},[58,1455,488],{"class":105},[58,1457,1458],{"class":79}," Promise",[58,1460,27],{"class":112},[58,1462,1463],{"class":284},"all",[58,1465,1466],{"class":112},"(\n",[58,1468,1470,1472,1475,1477,1479,1481,1484,1486,1489,1491,1494],{"class":60,"line":1469},28,[58,1471,1337],{"class":112},[58,1473,1474],{"class":284},"map",[58,1476,362],{"class":112},[58,1478,353],{"class":105},[58,1480,603],{"class":112},[58,1482,1483],{"class":71},"shard",[58,1485,374],{"class":112},[58,1487,1488],{"class":71},"i",[58,1490,800],{"class":112},[58,1492,1493],{"class":105},"=>",[58,1495,1496],{"class":112}," ({\n",[58,1498,1500],{"class":60,"line":1499},29,[58,1501,1502],{"class":112},"    host: hosts[i].publicKey,\n",[58,1504,1506,1509,1511,1514,1517],{"class":60,"line":1505},30,[58,1507,1508],{"class":112},"    root: ",[58,1510,785],{"class":105},[58,1512,1513],{"class":284}," writeSectorToProvider",[58,1515,1516],{"class":112},"(hosts[i], shard), ",[58,1518,1519],{"class":64},"\u002F\u002F your transfer client\n",[58,1521,1523],{"class":60,"line":1522},31,[58,1524,1525],{"class":112},"    contractID: hosts[i].contractID,\n",[58,1527,1529],{"class":60,"line":1528},32,[58,1530,1531],{"class":112},"  })),\n",[58,1533,1535],{"class":60,"line":1534},33,[58,1536,297],{"class":112},[218,1538,1541],{"title":1539,"tone":1540},"Write failures are expected, and cheap","note",[11,1542,1543,1544,1547],{},"Providers time out. When a shard write fails, do not retry it forever — request another provider\nfrom ",[18,1545,1546],{},"\u002Fprepare-write"," and place the shard there instead. You need 30 successful placements out of\nhowever many attempts it takes; which specific providers they land on does not matter.",[44,1549,1551],{"id":1550},"_5-register-the-slab","5 — Register the slab",[11,1553,1554],{},"Now tell Tessera what you did. This is what makes the data findable later.",[49,1556,1558],{"className":243,"code":1557,"language":245,"meta":54,"style":54},"const [slabID] = await call('POST', '\u002Fslabs', [\n  {\n    version: 1,\n    minShards: MIN_SHARDS,\n    encryptionKey: iv32Base64,   \u002F\u002F 32 bytes, standard base64\n    sectors,                      \u002F\u002F 30 entries, one per provider\n  },\n])\n",[18,1559,1560,1591,1596,1606,1615,1623,1631,1636],{"__ignoreMap":54},[58,1561,1562,1564,1567,1570,1573,1575,1577,1579,1581,1583,1585,1588],{"class":60,"line":61},[58,1563,272],{"class":105},[58,1565,1566],{"class":112}," [",[58,1568,1569],{"class":79},"slabID",[58,1571,1572],{"class":112},"] ",[58,1574,167],{"class":105},[58,1576,488],{"class":105},[58,1578,359],{"class":284},[58,1580,362],{"class":112},[58,1582,834],{"class":75},[58,1584,374],{"class":112},[58,1586,1587],{"class":75},"'\u002Fslabs'",[58,1589,1590],{"class":112},", [\n",[58,1592,1593],{"class":60,"line":68},[58,1594,1595],{"class":112},"  {\n",[58,1597,1598,1601,1604],{"class":60,"line":86},[58,1599,1600],{"class":112},"    version: ",[58,1602,1603],{"class":79},"1",[58,1605,323],{"class":112},[58,1607,1608,1611,1613],{"class":60,"line":97},[58,1609,1610],{"class":112},"    minShards: ",[58,1612,1414],{"class":79},[58,1614,323],{"class":112},[58,1616,1617,1620],{"class":60,"line":312},[58,1618,1619],{"class":112},"    encryptionKey: iv32Base64,   ",[58,1621,1622],{"class":64},"\u002F\u002F 32 bytes, standard base64\n",[58,1624,1625,1628],{"class":60,"line":326},[58,1626,1627],{"class":112},"    sectors,                      ",[58,1629,1630],{"class":64},"\u002F\u002F 30 entries, one per provider\n",[58,1632,1633],{"class":60,"line":339},[58,1634,1635],{"class":112},"  },\n",[58,1637,1638],{"class":60,"line":345},[58,1639,1640],{"class":112},"])\n",[11,1642,1643],{},"The response is an array of hex slab IDs, in the same order as your request. The ID is a digest of\nthe slab's parameters, so registering identical parameters twice returns the same ID rather than\ncreating a duplicate.",[44,1645,1647],{"id":1646},"_6-register-the-object","6 — Register the object",[49,1649,1651],{"className":243,"code":1650,"language":245,"meta":54,"style":54},"const objectKey = sha256Hex(plaintext) \u002F\u002F your choice; a content hash gives free dedup\n\nawait call('POST', '\u002Fobjects', {\n  id: objectKey,\n  encryptedDataKey: wrap(dataKey),          \u002F\u002F wrapped by your key — we cannot unwrap it\n  slabs: [{ id: slabID, offset: 0, length: ciphertext.length }],\n  encryptedMetadata: encrypt({ name: 'hello.txt', size: plaintext.length }),\n  encryptedMetadataKey: wrap(metadataKey),\n  dataSignature: signOverData,\n  metadataSignature: signOverMetadata,\n})\n",[18,1652,1653,1671,1675,1692,1697,1711,1727,1749,1759,1764,1769],{"__ignoreMap":54},[58,1654,1655,1657,1660,1662,1665,1668],{"class":60,"line":61},[58,1656,272],{"class":105},[58,1658,1659],{"class":79}," objectKey",[58,1661,278],{"class":105},[58,1663,1664],{"class":284}," sha256Hex",[58,1666,1667],{"class":112},"(plaintext) ",[58,1669,1670],{"class":64},"\u002F\u002F your choice; a content hash gives free dedup\n",[58,1672,1673],{"class":60,"line":68},[58,1674,267],{"emptyLinePlaceholder":266},[58,1676,1677,1679,1681,1683,1685,1687,1690],{"class":60,"line":86},[58,1678,785],{"class":105},[58,1680,359],{"class":284},[58,1682,362],{"class":112},[58,1684,834],{"class":75},[58,1686,374],{"class":112},[58,1688,1689],{"class":75},"'\u002Fobjects'",[58,1691,520],{"class":112},[58,1693,1694],{"class":60,"line":97},[58,1695,1696],{"class":112},"  id: objectKey,\n",[58,1698,1699,1702,1705,1708],{"class":60,"line":312},[58,1700,1701],{"class":112},"  encryptedDataKey: ",[58,1703,1704],{"class":284},"wrap",[58,1706,1707],{"class":112},"(dataKey),          ",[58,1709,1710],{"class":64},"\u002F\u002F wrapped by your key — we cannot unwrap it\n",[58,1712,1713,1716,1719,1722,1724],{"class":60,"line":326},[58,1714,1715],{"class":112},"  slabs: [{ id: slabID, offset: ",[58,1717,1718],{"class":79},"0",[58,1720,1721],{"class":112},", length: ciphertext.",[58,1723,1220],{"class":79},[58,1725,1726],{"class":112}," }],\n",[58,1728,1729,1732,1735,1738,1741,1744,1746],{"class":60,"line":339},[58,1730,1731],{"class":112},"  encryptedMetadata: ",[58,1733,1734],{"class":284},"encrypt",[58,1736,1737],{"class":112},"({ name: ",[58,1739,1740],{"class":75},"'hello.txt'",[58,1742,1743],{"class":112},", size: plaintext.",[58,1745,1220],{"class":79},[58,1747,1748],{"class":112}," }),\n",[58,1750,1751,1754,1756],{"class":60,"line":345},[58,1752,1753],{"class":112},"  encryptedMetadataKey: ",[58,1755,1704],{"class":284},[58,1757,1758],{"class":112},"(metadataKey),\n",[58,1760,1761],{"class":60,"line":350},[58,1762,1763],{"class":112},"  dataSignature: signOverData,\n",[58,1765,1766],{"class":60,"line":398},[58,1767,1768],{"class":112},"  metadataSignature: signOverMetadata,\n",[58,1770,1771],{"class":60,"line":451},[58,1772,866],{"class":112},[11,1774,1775,1776,1779],{},"The object is now stored. ",[18,1777,1778],{},"encryptedMetadata"," is where filenames live — the API has no field for\none, and never will.",[44,1781,1783],{"id":1782},"_7-read-it-back","7 — Read it back",[49,1785,1787],{"className":243,"code":1786,"language":245,"meta":54,"style":54},"\u002F\u002F 7a — placement record\nconst obj = await call('GET', `\u002Fobjects\u002F${objectKey}`)\n\n\u002F\u002F 7b — for each slab, the providers and sector roots\nconst slab = await call('GET', `\u002Fslabs\u002F${obj.slabs[0].id}`)\n\n\u002F\u002F 7c — fetch any 10 of the 30 shards, directly from providers\nconst fetched = await fetchAnyN(slab.sectors, slab.minShards)\n\n\u002F\u002F 7d — reconstruct, then decrypt\nconst rs = new ReedSolomon(slab.minShards, slab.sectors.length - slab.minShards)\nrs.reconstruct(fetched)\nconst plaintext = decrypt(join(fetched).subarray(0, obj.slabs[0].length), unwrap(obj.encryptedDataKey))\n",[18,1788,1789,1794,1823,1827,1832,1877,1881,1886,1903,1907,1912,1934,1944],{"__ignoreMap":54},[58,1790,1791],{"class":60,"line":61},[58,1792,1793],{"class":64},"\u002F\u002F 7a — placement record\n",[58,1795,1796,1798,1801,1803,1805,1807,1809,1811,1813,1816,1819,1821],{"class":60,"line":68},[58,1797,272],{"class":105},[58,1799,1800],{"class":79}," obj",[58,1802,278],{"class":105},[58,1804,488],{"class":105},[58,1806,359],{"class":284},[58,1808,362],{"class":112},[58,1810,792],{"class":75},[58,1812,374],{"class":112},[58,1814,1815],{"class":75},"`\u002Fobjects\u002F${",[58,1817,1818],{"class":112},"objectKey",[58,1820,517],{"class":75},[58,1822,297],{"class":112},[58,1824,1825],{"class":60,"line":86},[58,1826,267],{"emptyLinePlaceholder":266},[58,1828,1829],{"class":60,"line":97},[58,1830,1831],{"class":64},"\u002F\u002F 7b — for each slab, the providers and sector roots\n",[58,1833,1834,1836,1839,1841,1843,1845,1847,1849,1851,1854,1857,1859,1862,1865,1867,1870,1873,1875],{"class":60,"line":312},[58,1835,272],{"class":105},[58,1837,1838],{"class":79}," slab",[58,1840,278],{"class":105},[58,1842,488],{"class":105},[58,1844,359],{"class":284},[58,1846,362],{"class":112},[58,1848,792],{"class":75},[58,1850,374],{"class":112},[58,1852,1853],{"class":75},"`\u002Fslabs\u002F${",[58,1855,1856],{"class":112},"obj",[58,1858,27],{"class":75},[58,1860,1861],{"class":112},"slabs",[58,1863,1864],{"class":75},"[",[58,1866,1718],{"class":79},[58,1868,1869],{"class":75},"].",[58,1871,1872],{"class":112},"id",[58,1874,517],{"class":75},[58,1876,297],{"class":112},[58,1878,1879],{"class":60,"line":326},[58,1880,267],{"emptyLinePlaceholder":266},[58,1882,1883],{"class":60,"line":339},[58,1884,1885],{"class":64},"\u002F\u002F 7c — fetch any 10 of the 30 shards, directly from providers\n",[58,1887,1888,1890,1893,1895,1897,1900],{"class":60,"line":345},[58,1889,272],{"class":105},[58,1891,1892],{"class":79}," fetched",[58,1894,278],{"class":105},[58,1896,488],{"class":105},[58,1898,1899],{"class":284}," fetchAnyN",[58,1901,1902],{"class":112},"(slab.sectors, slab.minShards)\n",[58,1904,1905],{"class":60,"line":350},[58,1906,267],{"emptyLinePlaceholder":266},[58,1908,1909],{"class":60,"line":398},[58,1910,1911],{"class":64},"\u002F\u002F 7d — reconstruct, then decrypt\n",[58,1913,1914,1916,1918,1920,1922,1924,1927,1929,1931],{"class":60,"line":451},[58,1915,272],{"class":105},[58,1917,1402],{"class":79},[58,1919,278],{"class":105},[58,1921,281],{"class":105},[58,1923,1409],{"class":284},[58,1925,1926],{"class":112},"(slab.minShards, slab.sectors.",[58,1928,1220],{"class":79},[58,1930,1370],{"class":105},[58,1932,1933],{"class":112}," slab.minShards)\n",[58,1935,1936,1938,1941],{"class":60,"line":473},[58,1937,1430],{"class":112},[58,1939,1940],{"class":284},"reconstruct",[58,1942,1943],{"class":112},"(fetched)\n",[58,1945,1946,1948,1951,1953,1956,1958,1961,1964,1966,1968,1970,1973,1975,1977,1979,1982,1985],{"class":60,"line":478},[58,1947,272],{"class":105},[58,1949,1950],{"class":79}," plaintext",[58,1952,278],{"class":105},[58,1954,1955],{"class":284}," decrypt",[58,1957,362],{"class":112},[58,1959,1960],{"class":284},"join",[58,1962,1963],{"class":112},"(fetched).",[58,1965,1310],{"class":284},[58,1967,362],{"class":112},[58,1969,1718],{"class":79},[58,1971,1972],{"class":112},", obj.slabs[",[58,1974,1718],{"class":79},[58,1976,1869],{"class":112},[58,1978,1220],{"class":79},[58,1980,1981],{"class":112},"), ",[58,1983,1984],{"class":284},"unwrap",[58,1986,1987],{"class":112},"(obj.encryptedDataKey))\n",[11,1989,1990],{},"Ten shards is the threshold, but fetch a couple extra in parallel and take the first ten to return —\nit costs nothing and removes the slowest provider from your critical path.",[44,1992,1994],{"id":1993},"_8-clean-up","8 — Clean up",[49,1996,1998],{"className":51,"code":1997,"language":53,"meta":54,"style":54},"curl -X DELETE \"$TESSERA_API\u002Fobjects\u002F$OBJECT_KEY?$AUTH\"   # 204\ncurl -X POST   \"$TESSERA_API\u002Fslabs\u002Fprune?$AUTH\"           # {\"pruned\": 1}\n",[18,1999,2000,2034],{"__ignoreMap":54},[58,2001,2002,2005,2008,2011,2014,2017,2020,2023,2025,2028,2031],{"class":60,"line":61},[58,2003,2004],{"class":71},"curl",[58,2006,2007],{"class":79}," -X",[58,2009,2010],{"class":75}," DELETE",[58,2012,2013],{"class":75}," \"",[58,2015,2016],{"class":112},"$TESSERA_API",[58,2018,2019],{"class":75},"\u002Fobjects\u002F",[58,2021,2022],{"class":112},"$OBJECT_KEY",[58,2024,535],{"class":75},[58,2026,2027],{"class":112},"$AUTH",[58,2029,2030],{"class":75},"\"",[58,2032,2033],{"class":64},"   # 204\n",[58,2035,2036,2038,2040,2043,2046,2048,2051,2053,2055],{"class":60,"line":68},[58,2037,2004],{"class":71},[58,2039,2007],{"class":79},[58,2041,2042],{"class":75}," POST",[58,2044,2045],{"class":75},"   \"",[58,2047,2016],{"class":112},[58,2049,2050],{"class":75},"\u002Fslabs\u002Fprune?",[58,2052,2027],{"class":112},[58,2054,2030],{"class":75},[58,2056,2057],{"class":64},"           # {\"pruned\": 1}\n",[11,2059,2060,2061,2064],{},"Deleting an object does not delete its slabs, because another object may reference them. ",[18,2062,2063],{},"prune","\nreclaims slabs nothing references any more.",[11,2066,2067,2068,27],{},"Persist your placement records if you need to recover without Tessera — see\n",[23,2069,2071],{"href":2070},"\u002Fdocs\u002Frecovery","Recovery",[2073,2074,2075],"style",{},"html pre.shiki code .sI3U9, html code.shiki .sI3U9{--shiki-default:#8B949E;--shiki-dark:#8B949E}html pre.shiki code .sAxfE, html code.shiki .sAxfE{--shiki-default:#FFA657;--shiki-dark:#FFA657}html pre.shiki code .skZ57, html code.shiki .skZ57{--shiki-default:#A5D6FF;--shiki-dark:#A5D6FF}html pre.shiki code .sEQcL, html code.shiki .sEQcL{--shiki-default:#79C0FF;--shiki-dark:#79C0FF}html pre.shiki code .srH4v, html code.shiki .srH4v{--shiki-default:#FF7B72;--shiki-dark:#FF7B72}html pre.shiki code .sb7RM, html code.shiki .sb7RM{--shiki-default:#E6EDF3;--shiki-dark:#E6EDF3}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sYGIp, html code.shiki .sYGIp{--shiki-default:#D2A8FF;--shiki-dark:#D2A8FF}html pre.shiki code .sV7Mv, html code.shiki .sV7Mv{--shiki-default:#7EE787;--shiki-dark:#7EE787}",{"title":54,"searchDepth":86,"depth":86,"links":2077},[2078,2079,2080,2081,2082,2083,2084,2085,2086,2087],{"id":46,"depth":68,"text":47},{"id":133,"depth":68,"text":134},{"id":173,"depth":68,"text":174},{"id":227,"depth":68,"text":228},{"id":806,"depth":68,"text":807},{"id":1033,"depth":68,"text":1034},{"id":1550,"depth":68,"text":1551},{"id":1646,"depth":68,"text":1647},{"id":1782,"depth":68,"text":1783},{"id":1993,"depth":68,"text":1994},"md",{},"\u002Fdocs\u002Fquickstart","Guides",{"title":5,"description":54},"docs\u002Fquickstart","_bRQcLuSaDV7FLKzyvIk_XW1rJRUPv-4oxHGwlK7Z0A",[2096,2097,2101,2104,2107,2110,2113,2114,2118,2122,2125,2128,2131,2132],{"path":25,"title":26,"description":54,"section":2091,"order":68,"badge":6},{"path":2098,"title":2099,"description":54,"section":2100,"order":312,"badge":6},"\u002Fdocs\u002Fapi\u002Faccount","Account","API reference",{"path":2102,"title":2103,"description":54,"section":2100,"order":97,"badge":6},"\u002Fdocs\u002Fapi\u002Fobjects","Objects",{"path":2105,"title":2106,"description":54,"section":2100,"order":68,"badge":6},"\u002Fdocs\u002Fapi\u002Fplacement","Placement",{"path":2108,"title":2109,"description":54,"section":2100,"order":61,"badge":6},"\u002Fdocs\u002Fapi\u002Fprovisioning","Credentials",{"path":2111,"title":2112,"description":54,"section":2100,"order":86,"badge":6},"\u002Fdocs\u002Fapi\u002Fslabs","Slabs",{"path":238,"title":239,"description":54,"section":2091,"order":86,"badge":6},{"path":2115,"title":2116,"description":54,"section":2117,"order":68,"badge":6},"\u002Fdocs\u002Fconcepts","Concepts & data model","Introduction",{"path":2119,"title":2120,"description":54,"section":2121,"order":61,"badge":6},"\u002Fdocs\u002Ferrors","Errors","Reference",{"path":2123,"title":2124,"description":54,"section":2091,"order":86,"badge":6},"\u002Fdocs\u002Fhow-storage-is-measured","How storage is measured",{"path":2126,"title":2127,"description":54,"section":2117,"order":61,"badge":6},"\u002Fdocs","Overview",{"path":2129,"title":2130,"description":54,"section":2121,"order":68,"badge":6},"\u002Fdocs\u002Flimits","Limits & quotas",{"path":2090,"title":5,"description":54,"section":2091,"order":61,"badge":6},{"path":2070,"title":2133,"description":54,"section":2091,"order":97,"badge":6},"Recovery without Tessera",1794220764089]