> For the complete documentation index, see [llms.txt](https://safenetwork.gitbook.io/safe-dev-tutorials/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://safenetwork.gitbook.io/safe-dev-tutorials/email-app/save-an-email.md).

# Save an email

Your appendable data has a maximum size of 100 KiB. You can save the emails you want to keep by adding them your root structured data (which has no size limit). After you save an email, the app deletes that email from your appendable data. Therefore, it won't show up in your inbox anymore.

#### Contents

![Saved page](/files/-M2iQeatvPjIMsxTU9vj)

## Add the email to the root stuctured data

When you click on the "Save" button, the app adds the email you want to save to your saved folder and removes it from your inbox folder.

### Update the root structured data

The app updates your root structured data (which now contains the email you just saved) and encrypts it using symmetric encryption.

#### [Update structured data](https://api.safedev.org/low-level-api/structured-data/update-structured-data.html)

```
PATCH /structured-data/:handleId
```

**structured\_data\_actions.js**

```javascript
export const updateStructuredData = (token, handleId, data, cipherOpts) => ({
  type: ACTION_TYPES.UPDATE_STRUCTURED_DATA,
  payload: {
    request: {
      method: 'patch',
      url: `/structured-data/${handleId}`,
      headers: {
        'Authorization': token
      },
      data: {
        cipherOpts,
        data: new Buffer(JSON.stringify(data)).toString('base64')
      }
    }
  }
});
```

### Save the root structured data

The app saves your root structured data to the SAFE Network.

#### [Save structured data](https://api.safedev.org/low-level-api/structured-data/save-structured-data.html#post-endpoint)

```
POST /structured-data/:handleId
```

**structured\_data\_actions.js**

```javascript
export const postStructuredData = (token, handleId) => ({
  type: ACTION_TYPES.POST_STRUCTURED_DATA,
  payload: {
    request: {
      method: 'post',
      url: `/structured-data/${handleId}`,
      headers: {
        'Authorization': token
      }
    }
  }
});
```

## Get the appendable data of the inbox folder

The app needs to obtain an appendable data handle.

### Get a data identifier handle

First, the app fetches a data identifier handle for the appendable data representing your inbox folder.

#### [Get data ID handle](https://api.safedev.org/low-level-api/data-id/get-data-id-handle.html#for-appendable-data)

```
POST /data-id/appendable-data
```

**data\_id\_handle\_actions.js**

```javascript
export const getAppendableDataIdHandle = (token, name) => ({
  type: ACTION_TYPES.GET_STRUCTURED_DATA_ID_HANDLE,
  payload: {
    request: {
      method: 'post',
      url: '/data-id/appendable-data',
      headers: {
        'Authorization': token
      },
      data: {
        isPrivate: true,
        name
      }
    }
  }
});
```

The name of the appendable data is obtained by hashing your email ID:

**app\_utils.js**

```javascript
export const hashEmailId = emailId => {
  return crypto.createHash('sha256').update(emailId).digest('base64');
};
```

### Get an appendable data handle

The app fetches an appendable data handle using the data identifier handle representing your inbox folder.

#### [Get appendable data handle](https://api.safedev.org/low-level-api/appendable-data/get-appendable-data-handle.html)

```
GET /appendable-data/handle/:dataIdHandle
```

**appendable\_data\_actions.js**

```javascript
export const fetchAppendableDataHandle = (token, dataIdHandle) => { // id => appendable data id
  return {
    type: ACTION_TYPES.FETCH_APPENDABLE_DATA_HANDLER,
    payload: {
      request: {
        url: `/appendable-data/handle/${dataIdHandle}`,
        headers: {
          'Authorization': token,
          'Is-Private': true
        }
      }
    }
  };
};
```

### Drop the data identifier handle

The app drops the data identifier handle for the appendable data representing your inbox folder.

#### [Drop data ID handle](https://api.safedev.org/low-level-api/data-id/drop-data-id-handle.html)

```
DELETE /data-id/:handleId
```

**data\_id\_handle\_actions.js**

```javascript
export const dropHandler = (token, handleId) => ({
  type: ACTION_TYPES.DROP_HANDLER,
  payload: {
    request: {
      method: 'delete',
      url: `/data-id/${handleId}`,
      headers: {
        'Authorization': token
      }
    }
  }
});
```

## Remove the email from the appendable data

The app removes the email you just saved from your appendable data. This moves the email to the `deleted_data` field of the appendable data.

#### [Remove a data item](https://api.safedev.org/low-level-api/appendable-data/remove-data-at-index.html#remove-a-data-item)

```
DELETE /appendable-data/:handleId/:index
```

**appendable\_data\_actions.js**

```javascript
export const removeFromAppendableData = (token, handleId, index) => {
  return {
    type: ACTION_TYPES.REMOVE_FROM_APPENDABLE_DATA,
    payload: {
      request: {
        method: 'delete',
        url: `/appendable-data/${handleId}/${index}`,
        headers: {
          'Authorization': token
        }
      }
    }
  };
};
```

### Save the appendable data

The app saves your appendable data by sending a POST request to the SAFE Network.

#### [Save appendable data](https://api.safedev.org/low-level-api/appendable-data/save-appendable-data.html#post-endpoint)

```
POST /appendable-data/:handleId
```

**appendable\_data\_actions.js**

```javascript
export const postAppendableData = (token, handleId) => ({
  type: ACTION_TYPES.POST_APPENDABLE_DATA,
  payload: {
    request: {
      method: 'post',
      url: `/appendable-data/${handleId}`,
      headers: {
        'Authorization': token
      }
    }
  }
});
```

### Clear the deleted data of the appendable data

The app clears the `deleted_data` field of your appendable data.

#### [Clear all deleted data items](https://api.safedev.org/low-level-api/appendable-data/clear-all-data.html#clear-all-deleted-data-items)

```
DELETE /appendable-data/clear-deleted-data/:handleId
```

**appendable\_data\_actions.js**

```javascript
export const clearDeletedData = (token, handleId) => ({
  type: ACTION_TYPES.CLEAR_DELETE_DATA,
  payload: {
    request: {
      method: 'delete',
      url: `/appendable-data/clear-deleted-data/${handleId}`,
      headers: {
        'Authorization': token
      }
    }
  }
});
```

### Save the appendable data (again)

The app saves your appendable data by sending a POST request to the SAFE Network.

#### [Save appendable data](https://api.safedev.org/low-level-api/appendable-data/save-appendable-data.html#post-endpoint)

```
POST /appendable-data/:handleId
```

**appendable\_data\_actions.js**

```javascript
export const postAppendableData = (token, handleId) => ({
  type: ACTION_TYPES.POST_APPENDABLE_DATA,
  payload: {
    request: {
      method: 'post',
      url: `/appendable-data/${handleId}`,
      headers: {
        'Authorization': token
      }
    }
  }
});
```

### Drop the appendable data handle

The app drops the appendable data handle and [refreshes the inbox folder](/safe-dev-tutorials/email-app/refresh-the-inbox-folder.md).

#### [Drop appendable data handle](https://api.safedev.org/low-level-api/appendable-data/drop-appendable-data-handle.html)

```
DELETE /appendable-data/handle/:handleId
```

**appendable\_data\_actions.js**

```javascript
export const dropAppendableDataHandle = (token, handleId) => ({
  type: ACTION_TYPES.DROP_APPENDABLE_DATA_HANDLE,
  payload: {
    request: {
      method: 'delete',
      url: `/appendable-data/handle/${handleId}`,
      headers: {
        'Authorization': token
      }
    }
  }
});
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://safenetwork.gitbook.io/safe-dev-tutorials/email-app/save-an-email.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
