Generate Signed URL for File Upload
curl --request POST \
--url https://api.pictory.ai/pictoryapis/v1/media/generateurl \
--header 'Authorization: <authorization>' \
--header 'Content-Type: application/json' \
--data '
{
"fileName": "<string>",
"contentType": "<string>"
}
'import requests
url = "https://api.pictory.ai/pictoryapis/v1/media/generateurl"
payload = {
"fileName": "<string>",
"contentType": "<string>"
}
headers = {
"Authorization": "<authorization>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<authorization>', 'Content-Type': 'application/json'},
body: JSON.stringify({fileName: '<string>', contentType: '<string>'})
};
fetch('https://api.pictory.ai/pictoryapis/v1/media/generateurl', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.pictory.ai/pictoryapis/v1/media/generateurl",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'fileName' => '<string>',
'contentType' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.pictory.ai/pictoryapis/v1/media/generateurl"
payload := strings.NewReader("{\n \"fileName\": \"<string>\",\n \"contentType\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<authorization>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.pictory.ai/pictoryapis/v1/media/generateurl")
.header("Authorization", "<authorization>")
.header("Content-Type", "application/json")
.body("{\n \"fileName\": \"<string>\",\n \"contentType\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.pictory.ai/pictoryapis/v1/media/generateurl")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<authorization>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"fileName\": \"<string>\",\n \"contentType\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"signedUrl": "https://pictory-api-prod.s3.us-east-2.amazonaws.com/public/teams/aa46778d-7965-46e0-967d-b48ee5d6ead9/users/Google_100807387384973267064/47ca856b-a15a-41b8-9a4b-88386cfa77d9/test-sample.mp3?Content-Type=audio%2Fmpeg&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ASIA2GVAALU3KROYHJW4%2F20251223%2Fus-east-2%2Fs3%2Faws4_request&X-Amz-Date=20251223T061537Z&X-Amz-Expires=86400&X-Amz-Security-Token=...",
"url": "https://dg516uv4r33q1.cloudfront.net/public/teams/aa46778d-7965-46e0-967d-b48ee5d6ead9/users/Google_100807387384973267064/47ca856b-a15a-41b8-9a4b-88386cfa77d9/test-sample.mp3",
"key": "public/teams/aa46778d-7965-46e0-967d-b48ee5d6ead9/users/Google_100807387384973267064/47ca856b-a15a-41b8-9a4b-88386cfa77d9/test-sample.mp3"
}
}
{
"message": "Unauthorized"
}
{
"error": "Internal Server Error",
"message": "An unexpected error occurred"
}
Media Management
Generate Signed URL for File Upload
Generate a pre-signed URL for secure file upload to storage. This endpoint provides a temporary URL that allows direct upload of media files without exposing credentials.
POST
/
pictoryapis
/
v1
/
media
/
generateurl
Generate Signed URL for File Upload
curl --request POST \
--url https://api.pictory.ai/pictoryapis/v1/media/generateurl \
--header 'Authorization: <authorization>' \
--header 'Content-Type: application/json' \
--data '
{
"fileName": "<string>",
"contentType": "<string>"
}
'import requests
url = "https://api.pictory.ai/pictoryapis/v1/media/generateurl"
payload = {
"fileName": "<string>",
"contentType": "<string>"
}
headers = {
"Authorization": "<authorization>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<authorization>', 'Content-Type': 'application/json'},
body: JSON.stringify({fileName: '<string>', contentType: '<string>'})
};
fetch('https://api.pictory.ai/pictoryapis/v1/media/generateurl', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.pictory.ai/pictoryapis/v1/media/generateurl",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'fileName' => '<string>',
'contentType' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.pictory.ai/pictoryapis/v1/media/generateurl"
payload := strings.NewReader("{\n \"fileName\": \"<string>\",\n \"contentType\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<authorization>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.pictory.ai/pictoryapis/v1/media/generateurl")
.header("Authorization", "<authorization>")
.header("Content-Type", "application/json")
.body("{\n \"fileName\": \"<string>\",\n \"contentType\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.pictory.ai/pictoryapis/v1/media/generateurl")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<authorization>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"fileName\": \"<string>\",\n \"contentType\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"signedUrl": "https://pictory-api-prod.s3.us-east-2.amazonaws.com/public/teams/aa46778d-7965-46e0-967d-b48ee5d6ead9/users/Google_100807387384973267064/47ca856b-a15a-41b8-9a4b-88386cfa77d9/test-sample.mp3?Content-Type=audio%2Fmpeg&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ASIA2GVAALU3KROYHJW4%2F20251223%2Fus-east-2%2Fs3%2Faws4_request&X-Amz-Date=20251223T061537Z&X-Amz-Expires=86400&X-Amz-Security-Token=...",
"url": "https://dg516uv4r33q1.cloudfront.net/public/teams/aa46778d-7965-46e0-967d-b48ee5d6ead9/users/Google_100807387384973267064/47ca856b-a15a-41b8-9a4b-88386cfa77d9/test-sample.mp3",
"key": "public/teams/aa46778d-7965-46e0-967d-b48ee5d6ead9/users/Google_100807387384973267064/47ca856b-a15a-41b8-9a4b-88386cfa77d9/test-sample.mp3"
}
}
{
"message": "Unauthorized"
}
{
"error": "Internal Server Error",
"message": "An unexpected error occurred"
}
Overview
Generate a pre-signed URL that enables secure, direct upload of media files to storage without exposing your credentials. The signed URL is temporary and automatically expires after 24 hours.You need a valid API key to use this endpoint. Get your API key from the API Access page in your Pictory dashboard.
How to Generate a Signed URL and Upload a File
Step 1: Generate a Signed URL
Request a signed URL from the API to obtain temporary upload credentials.curl --request POST \
--url https://api.pictory.ai/pictoryapis/v1/media/generateurl \
--header 'Authorization: YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"fileName": "sample1.mp3",
"contentType": "audio/mpeg"
}' | python -m json.tool
import requests
url = "https://api.pictory.ai/pictoryapis/v1/media/generateurl"
headers = {
"Authorization": "YOUR_API_KEY",
"Content-Type": "application/json"
}
payload = {
"fileName": "sample1.mp3",
"contentType": "audio/mpeg"
}
response = requests.post(url, json=payload, headers=headers)
data = response.json()
signed_url = data["data"]["signedUrl"]
const response = await fetch('https://api.pictory.ai/pictoryapis/v1/media/generateurl', {
method: 'POST',
headers: {
'Authorization': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
fileName: 'sample1.mp3',
contentType: 'audio/mpeg'
})
});
const data = await response.json();
const signedUrl = data.data.signedUrl;
Step 2: Upload Your File
Use the signed URL to upload your file directly to storage via a PUT request.curl --location --request PUT 'SIGNED_URL_FROM_STEP_1' \
--header 'Content-Type: audio/mpeg' \
--data-binary '@/path/to/your/sample1.mp3'
import requests
with open('/path/to/your/sample1.mp3', 'rb') as file:
response = requests.put(
signed_url,
data=file,
headers={'Content-Type': 'audio/mpeg'}
)
if response.status_code == 200:
print("File uploaded successfully!")
const fileInput = document.querySelector('input[type="file"]');
const file = fileInput.files[0];
const uploadResponse = await fetch(signedUrl, {
method: 'PUT',
headers: {
'Content-Type': 'audio/mpeg'
},
body: file
});
if (uploadResponse.ok) {
console.log('File uploaded successfully!');
}
Request
Headers
string
required
API key for authentication (starts with
pictai_)Authorization: YOUR_API_KEY
Body Parameters
string
required
Name of the file to be uploaded (e.g.,
sample1.mp3)string
required
MIME type of the file. Common types include:
audio/mpeg- MP3 audio filesvideo/mp4- MP4 video filesimage/jpeg- JPEG imagesimage/png- PNG imagesaudio/wav- WAV audio files
Response
boolean
Indicates whether the request was successful
object
Show properties
Show properties
string
required
The temporary pre-signed URL for file upload. Use this URL in a PUT request to upload your file. Expires after 24 hours.
string
required
The permanent CloudFront CDN URL for accessing the uploaded file. Use this URL to reference or download the file in subsequent API calls.
string
required
The unique storage key identifying the file location in the storage system.
{
"success": true,
"data": {
"signedUrl": "https://pictory-api-prod.s3.us-east-2.amazonaws.com/public/teams/aa46778d-7965-46e0-967d-b48ee5d6ead9/users/Google_100807387384973267064/47ca856b-a15a-41b8-9a4b-88386cfa77d9/test-sample.mp3?Content-Type=audio%2Fmpeg&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ASIA2GVAALU3KROYHJW4%2F20251223%2Fus-east-2%2Fs3%2Faws4_request&X-Amz-Date=20251223T061537Z&X-Amz-Expires=86400&X-Amz-Security-Token=...",
"url": "https://dg516uv4r33q1.cloudfront.net/public/teams/aa46778d-7965-46e0-967d-b48ee5d6ead9/users/Google_100807387384973267064/47ca856b-a15a-41b8-9a4b-88386cfa77d9/test-sample.mp3",
"key": "public/teams/aa46778d-7965-46e0-967d-b48ee5d6ead9/users/Google_100807387384973267064/47ca856b-a15a-41b8-9a4b-88386cfa77d9/test-sample.mp3"
}
}
{
"message": "Unauthorized"
}
{
"error": "Internal Server Error",
"message": "An unexpected error occurred"
}
Important Notes
Signed URL Expiration: The signed URL automatically expires after 24 hours (86400 seconds). Upload your file promptly after receiving the URL to avoid expiration.
Content-Type Matching: The
Content-Type header in your upload request must exactly match the contentType specified when generating the signed URL, otherwise the upload will fail.After successfully uploading your file, use the permanent
url field from the response to access or reference the file in future API calls. Store this URL for later use.Additional Resources
For more information on working with pre-signed URLs, refer to the AWS S3 Pre-signed URL documentation.Was this page helpful?
⌘I
