All Collections
API & Webhooks
Uploading videos using the Rewatch API
Uploading videos using the Rewatch API
Natalie Pabón avatar
Written by Natalie Pabón
Updated over a week ago

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}!"
Did this answer your question?