puter.kv.update()Update one or more paths within the value stored at a key. You can update nested fields without overwriting the entire value. A missing or expired key is built from the paths you give, with no TTL unless you pass one.
puter.kv.update(key, pathAndValueMap)
puter.kv.update(key, pathAndValueMap, ttl)
puter.kv.update(key, pathAndValueMap, ttl, optConfig)
puter.kv.update({ key, pathAndValueMap, ttl })
key (String) (required)
The key to update.
pathAndValueMap (Object) (required)
An object where each key is a path (for example, "profile.name") and each value is the new value for that path.
Each value follows the same limits as puter.kv.set(): 400 KB, and every number within ±9,007,199,254,740,991 — a larger one is stored clamped to that bound.
ttl (Number | null) (optional)
Time-to-live in seconds. Omit it, or pass an empty string or false, to keep the key's current TTL; pass null to remove it. A numeric string such as '60' is read as that number. A positive number sets the TTL; 0 or a negative number expires the key right away. Any other value, such as true, an array, or Infinity, rejects with ttl_invalid.
Paths support dot notation, array indexes at any level ([0], items[0], or some.path[1].to.value), and quoted property names (["key.with.dots"]). An empty path ("") targets the whole stored value. Use non-negative integer indexes in brackets to address arrays. When a path continues through an array element (for example, [0].score), that element must already exist. Missing object parents are created automatically; sparse array elements are not created. A path may chain at most 31 levels; a deeper one rejects with bad_request. Quoted names can't be empty. All of a call's paths go into one write, so a call fits at most 1,500 path segments and, with short field names, about 140 paths; split larger changes across calls. See Rate Limits and Quotas.
optConfig (Object) (optional)
The last argument. It takes these properties:
handle (String): Work on data another user shared with you, using the handle from puter.kv.listShared(). The key is then relative to the shared prefix. The share needs write access. See Sharing with other users.appUuid (String): Work on another app's data, which the user let your app reach with puter.perms.request('appData', …). It can't be combined with handle.Returns a Promise that resolves to the updated value stored at key.
A rejection carries an Error with a stable code:
| Code | Meaning |
|---|---|
key_undefined |
No key was given. |
key_too_large |
The key is over the 1 KB limit. |
path_map_invalid |
pathAndValueMap is missing, empty, or not an object. |
ttl_invalid |
ttl isn't a finite number of seconds, a numeric string, null, an empty string, or false. |
invalid_path |
A path map addressed a field inside a stored number, boolean, null, string, or array, or went through a missing array element. |
value_too_large |
The write would take the stored value over 400 KB. |
bad_request |
A malformed path (including an empty quoted name such as [""]), a path nested over 31 levels, two paths that overlap or conflict (one treats a shared step as a list index, the other as a field name), more or longer paths than one write can apply (see Rate Limits and Quotas), a value nested more than 32 levels deep counting its path, or a single value over 400 KB. |
insufficient_funds |
No usage left on the account. |
forbidden |
Called with optConfig.appUuid for another app's data without permission, or the entry is private to that app. |
subject_does_not_exist |
optConfig.appUuid names an app that doesn't exist. |
response_timeout |
Too many writers on the key right now — retry. |
too_many_requests |
The rate limit was exceeded. See Rate Limits and Quotas. |
kv_handle_not_found |
handle doesn't exist, the share stopped, or it isn't shared with you. |
kv_handle_access_denied |
The share's access doesn't allow this method. |
kv_handle_option_invalid |
handle was combined with appUuid or disableSharing. |
kv_handle_key_invalid |
With handle, the key is empty or longer than 768 bytes. |
kv_handles_disabled |
Shares can't be used this way on this deployment. |
Update an element of a root array
<html>
<body>
<script src="https://js.puter.com/v2/"></script>
<script>
(async () => {
await puter.kv.set('players', [{ score: 1 }, { score: 2 }]);
const updated = await puter.kv.update('players', { '[0].score': 10 });
puter.print(JSON.stringify(updated));
})();
</script>
</body>
</html>
Update nested fields and refresh the TTL
<html>
<body>
<script src="https://js.puter.com/v2/"></script>
<script>
(async () => {
await puter.kv.set('profile', { name: 'Puter', stats: { score: 10 } });
const updated = await puter.kv.update(
'profile',
{ 'stats.score': 11, 'name': 'Puter Smith' },
3600
);
puter.print(`Updated profile: ${JSON.stringify(updated)}`);
})();
</script>
</body>
</html>