Script resource and endpoints
A Script is a declarative backend endpoint that the frontend calls over HTTP (its concept and top-level structure are covered in Script Overview). This page covers the sys structure and body properties of the Script resource, the specification of the HTTP endpoints that author and run a Script, and ScriptLog, the record of a run.
Creating and managing a Script (list, read, create, update, delete) happens on CMA (https://cma.weegloo.com/v1). Execution is handled by the execution paths on the dedicated Script host (https://script.weegloo.com/v1), and that one execution path accepts both a Weegloo User token and the token of a member who signed up for the product (ServiceUser). ACMA has no Script API, and neither do the read-only delivery APIs (CDA, ACDA).
A Script is a resource that carries a version, and it is a billable resource subject to a per-plan count limit. Unlike Content or Media, however, it has no publish status. Its sys has no publish-related properties such as status or publish; only version goes up with each change. Because there is no concept of publishing or unpublishing, deletion happens right away without unpublishing first.
Resource structure
The following is the single-read response for the Script "t6-http". Along with sys (system properties), it has as body properties name, definition, and the two switches that open and close its call paths, directCallEnabled and anonymousCallEnabled.
{
"sys": {
"id": "3trmXRMZcTAjDnphewjj1AaxYcaxlK",
"type": "Script",
"space": { "sys": { "id": "6jSUUAWT", "type": "Refer", "targetType": "Space" } },
"createdBy": { "sys": { "id": "3p4tcFbQYJNvYTBJf2rYKr42xegQLJ", "type": "Refer", "targetType": "User" } },
"createdAt": "2026-07-15T12:35:47.575Z",
"updatedBy": { "sys": { "id": "3p4tcFbQYJNvYTBJf2rYKr42xegQLJ", "type": "Refer", "targetType": "User" } },
"updatedAt": "2026-07-15T12:35:47.575Z",
"version": 1
},
"name": "t6-http",
"directCallEnabled": true,
"anonymousCallEnabled": false,
"definition": {
"method": "Post",
"statements": [
{
"name": "resp",
"method": "POST",
"url": "https://postman-echo.com/post",
"headers": [ { "key": "Content-Type", "value": "application/json", "secret": false } ],
"body": { "prompt": "{ /payload/prompt }" },
"timeoutMs": 10000,
"retry": 0,
"type": "Http"
},
{
"value": { "status": "{ /resp/status }", "prompt": "{ /resp/body/json/prompt }" },
"isError": false,
"statusCode": 200,
"type": "Return"
}
]
}
}Key properties:
sys.id: The unique identifier of the Script. It goes into{scriptId}in the single-read, update, delete, and execute paths.name: The name of the Script (1-64 characters). Used in the on-screen list and for management identification.definition: TheScriptDefinitionthat declares what this Script does. It consists of the call method (method), thestatementsarray, and an optional payload schema (payloadSchema). Its detailed structure is covered in Definition and name below and in the top-level structure in Script Overview.directCallEnabled: Whether this Script can be called directly via/execute(boolean,truewhen omitted). Iffalse, direct calls are rejected. Other paths for running this Script remain as they are: a Webhook's linked action (script) and a Scheduler do not go through this endpoint, so they run it as usual.anonymousCallEnabled: Whether this Script can be called without authentication via/execute/anonymous(boolean,falsewhen omitted). Turning it on lets a third party that cannot carry a token run this Script through that path, and the run is performed under the author's identity. The conditions and save-time rules are covered in Anonymous calls below.
Note that sys has no status, publish, or archive. A Script is not a resource that gets published to a delivery path; it is a resource you author and run through the management APIs.
System properties (sys)
Every Script carries common system properties in the sys object. space, createdBy, and updatedBy are in the Refer shape ({ "sys": { "id", "type": "Refer", "targetType" } }).
| Property | Type | Description |
|---|---|---|
id | string | Unique resource identifier. |
type | string | Resource kind. For a Script this is always "Script". |
space | Refer<Space> | The Space this Script belongs to. |
createdBy | Refer<User> | The user who created it. |
createdAt | string (date-time) | Creation time. |
updatedBy | Refer<User> | The user who last updated it. |
updatedAt | string (date-time) | Last update time. |
version | integer (≥1) | Resource version. It increases by 1 with every create and update. |
The status (publish status) and publish (publish history) found in the sys of Content, Content Type, and Media are not present on a Script, because a Script is not published. There is no archive property either. As a result, a Script's version increases purely with the number of creates and updates, without any publishing.
Definition and name (name, definition)
A Script has four body properties: name, definition, directCallEnabled, and anonymousCallEnabled.
| Property | Required | Description |
|---|---|---|
name | Required | The name of the Script. 1-64 characters. |
definition | Required | ScriptDefinition. Made up of the keys in the table below. |
directCallEnabled | Optional | Whether this Script can be called directly via /execute. Boolean, true when omitted. If false, direct calls are rejected. A Webhook's linked action (script) and a Scheduler do not go through this endpoint, so they run it as usual. |
anonymousCallEnabled | Optional | Whether this Script can be called without authentication via /execute/anonymous. Boolean, false when omitted. See Anonymous calls below. PUT is a full replacement, so omitting it returns the value to false. |
Keys of definition (ScriptDefinition):
| Key | Required | Description |
|---|---|---|
method | Required | The HTTP method used to call this Script. One of Get, Post, Put, Patch, Delete. Execution is matched against this value. |
statements | Required | An ordered array of statements to run. At least 1. |
payloadSchema | Optional | A JSON Schema. If set, the request payload is validated against this schema before execution. |
The kinds and fields of each statement you put in the statements array are covered in Statement catalog, and the { /pointer } expressions that pass values through are covered in Value expressions.
In the "t6-http" example above, definition has method Post; it calls an external API with an Http statement and then returns the result with a Return statement. A statement that makes an external call, such as Http, declares its own share of time, and that much is added to the time one execution gets (see How much time one execution gets).
Constraints
| Target | Constraint |
|---|---|
name | 1-64 characters, required. |
definition.statements | At least 1, required. |
External calls (Http, EmailSend) per definition | Per plan (see Pricing). |
| Total statements per definition | Per plan (see Pricing, including nested). |
SetVar per definition | Up to 10 (default, including nested). |
Regex.pattern | Up to 128 characters. |
A definition with anonymousCallEnabled set to true | A where may not carry createdBy: ":self". See Anonymous calls below. |
| A Script another resource references | Cannot be deleted. If a Webhook references the Script as a linked action, or a Scheduler references the Script as its execution target, the deletion is rejected, and the code you get back differs by which resource holds the reference (the same goes for a Scheduler that is switched off; see Errors). |
The static constraints above are checked at save time (create/update), and a violation causes the save to be rejected. The number of external calls and the total number of statements are not validation errors but plan limits, so the same definition is allowed on a higher plan.
At save time, permissions and resource kinds are checked as well.
- Whether the author actually holds the resource and action permissions those statements use (if any one is missing, the save is rejected; see Errors). A statement that reads members (ServiceUser) is checked not through a permission map but against
SETTING_SERVICE_LOGINin the SpaceRolesettings. - If a statement that mutates a member (ServiceUser) is present, the save is rejected. That resource is read-only from a Script, so no role can save it.
The detailed rules, the time budget, and the value length limits checked while running are covered in Execution semantics, limits, and security.
A Script is a billable resource, and the number per Organization is limited by plan (Free 10 / Basic 30 / Pro 100 / Enterprise unlimited). Once the limit is reached, creating a new Script is rejected (see per-plan count limits).
Anonymous calls (anonymousCallEnabled)
Setting anonymousCallEnabled to true also makes that Script runnable through a dedicated unauthenticated path.
{method} https://script.weegloo.com/v1/spaces/{spaceId}/scripts/{scriptId}/execute/anonymousNeeding this is rare. It exists for a third party that has to send us a callback but cannot carry an Access Token because it does not support custom headers, as with some payment providers (PG, MoR). Every caller that can carry a token uses the authenticated path (/execute).
- The authenticated path is untouched.
/executestill requires a Bearer token and the Script Execute permission. The only thing that becomes unauthenticated is this one path,/execute/anonymous. - It takes no token. Even if a token is sent, it is ignored and the run is always under the author's identity. To run under the caller's identity, use
/execute. - Both gates must pass. If
anonymousCallEnabledisfalse, the call is rejected as unauthenticated access; ifdirectCallEnabledisfalse, it is rejected because direct calls are blocked. The code you get back depends on which gate caught the call (see Errors). Because anonymous permission is examined first, a caller with no standing cannot learn anything about the Script's configuration. - From there it is the same as
/execute: the request HTTP method must matchdefinition.method, and the call consumes the Organization's Script execution quota and is metered as usage. - This path is on the same Script host as the authenticated execution path (
https://script.weegloo.com/v1).
It runs as the author
Because there is no caller, the run is performed under the identity of the user who created the Script (sys.createdBy).
- The
createdByandupdatedByof any Content or Media the Script creates or updates are set to the author (not the anonymous caller; there is no other identity to attribute them to). createdBy: ":self"in awherealso resolves to the author rather than the caller. Leaving an ownership filter written for an authenticated caller in place and then turning anonymous on would silently open the author's own resources, so such a definition cannot be saved in the first place (see below).
Additional save-time checks
A Script whose anonymousCallEnabled is true gets one more rule.
| Rule | Code |
|---|---|
A where on ResourceFind or ResourceForEach may not carry createdBy: ":self" | See Errors |
That is because an anonymous call has no caller identity, so :self resolves to the author. Checking it at save time keeps an ownership filter written for an authenticated caller from being silently bypassed.
The real authentication is what the Script does for itself
There is no platform-provided authentication on this path. Anyone who knows the URL can call it, the call consumes the Organization's Script execution quota, and there is no separate rate limit. So an anonymous Script has to verify for itself what it was sent.
- Put a
Signaturefirst to check the signature over{ /rawPayload }, and cut the run short withReturnif it does not pass. A complete example is in Verifying a webhook signature in the cookbook. - Checking a replay window with
/nowas well blocks re-sending an earlier request (see/now). - Put only what that callback actually has to do in an anonymous Script. A Script runs with the author's permissions delegated to it, so whatever you put in is what you opened without authentication (see Security model).
ScriptLog
Each time a Script runs, one record is left behind. That record is a ScriptLog. It is read-only and has no create, update, or delete endpoints. Its path is /spaces/{spaceId}/scripts/{scriptId}/logs, and its base URL is not the execution host but CMA's https://cma.weegloo.com/v1. Reading it requires the Read permission on that Script.
{
"sys": {
"id": "3trmXRM7pLdV5Rz8kWq2NcHfJt4bYs",
"type": "ScriptLog",
"space": { "sys": { "id": "6jSUUAWT", "type": "Refer", "targetType": "Space" } },
"script": { "sys": { "id": "3trmXRMZcTAjDnphewjj1AaxYcaxlK", "type": "Refer", "targetType": "Script" } },
"trigger": { "sys": { "id": "3trmXRMZcTAjDnphewjj1AaxYcaxlK", "type": "Refer", "targetType": "Script" } },
"requestId": "3trmXRM9wTbK4Vz7hLp2QsNdRf6cYm",
"returned": true,
"value": { "status": 200, "prompt": "Summer dress product description, 3 lines" },
"success": true,
"statusCode": 200,
"durationMs": 195,
"createdBy": { "sys": { "id": "3p4tcFbQYJNvYTBJf2rYKr42xegQLJ", "type": "Refer", "targetType": "User" } },
"createdAt": "2026-07-15T12:41:03.902Z",
"updatedBy": { "sys": { "id": "3p4tcFbQYJNvYTBJf2rYKr42xegQLJ", "type": "Refer", "targetType": "User" } },
"updatedAt": "2026-07-15T12:41:03.902Z"
}
}All values are inside sys, and there are no body properties. A key with no value is omitted from the response.
| Property | Type | Description |
|---|---|---|
id | string | The unique identifier of the record. |
type | string | Always "ScriptLog". |
space | Refer<Space> | The Space this record belongs to. |
script | Refer<Script> | The Script that ran. |
trigger | Refer | What set this run off. See the explanation below. |
requestId | string | The identifier of this run. It is the same value as the requestId in the execution response envelope. |
returned | boolean | Whether a Return statement was reached. |
value | any | The value returned by the Return that was reached. An object, an array, or a scalar goes in as it is. If the run failed, the reason for the failure is carried here. |
success | boolean | Whether it succeeded. |
statusCode | integer | The status code set by the Return that was reached. |
durationMs | integer | How long the run took, in milliseconds. |
createdBy | Refer<User> or Refer<ServiceUser> | The identity this record is attributed to. See the explanation below. |
createdAt | string (date-time) | The record creation time. |
updatedBy | Refer<User> or Refer<ServiceUser> | The same as createdBy. |
updatedAt | string (date-time) | The same as createdAt. |
trigger points to what set this run off. For a direct call it is the Script itself; if it ran through a Webhook's linked action it is that Webhook; and if a Scheduler ran it, it is that Scheduler.
requestId is the same value as the requestId in the execution response envelope. To find the record of a run from the response the caller received, use this value as the reference.
The record is written once after the run ends and never changes. A successful run disappears after 1 hour, and a failed run after 3 days. For values you need to keep longer than that, save them as Content from inside the Script.
createdBy points to the identity the run was performed under. A run called with a Weegloo User token is that user, and a run called with a member (ServiceUser) token is that member. For a run with no caller, the identity comes from the trigger: an anonymous run is that Script's author, a run started by a Scheduler is that Scheduler's creator (who may differ from the Script's author), and one a Webhook ran is that Webhook's creator. A Webhook's runAs only decides whose name the work inside the Script is done under; it does not change this log's attribution.
Errors
These are the codes that come back when you call or delete a Script. The codes that come back when you save a definition are in the errors of Execution semantics, limits, and security, the codes for breaking the value expression rules are in the errors of Value expressions, and the codes that are common to every resource are in common errors.
| Code | Condition |
|---|---|
WGL422066 | A Webhook references the Script you are trying to delete as its linked action (the same goes for a Webhook that is switched off). |
WGL422110 | A Scheduler references the Script you are trying to delete as its execution target (the same goes for a Scheduler that is switched off). |
WGL401001 | A Script whose anonymousCallEnabled is false was called through the anonymous execution path (/execute/anonymous). |
WGL422062 | A Script whose directCallEnabled is false was called directly through an execution path (/execute, /execute/anonymous). |
WGL400007 | The HTTP method of the execution request differs from that Script's definition.method. A request body that was sent but is not a JSON object, and a body that does not satisfy the schema on a Script that has a definition.payloadSchema, are rejected with the same code as well. |
WGL408002 | The execution exceeded its time budget and was stopped. The execution record up to that point remains in the ScriptLog. |
API
The base URL for the five endpoints below (list, read, create, update, delete) is CMA's https://cma.weegloo.com/v1, and a Bearer token that authenticates against CMA is required in the Authorization header. Update must also send the X-Weegloo-Version header (the current resource's sys.version) for optimistic concurrency control. The two ScriptLog reads at the very bottom use the same CMA base URL.
The base URL for the two execution endpoints is the dedicated Script host, https://script.weegloo.com/v1. Authenticated execution (/execute) accepts both a Bearer token of a Weegloo User identity and a Bearer token of a member (ServiceUser) identity, and either way the caller needs the Execute permission on that Script.
Anonymous execution (/execute/anonymous) is the one exception that does not require an authentication header. It is on the same Script host, and it is reachable only when that Script has turned anonymousCallEnabled on (see Anonymous calls above).
The response in the authenticated execution example above has no return, because the target Script finished without reaching a Return that carries a value (in which case statusCode defaults to 200). When a Return hands a value back, as in the anonymous execution example, the response carries return (or error if Return.isError is true). The full rules for the response are covered in the request and response section in Script Overview.
Related documents
- Script Overview: Covers the top-level
ScriptDefinitionstructure, request and response, and how much time one execution gets. - Statement catalog: Covers the fields and results of each statement you put in
statements. - Value expressions: Covers
{ /pointer }references and JsonLogic operations. - Execution semantics, limits, and security: Covers static constraints, per-plan count limits, and the permission and security model.
- SpaceRole and ServiceUserRole: Cover how to grant a Script's action permissions (including
Execute) to a role.
