{
  "openapi": "3.1.1",
  "info": {
    "title": "Opus Motion public API",
    "version": "1.0.0",
    "summary": "Read the catalog of promo and launch video templates, and make studio links filled from a website.",
    "description": "Read-only, no authentication. Versioned in the path (/api/v1): additions don't change it; a breaking change ships as /api/v2 and v1 keeps working at least six months after, announced with Deprecation and Sunset headers. Docs: https://opusmotion.com/developers",
    "contact": {
      "name": "Opus Motion",
      "email": "support@opusmotion.com",
      "url": "https://opusmotion.com/contact"
    },
    "termsOfService": "https://opusmotion.com/terms"
  },
  "servers": [
    {
      "url": "https://opusmotion.com",
      "description": "Opus Motion website"
    }
  ],
  "externalDocs": {
    "url": "https://opusmotion.com/developers",
    "description": "Developer and agent docs"
  },
  "tags": [
    {
      "name": "templates",
      "description": "The video template catalog"
    }
  ],
  "paths": {
    "/api/v1/templates": {
      "get": {
        "operationId": "listTemplates",
        "tags": [
          "templates"
        ],
        "summary": "List or search templates",
        "description": "The catalog, filtered by free text, category, tier and format.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Free text over title, description, category, tags and example brands.",
            "schema": {
              "type": "string",
              "maxLength": 200
            }
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "description": "A category id, for example launches.",
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9-]+$"
            }
          },
          {
            "name": "tier",
            "in": "query",
            "required": false,
            "description": "Only free or only premium templates.",
            "schema": {
              "type": "string",
              "enum": [
                "free",
                "premium"
              ]
            }
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "description": "Only templates offered in this format.",
            "schema": {
              "type": "string",
              "enum": [
                "16:9",
                "9:16"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The matching templates",
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateList"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests; see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/templates/{id}": {
      "get": {
        "operationId": "getTemplate",
        "tags": [
          "templates"
        ],
        "summary": "Get one template",
        "description": "One template by id or slug.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The template's id (t07-discover-play) or slug (discover-play).",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]+$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The template",
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "No template with that id or slug",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests; see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/studio-link": {
      "get": {
        "operationId": "createStudioLink",
        "tags": [
          "templates"
        ],
        "summary": "Studio link filled from a website",
        "description": "A link that opens the template in the studio, in the person's brand, read from their website. It creates nothing: the person opens it.",
        "parameters": [
          {
            "name": "template",
            "in": "query",
            "required": true,
            "description": "The template's id or slug.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]+$"
            }
          },
          {
            "name": "site",
            "in": "query",
            "required": false,
            "description": "The person's website domain, for example example.com.",
            "schema": {
              "type": "string",
              "maxLength": 253
            }
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "description": "Open the studio in this format.",
            "schema": {
              "type": "string",
              "enum": [
                "16:9",
                "9:16"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The link",
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StudioLink"
                }
              }
            }
          },
          "400": {
            "description": "The site isn't a domain name",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No template with that id or slug",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests; see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "headers": {
      "RateLimitPolicy": {
        "description": "The limit and its window, for example 120;w=60 (IETF draft-ietf-httpapi-ratelimit-headers).",
        "schema": {
          "type": "string"
        }
      },
      "RateLimit": {
        "description": "Requests left and seconds to reset, for example limit=120, remaining=119, reset=60.",
        "schema": {
          "type": "string"
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error",
          "message"
        ],
        "properties": {
          "error": {
            "type": "string",
            "description": "A stable code, for example template_not_found."
          },
          "message": {
            "type": "string"
          },
          "retryAfter": {
            "type": "integer"
          }
        }
      },
      "Example": {
        "type": "object",
        "required": [
          "brand",
          "format",
          "video",
          "poster"
        ],
        "properties": {
          "brand": {
            "type": "string"
          },
          "format": {
            "type": "string"
          },
          "video": {
            "type": "string",
            "format": "uri"
          },
          "poster": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "Template": {
        "type": "object",
        "required": [
          "id",
          "slug",
          "title",
          "description",
          "category",
          "tier",
          "priceCents",
          "durationSeconds",
          "formats",
          "url",
          "studioUrl"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "categoryLabel": {
            "type": "string"
          },
          "tier": {
            "type": "string",
            "enum": [
              "free",
              "premium"
            ]
          },
          "priceCents": {
            "type": "integer",
            "description": "Price per export in US cents; 0 for free templates."
          },
          "priceUsd": {
            "type": "number"
          },
          "durationSeconds": {
            "type": "number"
          },
          "formats": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "editable": {
            "type": "object",
            "properties": {
              "text": {
                "type": "integer"
              },
              "images": {
                "type": "integer"
              },
              "colors": {
                "type": "integer"
              },
              "music": {
                "type": "boolean"
              },
              "voice": {
                "type": "boolean"
              }
            }
          },
          "examples": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Example"
            }
          },
          "poster": {
            "type": "string",
            "format": "uri"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "markdownUrl": {
            "type": "string",
            "format": "uri"
          },
          "studioUrl": {
            "type": "string",
            "format": "uri"
          },
          "version": {
            "type": "string"
          },
          "publishedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "TemplateList": {
        "type": "object",
        "required": [
          "apiVersion",
          "count",
          "templates"
        ],
        "properties": {
          "apiVersion": {
            "type": "string"
          },
          "count": {
            "type": "integer"
          },
          "templates": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Template"
            }
          }
        }
      },
      "TemplateEnvelope": {
        "type": "object",
        "required": [
          "apiVersion",
          "template"
        ],
        "properties": {
          "apiVersion": {
            "type": "string"
          },
          "template": {
            "$ref": "#/components/schemas/Template"
          }
        }
      },
      "StudioLink": {
        "type": "object",
        "required": [
          "apiVersion",
          "url",
          "template"
        ],
        "properties": {
          "apiVersion": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "template": {
            "type": "string"
          },
          "site": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      }
    }
  }
}