MotionDynamic API

Fast highly dynamic video generation at scale 🚀

Home - Changelog - GraphQL Endpoint - Authentication - Getting started - Webhook event - Generation delays - Rate Limiting

Loading API description...

Authentication

MotionDynamic leverage Json Web Tokens (JWT) to handle authentication. In the examples below PUT_YOUR_JWT_HERE must be replaced by the JWT you got from our team.

Getting started

Let's start by listing themes we have access to:

curl -H 'Authorization: Bearer PUT_YOUR_JWT_HERE' https://api.motiondynamic.tech/rest/themes?select=theme_id,title,description,parameters

Here is what we've got:

[
  {
    "theme_id": "8239de5c-5cbd-4e39-a102-220e5354a551",
    "title": "Product demo",
    "description": "A video that displays a product",
    "parameters": [
      {
        "theme_id": "8239de5c-5cbd-4e39-a102-220e5354a551",
        "type": "color",
        "parameter": {
          "parameterType_id": "afcad4e5-d951-43a1-8a59-889f97b357b5",
          "theme_id": "8239de5c-5cbd-4e39-a102-220e5354a551",
          "createdAt": "2018-05-29T09:29:59.808074+00:00",
          "user_id": "358194c5-cdc7-46f3-aa83-23a869559119",
          "title": "title forbackground_color",
          "layer": "background_color",
          "defaultColor": "FF00FF"
        }
      },
      {
        "theme_id": "8239de5c-5cbd-4e39-a102-220e5354a551",
        "type": "picture",
        "parameter": {
          "parameterType_id": "867b9e64-0869-4631-be06-426eb46daf0d",
          "theme_id": "8239de5c-5cbd-4e39-a102-220e5354a551",
          "createdAt": "2018-05-29T09:29:59.808074+00:00",
          "user_id": "358194c5-cdc7-46f3-aa83-23a869559119",
          "title": "title for image_produit",
          "layer": "image_produit",
          "fileToReplace": "image_produit.png",
          "fitToCompWidth": true,
          "minWidth": 1200,
          "minHeight": 680,
          "accept": [
            "png"
          ]
        }
      },
      {
        "theme_id": "8239de5c-5cbd-4e39-a102-220e5354a551",
        "type": "text",
        "parameter": {
          "parameterType_id": "ab254fb9-58ca-4378-a833-2995a1a59178",
          "theme_id": "8239de5c-5cbd-4e39-a102-220e5354a551",
          "createdAt": "2018-05-29T09:29:59.808074+00:00",
          "user_id": "358194c5-cdc7-46f3-aa83-23a869559119",
          "title": "title for l6_ville_01",
          "layer": "l6_ville_01",
          "minLength": 1,
          "maxLength": 12,
          "pattern": null
        }
      },
      {
        "theme_id": "8239de5c-5cbd-4e39-a102-220e5354a551",
        "type": "text",
        "parameter": {
          "parameterType_id": "92d28875-1314-4be9-8c62-7e03e536abfd",
          "theme_id": "8239de5c-5cbd-4e39-a102-220e5354a551",
          "createdAt": "2018-05-29T09:29:59.808074+00:00",
          "user_id": "358194c5-cdc7-46f3-aa83-23a869559119",
          "title": "title for l2_date_01",
          "layer": "l2_date_01",
          "minLength": 1,
          "maxLength": 12,
          "pattern": null
        }
      },
      {
        "theme_id": "8239de5c-5cbd-4e39-a102-220e5354a551",
        "type": "text",
        "parameter": {
          "parameterType_id": "32985e30-40d4-4af9-ba33-ee02d1d77484",
          "theme_id": "8239de5c-5cbd-4e39-a102-220e5354a551",
          "createdAt": "2018-05-29T09:29:59.808074+00:00",
          "user_id": "358194c5-cdc7-46f3-aa83-23a869559119",
          "title": "title for l1_titre_01",
          "layer": "l1_titre_01",
          "minLength": 1,
          "maxLength": 7,
          "pattern": null
        }
      },
      {
        "theme_id": "8239de5c-5cbd-4e39-a102-220e5354a551",
        "type": "text",
        "parameter": {
          "parameterType_id": "aef50e6b-bf20-4222-a4de-fe38218e1916",
          "theme_id": "8239de5c-5cbd-4e39-a102-220e5354a551",
          "createdAt": "2018-05-29T09:29:59.808074+00:00",
          "user_id": "358194c5-cdc7-46f3-aa83-23a869559119",
          "title": "title for l4_quantite_01",
          "layer": "l4_quantite_01",
          "minLength": 1,
          "maxLength": 8,
          "pattern": null
        }
      },
      {
        "theme_id": "8239de5c-5cbd-4e39-a102-220e5354a551",
        "type": "text",
        "parameter": {
          "parameterType_id": "91359d71-2c65-499b-a409-d51d862589d6",
          "theme_id": "8239de5c-5cbd-4e39-a102-220e5354a551",
          "createdAt": "2018-05-29T09:29:59.808074+00:00",
          "user_id": "358194c5-cdc7-46f3-aa83-23a869559119",
          "title": "title for l5_descriptif_01",
          "layer": "l5_descriptif_01",
          "minLength": 1,
          "maxLength": 25,
          "pattern": null
        }
      },
      {
        "theme_id": "8239de5c-5cbd-4e39-a102-220e5354a551",
        "type": "text",
        "parameter": {
          "parameterType_id": "4de8eff8-c892-4e6d-a439-8b67ba81345d",
          "theme_id": "8239de5c-5cbd-4e39-a102-220e5354a551",
          "createdAt": "2018-05-29T09:29:59.808074+00:00",
          "user_id": "358194c5-cdc7-46f3-aa83-23a869559119",
          "title": "title for l5_descriptif_02",
          "layer": "l5_descriptif_02",
          "minLength": 1,
          "maxLength": 25,
          "pattern": null
        }
      },
      {
        "theme_id": "8239de5c-5cbd-4e39-a102-220e5354a551",
        "type": "text",
        "parameter": {
          "parameterType_id": "8b74142c-6cc3-4c8a-8520-825ef76b3d52",
          "theme_id": "8239de5c-5cbd-4e39-a102-220e5354a551",
          "createdAt": "2018-05-29T09:29:59.808074+00:00",
          "user_id": "358194c5-cdc7-46f3-aa83-23a869559119",
          "title": "title for l5_descriptif_03",
          "layer": "l5_descriptif_03",
          "minLength": 1,
          "maxLength": 25,
          "pattern": null
        }
      },
      {
        "theme_id": "8239de5c-5cbd-4e39-a102-220e5354a551",
        "type": "text",
        "parameter": {
          "parameterType_id": "e473471d-e715-4829-b096-15d055bc1fa7",
          "theme_id": "8239de5c-5cbd-4e39-a102-220e5354a551",
          "createdAt": "2018-05-29T09:29:59.808074+00:00",
          "user_id": "358194c5-cdc7-46f3-aa83-23a869559119",
          "title": "title for l3_prix_01",
          "layer": "l3_prix_01",
          "minLength": 1,
          "maxLength": 5,
          "pattern": "^[0-9\\.]+$"
        }
      },
      {
        "theme_id": "8239de5c-5cbd-4e39-a102-220e5354a551",
        "type": "output",
        "parameter": {
          "parameterType_id": "6e97e46d-b0a3-48dd-a7dd-208d28e074a3",
          "theme_id": "8239de5c-5cbd-4e39-a102-220e5354a551",
          "createdAt": "2018-05-30T21:34:30.070008+00:00",
          "user_id": "358194c5-cdc7-46f3-aa83-23a869559119",
          "title": "Variante",
          "layers": [
            "MASTER"
          ]
        }
      }
    ]
  }
]

The request yield an list containing 1 theme (8239de5c-5cbd-4e39-a102-220e5354a551). This theme is a public one and has 11 user-customizable parameters.

Theme 8239de5c-5cbd-4e39-a102-220e5354a551 is publicly available so everyone can start integrating MotionDynamic into their software. We will use this theme to generate a new video. Note that a theme has parameters (e.g. texts, colors, pictures) that we will ask our users to specify before starting a video render.


The CURL command below specify the theme_id we want to use, a webhook to call once the video generation is complete (see webhook event) and our user-defined values.

curl -X POST \
https://api.motiondynamic.tech/rest/generations \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer PUT_YOUR_JWT_HERE' \
-d '{
"theme_id": "8239de5c-5cbd-4e39-a102-220e5354A551",
"webhook": "https://webhook.site/47ed8ecd-51db-4c52-9d44-ff8de6f3013a",
"values": [
  {
    "value": "city_01",
    "parameter_id": "ab254fb9-58ca-4378-a833-2995a1a59178"
  },
  {
    "value": "date_01",
    "parameter_id": "92d28875-1314-4be9-8c62-7e03e536abfd"
  },
  {
    "value": "title",
    "parameter_id": "32985e30-40d4-4af9-ba33-ee02d1d77484"
  },
  {
    "value": "12.1",
    "parameter_id": "e473471d-e715-4829-b096-15d055bc1fa7"
  },
  {
    "value": "quantite",
    "parameter_id": "aef50e6b-bf20-4222-a4de-fe38218e1916"
  },
  {
    "value": "desc_01",
    "parameter_id": "91359d71-2c65-499b-a409-d51d862589d6"
  },
  {
    "value": "desc_02",
    "parameter_id": "4de8eff8-c892-4e6d-a439-8b67ba81345d"
  },
  {
    "value": "desc_03",
    "parameter_id": "8b74142c-6cc3-4c8a-8520-825ef76b3d52"
  },
  {
    "value": "0000FF",
    "parameter_id": "afcad4e5-d951-43a1-8a59-889f97b357b5"
  },
  {
    "value": "https://imgur.com/download/uNcCrzv",
    "parameter_id": "867b9e64-0869-4631-be06-426eb46daf0d"
  },
  {
    "value": "MASTER",
    "parameter_id": "6e97e46d-b0a3-48dd-a7dd-208d28e074a3"
  }
]}'

Before submitting this CURL request from your side, you must ensure that:

  • picture urls are downloadable and in the right format (see theme's picture parameter accept)
  • text values follows theme's parameter minLength and maxLength
  • output value is one of a theme's output parameter available layers
  • color value is the hex color representation (without the #)

MotionDynamic API will discard invalid inputs.

Now heads up to the webhook event section to download the generated video.

Webhook event

Once the generation request is submitted, open the webhook tester we used. Wait a little* and your webhook will then receive a POST request with the following body:

{
  video: "https://download.motiondynamic.tech/uuid.mp4"
}

Webhook endpoint must yield a 200 http code response to acknowledge that it handled the event. If not — in case of unavailable service, dns error, request timeouts, 4xx or 5xx http code responses — MotionDynamic will retry every 5 seconds for 1 hour until the service yield a 200 http code response. If after 1 hour the service was not reachable or never yield a 200, the event is discarded.

Local webhook

We might want that MotionDynamic webhook send data to our development machine where our development server is. We could do this by configuring firewall rules and opening network ports, but that takes a bit of time. We also don’t want to leave our environment exposed to the outside world when we’re not testing, so it would be an additional pain to constantly remember to enable and disable the rules when needed.

Instead, we’ll use a simple command-line tool called ngrok, which automatically creates a publicly-accessible URL that tunnels to a port on your local computer. Once downloaded, unzip ngrok and place it somewhere convenient on your PC.

Next, Shift+Right-Click inside the folder where you placed ngrok, and choose Open command window here. Enter the following command: ngrok http 81 (note that 81 is the http port our local development server is listening on, you might want to change it).

ngrok will create a tunnel to the port we specified, and will even give us an easy-to-use domain name. Use that domain name (something like afad1810.ngrok.io) with your own server path (e.g. https://afad1810.ngrok.io/my/own/callback) as MotionDynamic webhook attribute while requesting a new video generation.

If we try to use our ngrok URL right now, the request will get routed to our local machine.

Generation delays

Most of the time, generations won't take more than 1 minute to complete (wall clock from request to webhook event request).

If MotionDynamic rendering system begins from a cold start (worst-case scenario), first rendering will take up to 18 minutes, next one up to 7 minutes and then, other video generation requests won't take more than 1 minute for the whole process (from rendering to download availability).

Rate limiting

Currently MotionDynamic API only limits per ip address at 5 requests per second. Blocked clients will receive a 429 http code and will to need wait for 1 minute to start requesting again.