Complete JavaScript (Goja ES5.1) scripting API reference for backend scripts, widget scripts, and chart scripts.
Complete JavaScript (Goja ES5.1) scripting API for backend scripts, widget scripts, and chart scripts.
Global Variables#
| Variable | Type | Description |
|---|
userId | string | Current user ID |
groupId | string | Group ID (if group-scoped) |
instanceId | string | Instance ID |
scriptId | string | Current script ID |
scriptType | string | "backend", "widget", or "chart" |
itemId | string | Item ID (if item-scoped) |
isGroupScoped | boolean | True if script runs in a group context |
isInstanceScoped | boolean | True if script runs at instance level |
isItemScoped | boolean | True if script runs on a specific item |
user Object#
Available in all script types. Backend scripts get read-write access.
Read Methods (all scripts)#
| Method | Returns | Description |
|---|
user.ID() | string | Unique user identifier |
user.Name() | string | Display name |
user.Email() | string | Email address |
user.FirstName() | string | First name (extracted from Name) |
user.LastName() | string | Last name (extracted from Name) |
user.ProfilePicture() | string | Avatar URL |
user.Locale() | string | Language preference |
user.IsActive() | boolean | Whether account is active |
Write Methods (backend scripts only)#
| Method | Returns | Description |
|---|
user.Save() | {success, error?} | Save changes to database |
user.UpdateProfile(data) | {success, error?} | Update name/language. data: {name?: string, language?: string} |
group Object#
Available when isGroupScoped is true. Backend scripts get read-write access.
Read Methods (all scripts)#
| Method | Returns | Description |
|---|
group.ID() | string | Group identifier |
group.Name() | string | Group name |
group.Description() | string | Group description |
group.Icon() | string | Group icon |
group.Color() | string | Group color |
group.QueryItems(queryString) | Item[] | Execute a query. Example: group.QueryItems("type:task status:open") |
group.GetMemberById(userID) | User or null | Get a member by user ID |
group.GetMembers() | User[] | All group members |
group.GetItemTypes() | object[] | Item type definitions |
group.GetStatuses(itemTypeID) | object[] | Statuses for an item type |
group.GetFields(itemTypeID) | object[] | All fields (default + custom) for an item type |
group.GetCustomFields(itemTypeID) | object[] | Custom fields only |
group.GetDefaultFields(itemTypeID) | object[] | Default fields only |
Write Methods (backend scripts only)#
| Method | Returns | Description |
|---|
group.Save() | {success, error?} | Save group changes |
group.CreateItem(itemTypeID, data) | {success, itemId?, error?} | Create a new item. data: {title, description, status, assignee, dueDate, customFields} |
group.DeleteItem(itemID) | {success, error?} | Delete an item |
item Object#
Available when isItemScoped is true. Backend scripts get read-write access.
Read Methods (all scripts)#
| Method | Returns | Description |
|---|
item.ID() | string | Item identifier |
item.Title() | string | Item title |
item.Description() | string | Item description |
item.Status() | string or null | Current status ID |
item.ItemType() | string | Item type ID |
item.GroupID() | string | Parent group ID |
item.IDInGroup() | number | Sequential ID within group |
item.CreatedBy() | string | Creator user ID |
item.AssignedTo() | string | Assignee user ID |
item.IsCompleted() | boolean | Whether item is completed |
item.CreatedAt() | string | ISO 8601 creation timestamp |
item.UpdatedAt() | string | ISO 8601 last update timestamp |
item.DueDate() | string or null | ISO 8601 due date |
item.CompletedAt() | string or null | ISO 8601 completion timestamp |
item.GetField(fieldID) | any | Get any field value (default or custom) |
item.RenderField(fieldID) | string | Get rendered HTML for a field |
Write Methods (backend scripts only)#
| Method | Returns | Description |
|---|
item.Save() | {success, error?} | Save all changes |
item.Delete() | {success, error?} | Delete the item |
item.SetField(fieldID, value) | {success, error?} | Set any field value |
item.SetTitle(title) | {success, error?} | Set title |
item.SetDescription(desc) | {success, error?} | Set description |
item.SetStatus(statusID) | {success, error?} | Set status |
item.SetAssignedTo(userID) | {success, error?} | Set assignee (empty string to unassign) |
item.SetDueDate(isoDate) | {success, error?} | Set due date (ISO 8601, empty to clear) |
item.AddComment(text) | {success, error?} | Add a comment |
api Object#
Data transformation helpers, available in all script types.
| Method | Returns | Description |
|---|
api.groupBy(items, fieldName) | object | Group items by a field value. Returns {groupValue: items[]} |
api.aggregate(items, fieldName, fn) | number | Aggregate field values. fn: "sum", "avg", "min", "max", "count" |
api.filterItems(items, predicate) | any[] | Filter items using a predicate function |
Example#
var tasks = group.QueryItems("type:task");
var byStatus = api.groupBy(tasks, "status");
var totalEstimate = api.aggregate(tasks, "estimate", "sum");
var overdue = api.filterItems(tasks, function(t) {
return t.DueDate() !== null && new Date(t.DueDate()) < new Date();
});
echarts Object#
Chart configuration helpers for widget/chart scripts.
| Method | Returns | Description |
|---|
echarts.createPieChart(data, options?) | object | Create a pie chart configuration |
echarts.createBarChart(data, options?) | object | Create a bar chart configuration |
echarts.createLineChart(data, options?) | object | Create a line chart configuration |
echarts.createScatterChart(data, options?) | object | Create a scatter chart configuration |
fetch(url, options?) (Backend Scripts Only)#
Make HTTP requests to external URLs. Each call counts against the API call limit.
Parameters#
| Parameter | Type | Description |
|---|
url | string | URL to fetch (http/https only) |
options.method | string | HTTP method: "GET", "POST", "PUT", "DELETE", "PATCH", "HEAD". Default: "GET" |
options.headers | object | Request headers as key-value pairs |
options.body | string or object | Request body. Objects are auto-serialized to JSON |
Response#
| Property | Type | Description |
|---|
status | number | HTTP status code |
statusText | string | HTTP status text |
headers | object | Response headers (lowercase keys) |
body | string | Response body as string |
ok | boolean | True if status is 2xx |
json() | any | Parse body as JSON |
Security#
- Requests to private/loopback IPs are blocked (SSRF protection)
- Only
http:// and https:// schemes allowed - Max response body: 1MB
- Max 5 redirects
- Respects script timeout
Example#
var apiKey = secrets.get("EXTERNAL_API_KEY");
var resp = fetch("https://api.example.com/data", {
method: "POST",
headers: {
"Authorization": "Bearer " + apiKey,
"Content-Type": "application/json"
},
body: JSON.stringify({ query: "test" })
});
if (resp.ok) {
var data = resp.json();
log("Got " + data.results.length + " results");
} else {
log("Request failed: " + resp.status);
}
secrets.get(key) (Backend Scripts Only)#
Retrieve encrypted secrets by key. Secrets are resolved with group-then-instance fallback.
| Parameter | Type | Description |
|---|
key | string | Secret key (e.g., "API_KEY", "WEBHOOK_TOKEN") |
Returns: string (decrypted value) or null if not found.
Security#
- You must specify the exact key - no
list() or getAll() is available - Secret values are never logged by the system
- If you pass a secret to
log() or fetch(), that is your responsibility - Each call counts against the API call limit
Example#
var token = secrets.get("SLACK_WEBHOOK_TOKEN");
if (token) {
fetch("https://hooks.slack.com/services/...", {
method: "POST",
body: JSON.stringify({ text: "Item created: " + item.Title() })
});
}
log(...args) / console.log(...args)#
Log messages during script execution. Messages appear in the execution log.
log("Processing", items.length, "items");
console.log("User:", user.Name());
Resource Limits#
| Limit | Backend Scripts | Widget/Chart Scripts |
|---|
| Timeout | 30 seconds | 10 seconds |
| Max API calls | 100 | 50 |
| Max memory | 50 MB | 25 MB |
| Max fetch response | 1 MB | N/A (no fetch) |
API calls include: QueryItems, GetMemberById, GetMembers, fetch, secrets.get, and other data-fetching methods.
Trigger Types#
Backend scripts can be triggered in four ways:
| Type | Description |
|---|
| Manual | Execute on demand from the admin UI |
| Schedule | Run on a cron schedule (e.g., 0 9 * * * for daily at 9am) |
| Event | Fire when specific events occur (item created, status changed, etc.) with optional field conditions |
| Save Hook | Run after every item save, with optional field conditions |
Available Events#
CREATE, UPDATE, DELETE, STATUS_CHANGE, FIELD_UPDATE, ASSIGN, COMMENT_CREATE
Query Syntax#
The Timill query syntax supports filtering items by any field:
// Simple query
group.QueryItems("type:task")
// Multiple conditions
group.QueryItems("type:task status:open")
// Date range
group.QueryItems("type:task dueDate:>=2024-01-01")
// Complex query with parentheses
group.QueryItems("type:task (status:open OR status:in-progress)")
Supported Operators#
| Operator | Description | Example |
|---|
: | Equals (shorthand) | type:task |
= | Equals | status = 'open' |
!= | Not equals | status != 'closed' |
>= | Greater than or equal | dueDate >= 2024-01-01 |
<= | Less than or equal | dueDate <= 2024-12-31 |
> | Greater than | createdDate > 2024-01-01 |
< | Less than | createdDate < 2024-12-31 |
IN | In list | status IN ('open', 'in-progress') |
Supported Fields#
| Field | Type | Example |
|---|
type | string | type:task |
status | string | status:open |
assignee | string (user ID) | assignee:userId123 |
author | string (user ID) | author:userId123 |
dueDate | date | dueDate:>=2024-01-01 |
createdDate | date | createdDate:>2024-01-01 |
priority | string | priority:high |
| Custom fields | varies | Use field ID |
See also: