Catálogo de statements
Última actualización: 23 de julio de 2026
Cada elemento del array statements es un statement. Este documento recopila los campos, el comportamiento y el resultado de los 17 tipos de statement. Todas las posiciones de valor siguen las reglas de Expresiones de valor (referencias, literales, JsonLogic, mapas de locale).
Resumen de statements
| Categoría | type | Resumen en una línea |
|---|---|---|
| Escritura de recursos | ResourceCreate | Crea Content/Media (opcionalmente publica) |
ResourceUpdate | Reemplazo completo de los campos de Content/Media (elimina los field y locale no incluidos) | |
ResourcePatch | Fusión parcial de los campos de Content/Media (solo los field y locale indicados. El null literal elimina) | |
ResourceDelete | Elimina (solo Draft y Archived. Si está Published, primero hay que anular la publicación) | |
ResourcePublish / ResourceUnpublish | Publica / anula la publicación | |
ResourceArchive / ResourceUnarchive | Archiva / desarchiva | |
| Lectura de recursos | ResourceRead | Consulta un único elemento por id |
ResourceFind | Primera coincidencia por filtro (null si no hay) | |
ResourcePageRead | Consulta con filtro/orden/página ({ items, next }) | |
| Externo | Http | Llamada HTTP externa ({ status, body }). Exclusivo de Async |
| Variables | SetVar | Declara/actualiza una variable de ámbito de script |
| Flujo de control | If | Bifurcación condicional |
Loop | Bucle (foreach / while / counted) | |
Parallel | Ejecución en paralelo de ramas | |
Return | Devuelve el resultado y sale anticipadamente | |
Try | Manejo de excepciones (catch/finally) |
Las llamadas cíclicas se limitan a 3. Las sentencias de escritura de recursos anteriores (
ResourceCreate,ResourceUpdate,ResourcePublish, etc.) generan eventos de cambio, y esos eventos pueden ejecutar de nuevo un Script a través de un Webhook. Una cadena así (Script → evento → Webhook → Script → …) continúa como máximo 3 veces. A partir de ahí, la plataforma la interrumpe automáticamente para evitar bucles infinitos.
Campos comunes
{ "type": "<StatementType>", "name": "<opcional, único dentro del script>", /* ...campos según el tipo... */ }type: es el discriminador. Es uno de los valores de la tabla anterior (obligatorio).name: es opcional. Si se pone, el resultado se vincula al contexto como/<name>y los statements posteriores lo referencian con{ /<name>/... }. Si no se usa el resultado, se omite.- Reglas del nombre de vinculación:
name(y elasdeLoop) es una clave que se coloca directamente en la raíz del contexto, por lo que se valida al guardar. No puede ser una cadena vacía y no puede contener/ni~(debe poder usarse como clave de JSON Pointer), no puede coincidir con las raíces reservadas (payload,vars,error) y debe ser único dentro de un mismo Script. Si se incumple, el guardado se rechaza conWGL400033(formato),WGL400032(palabra reservada) oWGL400034(duplicado), respectivamente.
Forma de referencia a entidades
Las referencias a entidades como contentType y target se unifican en una única forma: { "sys": { "id": <expresión de valor> } }. Solo se necesita sys.id, y el tipo de destino se infiere de resource (sys.type y sys.targetType se omiten).
contentType.sys.idsuele ser un literal (por ejemplo,"ct_post").target.sys.ides normalmente una expresión de valor de la forma{ /ptr }(se resuelve en tiempo de ejecución; por ejemplo,{ /payload/sys/id }).
resource
Los statements de recursos indican el tipo de destino con resource: "Content" | "Media".
Escritura de recursos
Todos los statements de escritura tienen propagateEvents (por defecto false). Si se pone en true, esa escritura emite su propio EntityEvent (disparadores posteriores como el índice de búsqueda, Webhook, etc.). Por defecto no lo emite (escritura silenciosa del sistema).
ResourceCreate
Crea un Content o un Media. Content y Media comparten el modelo fields, y los valores son mapas de locale.
| Campo | Aplica a | Descripción |
|---|---|---|
resource | Común | "Content" o "Media" (obligatorio) |
contentType | Content | El Content Type que se va a crear ({ sys: { id } }). Obligatorio cuando es Content |
fields | Común | Mapa de campos { "<field>": { "<locale>": valor } }. Cada campo poblado requiere el bucket del locale por defecto. Las claves de Content siguen la definición del Content Type, y las de Media son fijas (title, description, file) |
locale | Común | (comodidad) Si se indica, envuelve automáticamente cada valor de fields como { <locale>: valor } |
publish | Común | Publica tras la escritura (exposición en CDA/ACDA). Por defecto true |
filedeMedia: el valor defields.file.{locale}es una instrucción de ingesta{ "source": <expresión de valor>, "encoding": "url"|"base64" }(ambos obligatorios). Una escritura de Media que incluye archivo es exclusiva de Async (en segundo plano, el motor la procesa en línea y luego la publica; igual para url y base64). También se puede crear un Media sin archivo (fileless). Sipublish:truepero no hay archivo o el procesamiento no ha terminado, se produce un error en la fase de publicación; conpublish:false, queda comoDraft.- Resultado (vinculado a
name): es el recurso creado.{ /<name>/sys/id },{ /<name>/fields/<field>/<locale> }.
// Content
{ "type": "ResourceCreate", "resource": "Content", "contentType": { "sys": { "id": "ct_post" } },
"fields": { "title": { "en-US": "{ /payload/fields/title }" } }, "publish": true, "name": "post" }
// Media. file es la instrucción de ingesta (solo Async)
{ "type": "ResourceCreate", "resource": "Media",
"fields": {
"title": { "en-US": "{ /payload/fields/prompt }" },
"file": { "en-US": { "source": "{ /gen/body/data/0/url }", "encoding": "url" } }
}, "name": "img" }ResourceUpdate
Reemplaza por completo los campos del Content o Media de destino (PUT). Lo que se pasa en fields se convierte tal cual en los nuevos campos, y los field y locale que no aparezcan aquí se eliminan. Para cambiar solo una parte, se usa ResourcePatch.
| Campo | Descripción |
|---|---|
resource | "Content" o "Media" |
target | Destino ({ sys: { id } }, obligatorio). El id suele ser { /ptr } |
fields | Todos los campos que se van a escribir. El valor es un mapa de locale. Al ser un reemplazo completo, se eliminan los field y locale que no aparezcan aquí. En Media, file es la instrucción de ingesta (véase ResourceCreate arriba). Los archivos enumerados se vuelven a ingerir siempre, y los archivos de los locale no incluidos se eliminan |
locale | (comodidad) Envuelve fields automáticamente |
version | (opcional) Expresión de valor (Int). Bloqueo optimista. Si se indica, actualiza solo cuando coincide con el sys.version actual del destino; si no coincide, aborta con un error de conflicto de versión (se puede capturar con Try). Si se omite, no hay comprobación (last-write-wins) |
publish | Vuelve a publicar tras la actualización. Por defecto true |
Si se usa Update para cambiar solo los metadatos de un Media, al faltar file se eliminan todos los archivos (porque es un reemplazo completo). Para un cambio parcial hay que usar ResourcePatch. Un Update que incluye archivo es exclusivo de Async.
{ "type": "ResourceUpdate", "resource": "Content", "target": { "sys": { "id": "{ /payload/sys/id }" } },
"fields": { "title": { "en-US": "Hello", "ko-KR": "안녕" }, "status": { "en-US": "published" } } }ResourcePatch
Fusiona parcialmente los campos del Content o Media de destino (PATCH). Sobrescribe solo los campos (y los locales dentro de ellos) que se indiquen, y mantiene sin cambios los campos y locales no mencionados. La forma del valor, locale, version y publish son iguales que en ResourceUpdate.
| Campo | Descripción |
|---|---|
resource | "Content" o "Media" |
target | Destino ({ sys: { id } }, obligatorio). El id suele ser { /ptr } |
fields | Los campos que se van a sobrescribir. El valor es un mapa de locale. Actualiza solo los campos y buckets de locale indicados (el resto se mantiene). Si el valor es un null literal, elimina ese (field, locale). En Media, file es la instrucción de ingesta (véase ResourceCreate arriba) |
locale | (comodidad) Envuelve fields automáticamente |
version | (opcional) Igual que en ResourceUpdate (bloqueo optimista) |
publish | Vuelve a publicar tras la actualización. Por defecto true |
- Eliminar un locale o un archivo concreto: se pasa un
nullliteral como valor. Por ejemplo:"title": { "fr-FR": null }(elimina el título fr-FR),"file": { "en-US": null }(elimina el archivo en-US). Que una expresión de valor se evalúe como null en tiempo de ejecución no es una eliminación, sino un error (solo el null literal elimina). - Si se da una instrucción de ingesta al
filede un Media, se reemplaza el archivo de ese locale (exclusivo de Async). Si no se da el archivo, se mantiene.
// +1 solo a viewCount(en-US). title, otros locales, etc. se conservan
{ "type": "ResourcePatch", "resource": "Content", "target": { "sys": { "id": "{ /payload/sys/id }" } },
"fields": { "viewCount": { "en-US": { "+": [ "{ /payload/fields/viewCount }", 1 ] } } } }ResourceDelete
Elimina el destino. Solo se puede eliminar en los estados Draft y Archived. Si está Published o Changed, se rechaza, por lo que primero hay que usar ResourceUnpublish (en Media, se rechaza si está procesando archivos (busy)). No anula la publicación automáticamente (igual en CMA/ACMA).
| Campo | Descripción |
|---|---|
resource | "Content" o "Media" |
target | Destino ({ sys: { id } }, obligatorio) |
{ "type": "ResourceDelete", "resource": "Content", "target": { "sys": { "id": "{ /payload/sys/id }" } } }ResourcePublish, ResourceUnpublish, ResourceArchive, ResourceUnarchive
Controla de forma independiente el estado de publicación y de archivado del destino. Los cuatro tienen los mismos campos. Las condiciones previas de status de cada operación son iguales que en CMA/ACMA (publicar no admite Archived y requiere que el procesamiento del archivo haya terminado; anular la publicación solo desde Published y Changed; archivar solo desde Draft; desarchivar solo desde Archived).
| Campo | Descripción |
|---|---|
resource | "Content" o "Media" |
target | Destino ({ sys: { id } }, obligatorio) |
version | (opcional) Expresión de valor (Int). Bloqueo optimista. Si se indica, se ejecuta solo cuando coincide con el sys.version actual |
{ "type": "ResourcePublish", "resource": "Content", "target": { "sys": { "id": "{ /payload/sys/id }" } } }
{ "type": "ResourceUnpublish", "resource": "Content", "target": { "sys": { "id": "{ /payload/sys/id }" } } }
{ "type": "ResourceArchive", "resource": "Media", "target": { "sys": { "id": "{ /m/sys/id }" } } }Lectura de recursos
Los statements de lectura no cambian el estado (no tienen propagateEvents).
Los tres statements de lectura determinan de qué versión almacenada leer con from (opcional, Current por defecto). Current es el borrador más reciente que ve el estudio de contenidos (el valor que leen CMA/ACMA), y Published es la instantánea publicada (el valor en el momento de la última publicación, que entregan CDA/ACDA).
Además, ResourceFind y ResourcePageRead pueden activar la búsqueda avanzada (Advanced Search) con advanced (opcional, por defecto false). Es exclusiva de Content, por lo que se ignora en las lecturas de Media. Cuando está activada, en where se pueden usar los operadores regex, near y within y la búsqueda de texto completo (en un campo LongText con la búsqueda de texto completo activada, eq también encuentra los elementos que contienen el valor, por coincidencia parcial y aproximada), y order puede ordenar por fields.*. Cuando está desactivada, esos tres operadores se rechazan, eq sobre texto es coincidencia exacta, y prefix y los operadores de comparación y de lista funcionan con independencia de la búsqueda avanzada. Un elemento recién creado o modificado tarda un breve instante (alrededor de 1 segundo) en reflejarse en la búsqueda avanzada, por lo que la consulta de búsqueda avanzada inmediatamente posterior puede no encontrarlo. Para leer de inmediato un elemento recién escrito, se usa ResourceRead por id (el almacén principal, sin retardo de reflejo) o se consulta por el sys.id que devolvió la escritura.
En where y order, los campos de contenido se escriben como fields.<field> (el nombre por sí solo no se reconoce). A fields.<field> se le aplica automáticamente el locale predeterminado del Space, por lo que no se le añade el locale directamente. En los ejemplos de abajo, fields.status y fields.slug son, tal cual, consultas del locale predeterminado. Solo cuando se quiere apuntar a un locale específico (no predeterminado) se especifica como fields.<field>.<locale> (por ejemplo, fields.title.ko-KR). sys.* (como sys.createdAt) y createdBy (:self) se escriben tal cual, sin fields.. Las reglas detalladas están en El locale en where y order.
ResourceRead
Es una consulta de un único elemento por id (get-by-id). El resultado vincula el recurso completo al nombre.
| Campo | Descripción |
|---|---|
resource | "Content" o "Media" |
target | Destino ({ sys: { id } }). El id es una expresión de valor |
from | (opcional) Current (por defecto, el borrador más reciente) o Published (la instantánea publicada) |
- Resultado: se referencian directamente
{ /<name>/sys/id }y{ /<name>/fields/<field>/<locale> }(no hace faltaitems/0). - Si el destino no existe, es un error. Se puede manejar envolviéndolo con
Try.
{ "type": "ResourceRead", "resource": "Content",
"target": { "sys": { "id": "{ /payload/fields/orderId }" } }, "name": "order" }ResourceFind
Lee el primer registro que coincide con el filtro. Si no hay ninguna, es null. Se usa para encontrar un único registro por una clave de negocio única (slug, email, sku).
| Campo | Descripción |
|---|---|
resource | "Content" o "Media" |
contentType | (Content) El Content Type que define el ámbito de búsqueda ({ sys: { id } }) |
where | Filtro ({ "<field>": { "<op>": <valor> } }). Los operadores son los de la lista de operadores (regex/near/within requieren advanced). Admite createdBy: ":self" |
order | Orden que determina cuál es «la primera» cuando hay varias coincidencias (por ejemplo, "-sys.createdAt") |
from | (opcional) Current (por defecto, el borrador más reciente) o Published (la instantánea publicada) |
advanced | (opcional) Ejecutar mediante búsqueda avanzada (Advanced Search). Solo Content (Media se ignora). Por defecto false. Véase la nota Lectura de recursos anterior. |
- Resultado: vincula al nombre el recurso de la primera coincidencia. Se referencia directamente con
{ /<name>/fields/<field>/<locale> }. Como esnullcuando no hay ninguna, se bifurca según su existencia con{ "==": [ "{ /<name> }", null ] }(el patrón típico de find-then-upsert).
{ "type": "ResourceFind", "resource": "Content", "contentType": { "sys": { "id": "ct_article" } },
"where": { "fields.slug": { "eq": "{ /payload/fields/slug }" } }, "name": "found" }ResourcePageRead
Es una consulta con filtro, orden y página.
| Campo | Descripción |
|---|---|
resource | "Content" o "Media" |
contentType | (Content) El Content Type que define el ámbito de búsqueda |
where | Filtro ({ "<field>": { "<op>": <valor> } }). Los operadores son los de la lista de operadores (regex/near/within requieren advanced). Admite createdBy: ":self" |
order | Orden (por ejemplo, "-sys.createdAt") |
limit | Tamaño de página (100 o menos) |
cursor | Para la página siguiente, el next del resultado anterior |
from | (opcional) Current (por defecto, el borrador más reciente) o Published (la instantánea publicada) |
advanced | (opcional) Ejecutar mediante búsqueda avanzada (Advanced Search). Solo Content (Media se ignora). Por defecto false. Véase la nota Lectura de recursos anterior. |
- Resultado: es
{ items, next }.{ /<name>/items/0/... }; para la página siguiente,{ /<name>/next }. - El recorrido completo se hace con
Loop while "{ /vars/hasMore }",cursory acumulación conSetVar(véase el Cookbook).
{ "type": "ResourcePageRead", "resource": "Content", "contentType": { "sys": { "id": "ct_post" } },
"where": { "fields.status": { "eq": "draft" } }, "order": "-sys.createdAt", "limit": 100, "name": "page" }Externo
Http
Llama a un HTTP externo. Si hay un Http, executionMode debe ser Async (ExternalIo).
| Campo | Descripción |
|---|---|
method | "GET", "POST", "PUT", "PATCH", "DELETE" |
url | La URL de destino (expresión de valor; se puede insertar { /ptr }) |
headers | [{ "key", "value", "secret"? }]. value es una expresión de valor. Las cabeceras con secret:true se tratan como de uso exclusivo de CMA (administrador): no se exponen al usuario final y solo se descifran justo antes de la transmisión |
body | El cuerpo de la petición (expresión de valor o JSON) |
timeoutMs | El tiempo de espera de esta llamada (ms) |
retry | Número de reintentos cuando el status de la respuesta es 400 o superior. Por defecto 0; el máximo es maxHttpRetry (por defecto 2) |
ignoreStatusCode | Determina si esta llamada se trata como un fallo cuando el status final (tras los reintentos) es 400 o superior. Con false (por defecto), se trata como un fallo y pasa a ser objeto de Try/catch. Con true, no se trata como un fallo y { status, body } se vincula tal cual (el llamante bifurca según el propio status) |
- Resultado: es
{ status, body }.{ /<name>/status },{ /<name>/body/... }. - Límite de tamaño de la respuesta: el cuerpo de la respuesta es de 10MiB como máximo. Si lo supera, esta llamada falla con una excepción y se puede manejar como cualquier otro fallo de tiempo de ejecución con
Try/catch(es un fallo basado en el tamaño, por lo que no se suprime conignoreStatusCode).
{ "type": "Http", "method": "POST", "url": "https://api.llm.com/v1/gen",
"headers": [ { "key": "Authorization", "value": "Bearer sk-...", "secret": true } ],
"body": { "prompt": "{ /payload/fields/prompt }" }, "timeoutMs": 15000, "retry": 1, "name": "resp" }Variables
SetVar
Declara o actualiza una variable mutable de ámbito de script. Se referencia con { /vars/<var> } (como JsonLogic no tiene declaración de variables, se ofrece como statement).
| Campo | Descripción |
|---|---|
var | El nombre de la variable. Se referencia con { /vars/<var> } |
value | Expresión de valor. Puede acumular haciendo referencia a sí misma |
{ "type": "SetVar", "var": "total", "value": 0 }
{ "type": "SetVar", "var": "total", "value": { "+": [ "{ /vars/total }", "{ /row/qty }" ] } } // acumulación
{ "type": "SetVar", "var": "ids", "value": { "merge": [ "{ /vars/ids }", [ "{ /row/sys/id }" ] ] } } // recolección en arrayFlujo de control
If
Es una bifurcación condicional. condition es JsonLogic, y lo verdadero y lo falso siguen las reglas de evaluación de verdadero y falso.
| Campo | Descripción |
|---|---|
condition | JsonLogic (se evalúa como boolean) |
then | Array de statements a ejecutar cuando es verdadero |
else | (opcional) Array de statements a ejecutar cuando es falso |
{ "type": "If",
"condition": { "<": [ "{ /wallet/fields/balance/en-US }", "{ /payload/fields/cost }" ] },
"then": [ { "type": "Return", "value": { "ok": false, "reason": "insufficient credit" } } ],
"else": [ /* ... */ ] }Loop
Es un bucle. Se elige un solo modo: over (foreach), while (condición) o for (recuento). En cualquier modo, el motor impone un límite superior con maxIterations (para evitar bucles infinitos). Dentro de body están prohibidas las llamadas externas (Http, ingesta de archivos de Media).
| Campo | Descripción |
|---|---|
over | foreach: expresión de valor que se resuelve como array |
while | condición: JsonLogic (repite mientras sea verdadero) |
for | recuento: { "from", "to", "step"? }. Desde from hasta to inclusive, step por defecto 1 |
maxIterations | Número máximo de iteraciones que impone el motor (obligatorio) |
as | Nombre al que se vincula el elemento o índice actual ({ /<as> }) |
body | Array de statements del cuerpo del bucle |
// foreach
{ "type": "Loop", "over": "{ /payload/fields/items }", "as": "item", "maxIterations": 100,
"body": [ { "type": "ResourceCreate", "resource": "Content", "contentType": { "sys": { "id": "ct_item" } },
"fields": { "name": { "en-US": "{ /item/name }" } } } ] }
// while
{ "type": "Loop", "while": "{ /vars/hasMore }", "maxIterations": 1000, "body": [ /* ... */ ] }
// counted (1..10 step 2)
{ "type": "Loop", "for": { "from": 1, "to": 10, "step": 2 }, "as": "i", "maxIterations": 100, "body": [ /* ... */ ] }Parallel
Ejecuta las ramas en paralelo y continúa tras la unión (join). No se puede hacer referencia entre ramas (si hay dependencias, se colocan de forma secuencial).
| Campo | Descripción |
|---|---|
branches | Statement[][]. Cada elemento es una rama (array de statements) |
{ "type": "Parallel", "branches": [
[ { "type": "Http", "method": "GET", "url": "https://api.a.com/x", "name": "a" } ],
[ { "type": "Http", "method": "GET", "url": "https://api.b.com/y", "name": "b" } ]
] }Return
Es el return habitual de la programación. Devuelve el resultado del Script al llamante y termina de forma normal en ese punto.
| Campo | Descripción |
|---|---|
value | (opcional) Expresión de valor a devolver |
isError | Por defecto false. Si es true, value sale como el error de la respuesta (si no, como return) |
statusCode | Código de estado de la respuesta. Por defecto 200 |
- Si no se llega a un
Return, no hay valor de retorno. Para devolver un resultado, se especificavalue. - Al ser una terminación normal y no una excepción o un throw, no es objeto de
catch(incluso dentro de unTrytermina todo el Script, pero elfinallysí se ejecuta). - Los guards también se expresan con este statement:
Ifconthen:[Return](si se viola la condición, retorna y no se ejecuta lo posterior), y es uno de sus varios usos.
{ "type": "Return", "value": { "orderId": "{ /order/sys/id }", "status": "paid" }, "statusCode": 201 }
{ "type": "Return", "value": { "reason": "payment failed" }, "isError": true, "statusCode": 402 }Try
Es el manejo de excepciones.
| Campo | Descripción |
|---|---|
body | Array de statements a intentar |
catch | (opcional) Se ejecuta si body falla. Expone { message, statement } en /error |
finally | (opcional) Se ejecuta siempre, con éxito o con fallo |
- Si
catchlo maneja, el Script no se interrumpe. Solo un fallo sincatchinterrumpe el Script (incluido el intento de compensación). - Qué se considera un «fallo» y los límites de la compensación (compensation) se tratan en Semántica de ejecución, restricciones y seguridad.
{ "type": "Try",
"body": [ { "type": "Http", "method": "POST", "url": "https://primary.api/gen", "name": "resp" },
{ "type": "ResourceCreate", "resource": "Content", "contentType": { "sys": { "id": "ct_result" } },
"fields": { "text": { "en-US": "{ /resp/body/text }" } } } ],
"catch": [ { "type": "ResourceCreate", "resource": "Content", "contentType": { "sys": { "id": "ct_result" } },
"fields": { "text": { "en-US": "Generación fallida" }, "error": { "en-US": "{ /error/message }" } } } ],
"finally": [ /* siempre se ejecuta */ ] }Documentos relacionados
- Expresiones de valor: las reglas de valor que siguen todos los campos anteriores.
- Semántica de ejecución, restricciones y seguridad: orden de ejecución, errores, restricciones estáticas y seguridad.
- Cookbook: ejemplos completos que combinan estos statements.
- Descripción general de Script: la estructura de nivel superior y los modos de ejecución.
