curl --request POST \
--url https://api.memories.ai/serve/api/v1/upload_url \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data url=https://example.com/test_video.mp4 \
--data callback=https://your.app/callback \
--data 'datetime_taken=2025-10-20 11:00:00' \
--data 'camera_model=Canon EOS 5D' \
--data latitude=66.66 \
--data longitude=66.66 \
--data-urlencode tags%5B0%5D=test1 \
--data-urlencode tags%5B1%5D=test2 \
--data retain_original_video=true \
--data 'video_transcription_prompt=Focus on the speaker and major scene changes.' \
--data folder_id=671631448308117500import requests
url = "https://api.memories.ai/serve/api/v1/upload_url"
payload = {
"url": "https://example.com/test_video.mp4",
"callback": "https://your.app/callback",
"datetime_taken": "2025-10-20 11:00:00",
"camera_model": "Canon EOS 5D",
"latitude": "66.66",
"longitude": "66.66",
"tags[0]": "test1",
"tags[1]": "test2",
"retain_original_video": "true",
"video_transcription_prompt": "Focus on the speaker and major scene changes.",
"folder_id": "671631448308117500"
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/x-www-form-urlencoded"
}
response = requests.post(url, data=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
Authorization: '<api-key>',
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
url: 'https://example.com/test_video.mp4',
callback: 'https://your.app/callback',
datetime_taken: '2025-10-20 11:00:00',
camera_model: 'Canon EOS 5D',
latitude: '66.66',
longitude: '66.66',
'tags[0]': 'test1',
'tags[1]': 'test2',
retain_original_video: 'true',
video_transcription_prompt: 'Focus on the speaker and major scene changes.',
folder_id: '671631448308117500'
})
};
fetch('https://api.memories.ai/serve/api/v1/upload_url', 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.memories.ai/serve/api/v1/upload_url",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "url=https%3A%2F%2Fexample.com%2Ftest_video.mp4&callback=https%3A%2F%2Fyour.app%2Fcallback&datetime_taken=2025-10-20%2011%3A00%3A00&camera_model=Canon%20EOS%205D&latitude=66.66&longitude=66.66&tags%5B0%5D=test1&tags%5B1%5D=test2&retain_original_video=true&video_transcription_prompt=Focus%20on%20the%20speaker%20and%20major%20scene%20changes.&folder_id=671631448308117500",
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/x-www-form-urlencoded"
],
]);
$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.memories.ai/serve/api/v1/upload_url"
payload := strings.NewReader("url=https%3A%2F%2Fexample.com%2Ftest_video.mp4&callback=https%3A%2F%2Fyour.app%2Fcallback&datetime_taken=2025-10-20%2011%3A00%3A00&camera_model=Canon%20EOS%205D&latitude=66.66&longitude=66.66&tags%5B0%5D=test1&tags%5B1%5D=test2&retain_original_video=true&video_transcription_prompt=Focus%20on%20the%20speaker%20and%20major%20scene%20changes.&folder_id=671631448308117500")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
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.memories.ai/serve/api/v1/upload_url")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/x-www-form-urlencoded")
.body("url=https%3A%2F%2Fexample.com%2Ftest_video.mp4&callback=https%3A%2F%2Fyour.app%2Fcallback&datetime_taken=2025-10-20%2011%3A00%3A00&camera_model=Canon%20EOS%205D&latitude=66.66&longitude=66.66&tags%5B0%5D=test1&tags%5B1%5D=test2&retain_original_video=true&video_transcription_prompt=Focus%20on%20the%20speaker%20and%20major%20scene%20changes.&folder_id=671631448308117500")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.memories.ai/serve/api/v1/upload_url")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/x-www-form-urlencoded'
request.body = "url=https%3A%2F%2Fexample.com%2Ftest_video.mp4&callback=https%3A%2F%2Fyour.app%2Fcallback&datetime_taken=2025-10-20%2011%3A00%3A00&camera_model=Canon%20EOS%205D&latitude=66.66&longitude=66.66&tags%5B0%5D=test1&tags%5B1%5D=test2&retain_original_video=true&video_transcription_prompt=Focus%20on%20the%20speaker%20and%20major%20scene%20changes.&folder_id=671631448308117500"
response = http.request(request)
puts response.read_body{
"code": "0000",
"msg": "success",
"data": {
"videoNo": "VI568102998803353600",
"videoName": "1be6a69f3c6e49bf986235d68807ab1f",
"videoStatus": "UNPARSE",
"uploadTime": "1744905509814"
},
"success": true,
"failed": false
}Upload Video — from URL
Upload a video by direct URL — the server fetches the file at request time and queues it for indexing.
curl --request POST \
--url https://api.memories.ai/serve/api/v1/upload_url \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data url=https://example.com/test_video.mp4 \
--data callback=https://your.app/callback \
--data 'datetime_taken=2025-10-20 11:00:00' \
--data 'camera_model=Canon EOS 5D' \
--data latitude=66.66 \
--data longitude=66.66 \
--data-urlencode tags%5B0%5D=test1 \
--data-urlencode tags%5B1%5D=test2 \
--data retain_original_video=true \
--data 'video_transcription_prompt=Focus on the speaker and major scene changes.' \
--data folder_id=671631448308117500import requests
url = "https://api.memories.ai/serve/api/v1/upload_url"
payload = {
"url": "https://example.com/test_video.mp4",
"callback": "https://your.app/callback",
"datetime_taken": "2025-10-20 11:00:00",
"camera_model": "Canon EOS 5D",
"latitude": "66.66",
"longitude": "66.66",
"tags[0]": "test1",
"tags[1]": "test2",
"retain_original_video": "true",
"video_transcription_prompt": "Focus on the speaker and major scene changes.",
"folder_id": "671631448308117500"
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/x-www-form-urlencoded"
}
response = requests.post(url, data=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
Authorization: '<api-key>',
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
url: 'https://example.com/test_video.mp4',
callback: 'https://your.app/callback',
datetime_taken: '2025-10-20 11:00:00',
camera_model: 'Canon EOS 5D',
latitude: '66.66',
longitude: '66.66',
'tags[0]': 'test1',
'tags[1]': 'test2',
retain_original_video: 'true',
video_transcription_prompt: 'Focus on the speaker and major scene changes.',
folder_id: '671631448308117500'
})
};
fetch('https://api.memories.ai/serve/api/v1/upload_url', 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.memories.ai/serve/api/v1/upload_url",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "url=https%3A%2F%2Fexample.com%2Ftest_video.mp4&callback=https%3A%2F%2Fyour.app%2Fcallback&datetime_taken=2025-10-20%2011%3A00%3A00&camera_model=Canon%20EOS%205D&latitude=66.66&longitude=66.66&tags%5B0%5D=test1&tags%5B1%5D=test2&retain_original_video=true&video_transcription_prompt=Focus%20on%20the%20speaker%20and%20major%20scene%20changes.&folder_id=671631448308117500",
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/x-www-form-urlencoded"
],
]);
$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.memories.ai/serve/api/v1/upload_url"
payload := strings.NewReader("url=https%3A%2F%2Fexample.com%2Ftest_video.mp4&callback=https%3A%2F%2Fyour.app%2Fcallback&datetime_taken=2025-10-20%2011%3A00%3A00&camera_model=Canon%20EOS%205D&latitude=66.66&longitude=66.66&tags%5B0%5D=test1&tags%5B1%5D=test2&retain_original_video=true&video_transcription_prompt=Focus%20on%20the%20speaker%20and%20major%20scene%20changes.&folder_id=671631448308117500")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
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.memories.ai/serve/api/v1/upload_url")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/x-www-form-urlencoded")
.body("url=https%3A%2F%2Fexample.com%2Ftest_video.mp4&callback=https%3A%2F%2Fyour.app%2Fcallback&datetime_taken=2025-10-20%2011%3A00%3A00&camera_model=Canon%20EOS%205D&latitude=66.66&longitude=66.66&tags%5B0%5D=test1&tags%5B1%5D=test2&retain_original_video=true&video_transcription_prompt=Focus%20on%20the%20speaker%20and%20major%20scene%20changes.&folder_id=671631448308117500")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.memories.ai/serve/api/v1/upload_url")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/x-www-form-urlencoded'
request.body = "url=https%3A%2F%2Fexample.com%2Ftest_video.mp4&callback=https%3A%2F%2Fyour.app%2Fcallback&datetime_taken=2025-10-20%2011%3A00%3A00&camera_model=Canon%20EOS%205D&latitude=66.66&longitude=66.66&tags%5B0%5D=test1&tags%5B1%5D=test2&retain_original_video=true&video_transcription_prompt=Focus%20on%20the%20speaker%20and%20major%20scene%20changes.&folder_id=671631448308117500"
response = http.request(request)
puts response.read_body{
"code": "0000",
"msg": "success",
"data": {
"videoNo": "VI568102998803353600",
"videoName": "1be6a69f3c6e49bf986235d68807ab1f",
"videoStatus": "UNPARSE",
"uploadTime": "1744905509814"
},
"success": true,
"failed": false
}https://api.memories.ai/serve/api/v1
Auth: Authorization: sk-mavi-... (no Bearer prefix)Prerequisites
- You have created a memories.ai API key.
- The video URL is publicly accessible via unauthenticated HTTP GET — the server fetches it at request time, so temporary or expiring links may fail.
- Video codecs: h264, h265, vp9, hevc. m3u8 streams are supported only if all internal paths are fully absolute.
- Max file size: 1 GB; files larger than 1 GB require special account permission — contact support.
Request Example
application/x-www-form-urlencoded. Send parameters as form fields, not JSON.import requests
headers = {"Authorization": "sk-mavi-..."}
response = requests.post(
"https://api.memories.ai/serve/api/v1/upload_url",
headers=headers,
data={
"url": "https://example.com/video.mp4",
"folder_id": 671631448308117504,
"callback": "https://your.app/callback",
"datetime_taken": "2025-10-20 11:00:00",
"camera_model": "Canon EOS 5D",
"latitude": "39.9042",
"longitude": "116.4074",
"tags": ["tag1", "tag2"],
"retain_original_video": True,
"video_transcription_prompt": "Focus on spoken dialogue"
}
)
print(response.json())
Parameters
-1) to store in your account’s Default folder (created automatically on first use). Pass a folder id from List Folders or Create Folder to store in that folder — it must belong to your account, otherwise the request is rejected.yyyy-MM-dd HH:mm:ss format. Invalid formats are rejected.api tag is appended automatically.Response Example
{
"code": "0000",
"msg": "success",
"data": {
"videoNo": "VI568102998803353600",
"videoName": "1be6a69f3c6e49bf986235d68807ab1f",
"videoStatus": "UNPARSE",
"uploadTime": "1744905509814"
}
}
Response Fields
0000 indicates success.UNPARSE immediately after upload; transitions to PARSE once indexing completes.Knowing When Indexing Is Done
The response returns immediately withvideoStatus: "UNPARSE" — the video is queued for indexing but is not yet searchable. Two ways to wait for PARSE:
| Approach | How |
|---|---|
| Push | Provide a callback URL on upload; memories.ai POSTs to it when indexing completes. |
| Poll | Call Get Metadata with video_no=<the videoNo above> and check data.status until it becomes PARSE. |
taskId, not a videoNo).Notes & Limits
- Source availability: The URL must remain accessible until the server fetches the video. Temporary or expiring links may fail.
- Rate limiting: Exceeding the per-account upload rate limit returns an error.
- Concurrent indexing cap: New uploads are rejected once the rolling 2-hour cap is reached.
- Billing: Each upload deducts credits from your account balance.
Authorizations
Body
Direct URL of the video. Must be reachable via unauthenticated HTTP GET.
"https://example.com/test_video.mp4"
Callback URL invoked when the video moves to the parsing stage. Max 299 characters.
299"https://your.app/callback"
Capture time in format yyyy-MM-dd HH:mm:ss.
"2025-10-20 11:00:00"
Camera/device model. Max 200 characters.
200"Canon EOS 5D"
66.66
66.66
User-defined tags. Max 20. The server automatically appends an 'api' tag.
20["test1", "test2"]
Whether to retain the original source video. Defaults to true.
"Focus on the speaker and major scene changes."
Optional target folder for the upload. Omit or pass -1 for the account's Default folder (auto-created on first use). A positive id must belong to your account.
671631448308117500
Response
Successful response
Business status code. 0000 indicates success.
"0000"
"success"
Show child attributes
Show child attributes
{ "videoNo": "VI568102998803353600", "videoName": "1be6a69f3c6e49bf986235d68807ab1f", "videoStatus": "UNPARSE", "uploadTime": "1744905509814" }
true
false
