---
title: "Storage & Variables in the SDK"
canonical: https://trickest.com/docs/developer-tools/sdk/storage-variables
description: "client.storage, client.variables, and client.secretVariables; files and configuration secrets."
---

# Storage & Variables in the SDK

Examples use a server-side `client` from
[Client setup](/docs/developer-tools/sdk/client-setup), and resource IDs supplied
by your application.

## `client.storage`

Vault file storage (`/api/files`).

| Method                                           | Description                                |
| ------------------------------------------------ | ------------------------------------------ |
| `list(folder?, options?)`                        | `AsyncGenerator<File>`                     |
| `listPage(folder?, options?)`                    | `PaginatedResponse<File>`                  |
| `get(fileId, options?)`                          | Metadata                                   |
| `getDownloadUrl(fileId, options?)`               | Signed download URL                        |
| `upload(filename, content, mimeType?, options?)` | Multipart upload; server size limits apply |
| `delete(fileId, options?)`                       | Delete                                     |
| `mkdir(path, options?)`                          | Create folder                              |

```ts
for await (const file of client.storage.list("reports/2026")) {
  console.log(file.name, file.pretty_size);
}

await client.storage.upload("scan.txt", "results…", "text/plain");

const url = await client.storage.getDownloadUrl(fileId);
```

The SDK builds a multipart request from a string, bytes, or a Blob. It does not
stream a local file path or enforce an upload byte ceiling. Uploads
make one attempt even if `retry: true` is supplied. Check the returned error
before deciding whether to retry a write. Signed download URLs expire; do not
forward your platform Authorization header to their storage host.

**Types:** `File`, `Folder`

<Info>
  **CLI:** [Storage & Variables](/docs/developer-tools/cli/storage-variables).
  **UI:** [Uploading
  files](/docs/using-the-app/workflow-and-executions/uploading-files).
</Info>

## `client.variables`

Regular (non-secret) variables.

| Method                         | Description                                               |
| ------------------------------ | --------------------------------------------------------- |
| `list(spaceId?, options?)`     | Generator                                                 |
| `listPage(spaceId?, options?)` | One page                                                  |
| `get(id, options?)`            | By id                                                     |
| `set(data, options?)`          | Create a variable: `{ name, value }`, both strings |
| `delete(id, options?)`         | Delete                                                    |

There is **no `is_secret` flag** on this service; secrets use `secretVariables`.

Despite its name, `set()` does not update an existing variable. The API rejects
duplicate names in the same scope. To change a known variable's value, use
`client.http.put('/api/variables/<id>', { value: 'new value' })`, replacing
`<id>` with its ID.

## `client.secretVariables`

The separate secrets API returns metadata without a `value` field. Do not
expect a masked string or retrieve the original secret through a list call.

| Method                                  | Description                                                |
| --------------------------------------- | ---------------------------------------------------------- |
| `list({ scopeType, space? }, options?)` | List secrets                                               |
| `create(data, options?)`                | `CreateSecretVariable`                                     |
| `update(id, value, options?)`           | Rotate value; returns `{ success }`, not the secret record |
| `delete(id, options?)`                  | Delete                                                     |

```ts
const apiKey = process.env.API_KEY;
if (!apiKey) throw new Error("API_KEY is required");

await client.secretVariables.create({
  name: "API_KEY",
  value: apiKey,
  scope_type: "space",
  space: spaceId,
});
```

A space-scoped secret requires `space`; use `scope_type: 'user'` for the
user scope. Omitting values from reads does not prevent consuming code from exposing a secret
in its logs or outputs. Keep values out of browser bundles and documentation.

**Types:** `Variable`, `CreateVariable`, `SecretVariable`, `CreateSecretVariable`

## Related

<CardGroup cols={2}>
  <Card
    title="Workflows"
    icon="diagram-project"
    href="/docs/developer-tools/sdk/workflows"
  >
    Variables resolve at workflow run time.
  </Card>
  <Card
    title="Runs"
    icon="play"
    href="/docs/developer-tools/sdk/runs-schedules"
  >
    Pass `inputs` on execute to override values per run.
  </Card>
</CardGroup>

---
_Markdown source of https://trickest.com/docs/developer-tools/sdk/storage-variables._
