# Scripting API \[Beta]

As of [version 2.0](/releases.md#2-0), *Workflower* has its own scripting **API in beta** to automate all kinds of processes in *After Effects* + *Workflower*.

{% hint style="warning" %}
**IMPORTANT:** As of [version 2.5.1](/releases.md#id-2-5), the scripting API variable has been changed from ***wfAPI*** to ***workflowerScriptAPI*** in order to prevent possible issues stemming from short global variables. Please adapt your scripts to this change. The legacy variable *wfAPI* is currently still active but will be disabled in the future. (You will always be able to use the old variable in coming versions by going to *Settings > System > Use Legacy Scripting API Variable wfAPI*.)
{% endhint %}

{% hint style="danger" %}
Please be aware that the **API is experimental** at the moment and has to be used with caution! Some functions might not work as expected.

Also, the API is still very limited but this will change in the future as more functions will get added.
{% endhint %}

## API Variable

The API variable (a global variable) is called:

```
workflowerScriptAPI
```

*Workflower* needs to have been started at least once in your current session for the API variable to be active.

You can easily check whether the API exists, like this (and if it doesn't exist, just open and close the ScriptUI Panel, so the variable gets established):

{% code lineNumbers="true" %}

```javascript
// FUNCTION: Check whether Workflower API Variable exists
function workflowerScriptAPIExists(){
    
    // If it exists --> Return true
    if (typeof workflowerScriptAPI !== 'undefined'){
        return true;
    }
    
    // Check whether the ScriptUI Panel is installed (& return false if not)
    var wfMenuID = app.findMenuCommandId('Workflower ScriptUI Panel.jsxbin');
    if (!wfMenuID){
        return false;
    }
    
    // Open & Close ScriptUI Panel to establish API Variable
    app.executeCommand(wfMenuID);
    app.executeCommand(wfMenuID);
    
    // If API Variable now exists, return true, else false
    if (typeof workflowerScriptAPI !== 'undefined'){
        return true;
    } else {
        return false;
    }

}
```

{% endcode %}

## How to use API Functions

The *Workflower* functions listed below are exposed to the API. Just call them and use their arguments if you want to.

If a parameter is undefined, the default execution value is used.

### Using Functions in Non-Active Comps

Currently, it is recommended to **only use API functions in your active comp**. They theoretically work when processing other comps but unexpected behaviors can occur!

The exception to this is [**workflowerScriptAPI.refreshLayout()**](#workflowerscriptapi.refreshlayout) and [**workflowerScriptAPI.refreshLayouts()**](#workflowerscriptapi.refreshlayouts) which should execute the other comps properly when fed into the function.

So to be safe when using all other functions, always check whether the comp you want to work on is active. Like this:

<pre class="language-javascript"><code class="lang-javascript">// FUNCTION: Start the Workflower Execution
<strong>function startWfExecution(elementsToProcess){
</strong><strong>
</strong><strong>    // Get Comp to Process from Element
</strong><strong>    var compToProcess;
</strong><strong>    if (elementsToProcess[0] instanceof CompItem){
</strong><strong>        compToProcess = elementsToProcess[0];
</strong><strong>    } else {
</strong><strong>        compToProcess = elementsToProcess[0].containingComp;
</strong><strong>    }
</strong><strong>
</strong><strong>    // Check Active Comp &#x26; Change if needed
</strong><strong>    var saveOrigActiveItem = app.project.activeItem;
</strong>    if (compToProcess !== app.project.activeItem){
        compToProcess.openInViewer();
    }

    // Return with Original Active Item, so we can revert back to it later
    return saveOrigActiveItem;
    
}

// FUNCTION: End the Workflower Execution
function endWfExecution(saveOrigActiveItem){

    // Switch Active Comp back if needed
    if (saveOrigActiveItem !== app.project.activeItem){
        saveOrigActiveItem.openInViewer();
    }
    
}

// Execute Workflower Action
app.beginUndoGroup("Create Multi-Layer Matte");
var layersToMatteTo = [layer1, layer2, layer3];
var startWfInfo = startWfExecution(layersToMatteTo);
workflowerScriptAPI.createMatte(layersToMatteTo);
endWfExecution(startWfInfo);
app.endUndoGroup();
</code></pre>

### Undo Groups

When calling a function through the API, *Workflower* will **not** create any undo groups to ensure that you can wrap everything in your own undo groups and don't get any undo mismatch errors.

The only exception to this is [**workflowerScriptAPI.execute()**](#workflowerscriptapi.execute) which lets you define whether you want *Workflower* to create undo groups or not.

### Error Handling

{% hint style="danger" %}
At the moment, the *Workflower* API will **not** throw any custom errors. So always double-check with the user guide that the function is called properly. If you come across any unexpected errors, please contact customer support.
{% endhint %}

## Attributes

### workflowerScriptAPI.<mark style="color:green;">scriptVersion</mark>

{% code overflow="wrap" %}

```javascript
workflowerScriptAPI.scriptVersion
```

{% endcode %}

The currently installed version number of *Workflower*.

#### Type

String of script version number; read-only

### workflowerScriptAPI.<mark style="color:green;">apiVersion</mark>

{% code overflow="wrap" %}

```javascript
workflowerScriptAPI.apiVersion
```

{% endcode %}

The current version number of the *Workflower* API.

#### Type

String of API version number; read-only

## System Check Functions

### workflowerScriptAPI.<mark style="color:orange;">scriptExists</mark>()

{% code overflow="wrap" %}

```javascript
workflowerScriptAPI.scriptExists()
```

{% endcode %}

Checks whether the *Workflower* script exists.

#### Returns

Boolean

### workflowerScriptAPI.<mark style="color:orange;">scriptUiPanelExists</mark>()

{% code overflow="wrap" %}

```javascript
workflowerScriptAPI.scriptUiPanelExists()
```

{% endcode %}

Checks whether the *Workflower* ScriptUI Panel exists.

#### Returns

Boolean

## Layer & Group Check Functions

### workflowerScriptAPI.<mark style="color:orange;">cleanNames</mark>()

{% code overflow="wrap" %}

```javascript
workflowerScriptAPI.cleanNames(layerNames)
```

{% endcode %}

Cleans layer names, i.e. removes all special characters added by *Workflower* as well as the indent.

#### Parameters

* **layerNames:** *Array of layer name strings* to be cleaned.

#### Returns

Array of layer name strings

### workflowerScriptAPI.<mark style="color:orange;">isWfComp</mark>()

{% code overflow="wrap" %}

```javascript
workflowerScriptAPI.isWfComp(comp)
```

{% endcode %}

Checks whether a given comp is a *Workflower* comp.

#### Parameters

* **comp:** *Comp object* to be checked.

#### Returns

Boolean

### workflowerScriptAPI.<mark style="color:orange;">isGroupHeader</mark>()

{% code overflow="wrap" %}

```javascript
workflowerScriptAPI.isGroupHeader(layer)
```

{% endcode %}

Checks whether a given layer is a group header.

#### Parameters

* **layer:** *Layer object* to be checked.

#### Returns

Boolean

### workflowerScriptAPI.<mark style="color:orange;">getAllGroupLayers</mark>()

{% code overflow="wrap" %}

```javascript
workflowerScriptAPI.getAllGroupLayers(groupHeader[, excludeStartersFooters])
```

{% endcode %}

Gets all group layers to a given group header.

#### Parameters

* **groupHeader:** *Layer object* of the group header.
* **excludeStartersFooters:** Optional. *Boolean* to determine whether returning array should exclude *Workflower's* [internal shy'd starter and footer layers](/group-functions/create-and-duplicate-groups.md#additional-layers-to-keep-in-mind). Default is false.

#### Returns

Array of layer objects of the group layers

### workflowerScriptAPI.<mark style="color:orange;">isInTagID</mark>()

{% code overflow="wrap" %}

```javascript
workflowerScriptAPI.isInTagID(layer, tagID)
```

{% endcode %}

Checks whether a given layer is within a [tag group](/layer-functions/tagging-layers.md) with a certain ID (0 - 16). Added in script version 2.04 / API version 0.2.

#### Parameters

* **layer:** *Layer object* to be checked.
* **tagID:** *Integer* of tag ID (0 - 16).

#### Returns

Boolean

### workflowerScriptAPI.<mark style="color:orange;">isInTagName</mark>()

{% code overflow="wrap" %}

```javascript
workflowerScriptAPI.isInTagName(layer, tagName)
```

{% endcode %}

Checks whether a given layer is within a [tag group](/layer-functions/tagging-layers.md) with a certain name. Added in script version 2.04 / API version 0.2.

#### Parameters

* **layer:** *Layer object* to be checked.
* **tagName:** *String* of tag name.

#### Returns

Boolean

## Major Functions

### workflowerScriptAPI.<mark style="color:orange;">execute</mark>()

{% code overflow="wrap" %}

```javascript
workflowerScriptAPI.execute(functionName[, doCreateUndoGroup])
```

{% endcode %}

Executes a function, as specified by the function name. Names are identical to [KBar function names](/installation.md#function-names).

{% hint style="warning" %}
This function only calls the regular *Workflower* functions as they are called by the user interface. The other dedicated API functions, on the other hand, let you define custom arguments as well.
{% endhint %}

{% hint style="info" %}
workflowerScriptAP&#x49;*.execute()* is the only API function that allows for the automatic creation of Workflower's regular undo groups. Set *doCreateUndoGroup* to *true* if you want to force it to create undo groups.
{% endhint %}

#### Parameters

* **functionName:** *String* of a function name to be executed. Names are identical to [KBar function names](/installation.md#function-names).&#x20;
* **doCreateUndoGroup:** Optional. *Boolean* to define whether you want Workflower to create its regular undo groups. Default is false.

#### Returns

Nothing

### workflowerScriptAPI.<mark style="color:orange;">kbarExecute</mark>()

{% code overflow="wrap" %}

```javascript
workflowerScriptAPI.kbarExecute(functionName)
```

{% endcode %}

Allows to execute a function, as specified by the function name, via KBar's *Run Scriplet* feature. Names are identical to [KBar function names](/installation.md#function-names).

Since [**workflowerScriptAPI.execute()**](#workflowerscriptapi.execute) cannot execute via KBar's *Run Scriptlet* feature, *workflowerScriptAPI.kbarExecute()* is needed instead.

{% hint style="info" %}
workflowerScriptAP&#x49;*.kbarExecute()* always creates undo groups compared to the other API functions.
{% endhint %}

workflowerScriptAP&#x49;*.kbarExecute()* **is only meant to execute a single command** via KBar's *Run Scriptlet* feature. If you want to run multiple commands, you need to use *workflowerScriptAPI.execute()* or any other function listed here, wrap the commands within a function and call the function with app.setTimeout(), so for example:

```javascript
function createAndStoreGroup(){
    app.beginUndoGroup("Create and Store Group");
    var layers = app.project.activeItem.selectedLayers;
    var newGroupHeader = workflowerScriptAPI.createGroup(layers, "New Group", false, false, false);
    newGroupHeader.selected = true;
    workflowerScriptAPI.execute("storeLayers1", false);
    app.endUndoGroup();
}
app.setTimeout(createAndStoreGroup, 1);
```

#### Parameters

* **functionName:** *String* of a function name to be executed. Names are identical to [KBar function names](/installation.md#function-names).&#x20;

#### Returns

Nothing

### workflowerScriptAPI.<mark style="color:orange;">refreshLayout</mark>()

{% code overflow="wrap" %}

```javascript
workflowerScriptAPI.refreshLayout([comp, doNotLabelLayersOutsideToNone])
```

{% endcode %}

Refreshes the comp layout.

#### Parameters

* **comp:** Optional. *Comp object* to be refreshed. Default is current comp.
* **doNotLabelLayersOutsideToNone:** Optional. Sets the current comp to [not label layers outside groups to 'None'](/layer-functions/relabeling.md#change-labeling-layers-outside-groups-to-none-in-active-comp). Default is false. Added in script version 2.03 / API version 0.11.

#### Returns

Nothing

### workflowerScriptAPI.<mark style="color:orange;">refreshLayouts</mark>()

{% code overflow="wrap" %}

```javascript
workflowerScriptAPI.refreshLayouts(comps[, doNotLabelLayersOutsideToNone])
```

{% endcode %}

Refreshes the layout of multiple comps. Added in script version 2.04 / API version 0.2.

#### Parameters

* **comps:** *Array of comp objects* to be refreshed. Default is none.
* **doNotLabelLayersOutsideToNone:** Optional. Sets the comps to [not label layers outside groups to 'None'](/layer-functions/relabeling.md#change-labeling-layers-outside-groups-to-none-in-active-comp). Default is false.&#x20;

#### Returns

Nothing

### workflowerScriptAPI.<mark style="color:orange;">createGroup</mark>()

{% code overflow="wrap" %}

```javascript
workflowerScriptAPI.createGroup(groupLayers[, groupName, parentGroup, groupOpacity, groupTrim])
```

{% endcode %}

Creates a *Workflower* group.

#### Parameters

* **groupLayers:** *Array of layer objects* to be grouped.
* **groupName:** Optional. *String* of the group name. Default is *GROUP \[Increment]*.
* **parentGroup:** Optional. *Boolean* to parent the group. Default is false.
* **groupOpacity:** Optional. *Boolean* to use group opacity. Default is false.
* **groupTrim:** Optional. *Boolean* to use group trim. Default is false.

#### Returns

Layer object of the group header

#### Example

This script creates a group and moves the group to the beginning of the composition.

{% code overflow="wrap" %}

```javascript
// Define Layer Array to be grouped
var layersToGroup = [layer1, layer2, layer3];

// Create the new Group with our Layer Array
var newHeader = workflowerScriptAPI.createGroup(layersToGroup, "My New Group", true, false, false);

// Get All Group Layers, so we can move them (including internal Starters & Footers)
var allGroupLayers = workflowerScriptAPI.getAllGroupLayers(newHeader, false);

// Move all Group Layers (& make sure to unlock + re-lock Layers since Starters & Footers are locked Layers)
for (var i = allGroupLayers.length - 1; i >= 0; i--){
    var groupLayer = allGroupLayers[i];
    var wasLocked = groupLayer.locked;
    groupLayer.locked = false;
    groupLayer.moveToBeginning();
    groupLayer.locked = wasLocked;
}

// Afterwards, refresh Layout (in case, Indent or similar has to be adjusted)
workflowerScriptAPI.refreshLayout();
```

{% endcode %}

### workflowerScriptAPI.<mark style="color:orange;">selectGroups</mark>()

{% code overflow="wrap" %}

```javascript
workflowerScriptAPI.selectGroups(groupHeaders)
```

{% endcode %}

Selects *Workflower* groups.

#### Parameters

* **groupHeaders:** *Array of group header layer objects* to be selected.

#### Returns

Nothing

### workflowerScriptAPI.<mark style="color:orange;">createMatte</mark>()

{% code overflow="wrap" %}

```javascript
workflowerScriptAPI.createMatte(layers)
```

{% endcode %}

Creates a matte to a given set of layers. On regular layers, creates a matte to them. On group headers, creates a group matte.

#### Parameters

* **layers:** *Array of layer objects* for the matte to be created to.

#### Returns

Layer object of the created matte


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://workflower.constantin-maier.com/main-functions/scripting-api.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
