Frame.io API

Frame.io API Documentation

Welcome to Frame.io's official documentation portal.In here, you'll find everything you need to:

Get up and running with Frame.io's public API 🤙
Leverage powerful features like Webhooks and Custom Actions 🚀
Build your own OAuth2.0 app 🚢

Get Started    Guides

Webhooks Overview

This page describes the basics and technical details of Webhooks. For help creating a Webhook workflow with the Frame.io Zapier app, please see our introductory Zapier guide.

📘

Example Application

If you'd like to build your own consumer for Frame.io Webhooks, feel free to grab and extend our Example App on Github.

Introduction

Webhooks provide a way to leverage events that occur inside of Frame.io into notifications that can be sent to external systems for processing, API callback, and ultimately, workflow automation.

Setup

Webhooks can be configured in the Webhooks area of Frame.io Developer. A Webhook requires:

  • Name — Will be shown in Frame.io Developer only.
  • URL — Where to deliver events.
  • Team — Which team this action will be installed on.
  • Events — Which event, or events, should trigger the Webhook.

Supported events

A single Webhook can subscribe to any number of the following events:

Projects

Event

Sent when

project.created

A new Project is created.

project.updated

A Project's settings are updated.

project.deleted

A Project is deleted.

Assets

Event

Sent when

asset.created

An Asset is added/created in Frame.io and transcoding starts.

asset.copied

An Asset has been copied.

asset.updated

An Asset's description, name, or other file information is changed.

asset.deleted

An Asset is deleted (manually or otherwise).

asset.ready

All transcodes are complete after an Asset is uploaded.

asset.label.updated

An Asset's status label is set, changed, or removed.

Comments

Event

Sent when

comment.created

A new Comment or Reply is created.

comment.updated

A Comment is edited.

comment.deleted

A Comment is deleted.

Review Links

Event

Sent when

reviewlink.created

A new Review Link is created.

Collaborators

Event

Sent when

collaborator.created

A Collaborator has been added to your account.

collaborator.deleted

A Collaborator has been removed from your account.

Team Members

Event

Sent when

teammember.created

A Team Member has been added to your account.

teammember.deleted

A Team Member has been removed from your account.

Payload

Frame.io delivers a JSON payload to the specified webhook endpoint. Here's an example payload for an asset.created event.

{
  "type": "asset.created",
  "resource": {
    "type": "asset",
    "id": "<asset-id>"
  },
  "user": {
    "id": "<user-id>"
  },
  "team": {
    "id": "<team-id>"
  }
}

All payloads contain a type field, indicating the type of event occurring, as well as a resource object. The resource object specifies the type and id of the resource related to this event.

In the above example of an asset.created event, this would be the id for the newly created Asset. Additionally, user and team objects are included. These reference the User who triggered the event, and the Team context for the resource.

Aside from the immediate User and Team context, we do not include any additional information about the subscribed resource. If your application requires additional information or context, we recommend using our HTTP API to make follow-up requests.

Retries

Should an error or timeout occur while delivering the webhook, the payload will be retried three times, for a total of four delivery attempts.

Security

By default, all Webhooks are provided with a signing key. This is not configurable. This key can be used to verify that the request originates from Frame.io.

Verify Webhook Signatures

To guard an integration against man-in-the-middle and replay attacks it is essential to verify webhook signatures. Verification ensures that webhook payloads were actually sent by Frame.io and payload content has not been modified in transport.

Included in the POST request are the following headers:

Name

Description

X-Frameio-Request-Timestamp

The time of Webhook delivery.

X-Frameio-Signature

The computed signature.

The timestamp is the time of delivery from Frame.io's systems. 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 SHA256 hash using the signing key provided when the Webhook is first created.

Follow these steps to verify 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. Be sure this prefix is prepended to your computed signature.
  4. Compare!
const crypto = require('crypto');

// Capture the signature, secret, timestamp and payload from a new webhook event:
const 
signature = 'v0=a77ce6856e609c884575c2fd211d07a9ad1c3f72e19c06ff710e8f086ffca883', 
secret = 'yxSE59T0gtZOFZxw6UhLwTkhd2m8ntNSdSWnApQ0xOnMEzSoXbD8sGFP4bzb7MbS',
timestamp = 1604004499,  // UNIX timestamp in seconds
payload = {
    "project": {
        "id": "f348e9f4-f142-42f9-b3bf-478d93f0feb4"
    },
    "resource": {
        "id": "6aad9151-c216-4d6f-b5e9-530df551a426",
        "type": "asset"
    },
    "team": {
        "id": "aa891687-4b1e-4150-9b6d-9e4911c5b436"
    },
    "type": "asset.label.updated",
    "user": {
        "id": "59c9ade1-311b-4c3b-8231-b9d88e9a1a85"
    }
},
body = JSON.stringify(payload),

// Validate that caught payload is not older than 5 minutes
currentTimeUTC = (new Date()).getTime(),
currentTimestamp = currentTimeUTC / 1000, // JavaScript uses milliseconds whereas Unix Time is in seconds.
minutes = 5, 
expired = (currentTimestamp - timestamp) > minutes*60
hmac1 = crypto.createHmac('sha256', secret),
generateSignature = hmac1.update(`v0:${timestamp}:${body}`).digest('hex')

// Evaluates to true if the webhook is verified
console.log(!expired && signature === `v0=${generateSignature}`)
// Full Go sample code: https://github.com/Frameio/webhooks-example-app/blob/master/main.go

func handler(w http.ResponseWriter, r *http.Request) {
    out, err := httputil.DumpRequest(r, true)
    if err != nil {
        w.WriteHeader(http.StatusInternalServerError)
        return
    }

    log.Println(string(out))

    // Verify the message has been delivered in the last 5 minutes.
    timestampStr := r.Header.Get("X-Frameio-Request-Timestamp")
    timestamp, err := strconv.ParseInt(timestampStr, 10, 64)
    if err != nil {
        w.WriteHeader(http.StatusBadRequest)
        return
    }

    if time.Since(time.Unix(timestamp, 0)) > 5*time.Minute {
        w.WriteHeader(http.StatusBadRequest)
        return
    }

    // Verify request signature.
    expected := r.Header.Get("X-Frameio-Signature")
    signature, _ := computeSignature(r, timestamp, secretKey)
    if expected != signature {
        w.WriteHeader(http.StatusUnauthorized)
        return
    }

    var event *Event
    decoder := json.NewDecoder(r.Body)
    err = decoder.Decode(&event)
    if err != nil {
        w.WriteHeader(http.StatusInternalServerError)
        return
    }

    // Handle webhook here.
    log.Println(event.ID)

    w.WriteHeader(http.StatusOK)
}

// The request includes headers to enable the recipient to validate
// that the request is from Frame.io and that it's been delivered within
// the expected time range. To learn more about how this works, take a
// look at our docs https://docs.frame.io/docs/webhooks#section-security.
func computeSignature(r *http.Request, timestamp int64, secret string) (string, error) {
    body, err := ioutil.ReadAll(r.Body)
    if err != nil {
        return "", err
    }
    copy := body[:]
    r.Body = ioutil.NopCloser(bytes.NewReader(copy))

    msg := fmt.Sprintf("%s:%d:%s", version, timestamp, string(body))

    key := []byte(secret)
    h := hmac.New(sha256.New, key)
    h.Write([]byte(msg))

    result := fmt.Sprintf("%s=%s", version, hex.EncodeToString(h.Sum(nil)))

    return result, nil
}

Updated 5 months ago

Webhooks Overview


This page describes the basics and technical details of Webhooks. For help creating a Webhook workflow with the Frame.io Zapier app, please see our introductory Zapier guide.

Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.