Skip to main content
A SCRIPT step runs JavaScript inside an Activity. It is the right tool when the workflow needs custom logic that is too specific for a declarative step. Script steps are commonly used to inspect documents, normalize extracted data, assign knowledge features, call Service Bridges, and decide which branch of the Activity Plan should run next.

When to Use a SCRIPT Step

Use a SCRIPT step when you need to:
  • Route the Activity based on document content, metadata, extraction results, or task status
  • Make several checks before deciding whether human review is needed
  • Update document metadata, labels, tags, data objects, or attributes
  • Assign knowledge features to document families
  • Call one or more Service Bridges and combine their responses
  • Emit a named action for downstream dependencies
Do not use a script just to make one external API call. Use a Service Bridge step for that so the external call has its own step status, logs, retry behavior, and result.

Step Configuration

The script must return an object with an action property when downstream routing depends on the step.
Downstream steps can depend on that action:
Actions are identified by their slug. Downstream dependsOn entries use "step:actionSlug" to match a specific outcome. The action’s name is the value the script returns (e.g. return { action: "review" }) and the display label the runtime surfaces in logs. Older plans use a uuid field on each action — that is the legacy spelling of slug and still resolves, but new authoring should use slug.

Return Value

The full return value can carry three optional pieces alongside action:
features and nextActivity are independent — return either, both, or neither.

Spawning a Follow-Up Activity

A SCRIPT step can request another Activity Plan to start automatically when the current Activity completes. Use this to chain related work, e.g. “after intake classifies an invoice, kick off the extraction plan.” The spawned Activity:
  • Starts only after the current Activity reaches COMPLETED (not on individual step completion).
  • Inherits the current Activity’s project. The target plan must already be bound to that project.
  • Inherits the current Activity’s document families when documentFamilyIds is omitted.
  • Records its source in triggerMetadata (sourceActivityId, sourceStepId, sourceActionUuid, sourceProjectId) so audit trails work in both directions.
  • Has triggerKind set to ACTIVITY_COMPLETED.

nextActivity shape

Failure handling

Spawn failures are soft. If the target plan doesn’t exist, the plan is not bound to the current project, or inputs fail validation, the source Activity still finishes cleanly. The failure is recorded on the source step in script_result.nextActivityError. On success, script_result.nextActivityId is set to the new Activity’s ID.

Multiple spawns

Each SCRIPT step in a plan may emit its own nextActivity. They fan out at the source Activity’s completion in step insertion order. Within a single script return, only one nextActivity is supported.

Same-project only

A script can only spawn Activity Plans bound to the current project. Cross-project spawns are rejected. If you need fan-out across projects, model it through a Service Bridge call instead.

Activity SCRIPT Runtime

Activity Plan SCRIPT steps run in the server-side JavaScript runtime. The runtime exposes the same business objects the Activity is working on, plus helper namespaces for task state, document families, document content, Service Bridges, LLM calls, and knowledge features. The current Activity Plan script context is centered on the Task and its document families. The Activity’s materialized inputs are also available through the read-only inputs global, which defaults to {} when the Activity has no inputs — so you can read values such as inputs.invoiceNumber, inputs.routeId, or inputs.correlationId directly. This inputs global is a snapshot for reading and is distinct from the nextActivity.inputs spawn payload above. For prior step outputs, use declarative step mappings and pass the needed values into document metadata, task data, or downstream step configuration.

Runtime Limits

The 300 second (5 minute) script timeout is the maximum wall-clock time the SCRIPT body’s JavaScript may run before it is aborted. Other step kinds use their own distinct timeouts: BRIDGE_CALL steps default to a 30 second HTTP timeout (author-overridable via the step’s timeout, capped at 120 seconds), and AI_PROMPT steps allow up to 120 seconds for the LLM call.
The script timeout and two related orchestrator budgets are operator-tunable through environment variables on the orchestrator. Authors do not set these per step; they are platform-wide defaults.Plan-advance runs on its own detached budget, so a returning step-result request no longer cancels it and long SCRIPT steps are no longer stranded mid-advance. Because a SCRIPT step running inside plan-advance has its binding-side database and Service Bridge calls bounded by the advance budget, always keep PLANNER_ADVANCE_TIMEOUT greater than or equal to PLANNER_SCRIPT_TIMEOUT (the defaults preserve roughly 3x headroom). If the advance budget expires first, the script fails with context deadline exceeded before its own script timeout would fire.
Document changes are saved after the script completes. Modified KDDB documents are persisted as new content object versions with the SCRIPT_MODIFICATION transition type.

Task Namespace

Use tasks when a script needs to inspect or update human review work inside the current project.

Document Family Namespace

Use documents when a script needs to manage document family state without loading the full KDDB document.

Routing Example

This script loads the first Task document, inspects its text, and routes the Activity to review, rejection, or straight-through posting.

Updating Documents

Document changes made by a script are persisted after the step completes.
Do not call doc.close() in Activity Plan scripts. Kodexa persists document changes after the script completes.

Calling Service Bridges from a Script

Use serviceBridge.call() inside a SCRIPT step when the decision requires more than a single declarative bridge call.
Service bridge credentials stay in the platform. Scripts reference the configured bridge and endpoint; they do not handle secrets directly.

Shared Script Sidecars

Use scriptSidecars to pre-load reusable JavaScript helpers.
Sidecars are useful for shared validation functions, string cleanup, request mapping, and common routing decisions. Keep sidecars small and version them like any other project resource.

Design Guidance

  • Declare every returned action in scriptActions.
  • Keep scripts focused on one decision or one transformation.
  • Prefer BRIDGE_CALL for a single external API call that operators should see as its own step.
  • Use logs at important decision points.
  • Make scripts idempotent when they can be retried.
  • Avoid long loops and repeated document loads.

Next Steps

Script API Reference

See the full JavaScript context, document helpers, LLM calls, and logging reference.

Service Bridge Steps

Learn when to model an external API call as its own Activity Plan step.