Skip to content
You are reading the HappyView v2 docs, which are no longer updated. Read the v3 docs.

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}` };
GET /admin/scripts

Optionally 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();
ParameterTypeRequiredDescription
suffixstringnoFilter 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 /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"
}
POST /admin/scripts

Creates 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();
FieldTypeRequiredDescription
idstringyesTrigger string (e.g. record.index:xyz.statusphere.status)
script_typestringnoScript language; defaults to "lua"
bodystringyesThe script source code
descriptionstringnoHuman-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"
}
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();
FieldTypeRequiredDescription
script_typestringnoScript language; requires body alongside
bodystringnoNew script source; re-validated against script_type
descriptionstring|nullnoNew 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 /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