Key-Value Store
Custom Entity Store
SQL (Preview)
Cache (EAP)

Storing unencrypted key-value pairs

This page lists the Key-Value Store's basic methods for storing unencrypted data. Data stored through these methods can be queries through the kvs.query tool.

To store sensitive data in a more secure manner, you'll need to encrypt your stored data instead. This data, however, can't be queried through the kvs.query tool.

To start, import the Forge KVS package in your app, as follows:

1
2
import { kvs } from '@forge/kvs';

Each installation of your app is subject to the API's quotas and limits. See Storage quotas and Storage limits for more details.

Scope requirement

Using the @forge/kvs package requires the storage:app scope in your manifest file:

1
2
permissions:
  scopes:
    - storage:app

See Permissions for more information about scopes.

kvs.set

Stores a JSON value with a specified key. Forge resolves write conflicts using a last-write-wins strategy.

You can learn more about limits and quotas here.

You don't need to include any identifiers for apps or installations in your key.

Internally, Forge automatically prepends an identifier to every key, mapping it to the right app and installation. This lets you use the full key length without risking conflicts across apps or installations.

Method signature

1
2
kvs.set(key: string, value: array | boolean | number | object | string ): Promise<void>;

Example

Sets the key example-key to one of the supported value types.

1
2
// array
kvs.set('example-key', [ 'Hello', 'World' ]);

// boolean
kvs.set('example-key', true);

// number
kvs.set('example-key', 123);

// object
kvs.set('example-key', { hello: 'world' });

// string
kvs.set('example-key', 'Hello world');

kvs.get

Gets a value by key. If the key doesn't exist, the API returns undefined.

Method signature

1
2
kvs.get(key: string): Promise<array | boolean | number | object | string>;

Example

Gets the value associated with the key example-key.

1
2
// Read the value for key `example-key`
await kvs.get('example-key');

kvs.delete

Deletes a value by key, this succeeds whether the key exists or not. Write conflicts are resolved using a last-write-wins strategy.

While you can use the kvs.delete method to delete app storage when deleting an app, we recommend you raise a ticket with the Atlassian Marketplace team to handle this for you. See Retiring your app for more details.

Method signature

1
2
kvs.delete(key: string): Promise<void>;

Example

Deletes the value associated with the key example-key, if it hasn't already been deleted.

1
2
// Delete the value with the key `example-key`
await kvs.delete('example-key');

storage.bulkSet (EAP)

Sets multiple key-value pairs in a single operation and returns a type BulkResponse which contains savedKeys and failedKeys.

Before you can test this API, you'll need to install the following package in your app:

1
2
npm i @forge/api@3.8.1-experimental-1828c63

Then, import the legacy storage module:

1
2
import { storage } from '@forge/api';

You can save up to 20 items in a single bulk request and send 45 requests per minute. Each item is subject to Forge’s hosted storage key and object size limits.

Method signature

1
2
storage.bulkSet(items: BulkItem[] ): Promise<BulkResponse>;

// Definition of what needs to be stored
interface BulkItem {
  key: string;
  value: string | number | boolean | Record<string, any> | any[];
}

interface BulkResponse {
  savedKeys: string[];
  failedKeys: string[];
}

Example

Set multiple key-value pairs with keys user1, user2, and user3, and their corresponding values.

1
2
import { storage } from "@forge/api";

const results = await storage.bulkSet([{
    key: 'user1'
    value: 'John'
  }, {
    key: 'user2':
    value: 'Mark'
  }, {
    key: 'user3':
    value: 'Norma'
  }
]);

kvs.query

Builds a query which returns a set of entities matching the provided list of criteria. See Querying data for more information on building and executing queries.

kvs.query does not return secret values set by kvs.setSecret.

Method signature

1
2
kvs.query(): Query

Examples

1
2
import { kvs, WhereConditions } from '@forge/kvs';

await kvs.query()
  // Filter the response to only keys that start with the string 'value'
  .where('key', WhereConditions.beginsWith('example'))

  // Limit the result size to 10 values
  .limit(10)

  // Use the cursor provided (returned from a previous invocation)
  .cursor('...')

  // Get a list of results
  .getMany();

The legacy storage module from the @forge/api package use the condition startsWith instead of beginsWith.

Rate this page: