> This page is for Designer API.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://developers.webflow.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developers.webflow.com/_mcp/server.

# Interaction schema

> Every field and value that webflow.interactions accepts: triggers, timelines, actions, properties, targets, and timing.

Every field and value that [`webflow.interactions`](/designer/reference/interactions-overview) accepts. For a complete `create` call for each trigger type, see [Interaction examples](/designer/reference/interaction-examples).

> **Read the interaction back after every write**
>
> The API drops some misplaced fields without an error. After each [create](/designer/reference/create-interaction) or [set](/designer/reference/set-interaction), call [get](/designer/reference/get-interaction) and compare the result with what you sent.

## Shape

**`create(params)`**

```typescript title="create(params)"
{
  pageId: string;
  name: string;
  scope?: Scope;                       // default {type: 'site'}
  triggers: Trigger[];                 // up to 20
  timelines: Timeline[];               // up to 5
  conditionalPlayback?: ConditionalPlayback[];
}
```

**`Scope`**

```typescript title="Scope"
{type: 'site'}                         // every page
{type: 'pages'; value: string[]}       // page ids
{type: 'component'; componentId: string; variants?: string[]}  // omit variants for all variants
```

**`Trigger`**

```typescript title="Trigger"
{
  extensionKey: string;                // see Triggers
  config: {
    control?: 'play' | 'restart' | 'reverse' | 'reverseFlipEase' | 'pause' | 'resume'
      | 'togglePlayReverse' | 'togglePlayReverseFlipEase' | 'stop' | 'none';
    delay?: number | string;           // seconds or '500ms'
    jump?: number | string;            // seconds or '500ms'
    speed?: number;                    // 0 to 10
    pluginConfig?: object;             // see Triggers
    scrollTriggerConfig?: object;      // wf:scroll only
    assignedGroupId?: string;          // matches Timeline.groupId
  };
  target?: Target;
}
```

**`Timeline`**

```typescript title="Timeline"
{
  id?: string;                         // omit on create; keep on set
  name?: string;
  groupId?: string;
  triggerMetadata?: {role: string};    // hover and mouse move only
  canvasDuration?: 1;                  // scroll scrub, mouseX, and mouseY only
  settings?: {
    control?: string;
    delay?: number | string;
    jump?: number | string;
    speed?: number;                    // 0 to 10
    repeat?: number;                   // -1 or 0 and up
    yoyo?: boolean;
  };
  actions: Action[];                   // up to 200
}
```

**`Action`**

```typescript title="Action"
{
  id: string;                          // unique
  name: string;                        // not empty
  tt?: 0 | 1 | 2 | 3;                  // to, from, from-to, set
  timing: Timing;
  properties: {[actionType: string]: {[property: string]: Value}};
  targets: Target[];                   // up to 20
  splitText?: {type: 'chars' | 'words' | 'lines'; mask?: 'chars' | 'words' | 'lines'};
  hidden?: boolean;                    // left out of Preview and the published page
}
```

**`Target`**

```typescript title="Target"
{
  extensionKey: string;                // see Targets
  value: string | string[];
  filterContext?: {
    relationship: string;              // see Filters
    filterBy: [string, unknown];       // [extensionKey, value]
    firstMatchOnly?: boolean;
  };
}
```

## Triggers

| Trigger      | `extensionKey`  | Target                      | `pluginConfig`                                                                                 | Timeline roles                                            | `control`         | Other triggers                          |
| :----------- | :-------------- | :-------------------------- | :--------------------------------------------------------------------------------------------- | :-------------------------------------------------------- | :---------------- | :-------------------------------------- |
| Click        | `wf:click`      | Required                    | `click`: `each`, `first`, `second`, `odd`, `even`, or `custom`. `custom`: a number, 1 or more. | None                                                      | All except `none` | Allowed                                 |
| Hover        | `wf:hover`      | Required                    | `multiTimeline`: boolean. `eventMode`: `both`, `enter`, or `leave`, next to `multiTimeline`.   | `mouseEnter`, `mouseLeave` when `multiTimeline` is `true` | All               | Allowed                                 |
| Page load    | `wf:load`       | Not allowed                 | Not allowed                                                                                    | None                                                      | `play`, `none`    | Allowed. One page load trigger at most. |
| Scroll       | `wf:scroll`     | Required                    | None                                                                                           | None                                                      | Not allowed       | Not allowed                             |
| Mouse move   | `wf:mouse-move` | `wf:viewport` or an element | `smoothness`: 0 to 2000 ms, default 50. `restingState`: `{x, y}`, 0 to 100 each, default 50.   | `mouseX`, `mouseY`, `interval`. One timeline per role.    | Not allowed       | Not allowed                             |
| Custom event | `wf:custom`     | `wf:body` only              | `eventName`: a non-empty string                                                                | None                                                      | All               | Allowed                                 |

* Scroll and mouse move triggers reject `control`, `delay`, `jump`, and `speed`.
* `jump` is not allowed with `control` `none`, `restart`, `resume`, `togglePlayReverse`, or `togglePlayReverseFlipEase`.
* `speed` is not allowed with `control` `pause`, `stop`, or `none`.
* Click with `click` other than `each` rejects `togglePlayReverse` and `togglePlayReverseFlipEase`.
* Two or more timelines with a `groupId` require `control: 'play'` on each trigger.

### Scroll trigger config

| `scrollTriggerConfig` field                | Value                                                                           |
| :----------------------------------------- | :------------------------------------------------------------------------------ |
| `start`                                    | Required. `'<element position> <viewport position>'`, such as `'top 85%'`       |
| `end`                                      | Required. Same format as `start`                                                |
| `scrub`                                    | Optional. Seconds, such as `0.3`. Ties the animation to the scroll position.    |
| `enter`, `leave`, `enterBack`, `leaveBack` | `play`, `pause`, `resume`, `reverse`, `restart`, `reset`, `complete`, or `none` |
| `pin`                                      | Optional boolean                                                                |

A position is `top`, `center`, `bottom`, `left`, `right`, a length such as `'50%'` or `'-20px'`, or a keyword with an offset such as `'top+=50'`.

## Action properties

Write each value as one of these:

* A single value, which plays as a To tween, such as `'50%'`
* `[from]`, `[from, to]`, or `[null, to]`
* A [value wrapper](#value-wrappers)

A bare number uses the property's default unit. Opacity and Alpha are the exception: write them as percent strings, because a bare number is read on a 0 to 1 scale.

Length units: `px`, `%`, `em`, `rem`, `ch`, `vw`, `vh`, `dvw`, `dvh`, `svw`, `svh`, `lvw`, and `lvh`.

### `wf:transform`

| Property               | Panel label | Value                                                                                                 | Example     | Range      | Random | Relative |
| :--------------------- | :---------- | :---------------------------------------------------------------------------------------------------- | :---------- | :--------- | :----- | :------- |
| `opacity`              | Opacity     | Percent string                                                                                        | `'50%'`     | 0% to 100% | ✓      | ✓        |
| `autoAlpha`            | Alpha       | Percent string                                                                                        | `'0%'`      | 0% to 100% | ✓      | ✓        |
| `display`              | Display     | `block`, `inline`, `inline-block`, `inline-flex`, `inline-grid`, `flex`, `grid`, or `none`. Set only. | `'none'`    |            | ✗      | ✗        |
| `x`                    | Move X      | Length string                                                                                         | `'40px'`    | Any        | ✓      | ✓        |
| `y`                    | Move Y      | Length string                                                                                         | `'-20px'`   | Any        | ✓      | ✓        |
| `xPercent`             | X %         | Percent string                                                                                        | `'-40%'`    | Any        | ✓      | ✓        |
| `yPercent`             | Y %         | Percent string                                                                                        | `'10%'`     | Any        | ✓      | ✓        |
| `scale`                | Scale       | Number                                                                                                | `1.2`       | 0 or more  | ✓      | ✓        |
| `scaleX`               | Scale X     | Number                                                                                                | `0.5`       | 0 or more  | ✓      | ✓        |
| `scaleY`               | Scale Y     | Number                                                                                                | `2`         | 0 or more  | ✓      | ✓        |
| `z`                    | Scale Z     | Number                                                                                                | `1`         | 0 or more  | ✓      | ✓        |
| `skewX`                | Skew X      | Degree string                                                                                         | `'10deg'`   | Any        | ✓      | ✓        |
| `skewY`                | Skew Y      | Degree string                                                                                         | `'-10deg'`  | Any        | ✓      | ✓        |
| `rotation`             | Rotate      | Degree string                                                                                         | `'45deg'`   | Any        | ✓      | ✓        |
| `rotationX`            | Rotate X    | Degree string                                                                                         | `'180deg'`  | Any        | ✓      | ✓        |
| `rotationY`            | Rotate Y    | Degree string                                                                                         | `'90deg'`   | Any        | ✓      | ✓        |
| `transformPerspective` | Perspective | Number                                                                                                | `800`       | 0 or more  | ✓      | ✓        |
| `transformOrigin`      | Origin      | Two lengths, x then y. One value for the whole tween.                                                 | `'50% 50%'` |            | ✗      | ✗        |
| `width`                | Width       | Length string, or `'auto'`                                                                            | `'200px'`   | 0 or more  | ✓      | ✓        |
| `height`               | Height      | Length string, or `'auto'`                                                                            | `'50vh'`    | 0 or more  | ✓      | ✓        |

`transformOrigin` accepts `px`, `%`, `em`, `vw`, `vh`, `dvw`, `dvh`, `svw`, `svh`, `lvw`, and `lvh`.

### `wf:style`

| Property          | Panel label | Value                                                             | Example      | Range           | Random     | Relative |
| :---------------- | :---------- | :---------------------------------------------------------------- | :----------- | :-------------- | :--------- | :------- |
| `backgroundColor` | Background  | Hex color string                                                  | `'#1a1a2e'`  |                 | Picks only | ✗        |
| `borderColor`     | Border      | Hex color string                                                  | `'#7a4de8'`  |                 | Picks only | ✗        |
| `color`           | Text        | Hex color string                                                  | `'#ffffff'`  |                 | Picks only | ✗        |
| `zIndex`          | Z-Index     | Integer. Set only.                                                | `10`         | 0 to 2147483647 | ✗          | ✗        |
| `position`        | Position    | `static`, `relative`, `absolute`, `fixed`, or `sticky`. Set only. | `'absolute'` |                 | ✗          | ✗        |
| `overflow`        | Overflow    | `visible`, `hidden`, `scroll`, `auto`, or `clip`. Set only.       | `'hidden'`   |                 | ✗          | ✗        |
| `pointerEvents`   | Events      | `auto` or `none`. Set only.                                       | `'none'`     |                 | ✗          | ✗        |

Animate `opacity` under `wf:transform`, not `wf:style`. Set-only properties require `tt: 3`.

### `wf:class`

| Property | Panel label | Value                                                                                                                                       |
| :------- | :---------- | :------------------------------------------------------------------------------------------------------------------------------------------ |
| `class`  | Class       | `{operation, selectors}`. `operation` is `addClass`, `removeClass`, or `toggleClass`. `selectors` is an array of style block ids. Set only. |

### Other action types

| Action type       | Property         | Value                                                                                                                                                                                                                   |
| :---------------- | :--------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `wf:lottie`       | `lottie`         | `{from, to}`. Each is a number or a variable.                                                                                                                                                                           |
| `wf:lottie`       | `manualDuration` | Boolean                                                                                                                                                                                                                 |
| `wf:spline`       | `objectId`       | String                                                                                                                                                                                                                  |
| `wf:spline`       | `animatingState` | Boolean                                                                                                                                                                                                                 |
| `wf:spline`       | `spline`         | An object of channels, each `{from?, to?}`. Channels: `positionX`, `positionY`, `positionZ`, `rotationX`, `rotationY`, `rotationZ`, `scaleX`, `scaleY`, `scaleZ`, `intensity`, `opacity`, `zoom`, `color`, `stateName`. |
| `wf:mouse-follow` | `followMode`     | `full`, `x-only`, or `y-only`. Default `full`.                                                                                                                                                                          |
| `wf:mouse-follow` | `onEnter`        | `animate` or `snap`. Default `animate`.                                                                                                                                                                                 |
| `wf:mouse-follow` | `leaveBehavior`  | `return` or `stay`. Default `return`.                                                                                                                                                                                   |
| `wf:mouse-follow` | `anchor`         | Two lengths, x then y, such as `'50% 50%'`. Default is the center.                                                                                                                                                      |
| `wf:mouse-follow` | `axis`           | `x` or `y`. The timeline role sets it.                                                                                                                                                                                  |
| `wf:variable`     | `variable`       | `{variables: [{variableId, value}]}`. See [Variable values](#variable-values).                                                                                                                                          |
| `wf:rive`         | `rive`           | `{animationSource, addedProperties}`. See [Rive values](#rive-values).                                                                                                                                                  |
| `wf:animate-rive` | `rive`           | Same as `wf:rive`. `propertyType` is `number` or `color` only.                                                                                                                                                          |

`wf:mouse-follow` is valid only on a `mouseX` or `mouseY` timeline of a mouse move interaction, one per timeline. `y-only` conflicts with `mouseX`, and `x-only` conflicts with `mouseY`.

### Variable values

| `value.type` | `value.value`                   | Example                                               |
| :----------- | :------------------------------ | :---------------------------------------------------- |
| `length`     | `{value: number, unit: string}` | `{type: 'length', value: {value: 16, unit: 'px'}}`    |
| `percentage` | `{value: number, unit: '%'}`    | `{type: 'percentage', value: {value: 50, unit: '%'}}` |
| `number`     | `{value: number, unit: '-'}`    | `{type: 'number', value: {value: 2, unit: '-'}}`      |
| `color`      | Color string                    | `{type: 'color', value: '#1a1a2e'}`                   |
| `ref`        | `{variableId}`                  | `{type: 'ref', value: {variableId: 'variable-id'}}`   |

`value: null` leaves the variable unset.

### Rive values

| Field             | Value                                                                                                      |
| :---------------- | :--------------------------------------------------------------------------------------------------------- |
| `animationSource` | `null` or `{name, instanceName?}`. Required when `addedProperties` has entries.                            |
| `addedProperties` | An object of `{propertyName, propertyType, value?}` entries. Each key ends with `:` and the property name. |
| `propertyType`    | `string`, `number`, `boolean`, `color`, `enum`, `trigger`, or `artboard`                                   |

## Value wrappers

| Wrapper      | Shape                                                                          | Works on                                                                     |
| :----------- | :----------------------------------------------------------------------------- | :--------------------------------------------------------------------------- |
| Random range | `{type: 'ix3-random', min: number, max: number, step?: number, unit?: string}` | Properties marked ✓ under Random                                             |
| Random pick  | `{type: 'ix3-random-array', values: [...], unit?: string}`                     | Properties marked ✓ or "Picks only". 2 to 12 values. Colors use hex strings. |
| Relative     | `{type: 'ix3-additive', value: number, unit?: string}`                         | Properties marked ✓ under Relative. `value` can also be a random range.      |
| Variable     | `{type: 'ref', value: {variableId: string}}`                                   | Number, length, percent, degree, and color properties                        |

Put the unit in `unit`, not in the number.

**`Wrapper examples`**

```typescript title="Wrapper examples"
x: {type: 'ix3-random', min: -100, max: 100, unit: 'px'},
rotation: {type: 'ix3-additive', value: 90, unit: 'deg'},
backgroundColor: {type: 'ix3-random-array', values: ['#1a1a2e', '#7a4de8']},
```

## Tween types

| `tt` | Name    | Value form                      | Example          |
| :--- | :------ | :------------------------------ | :--------------- |
| `0`  | To      | A single value, or `[null, to]` | `'50%'`          |
| `1`  | From    | `[from]` or `[from, null]`      | `['0%']`         |
| `2`  | From-to | `[from, to]`                    | `['0%', '100%']` |
| `3`  | Set     | A single value                  | `'none'`         |

* If you omit `tt`, the API stores `2` for `[from, to]` and `1` for all-from values. Single values play as To.
* `[from, to]` with `tt` `0`, `1`, or `3` is rejected. So is mixing from-only and to-only values without `tt`.
* A `{from, to}` object is rejected, except on Lottie and Spline.

## Timing

| Field         | Value                                                                    |
| :------------ | :----------------------------------------------------------------------- |
| `duration`    | Seconds, or a string such as `'400ms'`. `400` means 400 seconds.         |
| `position`    | Seconds, or a string such as `'500ms'`. `+=`, `<`, and `>` are rejected. |
| `ease`        | An index from 0 to 30, or an advanced ease object. Strings are rejected. |
| `stagger`     | An object. See [Stagger](#stagger).                                      |
| `repeat`      | A number. `-1` repeats without end.                                      |
| `repeatDelay` | Seconds, or a string such as `'200ms'`                                   |
| `yoyo`        | Boolean                                                                  |

An action's `timing` rejects `delay` and `autoReverse`.

### Stagger

| Field    | Value                                                             |
| :------- | :---------------------------------------------------------------- |
| `each`   | Seconds between targets, or a string such as `'50ms'`             |
| `amount` | Total seconds split across targets, or a string such as `'300ms'` |
| `axis`   | `x` or `y`                                                        |
| `from`   | `start`, `center`, `end`, `edges`, `random`, or a number          |
| `ease`   | Same values as `timing.ease`                                      |
| `grid`   | `'auto'` or `[columns, rows]`                                     |

### Ease

| Index | Ease           | Index | Ease            |
| :---- | :------------- | :---- | :-------------- |
| 0     | `none`         | 16    | `bounce.in`     |
| 1     | `power1.in`    | 17    | `bounce.out`    |
| 2     | `power1.out`   | 18    | `bounce.inOut`  |
| 3     | `power1.inOut` | 19    | `circ.in`       |
| 4     | `power2.in`    | 20    | `circ.out`      |
| 5     | `power2.out`   | 21    | `circ.inOut`    |
| 6     | `power2.inOut` | 22    | `elastic.in`    |
| 7     | `power3.in`    | 23    | `elastic.out`   |
| 8     | `power3.out`   | 24    | `elastic.inOut` |
| 9     | `power3.inOut` | 25    | `expo.in`       |
| 10    | `power4.in`    | 26    | `expo.out`      |
| 11    | `power4.out`   | 27    | `expo.inOut`    |
| 12    | `power4.inOut` | 28    | `sine.in`       |
| 13    | `back.in`      | 29    | `sine.out`      |
| 14    | `back.out`     | 30    | `sine.inOut`    |
| 15    | `back.inOut`   |       |                 |

| Advanced `type` | Fields                                                                           |
| :-------------- | :------------------------------------------------------------------------------- |
| `back`          | `curve`, `power`                                                                 |
| `elastic`       | `curve`, `amplitude`, `period`                                                   |
| `steps`         | `stepCount`                                                                      |
| `rough`         | `templateCurve`, `points`, `strength`, `taper`, `randomizePoints`, `clampPoints` |
| `slowMo`        | `linearRatio`, `power`, `yoyoMode`                                               |
| `expoScale`     | `startingScale`, `endingScale`, `templateCurve`                                  |
| `customWiggle`  | `wiggles`, `wiggleType`                                                          |
| `customBounce`  | `strength`, `squash`, `endAtStart`                                               |
| `customEase`    | `bezierCurve`                                                                    |

`curve` is `in`, `out`, or `inOut`. `taper` is `none`, `in`, `out`, or `both`. `wiggleType` is `easeOut`, `easeInOut`, `anticipate`, `uniform`, or `random`. Extra fields are rejected.

**`Ease examples`**

```typescript title="Ease examples"
timing: {duration: 0.4, ease: 2},
timing: {duration: 0.4, ease: {type: 'back', curve: 'out', power: 1.7}},
```

## Targets

| Target                   | `value`                                             | On a trigger                 | On an action |
| :----------------------- | :-------------------------------------------------- | :--------------------------- | :----------- |
| `wf:class`               | A class slug, or an array of style block ids        | ✓                            | ✓            |
| `wf:selector`            | A CSS selector                                      | ✓                            | ✓            |
| `wf:attribute`           | `'[name]'` or `'[name="value"]'`                    | ✓                            | ✓            |
| `wf:inst`                | `[ownerId, elementId]`                              | ✓                            | ✓            |
| `wf:body`                | `''`                                                | Scroll and custom event only | ✗            |
| `wf:viewport`            | `''`                                                | Mouse move only              | ✗            |
| `wf:trigger-only`        | `''`, the element that fired the trigger            | ✗                            | ✓            |
| `wf:trigger-only-parent` | `''`, the parent of that element                    | ✗                            | ✓            |
| `wf:any-element`         | `'*'`, with a filter relationship other than `none` | ✗                            | ✓            |

* A class slug must match exactly one class. Otherwise, pass style block ids from `webflow.getStyleByName` or `webflow.getAllStyles`.
* For `wf:inst`, `ownerId` is the page id on a site or pages scope, and the component id on a component scope.
* `wf:id` is rejected. Use `wf:selector`, `wf:class`, or `wf:inst`.

### Filters

| Field            | Value                                                                                                                              |
| :--------------- | :--------------------------------------------------------------------------------------------------------------------------------- |
| `relationship`   | `none`, `within`, `direct-child-of`, `contains`, `direct-parent-of`, `next-to`, `next-sibling-of`, or `prev-sibling-of`            |
| `filterBy`       | `[extensionKey, value]` using `wf:class`, `wf:selector`, `wf:attribute`, `wf:inst`, `wf:trigger-only`, or `wf:trigger-only-parent` |
| `firstMatchOnly` | Boolean. `true` needs a relationship other than `none`.                                                                            |

## Conditional playback

**`ConditionalPlayback`**

```typescript title="ConditionalPlayback"
{type: 'prefers-reduced-motion'; behavior: 'dont-animate' | 'skip-to-end'}
{type: 'breakpoint'; breakpoints: ('main' | 'medium' | 'small' | 'tiny')[]; behavior: 'dont-animate' | 'skip-to-end'}
```

One row per `type`. Mouse move interactions accept `dont-animate` only.

## Limits

| Item                      | Maximum |
| :------------------------ | :------ |
| Triggers per interaction  | 20      |
| Timelines per interaction | 5       |
| Actions per timeline      | 200     |
| Targets per action        | 20      |
| Random pick values        | 12      |

## Not accepted

| Field or value                                                               | Use instead                                                         |
| :--------------------------------------------------------------------------- | :------------------------------------------------------------------ |
| `wf:navbar`, `wf:dropdown`, `wf:focus`, `wf:blur`, and `wf:change` triggers  | None                                                                |
| `config.conditionalLogic`                                                    | `conditionalPlayback`                                               |
| `config.assignedTimelineRole` on a new trigger                               | `assignedGroupId`                                                   |
| `wf:id` target                                                               | `wf:selector`, `wf:class`, or `wf:inst`                             |
| `timing.delay` on an action                                                  | `timing.position`, or `delay` on the trigger or timeline `settings` |
| `timing.autoReverse`                                                         | `repeat` with `yoyo`                                                |
| `timelineDefaults` on `create`                                               | Omit it                                                             |
| Timeline `actionPresetIds`, `previewSpeed`, `playInReverse`, and `immediate` | Omit them                                                           |
| `scrub: true`                                                                | Seconds, such as `0.3`                                              |
| Ease names, such as `'power2.out'`                                           | An index from the ease table                                        |

## Stored differently

| You send                                                | `get` returns                                                               |
| :------------------------------------------------------ | :-------------------------------------------------------------------------- |
| An unknown field on `config`, `timing`, or `stagger`    | Nothing. The field is dropped.                                              |
| A class slug                                            | Style block ids. Combo classes include parent ids.                          |
| `'data-state'` on `wf:attribute`                        | `'[data-state]'`                                                            |
| `'500ms'`                                               | `0.5`                                                                       |
| `delay: null`                                           | `0.25`                                                                      |
| No `scope`                                              | `{type: 'site'}`                                                            |
| No scroll `enter`, `leave`, `enterBack`, or `leaveBack` | `play`, `none`, `none`, `none`                                              |
| No `tt`                                                 | `1` or `2`, when the values imply it                                        |
| No `filterContext`                                      | `{relationship: 'none', filterBy: ['wf:class', []], firstMatchOnly: false}` |
| An ease index above 30                                  | The index. The action plays with no easing.                                 |