Scripts
Manage trigger-keyed scripts. Scripts run automatically in response to events like record indexing, XRPC calls, or labeler actions. The trigger id (e.g. record.index:xyz.statusphere.status) determines when a script fires.
Permissions: scripts:read for GET endpoints, scripts:manage for mutating endpoints.
const TOKEN = "hv_..."; // your API key
const headers = { Authorization: `Bearer ${TOKEN}` };List scripts
GET /admin/scriptsOptionally filter by NSID suffix with the ?suffix= query parameter.
interface Script {
id: string;
script_type: string;
body: string;
description: string | null;
created_at: string;
updated_at: string;
}
// List all scripts
const response = await fetch("http://127.0.0.1:3000/admin/scripts", {
headers,
});
const data: Script[] = await response.json();
// Filter by NSID suffix
const filtered = await fetch(
"http://127.0.0.1:3000/admin/scripts?suffix=xyz.statusphere.status",
{ headers },
);
const filteredData: Script[] = await filtered.json();| Parameter | Type | Required | Description |
|---|---|---|---|
suffix | string | no | Filter to scripts whose id ends with :<suffix> (query param) |
Response: 200 OK
[
{
"id": "record.index:xyz.statusphere.status",
"script_type": "lua",
"body": "function handle()\n return event\nend",
"description": "Process indexed statuses",
"created_at": "2026-01-01T00:00:00Z",
"updated_at": "2026-01-01T00:00:00Z"
}
]Get a script
GET /admin/scripts/{id}The {id} path parameter is the trigger string, URL-encoded (e.g. record.index%3Axyz.statusphere.status).
const response = await fetch(
"http://127.0.0.1:3000/admin/scripts/record.index%3Axyz.statusphere.status",
{ headers },
);
const data: Script = await response.json();Response: 200 OK
{
"id": "record.index:xyz.statusphere.status",
"script_type": "lua",
"body": "function handle()\n return event\nend",
"description": "Process indexed statuses",
"created_at": "2026-01-01T00:00:00Z",
"updated_at": "2026-01-01T00:00:00Z"
}Create or replace a script
POST /admin/scriptsCreates a new script or replaces an existing one by id. The trigger grammar and Lua body are validated at write-time.
const response = await fetch("http://127.0.0.1:3000/admin/scripts", {
method: "POST",
headers: {
...headers,
"Content-Type": "application/json",
},
body: JSON.stringify({
id: "record.index:xyz.statusphere.status",
script_type: "lua",
body: "function handle()\n return event\nend",
description: "Process indexed statuses",
}),
});
const data: Script = await response.json();| Field | Type | Required | Description |
|---|---|---|---|
id | string | yes | Trigger string (e.g. record.index:xyz.statusphere.status) |
script_type | string | no | Script language; defaults to "lua" |
body | string | yes | The script source code |
description | string | no | Human-readable description (max 300 characters) |
Response: 201 Created (new) or 200 OK (update)
{
"id": "record.index:xyz.statusphere.status",
"script_type": "lua",
"body": "function handle()\n return event\nend",
"description": "Process indexed statuses",
"created_at": "2026-01-01T00:00:00Z",
"updated_at": "2026-01-01T00:00:00Z"
}Partial update a script
PATCH /admin/scripts/{id}Updates individual fields of an existing script. At least one field must be provided. Setting description to null in JSON clears it. If script_type is changed, body must also be provided so validation can run against the new type.
const response = await fetch(
"http://127.0.0.1:3000/admin/scripts/record.index%3Axyz.statusphere.status",
{
method: "PATCH",
headers: {
...headers,
"Content-Type": "application/json",
},
body: JSON.stringify({
description: "Updated description for status processing",
}),
},
);
const data: Script = await response.json();| Field | Type | Required | Description |
|---|---|---|---|
script_type | string | no | Script language; requires body alongside |
body | string | no | New script source; re-validated against script_type |
description | string|null | no | New description, or null to clear |
Response: 200 OK
{
"id": "record.index:xyz.statusphere.status",
"script_type": "lua",
"body": "function handle()\n return event\nend",
"description": "Updated description for status processing",
"created_at": "2026-01-01T00:00:00Z",
"updated_at": "2026-01-01T00:00:00Z"
}Delete a script
DELETE /admin/scripts/{id}const response = await fetch(
"http://127.0.0.1:3000/admin/scripts/record.index%3Axyz.statusphere.status",
{
method: "DELETE",
headers,
},
);Response: 204 No Content