Async events API
Fetch API
Storage API

Rate this page:

Storage API

This resource provides methods to store values in Forge app storage, rather than product properties via the Properties API.

Data stored using the Storage API isn't shared between Forge apps on the same site or across different Atlassian sites.

Each installation of your app is is subject to quotas and limits on the Storage API. For more information, see Platform quotas and limits.

The Storage API requires your app to have the storage:app scope. See Add scopes to call an Atlassian REST API to add new scopes to your app.

Import the Forge API package in your app, as follows:

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

Recommendations

When using the app storage API, we strongly recommend that you:

  • only use encrypted environment variables and storage.setSecret to store secrets or credentials in your app.
  • avoid using the app Storage API for storing files.
  • avoid employing data models with entities that grow in an unbounded manner (in terms of depth and/or size), as this may lead to exceeding storage limits.

The Atlassian Cloud backs up the entire hosted storage for disaster recovery. This includes content stored from the Forge storage API.

We will add admin-driven backup (and restore) capabilities for app-level data in a future update.

storage.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
storage.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
storage.set('example-key', [ 'Hello', 'World' ]);

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

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

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

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

storage.setSecret

Similar to storage.set, storage.setSecret provides a way to store sensitive credentials. Values set with storage.setSecret can only be accessed with storage.getSecret.

The same limitation is applied: persisted JSON values may be up to 128 KB in size and have a key of up to 500 bytes.

You do not need to identify your app or the active site/installation in your key, as Forge will do this automatically.

Write conflicts are resolved using a last-write-wins strategy.

Method signature

1
2
storage.setSecret(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
storage.setSecret('example-key', [ 'Hello', 'World' ]);

// boolean
storage.setSecret('example-key', true);

// number
storage.setSecret('example-key', 123);

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

// string
storage.setSecret('example-key', 'Hello world');

storage.get

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

Method signature

1
2
storage.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 storage.get('example-key');

storage.getSecret

Gets a value by key, which was stored using storage.setSecret. If the key doesn't exist, the API returns undefined.

Method signature

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

Example

Gets the secret value associated with the key example-key.

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

storage.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 storage.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
storage.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 `key`
await storage.delete('example-key');

storage.deleteSecret

Deletes a secret value by key, this succeeds whether the key exists or not.

Write conflicts are resolved using a last-write-wins strategy.

Method signature

1
2
storage.deleteSecret(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 `key`
await storage.deleteSecret('example-key');

storage.query

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

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

Method signature

1
2
storage.query(): Query

Examples

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

await storage.query()
  // Filter the response to only keys that start with the string 'value'
  .where('key', startsWith('value'))

  // 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();

Custom entities (preview)

Custom entities and complex queries are now available as preview features. You can now use them on production apps, although any breaking changes are now subject to a 1-month deprecation.

To request assistance or report any bugs, visit Developer and Marketplace support.

This page describes a Forge preview feature. Preview features are deemed stable; however, they remain under active development and may be subject to shorter deprecation windows. Preview features are suitable for early adopters in production environments.

We release preview features so partners and developers can study, test, and integrate them prior to General Availability (GA). For more information, see Forge release phases: EAP, Preview, and GA.

The Storage API also lets you set, get, and delete values for custom entities. Custom entities are user-defined data structures for storing app data. Forge's storage API lets you query data stored in these structures using a wide array of query conditions. These query conditions make it possible to build advanced, complex queries to suit your app's operations.

See Complex queries (preview) for more detailed information about defining custom entities and building queries for them.

storage.entity("entity-name").set

Stores a JSON value with a specified key, for the selected entity.

You can learn more about limits and quotas here.

Method signature

1
2
storage.entity(entityName: string).set(key: string, value: object): Promise<void>;

Limitations

A key should:

  • match the regex /^[a-zA-Z0-9:._\s-#]+$/
  • contain at least 1 character
  • contain maximum of 100 characters
  • not be empty
  • not contain only blank space

Example

Sets the key example-key for an entity named employee.

1
2
storage.entity("employee").set('example-key', {
    surname:"Davis",
    age: 30,
    employmentyear: 2022,
    gender: "male",
    nationality: "Australian"
});

storage.entity("entity-name").get

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

Method signature

1
2
storage.entity(entityName: string).get(key: string): Promise<object>;

Example

Gets the value associated with the key example-key.

1
2
// Read the value for key `example-key`
await storage.entity("employee").get('example-key');

storage.entity("entity-name").delete

Deletes a value by key, for the selected entity. This succeeds whether the key exists or not.

While you can use the storage.entity.delete method to delete app data 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
storage.entity(entityName: string).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 `key`
await storage.entity('employee').delete('example-key');

More information

To learn more about the Storage API:

  • Find out how to query against data stored in the Storage API.
  • Explore the Storage API reference for more details on how it works.
  • View the limits that apply to apps using the Storage API.

Rate this page: