> For the complete documentation index, see [llms.txt](https://blocknote-js.gitbook.io/doc/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://blocknote-js.gitbook.io/doc/upload-content/upload-content-on-chain.md).

# Upload content on-chain

This document details how to use Blocknote in a **standalone script.**\
If you want to run Blocknote behind an **API**, users won't share their mnemonics but should instead sign with their wallet. You should refer to the [BlocknoteManager](/doc/upload-content/blocknotemanager.md) section of this documentation to handle this situation.

## Basic Usage

{% code fullWidth="false" %}

```javascript
import  {Blocknote} from  "blocknote"
import fs from 'fs';

// Sends a PDF. 
// The file is encrypted with a password but the title is kept unencrypted.
const options = {   
    mime:  "application/pdf",
    title: "Sales report 2025"
}
const sender_mnemonic =  "gorilla shiver hood theory letter absorb arctic ...";
const blocknote       = new Blocknote(sender_mnemonic, options);
const file	          = fs.readFileSync("./sales_report_2025.pdf");

blocknote.save(file).then((response)=>{    
    console.log(response);
});
```

{% endcode %}

<details>

<summary>View a response example</summary>

```json
{
  start: 1765932835344,
  simulation: false,
  fees: 17000,
  compression: {
    compression: "brotli",
    original_size: 19851,
    compressed_size: 15647
  },
  payload_transaction_id: "7VR62WIMCSA5POMS2QAY64SMKW5GBTN2WCBTNA5H4W3WFMYLFHWQ",
  end: 1765932851610,
  duration: 16266,
  payload: {
    title: "Sales report 2025",
    mime: "application/pdf",
    size: 19851,
    addid: 260321436,
    accid: 1583377570,
    compression: "brotli",
    txns: 16
  }
}
```

</details>

## Constructor&#x20;

<table><thead><tr><th width="190">Name</th><th width="430">Description</th><th>Type</th></tr></thead><tbody><tr><td>sender_mnemonic</td><td>The sender's mnemonic</td><td>string</td></tr><tr><td>options</td><td>See the options table below</td><td>object</td></tr></tbody></table>

### Options

<table><thead><tr><th width="131">Name</th><th width="418">Description</th><th width="106">Type</th><th>Default</th></tr></thead><tbody><tr><td>title</td><td>The content's title</td><td>string</td><td>Untitled</td></tr><tr><td>mime </td><td>The content's mime type</td><td>string</td><td>plain/text</td></tr><tr><td>compression</td><td><p></p><ul><li>If not set, Blocknote will automaticaly choose the best compression for the given data.</li><li>The compression algorithm's name: <code>brotli, gzip, lz4, lz-string, pako, snappy</code></li><li>"<code>fast</code>" will choose the fastest compression for the given content.</li><li>"<code>none</code>" won't compress the data.</li></ul></td><td>string</td><td></td></tr><tr><td>aes_key</td><td>An AES key to encrypt the content.<br><br><mark style="color:$info;">Do not set an AES key if you are already encrypting with a password.</mark></td><td>string</td><td></td></tr><tr><td>password</td><td>A password to encrypt the content.<br>(The strength of the password is not verified)<br><br><mark style="color:$info;">Do not set a password if you are already encrypting with an AES key.</mark></td><td>string</td><td></td></tr><tr><td>encrypt_title</td><td>Encrypt the title.<br>This option will be ignored if <code>aes_key</code> or <code>password</code> is not set.</td><td>boolean</td><td>true</td></tr><tr><td>revision_of</td><td>The initial payload transaction id of the file to update.<br>Look at the "About revisions" table right below to understand how it works.</td><td>string</td><td></td></tr><tr><td>simulate</td><td>If true, transactions are not sent.<br>This helps determine the number of algos needed for actual operations.</td><td>boolean</td><td>false</td></tr><tr><td>onProgress<br>⇒ (status)</td><td>Callback function to get the different progress statuses as they come in.<br><br><a href="/doc/upload-content/onprogress-statuses.md">View the complete list</a></td><td>function</td><td></td></tr><tr><td>onFinish<br>⇒ (result)</td><td>Callback executes once saving completes, including upload details in the message.</td><td>function</td><td></td></tr><tr><td>onError<br>⇒ (error)</td><td>Triggered if an error occurs while sending the batch of transactions. Note that Blocknote will always retry to send a transaction when failed, so they are not throwable errors. It is more like a log of failing transaction. </td><td>function</td><td></td></tr></tbody></table>

### About revisions

The developer must refer to the initial payload transaction id of the file to revised.\
By consistently using the original payload transaction id in the `revision_of` option, the protocol can correctly track that linear chain and validate it.

<table><thead><tr><th width="175">Action</th><th width="150">revision_of</th><th>Notes</th></tr></thead><tbody><tr><td>Initial upload</td><td>null</td><td>Creates a payload transaction id: <code>LMO4POL ...</code> </td></tr><tr><td>First revision</td><td><code>LMO4POL ...</code></td><td>References the original payload id</td></tr><tr><td>Second revision</td><td><code>LMO4POL ...</code></td><td>Still references the original payload id</td></tr><tr><td>Third revision</td><td><code>LMO4POL ...</code></td><td>Always reference the original payload id</td></tr></tbody></table>

#### Branching Revisions (Advanced/Experimental)

<table><thead><tr><th width="175">Action</th><th width="150">revision_of</th><th>Notes</th></tr></thead><tbody><tr><td>Initial upload</td><td>null</td><td>Creates a payload transaction id: <code>LMO4POL ...</code> </td></tr><tr><td>First revision</td><td><code>LMO4POL ...</code></td><td>References the original payload id.<br>Creates its own payload transaction id: <code>VBHDO2Z ...</code></td></tr><tr><td>Second revision</td><td><code>LMO4POL ...</code></td><td>Still references the original payload id.<br>Creates its own payload transaction id: <code>PWX8BZOL ...</code></td></tr><tr><td>First revision of the second revision</td><td><code>PWX8BZOL ...</code></td><td>References the payload id of the second revision.<br>A new branch starts here.</td></tr></tbody></table>

While branching is technically possible, most use cases should stick to the linear model by always referencing the original payload transaction id. Branching may complicate version tracking and resolution depending on how your application queries and displays revision history.\
Feel free to experiment but the `BlocknoteReader` doesn't support branching out-of-the-box.

***

## Methods

### <mark style="color:$primary;">save</mark>

#### Parameters

<table><thead><tr><th>Name</th><th width="316">Description</th><th>Type</th></tr></thead><tbody><tr><td>raw_content</td><td>The content to upload</td><td>string, Uint8Array, Buffer</td></tr></tbody></table>

#### Return

A promise that contains the upload details and the payload.
