Shotstack Serve API

Inspect, manage, and delete the hosting of assets generated by the Edit and Ingest APIs, retrieve CDN URLs by asset or render ID, and transfer files to external destinations.

OpenAPI Specification

shotstack-openapi.yml Raw ↑
openapi: 3.0.1
info:
  title: Shotstack API
  description: >-
    Shotstack is a cloud video-editing platform that renders video, image, and
    audio assets from a JSON edit specification. This document covers the Edit
    API (render and templates), the Ingest API (source assets), the Serve API
    (asset hosting and delivery), and the Create API (AI-generated assets). All
    endpoints authenticate with an `x-api-key` header. Each API is available in
    a `v1` (production) and `stage` (sandbox) environment.
  termsOfService: https://shotstack.io/terms/
  contact:
    name: Shotstack Support
    url: https://shotstack.io/contact/
  version: '1.0'
servers:
  - url: https://api.shotstack.io
    description: Shotstack production and sandbox host (use /edit/v1 or /edit/stage, etc.)
security:
  - apiKey: []
tags:
  - name: Edit
    description: Render videos, images, and audio from a JSON edit specification.
  - name: Templates
    description: Manage and render reusable edit templates with merge fields.
  - name: Ingest
    description: Upload, store, and transform source assets.
  - name: Serve
    description: Inspect, manage, and deliver hosted assets.
  - name: Create
    description: Generate AI assets such as text-to-speech and text-to-image.
paths:
  /edit/v1/render:
    post:
      operationId: postRender
      tags:
        - Edit
      summary: Queue a render
      description: >-
        Queue a video, image, or audio for rendering from a JSON edit
        specification consisting of a timeline and an output. Returns a render
        ID used to poll status.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Edit'
      responses:
        '201':
          description: Render queued.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QueuedResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /edit/v1/render/{id}:
    get:
      operationId: getRender
      tags:
        - Edit
      summary: Get render status
      description: >-
        Retrieve the status, progress, and output URL of a render by its ID.
        Status values progress through queued, fetching, rendering, saving,
        done, and failed.
      parameters:
        - name: id
          in: path
          required: true
          description: The render ID returned when the render was queued.
          schema:
            type: string
            format: uuid
        - name: data
          in: query
          required: false
          description: Include the original edit JSON in the response.
          schema:
            type: boolean
            default: false
      responses:
        '200':
          description: Render status.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RenderResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
  /edit/v1/probe/{url}:
    get:
      operationId: probeAsset
      tags:
        - Edit
      summary: Probe a media asset
      description: >-
        Inspect the metadata of a media asset (duration, dimensions, codecs)
        using FFprobe. The asset URL must be URL-encoded.
      parameters:
        - name: url
          in: path
          required: true
          description: URL-encoded URL of the media asset to inspect.
          schema:
            type: string
      responses:
        '200':
          description: Asset metadata.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProbeResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /edit/v1/templates:
    post:
      operationId: createTemplate
      tags:
        - Templates
      summary: Create a template
      description: Save an edit as a reusable template with optional merge fields.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Template'
      responses:
        '201':
          description: Template created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TemplateResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
    get:
      operationId: listTemplates
      tags:
        - Templates
      summary: List templates
      description: List all templates for the authenticated account.
      responses:
        '200':
          description: A list of templates.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TemplateListResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /edit/v1/templates/{id}:
    get:
      operationId: getTemplate
      tags:
        - Templates
      summary: Get a template
      parameters:
        - $ref: '#/components/parameters/TemplateId'
      responses:
        '200':
          description: A template.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TemplateResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
    put:
      operationId: updateTemplate
      tags:
        - Templates
      summary: Update a template
      parameters:
        - $ref: '#/components/parameters/TemplateId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Template'
      responses:
        '200':
          description: Template updated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TemplateResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
    delete:
      operationId: deleteTemplate
      tags:
        - Templates
      summary: Delete a template
      parameters:
        - $ref: '#/components/parameters/TemplateId'
      responses:
        '200':
          description: Template deleted.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
  /edit/v1/templates/render:
    post:
      operationId: renderTemplate
      tags:
        - Templates
      summary: Render a template
      description: >-
        Render an asset from a saved template, supplying optional merge fields
        to substitute variables in the template.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TemplateRenderRequest'
      responses:
        '201':
          description: Render queued.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QueuedResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /ingest/v1/sources:
    post:
      operationId: fetchSource
      tags:
        - Ingest
      summary: Ingest a source from a URL
      description: >-
        Queue a source file (video, image, audio, or font) to be fetched from a
        URL, stored, and optionally transformed into renditions or transcribed.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SourceRequest'
      responses:
        '201':
          description: Source queued.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SourceResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
    get:
      operationId: listSources
      tags:
        - Ingest
      summary: List sources
      responses:
        '200':
          description: A list of ingested sources.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SourceListResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /ingest/v1/sources/{id}:
    get:
      operationId: getSource
      tags:
        - Ingest
      summary: Get a source
      parameters:
        - $ref: '#/components/parameters/SourceId'
      responses:
        '200':
          description: A source.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SourceResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
    delete:
      operationId: deleteSource
      tags:
        - Ingest
      summary: Delete a source
      parameters:
        - $ref: '#/components/parameters/SourceId'
      responses:
        '200':
          description: Source deleted.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
  /ingest/v1/upload:
    post:
      operationId: requestUpload
      tags:
        - Ingest
      summary: Request a direct upload
      description: >-
        Request a signed URL to upload a source file directly to Shotstack
        storage.
      responses:
        '201':
          description: Signed upload URL issued.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UploadResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /serve/v1/assets/{id}:
    get:
      operationId: getAsset
      tags:
        - Serve
      summary: Get an asset
      description: Retrieve the details and CDN URL of a hosted asset by asset ID.
      parameters:
        - $ref: '#/components/parameters/AssetId'
      responses:
        '200':
          description: An asset.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AssetResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
    delete:
      operationId: deleteAsset
      tags:
        - Serve
      summary: Delete an asset
      parameters:
        - $ref: '#/components/parameters/AssetId'
      responses:
        '200':
          description: Asset deleted.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
  /serve/v1/assets/render/{id}:
    get:
      operationId: getAssetsByRender
      tags:
        - Serve
      summary: Get assets by render ID
      description: >-
        Retrieve all assets (video, thumbnail, poster) associated with a render
        ID.
      parameters:
        - name: id
          in: path
          required: true
          description: The render ID.
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: A list of assets for the render.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AssetListResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
  /serve/v1/assets:
    post:
      operationId: transferAsset
      tags:
        - Serve
      summary: Transfer an asset
      description: Transfer a file from a URL to one or more hosting destinations.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TransferRequest'
      responses:
        '201':
          description: Transfer queued.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AssetResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /create/v1/assets:
    post:
      operationId: generateAsset
      tags:
        - Create
      summary: Generate an AI asset
      description: >-
        Generate an AI asset (text-to-speech, text-to-image, image-to-video, or
        text generation) using a built-in or third-party provider. Returns an
        asset ID to poll for the generated, hosted asset.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GenerateAssetRequest'
      responses:
        '201':
          description: Generation queued.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GenerateAssetResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /create/v1/assets/{id}:
    get:
      operationId: getGeneratedAsset
      tags:
        - Create
      summary: Get a generated asset
      description: Retrieve the status and URL of a generated AI asset by ID.
      parameters:
        - $ref: '#/components/parameters/AssetId'
      responses:
        '200':
          description: A generated asset.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GenerateAssetResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
components:
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: x-api-key
      description: Developer API key. The same key set is used by all Shotstack APIs.
  parameters:
    TemplateId:
      name: id
      in: path
      required: true
      description: The template ID.
      schema:
        type: string
        format: uuid
    SourceId:
      name: id
      in: path
      required: true
      description: The source ID.
      schema:
        type: string
        format: uuid
    AssetId:
      name: id
      in: path
      required: true
      description: The asset ID.
      schema:
        type: string
        format: uuid
  responses:
    BadRequest:
      description: The request was malformed or failed validation.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: Missing or invalid x-api-key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    NotFound:
      description: The requested resource was not found.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  schemas:
    Edit:
      type: object
      required:
        - timeline
        - output
      properties:
        timeline:
          $ref: '#/components/schemas/Timeline'
        output:
          $ref: '#/components/schemas/Output'
        merge:
          type: array
          description: Find-and-replace merge fields applied before rendering.
          items:
            $ref: '#/components/schemas/MergeField'
        callback:
          type: string
          format: uri
          description: HTTPS webhook URL called when the render status changes.
    Timeline:
      type: object
      required:
        - tracks
      properties:
        soundtrack:
          $ref: '#/components/schemas/Soundtrack'
        background:
          type: string
          description: Hex color of the background canvas.
          example: '#000000'
        fonts:
          type: array
          items:
            type: object
            properties:
              src:
                type: string
                format: uri
        tracks:
          type: array
          description: Layers of clips composited from bottom to top.
          items:
            $ref: '#/components/schemas/Track'
    Track:
      type: object
      required:
        - clips
      properties:
        clips:
          type: array
          items:
            $ref: '#/components/schemas/Clip'
    Clip:
      type: object
      required:
        - asset
        - start
        - length
      properties:
        asset:
          $ref: '#/components/schemas/Asset'
        start:
          type: number
          description: Start time on the timeline in seconds.
        length:
          oneOf:
            - type: number
            - type: string
          description: Duration of the clip in seconds, or "auto"/"end".
        fit:
          type: string
          enum: [crop, cover, contain, none]
        scale:
          type: number
        position:
          type: string
          enum: [top, topRight, right, bottomRight, bottom, bottomLeft, left, topLeft, center]
        opacity:
          type: number
        transition:
          type: object
          properties:
            in:
              type: string
            out:
              type: string
        effect:
          type: string
    Asset:
      type: object
      description: >-
        A clip asset. The "type" discriminates between video, image, audio,
        title, html, luma, caption, and the AI generative asset types
        (text-to-speech, text-to-image, image-to-video).
      required:
        - type
      properties:
        type:
          type: string
          enum:
            - video
            - image
            - audio
            - title
            - html
            - luma
            - caption
            - text-to-speech
            - text-to-image
            - image-to-video
        src:
          type: string
          format: uri
          description: Source URL for video, image, audio, and luma assets.
        text:
          type: string
          description: Text content for title, caption, and AI text-based assets.
        trim:
          type: number
        volume:
          type: number
    Soundtrack:
      type: object
      properties:
        src:
          type: string
          format: uri
        effect:
          type: string
          enum: [fadeIn, fadeOut, fadeInFadeOut]
        volume:
          type: number
    Output:
      type: object
      required:
        - format
      properties:
        format:
          type: string
          enum: [mp4, gif, jpg, png, bmp, mp3, webm]
        resolution:
          type: string
          enum: [preview, mobile, sd, hd, '1080']
        aspectRatio:
          type: string
          enum: ['16:9', '9:16', '1:1', '4:5', '4:3']
        fps:
          type: number
          enum: [12, 15, 24, 25, 30, 60]
        quality:
          type: string
          enum: [low, medium, high]
        destinations:
          type: array
          description: Where to deliver the rendered output.
          items:
            type: object
            properties:
              provider:
                type: string
                enum: [shotstack, s3, googlecloudstorage, googledrive, mux, vimeo]
    MergeField:
      type: object
      properties:
        find:
          type: string
        replace:
          type: string
    QueuedResponse:
      type: object
      properties:
        success:
          type: boolean
        message:
          type: string
        response:
          type: object
          properties:
            message:
              type: string
            id:
              type: string
              format: uuid
    RenderResponse:
      type: object
      properties:
        success:
          type: boolean
        message:
          type: string
        response:
          type: object
          properties:
            id:
              type: string
              format: uuid
            owner:
              type: string
            status:
              type: string
              enum: [queued, fetching, rendering, saving, done, failed]
            url:
              type: string
              format: uri
            poster:
              type: string
              format: uri
            thumbnail:
              type: string
              format: uri
            duration:
              type: number
            renderTime:
              type: number
            created:
              type: string
              format: date-time
            updated:
              type: string
              format: date-time
    ProbeResponse:
      type: object
      properties:
        success:
          type: boolean
        response:
          type: object
          properties:
            metadata:
              type: object
    Template:
      type: object
      required:
        - name
        - template
      properties:
        name:
          type: string
        template:
          $ref: '#/components/schemas/Edit'
    TemplateResponse:
      type: object
      properties:
        success:
          type: boolean
        message:
          type: string
        response:
          type: object
          properties:
            id:
              type: string
              format: uuid
            name:
              type: string
            template:
              $ref: '#/components/schemas/Edit'
    TemplateListResponse:
      type: object
      properties:
        success:
          type: boolean
        response:
          type: object
          properties:
            templates:
              type: array
              items:
                type: object
                properties:
                  id:
                    type: string
                    format: uuid
                  name:
                    type: string
    TemplateRenderRequest:
      type: object
      required:
        - id
      properties:
        id:
          type: string
          format: uuid
          description: The template ID to render.
        merge:
          type: array
          items:
            $ref: '#/components/schemas/MergeField'
    SourceRequest:
      type: object
      required:
        - url
      properties:
        url:
          type: string
          format: uri
          description: URL of the source file to fetch and store.
        outputs:
          type: object
          description: Optional renditions and/or transcription to generate.
          properties:
            renditions:
              type: array
              items:
                type: object
                properties:
                  format:
                    type: string
                  resolution:
                    type: string
            transcription:
              type: object
              properties:
                format:
                  type: string
    SourceResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            type:
              type: string
              example: source
            id:
              type: string
              format: uuid
            attributes:
              type: object
              properties:
                id:
                  type: string
                  format: uuid
                owner:
                  type: string
                source:
                  type: string
                  format: uri
                status:
                  type: string
                  enum: [queued, importing, ready, failed, deleted]
                created:
                  type: string
                  format: date-time
                updated:
                  type: string
                  format: date-time
    SourceListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/SourceResponse'
    UploadResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            type:
              type: string
              example: upload
            id:
              type: string
              format: uuid
            attributes:
              type: object
              properties:
                id:
                  type: string
                  format: uuid
                url:
                  type: string
                  format: uri
                  description: Signed URL to PUT the file to.
    AssetResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            type:
              type: string
              example: asset
            id:
              type: string
              format: uuid
            attributes:
              type: object
              properties:
                id:
                  type: string
                  format: uuid
                owner:
                  type: string
                region:
                  type: string
                renderId:
                  type: string
                  format: uuid
                filename:
                  type: string
                url:
                  type: string
                  format: uri
                status:
                  type: string
                  enum: [queued, transferring, ready, failed, deleted]
                created:
                  type: string
                  format: date-time
                updated:
                  type: string
                  format: date-time
    AssetListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/AssetResponse'
    TransferRequest:
      type: object
      required:
        - url
      properties:
        url:
          type: string
          format: uri
          description: URL of the file to transfer.
        destinations:
          type: array
          items:
            type: object
            properties:
              provider:
                type: string
                enum: [shotstack, s3, googlecloudstorage, googledrive, mux, vimeo]
    GenerateAssetRequest:
      type: object
      required:
        - provider
        - options
      properties:
        provider:
          type: string
          description: The generation provider.
          enum: [shotstack, elevenlabs, stability-ai, openai]
        options:
          type: object
          required:
            - type
          properties:
            type:
              type: string
              enum: [text-to-speech, text-to-image, image-to-video, text-generation]
            text:
              type: string
              description: Prompt or text input for the generation.
            prompt:
              type: string
            voice:
              type: string
            language:
              type: string
    GenerateAssetResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            type:
              type: string
              example: asset
            id:
              type: string
              format: uuid
            attributes:
              type: object
              properties:
                id:
                  type: string
                  format: uuid
                owner:
                  type: string
                provider:
                  type: string
                type:
                  type: string
                status:
                  type: string
                  enum: [queued, processing, done, failed]
                url:
                  type: string
                  format: uri
                created:
                  type: string
                  format: date-time
                updated:
                  type: string
                  format: date-time
    Error:
      type: object
      properties:
        success:
          type: boolean
          example: false
        message:
          type: string
        response:
          type: object
          properties:
            error:
              type: string
            code:
              type: string