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.
Access Methods
Section titled “Access Methods”The datastore can be reached in several ways, all of them reading and writing the same entries in your workspace:
1. From Process Source Code
Section titled “1. From Process Source Code”The most direct way to use the datastore is from within your process source code, using the fcode.datastore helper:
await fcode.datastore.set("key", "value");const value = await fcode.datastore.get("key");await fcode.datastore.del("key");// Get all keysconst allKeys = await fcode.datastore.keys();
// Get keys matching a pattern (e.g., all keys starting with "user:")const userKeys = await fcode.datastore.keys("user-*");const total = await fcode.datastore.count();// Remove the entry automatically one hour from nowawait fcode.datastore.expire("key", 3600);await fcode.datastore.set("key", "value", true);fcode.datastore.set("key", "value")value = fcode.datastore.get("key")fcode.datastore.delete("key")# Get all keysall_keys = fcode.datastore.keys()
# Get keys matching a pattern (e.g., all keys starting with "user:")user_keys = fcode.datastore.keys("user-*")total = fcode.datastore.count()# Remove the entry automatically one hour from nowfcode.datastore.expire("key", 3600)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.
2. From External Systems via REST API
Section titled “2. From External Systems via REST API”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.
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"}'curl "https://code.factorialhr.com/platform/api/your-workspace/rest/datastore/entries/last-sync-at" \ -H "Authorization: Bearer $FCODE_ACCESS_TOKEN"curl "https://code.factorialhr.com/platform/api/your-workspace/rest/datastore/entries?pattern=user-*" \ -H "Authorization: Bearer $FCODE_ACCESS_TOKEN"curl -X DELETE "https://code.factorialhr.com/platform/api/your-workspace/rest/datastore/entries/last-sync-at" \ -H "Authorization: Bearer $FCODE_ACCESS_TOKEN"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": 3600in the body, or afterwards withPUT .../entries/{key}/ttl. - Listing is capped. When the response has
"truncated": true, more keys match than were returned — narrow the pattern. The same applies tocountin/stats, which also reports the limits your plan allows. - Keys cannot contain a slash over REST.
3. Using Factorial Code Run SDK
Section titled “3. Using Factorial Code Run SDK”You can reach the datastore from your own applications with our Factorial Code Run SDK, available for both JavaScript and Python:
const { FcodeDatastore } = require('@factorialco/fcode-sdk');
const datastore = new FcodeDatastore({ apiToken: 'your-api-token' });
// Store a valueawait datastore.set('last-sync-at', new Date().toISOString());
// Store a secret, encrypted at restawait datastore.set('api-token', 's3cret', { encrypted: true });
// Store a value that expires in an hourawait datastore.set('session', 'abc', { ttlSeconds: 3600 });
// Read a value — undefined when the entry does not existconst value = await datastore.get('last-sync-at');
// List keys, optionally filteredconst keys = await datastore.keys('user-*');
// Count entries, and check your plan limitsconst total = await datastore.count();const { maxEntries, maxEntrySizeInBytes } = await datastore.stats();
// Expire and deleteawait datastore.expire('session', 60);await datastore.del('last-sync-at');Install the SDK: pnpm install @factorialco/fcode-sdk
from datetime import datetime, timezone
from fcode_sdk import FcodeDatastore, FcodeApiConfig
datastore = FcodeDatastore(FcodeApiConfig(api_token='your-api-token'))
# Store a valuedatastore.set('last-sync-at', datetime.now(timezone.utc).isoformat())
# Store a secret, encrypted at restdatastore.set('api-token', 's3cret', encrypted=True)
# Store a value that expires in an hourdatastore.set('session', 'abc', ttl_seconds=3600)
# Read a value — None when the entry does not existvalue = datastore.get('last-sync-at')
# List keys, optionally filteredkeys = datastore.keys('user-*')
# Count entries, and check your plan limitstotal = datastore.count()stats = datastore.stats()print(stats.max_entries, stats.max_entry_size_in_bytes)
# Expire and deletedatastore.expire('session', 60)datastore.delete('last-sync-at')Install the SDK: pip install factorial-fcode-sdk
Encryption
Section titled “Encryption”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 withenc: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.