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íatypeResumen en una línea
Escritura de recursosResourceCreateCrea Content/Media (opcionalmente publica)
ResourceUpdateReemplazo completo de los campos de Content/Media (elimina los field y locale no incluidos)
ResourcePatchFusión parcial de los campos de Content/Media (solo los field y locale indicados. El null literal elimina)
ResourceDeleteElimina (solo Draft y Archived. Si está Published, primero hay que anular la publicación)
ResourcePublish / ResourceUnpublishPublica / anula la publicación
ResourceArchive / ResourceUnarchiveArchiva / desarchiva
Lectura de recursosResourceReadConsulta un único elemento por id
ResourceFindPrimera coincidencia por filtro (null si no hay)
ResourcePageReadConsulta con filtro/orden/página ({ items, next })
ExternoHttpLlamada HTTP externa ({ status, body }). Exclusivo de Async
VariablesSetVarDeclara/actualiza una variable de ámbito de script
Flujo de controlIfBifurcación condicional
LoopBucle (foreach / while / counted)
ParallelEjecución en paralelo de ramas
ReturnDevuelve el resultado y sale anticipadamente
TryManejo 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 el as de Loop) 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 con WGL400033 (formato), WGL400032 (palabra reservada) o WGL400034 (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.id suele ser un literal (por ejemplo, "ct_post").
  • target.sys.id es 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.

CampoAplica aDescripción
resourceComún"Content" o "Media" (obligatorio)
contentTypeContentEl Content Type que se va a crear ({ sys: { id } }). Obligatorio cuando es Content
fieldsComúnMapa 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)
localeComún(comodidad) Si se indica, envuelve automáticamente cada valor de fields como { <locale>: valor }
publishComúnPublica tras la escritura (exposición en CDA/ACDA). Por defecto true
  • file de Media: el valor de fields.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). Si publish:true pero no hay archivo o el procesamiento no ha terminado, se produce un error en la fase de publicación; con publish:false, queda como Draft.
  • 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.

CampoDescripción
resource"Content" o "Media"
targetDestino ({ sys: { id } }, obligatorio). El id suele ser { /ptr }
fieldsTodos 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)
publishVuelve 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.

CampoDescripción
resource"Content" o "Media"
targetDestino ({ sys: { id } }, obligatorio). El id suele ser { /ptr }
fieldsLos 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)
publishVuelve a publicar tras la actualización. Por defecto true
  • Eliminar un locale o un archivo concreto: se pasa un null literal 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 file de 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).

CampoDescripción
resource"Content" o "Media"
targetDestino ({ 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).

CampoDescripción
resource"Content" o "Media"
targetDestino ({ 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.

CampoDescripción
resource"Content" o "Media"
targetDestino ({ 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 falta items/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).

CampoDescripción
resource"Content" o "Media"
contentType(Content) El Content Type que define el ámbito de búsqueda ({ sys: { id } })
whereFiltro ({ "<field>": { "<op>": <valor> } }). Los operadores son los de la lista de operadores (regex/near/within requieren advanced). Admite createdBy: ":self"
orderOrden 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 es null cuando 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.

CampoDescripción
resource"Content" o "Media"
contentType(Content) El Content Type que define el ámbito de búsqueda
whereFiltro ({ "<field>": { "<op>": <valor> } }). Los operadores son los de la lista de operadores (regex/near/within requieren advanced). Admite createdBy: ":self"
orderOrden (por ejemplo, "-sys.createdAt")
limitTamaño de página (100 o menos)
cursorPara 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 }", cursor y acumulación con SetVar (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).

CampoDescripción
method"GET", "POST", "PUT", "PATCH", "DELETE"
urlLa 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
bodyEl cuerpo de la petición (expresión de valor o JSON)
timeoutMsEl tiempo de espera de esta llamada (ms)
retryNúmero de reintentos cuando el status de la respuesta es 400 o superior. Por defecto 0; el máximo es maxHttpRetry (por defecto 2)
ignoreStatusCodeDetermina 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 con ignoreStatusCode).
{ "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).

CampoDescripción
varEl nombre de la variable. Se referencia con { /vars/<var> }
valueExpresió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 array

Flujo 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.

CampoDescripción
conditionJsonLogic (se evalúa como boolean)
thenArray 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).

CampoDescripción
overforeach: expresión de valor que se resuelve como array
whilecondición: JsonLogic (repite mientras sea verdadero)
forrecuento: { "from", "to", "step"? }. Desde from hasta to inclusive, step por defecto 1
maxIterationsNúmero máximo de iteraciones que impone el motor (obligatorio)
asNombre al que se vincula el elemento o índice actual ({ /<as> })
bodyArray 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).

CampoDescripción
branchesStatement[][]. 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.

CampoDescripción
value(opcional) Expresión de valor a devolver
isErrorPor defecto false. Si es true, value sale como el error de la respuesta (si no, como return)
statusCodeCó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 especifica value.
  • Al ser una terminación normal y no una excepción o un throw, no es objeto de catch (incluso dentro de un Try termina todo el Script, pero el finally sí se ejecuta).
  • Los guards también se expresan con este statement: If con then:[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.

CampoDescripción
bodyArray 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 catch lo maneja, el Script no se interrumpe. Solo un fallo sin catch interrumpe 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 */ ] }