Rewatch Help Center
Home API Uploading videos using the Rewatch API

Uploading videos using the Rewatch API

The Rewatch API and webhooks are currently in private beta and are subject to change during the beta period. If you’d like to learn more about the beta, please contact your account manager or get in touch at support@rewatch.com.

As a prerequisite for uploading videos, be sure to generate an API token and familiarize yourself with querying the Rewatch GraphQL API.

Uploading videos using the API

Uploading a video to Rewatch via the API is a multi-step process:

  1. Execute an initiateDirectVideoUpload GraphQL mutation to receive a URL to upload the video file to, HTTP headers to include in the request, and an upload ID to use after the video has been uploaded.
  2. Issue an HTTP PUT request to the given URL, including the given headers, with the video file as the request body.
  3. Execute a createVideoFromDirectUpload mutation, passing the upload ID returned in the first step along with the video’s details, such as its title, description, initial collections, and visibility on the channel.

Here is a full example written in the Ruby programming language, using the graphql-client library, that illustrates each step:

require "digest/md5"
require "json"
require "net/http"
require "uri"

require "graphql/client"
require "graphql/client/http"

# Initialize a GraphQL client that has introspected the Rewatch API schema
adapter = GraphQL::Client::HTTP.new("https://example-channel.rewatch.com/api/graphql") do
  def headers(context)
    {
      "Authorization": "Token token=MY-API-TOKEN",
      "Content-Type": "application/json",
    }
  end
end
schema = GraphQL::Client.load_schema(adapter)
client = GraphQL::Client.new(schema: schema, execute: adapter)

file_path = "/path/to/my-video.mp4"
file_data = File.read(file_path)

# Send a mutation query to initiate an upload. The response will contain
# a URL to upload the file data to and an upload id to use once the file
# has been uploaded.
INITIATE_UPLOAD_MUTATION = client.parse <<-'GRAPHQL'
  mutation ($input: InitiateDirectVideoUploadInput!) {
    initiateDirectVideoUpload(input: $input) {
      uploadHeaders
      uploadId
      uploadUrl
      errors {
        message
        path
      }
    }
  }
GRAPHQL
query_response = client.query(
  INITIATE_UPLOAD_MUTATION,
  variables: {
    input: {
      byteSize: File.size(file_path),
      checksum: Digest::MD5.base64digest(file_data),
      contentType: "video/mp4",
      filename: "my-video.mp4",
    },
  },
)

# Check for any query-level errors, such as a type mismatch.
if query_response.errors.any?
  error_messages = query_response.errors.map(&:message)
  puts "initiateDirectVideoUpload mutation failed: #{error_messages.join(", ")}"
  exit 1
end

initiation_result = query_response.data.initiate_direct_video_upload

# Check for any mutation errors, such as passing an invalid media type or filename.
if initiation_result.errors.any?
  error_messages = initiation_result.errors.map(&:message)
  puts "initiateDirectVideoUpload mutation failed: #{error_messages.join(", ")}"
  exit 1
end

# Using the upload URL and request headers returned from the mutation,
# construct an HTTP PUT request to upload the file data directly.
upload_uri = URI(initiation_result.upload_url)
upload_headers = JSON.parse(initiation_result.upload_headers)
upload_request = Net::HTTP::Put.new(upload_uri)
upload_headers.each do |name, value|
  upload_request[name] = value
end
upload_request.body = file_data

upload_response = Net::HTTP.start(upload_uri.host, upload_uri.port, use_ssl: true) do |http|
  http.request upload_request
end

if upload_response.code.to_i >= 300
  puts "Upload failed with status #{upload_response.code}: #{upload_response.message}."
  exit 1
end

# Once the upload has finished, use the upload ID returned by the
# initation mutation to create a new video on the channel.
CREATE_VIDEO_MUTATION = client.parse <<-'GRAPHQL'
  mutation ($input: CreateVideoFromDirectUploadInput!) {
    createVideoFromDirectUpload(input: $input) {
      video {
        title
        url
      }
      errors {
        message
        path
      }
    }
  }
GRAPHQL
query_response = client.query(
  CREATE_VIDEO_MUTATION,
  variables: {
    input: {
      uploadId: initiation_result.upload_id,
      title: "My Video",
      description: "My super neat video.",
      visibility: "ON_CHANNEL",
    },
  },
)

if query_response.errors.any?
  error_messages = query_response.errors.map(&:message)
  puts "createVideoFromDirectUpload mutation failed: #{error_messages.join(", ")}"
  exit 1
end

create_video_result = query_response.data.create_video_from_direct_upload

if create_video_result.errors.any?
  error_messages = create_video_result.errors.map(&:message)
  puts "createVideoFromDirectUpload mutation failed: #{error_messages.join(", ")}"
  exit 1
end

puts "Uploaded '#{create_video_result.video.title}' to #{create_video_result.video.url}!"

Lasted edited on August 9th, 2021