JSON Structure and Field Rules

1. Top-level structure

The full top-level JSON shape is:

{
  "meta": {},
  "assets": {},
  "tracks": []
}

Rules:

  • meta is required
  • tracks is required and must contain at least one track
  • assets is optional

Not supported:

  • Legacy top-level video
  • Legacy top-level audio

2. meta

interface Meta {
  version: string;
  title?: string;
  description?: string;
  author?: string;
  createdAt?: string;
  tags?: string[];
  width: number;
  height: number;
  fps: number;
  background?: string | "transparent" | Gradient;
}

version

  • Type: string
  • Required: yes
  • Purpose: schema version marker
  • Recommended value: "2.0.0"

title

  • Type: string
  • Required: no
  • Purpose: video title metadata

description

  • Type: string
  • Required: no
  • Purpose: video description metadata

author

  • Type: string
  • Required: no
  • Purpose: author metadata

createdAt

  • Type: string
  • Required: no
  • Purpose: creation-time metadata

tags

  • Type: string[]
  • Required: no
  • Purpose: tagging metadata

width

  • Type: number
  • Required: yes
  • Constraint: positive integer
  • Purpose: canvas width

height

  • Type: number
  • Required: yes
  • Constraint: positive integer
  • Purpose: canvas height

fps

  • Type: number
  • Required: yes
  • Constraint: positive integer
  • Purpose: frame rate

background

  • Type: string | "transparent" | Gradient
  • Required: no
  • Default: "#000000"
  • Purpose: global background

Gradient shape:

interface Gradient {
  type: "linear" | "radial" | "conic";
  angle?: number;
  stops: Array<{
    offset: number;
    color: string;
  }>;
}

3. assets

interface Assets {
  fonts?: FontAsset[];
  images?: ImageAsset[];
  videos?: VideoAsset[];
  audios?: AudioAsset[];
  subtitles?: SubtitleAsset[];
}

fonts

interface FontAsset {
  id: string;
  src: string;
  family: string;
}

Current runtime status:

  • It can appear in JSON
  • The runtime does not automatically download or register fonts
  • Do not treat it as a complete font-loading system

images

interface ImageAsset {
  id: string;
  src: string;
}

videos

interface VideoAsset {
  id: string;
  src: string;
}

audios

interface AudioAsset {
  id: string;
  src: string;
}

subtitles

interface SubtitleAsset {
  id: string;
  words: SubtitleWord[];
}

$ref usage

Resource pools that support $ref:

  • images
  • videos
  • audios
  • subtitles

Example:

{
  "src": { "$ref": "video-hero" }
}

Or:

{
  "words": { "$ref": "subtitle-main" }
}

4. tracks

interface Track {
  id?: string;
  clips: Clip[];
}

id

  • Type: string
  • Required: no
  • Purpose: track identifier

clips

  • Type: Clip[]
  • Required: yes
  • Constraint: at least one clip

5. Shared Clip shape

interface BaseClip {
  id?: string;
  type: ClipType;
  start: number;
  duration: number;
  transform?: Transform;
  zIndex?: number;
  opacity?: number;
  style?: Style;
  animations?: Animation[];
  keyframes?: Keyframe[];
  transition?: Transition;
}

Shared core fields:

id

  • Type: string
  • Required: no
  • Purpose: clip identifier

type

  • Type: ClipType
  • Required: yes

Currently supported:

  • video
  • image
  • text
  • rect
  • circle
  • polygon
  • audio
  • subtitle
  • layout
  • template

start

  • Type: number
  • Required: yes
  • Unit: seconds
  • Purpose: clip start time

duration

  • Type: number
  • Required: yes
  • Unit: seconds
  • Purpose: clip duration

transform

  • Type: Transform
  • Required: no

zIndex

  • Type: number
  • Required: no
  • Default: 0

opacity

  • Type: number
  • Required: no
  • Default: 1
  • Purpose: shorthand opacity for visible elements
  • Compatibility rule: style.opacity has higher priority than top-level opacity

style

  • Type: Style
  • Required: no

animations

  • Type: Animation[]
  • Required: no

keyframes

  • Type: Keyframe[]
  • Required: no

transition

  • Type: Transition
  • Required: no

6. Coordinate and percentage rules

Percentage coordinates are based on the Revideo-centered coordinate system, not a DOM-style top-left origin.

Examples:

  • x: "50%" means horizontally centered
  • y: "50%" means vertically centered
  • x: "0%" means far left
  • x: "100%" means far right
  • y: "0%" means top
  • y: "100%" means bottom

7. Minimal valid JSON

{
  "meta": {
    "version": "2.0.0",
    "width": 1920,
    "height": 1080,
    "fps": 30,
    "background": "#000000"
  },
  "tracks": [
    {
      "clips": [
        {
          "type": "text",
          "start": 0,
          "duration": 3,
          "text": "Hello, world",
          "transform": {
            "x": "50%",
            "y": "50%"
          },
          "style": {
            "fontSize": 72,
            "fill": "#ffffff",
            "textAlign": "center"
          }
        }
      ]
    }
  ]
}

8. Public integration note

For external integrations, use the flow documented in API and Usage:

  • Submit your schema through POST /api/preview
  • Send the full schema JSON as the request body
  • Missing top-level meta or tracks should still be treated as invalid input
  • A wrong field name inside a clip may not always fail at request time
  • Some mistakes may only become visible during preview, playback, or rendering