Cache & Shared State
Section titled “Cache & Shared State”The exec service caches compiled V8 isolates per hostname and exposes a small shared state document scoped to each hostname. The endpoints on this page let you invalidate that cache and read, write, or clear shared state that survives across script invocations.
Use cache/clear when a script’s shape has changed and the cached VM is stale, or when you want to reset the shared state for a hostname. Use the shared-state/* endpoints to coordinate lightweight values between scripts running against the same hostname.
POST /api/v1/exec/cache/clear
Section titled “POST /api/v1/exec/cache/clear”Clears the cached V8 isolate and, optionally, the shared state document for a hostname. The cache is keyed by hostname, not by script path, so passing scriptPath is deprecated and returns HTTP 400.
Request Body
Section titled “Request Body”| Name | Type | Required | Default | Description |
|---|---|---|---|---|
hostname | string | No | Hostname whose cached VM and shared state should be cleared | |
execId | string | No | Alternative to hostname: scopes the clear to a specific exec deployment | |
scriptPath | string | No | Deprecated. Passing scriptPath returns HTTP 400. The VM cache is keyed by hostname, so use hostname or clearAll=true instead | |
clearVm | boolean | No | true | Clear the cached V8 VM for the selector |
clearState | boolean | No | false | Clear the shared state document for the selector |
clearAll | boolean | No | false | Clear every cache and shared state entry across all hostnames |
Response
Section titled “Response”Summary of what was cleared, including the selector that was matched and how many entries were removed from each store.
{ "cleared": true, "selector": "example.com", "matched": 1, "vmCache": { "cleared": 1, "remaining": 0 }, "sharedState": { "cleared": 0, "remaining": 1 }}Validation failed, typically because scriptPath was supplied or the body could not be parsed.
{ "error": "hostname / execId is not a usable selector", "code": "ERROR_400", "timestamp": "2026-01-01T00:00:00.000Z"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_400 | Bad request | The service answers 400 with this code; the message names the cause. Messages: “hostname / execId is not a usable selector”, “hostname or clearAll=true is required”, “Malformed query string” (Percent-encoding failed to decode. Use valid %XX escapes.), “Invalid JSON body” (Ensure the request body is valid JSON. Example: a backslash followed by a backtick is not a valid JSON escape.), “Request aborted before the body was fully received”. Other messages on this status are composed at runtime and are not listed here. | — |
| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_408 | Request timeout | The service answers 408 with this code; the message names the cause. | — |
| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_413 | Payload too large | The service answers 413 with this code; the message names the cause. | — |
| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_429 | Too many requests | The service answers 429 with this code; the message names the cause. Messages: “Too many distinct clients”, “Too many requests”. | — |
{ "error": "Internal server error", "code": "ERROR_500", "timestamp": "2026-01-01T00:00:00.000Z"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_500 | Internal server error | The service answers 500 with this code; the message names the cause. Other messages on this status are composed at runtime and are not listed here. | — |
Example
Section titled “Example”curl -X POST https://{projectId}-{containerId}-exec-1.{server}.containers.hoody.com/api/v1/exec/cache/clear \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{ "hostname": "example.com", "clearVm": true, "clearState": false, "clearAll": false }'import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-exec-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.exec.cache.clear({ hostname: 'example.com', clearVm: true, clearState: false, clearAll: false,});{ "cleared": true, "selector": "example.com", "matched": 1, "vmCache": { "cleared": 1, "remaining": 0 }, "sharedState": { "cleared": 0, "remaining": 1 }}Shared state
Section titled “Shared state”POST /api/v1/exec/shared-state/get
Section titled “POST /api/v1/exec/shared-state/get”Reads the shared state document for a hostname, optionally narrowed to a specific path. Returns exists: false when the document or path is not present.
Request Body
Section titled “Request Body”| Name | Type | Required | Default | Description |
|---|---|---|---|---|
hostname | string | Yes | Hostname that owns the shared state document | |
execId | string | No | Alternative to hostname: narrows the read to a specific exec deployment | |
path | string | No | Path within the state document (omit to read the root) |
Response
Section titled “Response”The shared state value at the requested path, or a not-found response when the path does not exist.
When the path exists, the response carries exists: true, the current value in state, and the serialized size in size:
{ "hostname": "example.com", "path": "user/12345", "exists": true, "state": { "lastSeen": "2026-03-15T10:30:00Z", "score": 42 }, "size": 78}When the path is missing, the response carries exists: false and state: null:
{ "hostname": "example.com", "path": "user/99999", "exists": false, "state": null}Validation failed, typically because hostname was missing.
{ "error": "hostname is required", "code": "ERROR_400", "timestamp": "2026-01-01T00:00:00.000Z"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_400 | Bad request | The service answers 400 with this code; the message names the cause. Messages: “hostname is required”, “hostname / execId is not a usable selector”, “Malformed query string” (Percent-encoding failed to decode. Use valid %XX escapes.), “Invalid JSON body” (Ensure the request body is valid JSON. Example: a backslash followed by a backtick is not a valid JSON escape.), “Request aborted before the body was fully received”. | — |
| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_408 | Request timeout | The service answers 408 with this code; the message names the cause. | — |
| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_413 | Payload too large | The service answers 413 with this code; the message names the cause. | — |
| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_429 | Too many requests | The service answers 429 with this code; the message names the cause. Messages: “Too many distinct clients”, “Too many requests”. | — |
{ "error": "Internal server error", "code": "ERROR_500", "timestamp": "2026-01-01T00:00:00.000Z"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_500 | Internal server error | The service answers 500 with this code; the message names the cause. Other messages on this status are composed at runtime and are not listed here. | — |
Example
Section titled “Example”curl -X POST https://{projectId}-{containerId}-exec-1.{server}.containers.hoody.com/api/v1/exec/shared-state/get \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{ "hostname": "example.com", "path": "user/12345" }'import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-exec-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.exec.store.get({ hostname: 'example.com', path: 'user/12345',});{ "hostname": "example.com", "path": "user/12345", "exists": true, "state": { "lastSeen": "2026-03-15T10:30:00Z", "score": 42 }, "size": 78}POST /api/v1/exec/shared-state/set
Section titled “POST /api/v1/exec/shared-state/set”Writes a value into the shared state document for a hostname. By default, the value replaces the document at the target path. When merge: true, the incoming value is merged into the existing object at that path.
Request Body
Section titled “Request Body”| Name | Type | Required | Default | Description |
|---|---|---|---|---|
hostname | string | Yes | Hostname that owns the shared state document | |
execId | string | No | Alternative to hostname: narrows the write to a specific exec deployment | |
path | string | No | Path within the state document (omit to write to the root) | |
value | any (JSON) | Yes | Value to store: object, array, number, boolean, string, or null | |
merge | boolean | No | false | When true, merge the incoming value into the existing document. When false (default), replace the document at the target path |
Response
Section titled “Response”Confirmation that the document was written, along with the resolved key, the resulting size, and whether the value was merged.
{ "hostname": "example.com", "key": "example.com", "path": "user/12345", "updated": true, "merged": true, "size": 78}Validation failed, typically because hostname or value was missing, or because merge: true was used with a non-object value.
{ "error": "hostname is required", "code": "ERROR_400", "timestamp": "2026-01-01T00:00:00.000Z"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_400 | Bad request | The service answers 400 with this code; the message names the cause. Messages: “hostname is required”, “value is required”, “hostname / execId is not a usable selector”, “Invalid path: reserved segment”, “Malformed query string” (Percent-encoding failed to decode. Use valid %XX escapes.), “Invalid JSON body” (Ensure the request body is valid JSON. Example: a backslash followed by a backtick is not a valid JSON escape.), “Request aborted before the body was fully received”. | — |
| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_408 | Request timeout | The service answers 408 with this code; the message names the cause. | — |
| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_413 | Payload too large | The service answers 413 with this code; the message names the cause. | — |
| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_429 | Too many requests | The service answers 429 with this code; the message names the cause. Messages: “Too many distinct clients”, “Too many requests”. | — |
{ "error": "Internal server error", "code": "ERROR_500", "timestamp": "2026-01-01T00:00:00.000Z"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_500 | Internal server error | The service answers 500 with this code; the message names the cause. Other messages on this status are composed at runtime and are not listed here. | — |
Example
Section titled “Example”curl -X POST https://{projectId}-{containerId}-exec-1.{server}.containers.hoody.com/api/v1/exec/shared-state/set \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{ "hostname": "example.com", "path": "user/12345", "value": { "lastSeen": "2026-03-15T10:30:00Z", "score": 42 }, "merge": true }'import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-exec-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.exec.store.set({ hostname: 'example.com', path: 'user/12345', value: { lastSeen: '2026-03-15T10:30:00Z', score: 42, }, merge: true,});{ "hostname": "example.com", "key": "example.com", "path": "user/12345", "updated": true, "merged": true, "size": 78}POST /api/v1/exec/shared-state/clear
Section titled “POST /api/v1/exec/shared-state/clear”Clears a path within the shared state document for a hostname, or clears every entry across all hostnames when clearAll: true.
Request Body
Section titled “Request Body”| Name | Type | Required | Default | Description |
|---|---|---|---|---|
hostname | string | No | Hostname that owns the shared state document | |
execId | string | No | Alternative to hostname: narrows the clear to a specific exec deployment | |
path | string | No | Path within the state document to clear (omit with clearAll: true to wipe everything) | |
clearAll | boolean | No | false | When true, clear every shared state entry across all hostnames; otherwise clear the path within hostname |
Response
Section titled “Response”Confirmation that the state was cleared. The shape differs depending on whether a single path was removed or clearAll was used.
When a specific path is removed, the response carries the hostname, path, selector, count, the cleared flag, and a reason:
{ "hostname": "example.com", "selector": "example.com", "path": "user/12345", "cleared": true, "count": 1, "reason": "Path removed"}When clearAll: true is used, the response carries the number of entries removed, the selector, and how many remain:
{ "cleared": true, "count": 7, "selector": null, "remaining": 0}Validation failed, typically because hostname was missing.
{ "error": "hostname / execId is not a usable selector", "code": "ERROR_400", "timestamp": "2026-01-01T00:00:00.000Z"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_400 | Bad request | The service answers 400 with this code; the message names the cause. Messages: “hostname / execId is not a usable selector”, “hostname or clearAll=true is required”, “Invalid path: reserved segment”, “Malformed query string” (Percent-encoding failed to decode. Use valid %XX escapes.), “Invalid JSON body” (Ensure the request body is valid JSON. Example: a backslash followed by a backtick is not a valid JSON escape.), “Request aborted before the body was fully received”. | — |
| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_408 | Request timeout | The service answers 408 with this code; the message names the cause. | — |
| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_413 | Payload too large | The service answers 413 with this code; the message names the cause. | — |
| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_429 | Too many requests | The service answers 429 with this code; the message names the cause. Messages: “Too many distinct clients”, “Too many requests”. | — |
{ "error": "Internal server error", "code": "ERROR_500", "timestamp": "2026-01-01T00:00:00.000Z"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_500 | Internal server error | The service answers 500 with this code; the message names the cause. Other messages on this status are composed at runtime and are not listed here. | — |
Example
Section titled “Example”curl -X POST https://{projectId}-{containerId}-exec-1.{server}.containers.hoody.com/api/v1/exec/shared-state/clear \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{ "hostname": "example.com", "path": "user/12345", "clearAll": false }'import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-exec-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.exec.store.clear({ hostname: 'example.com', path: 'user/12345', clearAll: false,});{ "hostname": "example.com", "selector": "example.com", "path": "user/12345", "cleared": true, "count": 1, "reason": "Path removed"}