Edit in GitHubLog an issue

Configuring Custom Actions

Actions can be created and managed via the Frame.io V4 Developer API, or through the new Actions settings (Beta) available in Frame.io V4 on Web. Only Content Admins and Account Owners can Create, Edit, Delete or Update custom Actions.

Field nameDescription
Name
The name you choose for your Action. It will be displayed in the Frame.io UI in places like the context menu and form-field modals
Description
Explains what the Action does. It will be displayed under the Action's name in the Frame.io UI
Event
An internal Event key to help you differentiate between Frame.io system Events and your own
URL
Where to deliver Events, either your own self-hosted application or an IPaSS tool
Workspace
The Workspace your Action will be made available in

Receive an Action Payload From Frame.io

When your Action is executed, a payload is sent to the URL set in the Action's configuration. Use this payload to identify:

  • Which Action was executed
  • Which Account is associated with the Action
  • Which Project contains the asset the Action was executed on
  • Which Resource the Action was executed on and its type
  • Which Event was executed
  • Which User executed the Action
  • Which Workspace is associated with the Action
Copied to your clipboard
POST /your/url
{
"account_id": "9a44f696-ae69-4e0c-9731-806d27ea46f1",
"action_id": "ecd40785-4485-4f07-9d26-a006ea84efdf",
"interaction_id": "e0a1c945-a8da-480d-92fb-e895cb640a01",
"project":
{
"id": "3dda6833-ec3b-46bd-a7d9-1a77c03a165b"
},
"resource":
{
"id": "f9d5728c-ac1a-4f48-92bb-ea2f9be3c58b",
"type": "file"
},
"type": "two.event",
"user":
{
"id": "50d976e6-27d2-47cb-9388-45b38d55f4f0"
},
"workspace":
{
"id": "382a1fe6-67cf-481e-9b65-79cfd9e9727f"
}
}
Field nameDescription
account_id
The unique Account identifier this Action belongs to. It is always the same for a given Action.
action_id
The unique identifier of the Action itself. It is always the same for a given Action.
interaction_id
Unique identifier generated by Frame.io representing each time an Action is executed.
project_id
Unique identifier of the Project containing the asset this Action was triggered on.
resource.id
The id of the resource your Action was executed on (usually an asset).
resource.type
The type of resource your Action was executed on. Possible values include file,folder or version_stack.
type
The internal Event key defined when configuring your Action.
user.id
The unique identifier of the User who executed the Action.
workspace.id
The unique identifier of the Workspace the Action belongs to. It is always the same for a given Action.
data
Object containing key-value pairs denoting the name of each form element and the value selected.

Interactions, Retries and Timeouts

The interaction_id is a unique identifier to track an Action's execution as it evolves over time. The ID persists throughout any sequence of an Action, including callback forms. If a response to the user is not required, simply return a 200 status code and the interaction is done. We recommend including information about the result of the interaction, such as a success or error message.

Actions support message callbacks. Frame.io expects a response in under 5 seconds and attempts to retry up to 5 times while waiting for a response. Ideally the response is immediate and asynchronous operations occur after an Action is executed.

Create a Message Callback

In your HTTP response to the webhook event, you can return a JSON object describing a message that will be returned to the initiating user in the Frame.io UI.

Copied to your clipboard
{
"title": "Success!",
"description": "The thing worked! Nice."
}

Messages close an Action's interaction loop providing variable context to the User without asking them to switch contexts. If the initial payload, and any subsequent calls to the Frame.io API, don't provide enough context for the receiving application to complete the Action, use Form Callbacks.

Create a Form Callback

When your use case requires more information from the User before you start your process, Actions enable you to render form field modals in the Frame.io UI.

For example, you may want to create an Action to orchestrate the upload of a file from Frame.io into another system but it requires the User to provide additional details and settings before it can be completed. You can describe a form in your inital response which will be presented to the User in Frame.io to fill out. Once submitted, the form values are included in a subsequent payload back to the URL defined in your Action's configuration.

Copied to your clipboard
{
"title": "Need some more info!",
"description": "Getting ready to submit this file!",
"fields": [
{
"type": "text",
"label": "Title",
"name": "title",
"value": "MyVideo.mp4"
},
{
"type": "select",
"label": "Captions",
"name": "captions",
"options": [
{
"name": "Off",
"value": "off"
},
{
"name": "On",
"value": "on"
}
]
}
]
}

When the user submits the form, you'll receive an event on the same URL as the initial POST:

Copied to your clipboard
POST /your/url
{
"type": "your-specified-event-name",
"interaction_id": "the-same-id-as-before",
"action_id": "unique-id-for-this-custom-action",
"data":{
"title": "MyVideo.mp4",
"captions": "off"
}
}

All fields added on a form appear in the data section of the JSON payload sent by Frame.io. Use the interaction_id to map the initial request and this new form data. And again, you can respond with a message (or even another form!) By chaining Actions, Forms, and Messages, you can effectively program entire Asset workflows in Frame.io with business logic from an external system.

Form Details

Like Messages, Forms support title and description attributes that render at the top of the Form. Beyond that, each form field accepts the following base attributes:

  • type -- Tells Frame.io which type of data to expect, and which component to render in the UI
  • label -- Appears in the UI as descriptor for your field
  • name -- Key by which the field will be identified on the subsequent payload
  • value -- Value with which to pre-populate the field

Supported Field Types

Text Field

A simple text field with no additional parameters.

Copied to your clipboard
{
"type": "text",
"label": "Title",
"name": "title",
"value": "MyVideo.mp4"
}

Text Area

A simple text area with no additional parameters.

Copied to your clipboard
{
"type": "textarea",
"label": "Description",
"name": "description",
"value": "This video is really, really popular."
}

Select List

Defines a picklist that the user can choose from. Must include an options list, each member of which should include a human-readable name, and a machine-parseable value.

Copied to your clipboard
{
"type": "select",
"label": "Captions",
"name": "captions",
"value": "off",
"options": [
{
"name": "Off",
"value": "off"
},
{
"name": "On",
"value": "on"
}
]
}

Checkbox

A simple checkbox with no additional parameters.

Copied to your clipboard
{
"type": "boolean",
"name": "enabled",
"label": "Enabled",
"value": "false"
}

A simple link with no additional parameters.

Copied to your clipboard
{
"type": "link",
"name": "videoLink",
"label": "Video Link",
"value": "https://www.youtube.com/watch?v=XtX1zv9CEVc"
}

Custom Actions Permissions

Custom Actions have a special permissions model: they belong to a Workspace, not to any specific user who exists on an Account. That means:

  • Any Content Admin can create a custom Action in a Workspace
  • Any Member with permission to the Workspace the Action is in can execute that Action
  • Any Content Admin can modify or delete a custom Action in a Workspace. Once modified, all users with permissions to that Workspace will immediately see the change
  • Any subsequent Frame.io API requests performed as a result of the Action's execution will respect the permissions of the token used to make those requests

Security and Verification

By default, all Actions have a signing key generated when created. This is not configurable. This key can be used to verify that the request originates from Frame.io. Included in the POST request are the following:

NameDescription
X-Frameio-Request-Timestamp
The time your Custom Action was triggered.
X-Frameio-Signature
The computed signature.
  • The timestamp is the time the request was signed on its way out of Frame.io's network. This can be used to prevent replay attacks. We recommended verifying this time is within 5 minutes of local time.
  • The signature is a HMAC SHA-256 hash using the signing key provided when the Custom Action is first created.

Verifying the Signature

  1. Extract the signature from the HTTP headers.
  2. Create a message to sign by combining the version, delivery time, and request body v0:timestamp:body.
  3. Compute the HMAC SHA256 signature using your signing secret.

Note: The provided signature is prefixed with v0=. Currently Frame.io only has this one version for signing requests. You will need to add this prefix to your computed signature.

Compare!

Copied to your clipboard
import hmac
import hashlib
**def** verify_signature(curr_time, req_time, signature, body, secret):
"""
Verify webhook/custom action signature
:Args:
curr_time (float): Current epoch time
req_time (float): Request epoch time
signature (str): Signature provided by the frame.io API for the given request
body (str): Custom Action body from the received POST
secret (str): The secret for this Custom Action that you saved when you first created it
"""
if int(curr_time) - int(req_time) < 500:
message = 'v0:{}:{}'.format(req_time, body)
calculated_signature = 'v0={}'.format(hmac.new(
bytes(secret, 'latin-1'),
msg=bytes(message, 'latin-1'),
digestmod=hashlib.sha256).hexdigest())
if calculated_signature == signature:
return True
return False
  • Privacy
  • Terms of Use
  • Do not sell or share my personal information
  • AdChoices
Copyright © 2025 Adobe. All rights reserved.