{
  "openapi": "3.1.1",
  "info": {
    "title": "Video to GIF Creator API",
    "version": "1.0.0",
    "summary": "Turn a video clip into a high-quality GIF or animated WebP with fps, width and dithering.",
    "description": "Every endpoint performs the same calculation as the human page and returns inputs, result, units, assumptions, sources, warnings and computedAt. MCP endpoint: /mcp."
  },
  "servers": [
    {
      "url": "https://videotogifcreator.usefulweb.site"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "Turn a video clip into a high-quality GIF or animated WebP with fps, width and dithering.",
        "description": "Makes a GIF or animated WebP from up to 15 seconds of a video. Choose start, length, frame rate and width; GIFs use ffmpeg's two-stage palette (palettegen/paletteuse) with selectable dithering for much better colours than a default conversion. Shows the size, frame count and a preview.\n\nMethodology:\n- ffmpeg seeks to the start time and reads up to 15 seconds. The frames are resampled to the chosen fps and scaled with Lanczos to the width (never wider than the source); the height follows the aspect ratio.\n- GIF: palettegen builds an optimal palette of up to 256 colours from the clip (from all pixels or only changing ones), and paletteuse maps every frame to it with the chosen dithering. This is the standard two-stage method for high-quality GIFs.\n- Animated WebP uses libwebp (lossy, quality 1–100), which is typically several times smaller than a GIF of the same clip.\n- All values (times, fps, width, colours) are validated numbers or fixed option names before they go into the filtergraph.",
        "tags": [
          "media"
        ],
        "x-mcp-tool": "video_to_gif_creator",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VideoToGifCreatorInput"
              },
              "examples": {
                "example1": {
                  "summary": "1 s test clip to a 64 px GIF at 10 fps",
                  "value": {
                    "file": {
                      "filename": "clip.mp4",
                      "contentType": "video/mp4",
                      "contentBase64": "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"
                    },
                    "duration": 1,
                    "fps": 10,
                    "width": 64
                  }
                },
                "example2": {
                  "summary": "Same clip as animated WebP",
                  "value": {
                    "file": {
                      "filename": "clip.mp4",
                      "contentType": "video/mp4",
                      "contentBase64": "AAAAIGZ0eXBpc29tAAACAGlzb21pc28yYXZjMW1wNDEAAAatbW9vdgAAAGxtdmhkAAAAAAAAAAAAAAAAAAA+gAAAPoAAAQAAAQAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAwt0cmFrAAAAXHRraGQAAAADAAAAAAAAAAAAAAABAAAAAAAAPoAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAABAAAAAAEAAAAAwAAAAAAAkZWR0cwAAABxlbHN0AAAAAAAAAAEAAD6AAAAIAAABAAAAAAKDbWRpYQAAACBtZGhkAAAAAAAAAAAAAAAAAAAoAAAAKABVxAAAAAAALWhkbHIAAAAAAAAAAHZpZGUAAAAAAAAAAAAAAABWaWRlb0hhbmRsZXIAAAACLm1pbmYAAAAUdm1oZAAAAAEAAAAAAAAAAAAAACRkaW5mAAAAHGRyZWYAAAAAAAAAAQAAAAx1cmwgAAAAAQAAAe5zdGJsAAAAvnN0c2QAAAAAAAAAAQAAAK5hdmMxAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAEAAMABIAAAASAAAAAAAAAABDExhdmMgbGlieDI2NAAAAAAAAAAAAAAAAAAAAAAAAAAAGP//AAAANGF2Y0MBZAAK/+EAGGdkAAqs2UR7ARAAAAMAEAAAAwFA8SJZYAEABWjvgxyw/fj4AAAAABBwYXNwAAAAAQAAAAEAAAAUYnRydAAAAAAAACy4AAAAAAAAABhzdHRzAAAAAAAAAAEAAAAKAAAEAAAAABhzdHNzAAAAAAAAAAIAAAABAAAABgAAAGBjdHRzAAAAAAAAAAoAAAABAAAIAAAAAAEAABQAAAAAAQAACAAAAAABAAAAAAAAAAEAAAQAAAAAAQAACAAAAAABAAAUAAAAAAEAAAgAAAAAAQAAAAAAAAABAAAEAAAAAChzdHNjAAAAAAAAAAIAAAABAAAAAgAAAAEAAAACAAAAAQAAAAEAAAA8c3RzegAAAAAAAAAAAAAACgAAA8MAAAAmAAAADAAAAAwAAAAMAAABRQAAACEAAAAMAAAADAAAAAwAAAA0c3RjbwAAAAAAAAAJAAAG3QAAC38AAAziAAAOEAAADqUAABDmAAARjAAAEp4AABMsAAAC8XRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAA+gAAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAPoAAAAQAAAEAAAAAAmltZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAD6AAABCgFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAIUbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAAHYc3RibAAAAH5zdHNkAAAAAAAAAAEAAABubXA0YQAAAAAAAAABAAAAAAAAAAAAAQAQAAAAAD6AAAAAAAA2ZXNkcwAAAAADgICAJQACAASAgIAXQBUAAAAAAEZuAABGbgWAgIAFFAhW5QAGgICAAQIAAAAUYnRydAAAAAAAAEZuAABGbgAAACBzdHRzAAAAAAAAAAIAAAAQAAAEAAAAAAEAAAKAAAAAcHN0c2MAAAAAAAAACAAAAAEAAAABAAAAAQAAAAIAAAACAAAAAQAAAAQAAAABAAAAAQAAAAUAAAACAAAAAQAAAAYAAAABAAAAAQAAAAcAAAACAAAAAQAAAAgAAAABAAAAAQAAAAkAAAAFAAAAAQAAAFhzdHN6AAAAAAAAAAAAAAARAAAAuQAAALYAAAChAAAAmQAAAIkAAACJAAAAfQAAAH8AAACFAAAAgQAAAIUAAACCAAAAfgAAAIAAAACOAAAAjAAAAIIAAAA0c3RjbwAAAAAAAAAJAAAKxgAAC4sAAAzuAAAOHAAAD+oAABEHAAARmAAAEqoAABM4AAAAGnNncGQBAAAAcm9sbAAAAAIAAAAB//8AAAAcc2JncAAAAAByb2xsAAAAAQAAABEAAAABAAAAPXVkdGEAAAA1bWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAIaWxzdAAAAAhmcmVlAAAO/W1kYXQAAAKbBgX//5fcRem95tlIt5Ys2CDZI+7veDI2NCAtIGNvcmUgMTY1IC0gSC4yNjQvTVBFRy00IEFWQyBjb2RlYyAtIENvcHlsZWZ0IDIwMDMtMjAyNSAtIGh0dHA6Ly93d3cudmlkZW9sYW4ub3JnL3gyNjQuaHRtbCAtIG9wdGlvbnM6IGNhYmFjPTEgcmVmPTEgZGVibG9jaz0xOjA6MCBhbmFseXNlPTB4MzoweDExMyBtZT1oZXggc3VibWU9MiBwc3k9MSBwc3lfcmQ9MS4wMDowLjAwIG1peGVkX3JlZj0wIG1lX3JhbmdlPTE2IGNocm9tYV9tZT0xIHRyZWxsaXM9MCA4eDhkY3Q9MSBjcW09MCBkZWFkem9uZT0yMSwxMSBmYXN0X3Bza2lwPTEgY2hyb21hX3FwX29mZnNldD0wIHRocmVhZHM9MSBsb29rYWhlYWRfdGhyZWFkcz0xIHNsaWNlZF90aHJlYWRzPTAgbnI9MCBkZWNpbWF0ZT0xIGludGVybGFjZWQ9MCBibHVyYXlfY29tcGF0PTAgY29uc3RyYWluZWRfaW50cmE9MCBiZnJhbWVzPTMgYl9weXJhbWlkPTIgYl9hZGFwdD0xIGJfYmlhcz0wIGRpcmVjdD0xIHdlaWdodGI9MSBvcGVuX2dvcD0wIHdlaWdodHA9MSBrZXlpbnQ9NSBrZXlpbnRfbWluPTEgc2NlbmVjdXQ9NDAgaW50cmFfcmVmcmVzaD0wIHJjX2xvb2thaGVhZD01IHJjPWNyZiBtYnRyZWU9MSBjcmY9MzguMCBxY29tcD0wLjYwIHFwbWluPTAgcXBtYXg9NjkgcXBzdGVwPTQgaXBfcmF0aW89MS40MCBhcT0xOjEuMDAAgAAAASBliIQAR9I6DE+XmH8S+MUThkAmDt/AAaUe0TPuwtKuXPfJ/Uv5EhMrCwMZmvngBPORW4BTrY872aABEXimGiKPPKWi+0+uj6jq5nnFTehYc+fQ8y5nlLT4WoIA0sNC0tHvVic+jcZel4QejR0P/Dyza9DwFp6CutsOdBgwAaxz/SdU+kvYUtd94SXwbVpDTwd1C4rI3Xj8Ci05w9n3F44qDWVK/Ukh5vmjDnFK4HZ4e95RfDBgbiimr1nNMe0DXyzIaIhThpC+yt2tYHIYmERZnwlXDo+iSeZbNKrQ37Ytt8LssQ8EoVLxopyCRBD0LhMYBYhjH4OFgwmIKgdwmLbfLpXsvnW/NaIsJpEsRo3POmKzV11s/dcwt//LsMFATEsAAAAiQZokGIS/ipPPJIwyjL40VjHe2cC8anJOMxbuAI5xVPPxEAEgUKz0lkElu9/Pj78TW+JUm5EkbRCw7y859e7VzFmHSWjfOvifr32nY3ZPYXtr+o3U/1vZfwGbG5zh77JMC6LisTWrLcpGtYnHWGeUslJqsx0bHNX5rHNY59bKTSk0pNKVRlUZVKVSk0tNSNIzs8zzO0k0jSNIzs7PM7SM7SNJM8zzSTSTSNI0jOzs7RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRcAAAACEGeQkI7/6uBASCW2lF1ZiFrMNOLpZ/+H/PnrWpc1+n/p/5eRc1f7f+n/l7C5xP2/+P/Pgl3rQ5X2HeeeeeeeeeeY8wU7bwHFsCFT+PYHrjck+tndO9tG8Wdx3qCbJT7wB/Kh75UM+VDPl8qDAfLjQYD5fKKhYAE2z8KLdkpO39QeeapPkpc6LmF0WrabEL1N8p2EGCZQYJUDBKga8cmU4MDBITK4MDKCTi3d45rgclBC3p7ZMzJ5555555+bm4BBvCtLEKSCX3v+3z+/1GdNySS0iNJWroObP3cXa337vJ9aJ0j6z+B/W6NkGlshBYoyz9bwZSBRJ5hafsvFuKxXsGYVzFGU9T1BvNij14YYdsgtTjjjMyF7++gZPjMHffQH/jMM/voD/xmDvvoD/x8BPvCD/GYJ94VD4AT7+4Hx8B339w/8Zh5+iwfhaIff3UfgFWDSaFUXBBS4UILnFEd4AAAAAgBnmFEJf+xgADcMK0CtTkOAoNI//1+//8fnvS6uq63Va76zUqq4ywi0Yu6E3NcMKvnWWZeetZ6yzzwZVAA8JxwGUSghDfUGbcU3pHr16+HQ9aStqauiNKxtnpuja3ZSCs2qp4aIWM2kIUjCkpjdrRv7OiKuOnkZ6uwyjRrJ2YLDn601YSZsl94cC3Cw47f7q1YXHrs4JUS9TFoecHPOdBljwDaMKzMMYKhx3X/+f5//h53da3OK08cb1VRGXUgmLPttYrxtkEH2b9bYWfdfZ92Nommn6ABcXm3obyH37sa+vDF2di6ePCy90kkZ/pS0a2bePXBaiPDt9qpzlHwW7hOtN1LRI98pq9zKklhDZN3cyARVcfGI53nSplMKWKFhdkWmTE0MWlNF2OAAAAACAGeY0Ql/7GBANowrMxBeqEy//6X+v/6+0y80ZxVTFiZrLwMpWzTWXeLtC7K2TobHOatU9bcq7CmEAK86hVDlmoTappPhq0STSM7Cw9UZrR+cuPqst1EmrClLD32XqnCSaeFPr5tqDhmkffg1zzEKCwhoQtMCF3nHPu9qcaiqSrijleNGrNhQxaS98rsibloRQ4AAAFBZYiCACfRVincV3t/41s3ihhL/RSXWttt72R4j1YMiTYruZgrpfiBtmFrmK4nr+//ZgAAgAipXJ8mfL8EEJjG1Hm5gzT/CfGbZngHW+zYoHoTPTdkRTrf33t9WEYKox3zbKaOthv8IZCzmntUhduDczly+Tfa3kTikcuWo9EBtJIOQp1y0U9HHewAX7zcpPcL3dOqjXsJRtBYYKv2ZdVN0v19HH9zaxn03Kvdc3KqwkRXqpRSCDMSnttKGa6RIrJ+1ZeE3kEBK8S2gnsfy4Q050hu/k4fnFZ9o2XKSJRN0IQu1kh7vWJEJEGqbai4Dygq3EpTu3cCU8+HYDrFH77LYFL6w+n2KXdKLv5DOoi1sDf8jih6lADEq4/64Pd/rzIcfVZT/C+af52QKyyyfkugHxsndIA/DTMM5+fHHlB0o1o5AOIwrMwieal3f/9X/j/+HxV1qUdbxU1zIpUgPKU8qo2hbfEfzBSecNh9GZvnkAK+fr/gS8LpZ12Szr0UfqiMUc4OaIY/eQA1SUHOSmOgrLWLDIASkTuBjXmhOhw/8vfY26U40JKUhphXmfOQ1bVheGPRhUXhmunq0aNchFwA4jCtAxUojdZf/+v3//j9vE42cVxzUqEvKqK4DSmQtUDm7DbgsGvMj0pwXsal1EADI/HQbGXhC3IpoIGwKahvvR+l11Ei9GrnppWXohNRDObmvih53GpHVqlBOKa/ZBHXHAoEqotSSIgC5mnjKsTC5hbDNNBInaVd7rp9LdBwAAAAHUGaJBiEv4pVtmhz+OMuJp+q8OJq7KLcDWSUwxmBANwwqQUVQqP/+X8f/x+cZxF5rIyuudburqVoXHOsjxrabFkdi33lXge1eq794GHiii/F/99ccRQLIyMxNChfKeEECiD5TBPGUEISD54lCSIz0sLAwgGA0QSGSpI711J2STVoJm7SUUIVEAE6vXqRrHLaycQ5XVAiA2hlSF6zkapE0b1BPAAAAAhBnkJCM/+ngQDgMKzMM8OGf/1f7//x9cVVzd1q8rL1zrnVSpKERg0Yxa2cxZhzVqnb3ePeWteJapj4ADDW70YuCTRJNJM7SM6QzazZoQ3yVLk6lpdGwVy3i2aXXijtOrwrQpwzsphX+3MMLcEoIVKF1uR+ue71OulLttCNUHXbM6ydM12rfLW8HADoMK0DFUL9p//V/t/+763L14uVp41fPFK1Wts0Dp4UaaLSov6Mznu3o/aGm+uI2AC/dNKS6eaAkVzh9wONUX+DVzr4ae71pJXhw/cvcrTdovQvu7+1X7F3S6jy+2QiTygu5nRMFBKhiqmdl7tU4ry5TU5mKtM5llcwCgsVYE0JmjInI4AAAAAIAZ5hRCX/sYAA3jCszCGKlEatT//l/H/5fW7rUq80Zmr71vjIIIkdczlam+3G7JVH3xovnrpOjDoAZOgPrHVK4Ntyx2XWXa09cHTulGymz6Sccham7navPBeErHWTVb37Fo3sixzHcFpomKqglZEEyskqIvy6ZnjnG4mEXfdkTXbUnKnw3v+zstdwAAAACAGeY0Ql/7GAANowrMwxooRGnjj//T6//L2qvO5zw65TbjG+sqM0LKtm5rlw7mXjLmGMojEpF19mGnnCABkauhdhrw110v110kxG8nTxx1kexesix+NKxtlRpqnZWKE3z2FsX4o0rA9jvHvaFIyTT8oV+nr2rO12hOO17wJqKTUrF8LclZuAAOQwqQUFEZ3Fa//v/2//f8ZJeaqvauy2LUy4D01bMeG4XrXQcVtvVuM/tv6v1WNiii36pfDuYjRJQK4konXr+hm0/T6A4SKELAeWE9J5fS87DUrU8ENguhE7ACZWICIE37tIreUbQRmqhWIvxe7HebdEna6cKqpp2nLfcLgtYq4A5DCszCQxKcxDean/9T+//7vpXAma3AqVdVxiw1JTyrBpgsrr175JzdqC89kaipkAK4zhctCeQnlnHZpoq6qbBZi1w17FYUxeongaygg8eVgRpupSVqUSnHEU3ABm48lpoK4kk7qmBOZJZkTN3MyILms+506rfW3ZnUxhlL7PhguC2HsQf8Nv/NUgluHAASAwqCg7FQ0w/tWff9P9LqueEtJJEkiSJBxh8o+PtwMRrENB2R/b+i+qix+hv6ScsCwdurLEMbAHtwGB7Yhge2IYHtiGB7Yhge2IYHtiGB7Yhge2IUPWIUPWIUPWIUPWIUHrAFB6xCh6xCg9YAoPWAKD2wBQesAUHrAHD3AFB6wBQe4AoPWAKD3AH4ABLDChBZe9Zm+OMku5JJEkkkSJBR7nubUTTQgsshU00ILNTU1O1mmSaKOiySbI3nhyN54cjeeHI3nhyN54cjeeHI3nhyN5yyN5yyN5yyN5yyN5yyN+5fBvcvg3vD8G9y+De5fBvcvg3uXwb3L4N7l8G9y+De5fBvcvg3uXwb3L4N78"
                    },
                    "duration": 1,
                    "fps": 10,
                    "width": 64,
                    "format": "webp"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VideoToGifCreatorResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tool": {
      "get": {
        "operationId": "getToolDefinition",
        "summary": "Inputs, output schema and examples for this tool",
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details. 422 responses include per-field `errors`.",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "VideoToGifCreatorInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "file": {
            "title": "Video file",
            "description": "MP4, MOV, MKV, WebM, AVI; max 250 MB and 20 minutes. Processed on our server in a private temporary folder that is deleted afterwards; the result can be downloaded for about 2 hours. Upload as {filename, contentType?, contentBase64}. Max 256000 KiB. Accepts .mp4,.m4v,.mov,.mkv,.webm,.avi,.ts,.mts,.m2ts,.mpg,.mpeg,.wmv,.flv,.3gp,video/*.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "filename",
              "contentBase64"
            ],
            "properties": {
              "filename": {
                "type": "string"
              },
              "contentType": {
                "type": "string"
              },
              "contentBase64": {
                "type": "string"
              }
            }
          },
          "start": {
            "title": "Start time",
            "description": "Seconds, mm:ss or hh:mm:ss.mmm.",
            "type": "string",
            "maxLength": 20
          },
          "duration": {
            "title": "Length",
            "description": "At most 15 seconds.",
            "type": "number",
            "minimum": 0.2,
            "maximum": 15,
            "default": 3,
            "x-unit": "s"
          },
          "fps": {
            "title": "Frame rate",
            "description": "10–15 fps is typical for GIFs; more frames = larger file.",
            "type": "integer",
            "minimum": 1,
            "maximum": 30,
            "default": 12,
            "x-unit": "fps"
          },
          "width": {
            "title": "Width",
            "description": "Height follows the aspect ratio. Never wider than the source.",
            "type": "integer",
            "minimum": 32,
            "maximum": 800,
            "default": 480,
            "x-unit": "px"
          },
          "format": {
            "title": "Output format",
            "type": "string",
            "enum": [
              "gif",
              "webp"
            ],
            "default": "gif"
          },
          "dither": {
            "title": "Dithering (GIF)",
            "type": "string",
            "enum": [
              "sierra2_4a",
              "floyd_steinberg",
              "bayer",
              "none"
            ],
            "default": "sierra2_4a"
          },
          "colors": {
            "title": "Palette colours (GIF)",
            "type": "integer",
            "minimum": 8,
            "maximum": 256,
            "default": 256
          },
          "statsMode": {
            "title": "Palette from (GIF)",
            "type": "string",
            "enum": [
              "full",
              "diff"
            ],
            "default": "full"
          },
          "loop": {
            "title": "Loop forever",
            "type": "boolean",
            "default": true
          },
          "webpQuality": {
            "title": "WebP quality",
            "type": "integer",
            "minimum": 1,
            "maximum": 100,
            "default": 75
          }
        },
        "required": [
          "file"
        ]
      },
      "VideoToGifCreatorResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "format",
              "startSeconds",
              "durationSeconds",
              "fps",
              "width",
              "height",
              "frames",
              "outputBytes",
              "bytesPerFrame",
              "artifact"
            ],
            "properties": {
              "format": {
                "type": "string",
                "enum": [
                  "gif",
                  "webp"
                ]
              },
              "startSeconds": {
                "type": "number"
              },
              "durationSeconds": {
                "type": "number"
              },
              "fps": {
                "type": "integer"
              },
              "width": {
                "type": "integer"
              },
              "height": {
                "type": "integer"
              },
              "frames": {
                "type": "integer"
              },
              "dither": {
                "type": "string"
              },
              "colors": {
                "type": "integer"
              },
              "outputBytes": {
                "type": "integer"
              },
              "bytesPerFrame": {
                "type": "integer"
              },
              "artifact": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "artifactId",
                  "filename",
                  "mime",
                  "bytes",
                  "sha256",
                  "path"
                ],
                "properties": {
                  "artifactId": {
                    "type": "string"
                  },
                  "filename": {
                    "type": "string"
                  },
                  "mime": {
                    "type": "string"
                  },
                  "bytes": {
                    "type": "integer"
                  },
                  "sha256": {
                    "type": "string"
                  },
                  "path": {
                    "type": "string",
                    "description": "Download path on the same site (valid for about 2 hours)."
                  }
                }
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      }
    }
  }
}