Skip to content
Local environment Preproduction — not production data

Factorial Code Datastore

Factorial Code Datastore is a robust key-value storage system that is both simple and fast. It’s designed to empower your processes through accessible source code integration, and it is reachable from outside your processes too.

With Factorial Code Datastore, you can store and retrieve data within your processes and modules, facilitating information sharing across different executions. Unlock a myriad of possibilities, including:

  • Preserving process states between executions (e.g., maintaining the last loaded date for use in subsequent executions of an ETL process).
  • Efficient session management (e.g., performing a login only if your session has expired).
  • Maintaining a shared team global state (e.g., tracking counters, execution usage, and more).
  • Seeding or inspecting that state from your own systems, without running a process.

The datastore can be reached in several ways, all of them reading and writing the same entries in your workspace:

The most direct way to use the datastore is from within your process source code, using the fcode.datastore helper:

Storing data
await fcode.datastore.set("key", "value");
Retrieving data
const value = await fcode.datastore.get("key");
Deleting data
await fcode.datastore.del("key");
Listing keys
// Get all keys
const allKeys = await fcode.datastore.keys();
// Get keys matching a pattern (e.g., all keys starting with "user:")
const userKeys = await fcode.datastore.keys("user-*");
Counting entries
const total = await fcode.datastore.count();
Expiring an entry
// Remove the entry automatically one hour from now
await fcode.datastore.expire("key", 3600);
Encrypting values
await fcode.datastore.set("key", "value", true);

expire sets a time to live, in seconds, on an entry that already exists; count returns how many entries your workspace currently holds.

The datastore is also available through our REST API, so you can read and write the same entries from any system that can make HTTP requests — to seed configuration before a process runs, to inspect state while debugging, or to hand data to a process from an application of your own.

Every endpoint lives under https://code.factorialhr.com/platform/api/{workspace}/rest/datastore and takes an API credential; see API credentials for how to get one.

Storing a value
curl -X PUT "https://code.factorialhr.com/platform/api/your-workspace/rest/datastore/entries/last-sync-at" \
-H "Authorization: Bearer $FCODE_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"value": "2024-04-24T08:46:15.735Z"}'
Retrieving a value
curl "https://code.factorialhr.com/platform/api/your-workspace/rest/datastore/entries/last-sync-at" \
-H "Authorization: Bearer $FCODE_ACCESS_TOKEN"
Listing keys
curl "https://code.factorialhr.com/platform/api/your-workspace/rest/datastore/entries?pattern=user-*" \
-H "Authorization: Bearer $FCODE_ACCESS_TOKEN"
Deleting an entry
curl -X DELETE "https://code.factorialhr.com/platform/api/your-workspace/rest/datastore/entries/last-sync-at" \
-H "Authorization: Bearer $FCODE_ACCESS_TOKEN"
Checking your usage against your plan
curl "https://code.factorialhr.com/platform/api/your-workspace/rest/datastore/stats" \
-H "Authorization: Bearer $FCODE_ACCESS_TOKEN"

A few things worth knowing about the REST surface:

  • Values are JSON strings. The datastore holds text, so send numbers and booleans quoted ({"value": "42"}) and serialise anything structured yourself.
  • A missing entry is a 404, which is more precise than the in-process helper: there, a missing key and an entry holding an empty string look the same.
  • Set an expiry either when writing, with "ttlSeconds": 3600 in the body, or afterwards with PUT .../entries/{key}/ttl.
  • Listing is capped. When the response has "truncated": true, more keys match than were returned — narrow the pattern. The same applies to count in /stats, which also reports the limits your plan allows.
  • Keys cannot contain a slash over REST.

You can reach the datastore from your own applications with our Factorial Code Run SDK, available for both JavaScript and Python:

Using Factorial Code Run SDK for JavaScript
const { FcodeDatastore } = require('@factorialco/fcode-sdk');
const datastore = new FcodeDatastore({ apiToken: 'your-api-token' });
// Store a value
await datastore.set('last-sync-at', new Date().toISOString());
// Store a secret, encrypted at rest
await datastore.set('api-token', 's3cret', { encrypted: true });
// Store a value that expires in an hour
await datastore.set('session', 'abc', { ttlSeconds: 3600 });
// Read a value — undefined when the entry does not exist
const value = await datastore.get('last-sync-at');
// List keys, optionally filtered
const keys = await datastore.keys('user-*');
// Count entries, and check your plan limits
const total = await datastore.count();
const { maxEntries, maxEntrySizeInBytes } = await datastore.stats();
// Expire and delete
await datastore.expire('session', 60);
await datastore.del('last-sync-at');

Install the SDK: pnpm install @factorialco/fcode-sdk

Passing true as the third argument to set — or "encrypted": true over REST — encrypts the value at rest with a key that belongs to your workspace before it is written to the datastore. Reading it back is transparent — you always get the original value — so it is the right choice for tokens, API credentials and personal data.

Two things to keep in mind:

  • Only values are encrypted. Keys (the entry names) are always stored in clear, so never put sensitive data in them.
  • enc: is reserved. A value starting with enc: is rejected on an unencrypted write, because a later read would otherwise try to decrypt it. Encrypt the value, or prefix it differently.

Everything that can read your workspace’s datastore — a process, an API credential, the SDK — sees the decrypted value. Encryption protects the data at rest, not from callers who are already authorised for your workspace.