curl -X POST 'https://api.legitmark.com/api/media/signed-urls/8e61c991-553a-4a58-9eb6-561b64c11908' \
-H 'Authorization: Bearer leo_your_api_key' \
-H 'Content-Type: application/json' \
-d '{
"sides": [
{
"uuid": "ec883c70-f896-47c9-81b6-8d6ff0b5856a",
"filename": "ec883c70-f896-47c9-81b6-8d6ff0b5856a.jpg",
"content_type": "image/jpeg"
}
],
"expires_in": 900
}'
curl -X PUT 'SIGNED_URL_FROM_ABOVE' \
-H 'Content-Type: image/jpeg' \
--data-binary @photo.jpgconst response = await fetch(
'https://api.legitmark.com/api/media/signed-urls/8e61c991-553a-4a58-9eb6-561b64c11908',
{
method: 'POST',
headers: {
Authorization: 'Bearer leo_your_api_key',
'Content-Type': 'application/json',
},
body: JSON.stringify({
sides: [
{
uuid: 'ec883c70-f896-47c9-81b6-8d6ff0b5856a',
filename: 'ec883c70-f896-47c9-81b6-8d6ff0b5856a.jpg',
content_type: 'image/jpeg',
},
],
expires_in: 900,
}),
}
);
const { urls } = await response.json();
await fetch(urls['ec883c70-f896-47c9-81b6-8d6ff0b5856a'].signed_url, {
method: 'PUT',
body: imageFile,
headers: { 'Content-Type': 'image/jpeg' },
});import requests
url = "https://api.legitmark.com/api/media/signed-urls/{sr_uuid}"
payload = {
"sides": [
{
"uuid": "ec883c70-f896-47c9-81b6-8d6ff0b5856a",
"filename": "ec883c70-f896-47c9-81b6-8d6ff0b5856a.jpg",
"content_type": "image/jpeg"
}
],
"expires_in": 900
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.legitmark.com/api/media/signed-urls/{sr_uuid}"
payload := strings.NewReader("{\n \"sides\": [\n {\n \"uuid\": \"ec883c70-f896-47c9-81b6-8d6ff0b5856a\",\n \"filename\": \"ec883c70-f896-47c9-81b6-8d6ff0b5856a.jpg\",\n \"content_type\": \"image/jpeg\"\n }\n ],\n \"expires_in\": 900\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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))
}{
"success": true,
"message": "Batch signed URLs generated successfully.",
"urls": {
"ec883c70-f896-47c9-81b6-8d6ff0b5856a": {
"signed_url": "https://s3.us-east-1.amazonaws.com/cdn.legitmark.com/org/9d31b4b9-13c5-4db4-8893-a792736965ef/sr/8e61c991-553a-4a58-9eb6-561b64c11908/ec883c70-f896-47c9-81b6-8d6ff0b5856a.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=...&X-Amz-Expires=900&X-Amz-Signature=...",
"expires_at": "2026-09-01T08:15:00.000Z",
"is_multipart": false
}
},
"metadata": {
"total_urls": 1,
"failed_urls": 0,
"sr_uuid": "8e61c991-553a-4a58-9eb6-561b64c11908",
"expires_in": 900
}
}{
"success": false,
"error": {
"code": 123,
"timestamp": "2023-11-07T05:31:56Z",
"message": "<string>",
"details": "<string>"
}
}{
"success": false,
"error": {
"code": 123,
"timestamp": "2023-11-07T05:31:56Z",
"message": "<string>",
"details": "<string>"
}
}Get Batch Upload URLs
Generate pre-signed S3 PUT URLs for one or more sides on a service request.
Required for private-CDN organizations. GET /intent writes to the public bucket and cannot route private uploads. Public-CDN organizations may keep using /intent.
Authenticate with your leo_ API key. Then PUT each image to the returned signed_url without an Authorization header.
See Private CDN.
curl -X POST 'https://api.legitmark.com/api/media/signed-urls/8e61c991-553a-4a58-9eb6-561b64c11908' \
-H 'Authorization: Bearer leo_your_api_key' \
-H 'Content-Type: application/json' \
-d '{
"sides": [
{
"uuid": "ec883c70-f896-47c9-81b6-8d6ff0b5856a",
"filename": "ec883c70-f896-47c9-81b6-8d6ff0b5856a.jpg",
"content_type": "image/jpeg"
}
],
"expires_in": 900
}'
curl -X PUT 'SIGNED_URL_FROM_ABOVE' \
-H 'Content-Type: image/jpeg' \
--data-binary @photo.jpgconst response = await fetch(
'https://api.legitmark.com/api/media/signed-urls/8e61c991-553a-4a58-9eb6-561b64c11908',
{
method: 'POST',
headers: {
Authorization: 'Bearer leo_your_api_key',
'Content-Type': 'application/json',
},
body: JSON.stringify({
sides: [
{
uuid: 'ec883c70-f896-47c9-81b6-8d6ff0b5856a',
filename: 'ec883c70-f896-47c9-81b6-8d6ff0b5856a.jpg',
content_type: 'image/jpeg',
},
],
expires_in: 900,
}),
}
);
const { urls } = await response.json();
await fetch(urls['ec883c70-f896-47c9-81b6-8d6ff0b5856a'].signed_url, {
method: 'PUT',
body: imageFile,
headers: { 'Content-Type': 'image/jpeg' },
});import requests
url = "https://api.legitmark.com/api/media/signed-urls/{sr_uuid}"
payload = {
"sides": [
{
"uuid": "ec883c70-f896-47c9-81b6-8d6ff0b5856a",
"filename": "ec883c70-f896-47c9-81b6-8d6ff0b5856a.jpg",
"content_type": "image/jpeg"
}
],
"expires_in": 900
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.legitmark.com/api/media/signed-urls/{sr_uuid}"
payload := strings.NewReader("{\n \"sides\": [\n {\n \"uuid\": \"ec883c70-f896-47c9-81b6-8d6ff0b5856a\",\n \"filename\": \"ec883c70-f896-47c9-81b6-8d6ff0b5856a.jpg\",\n \"content_type\": \"image/jpeg\"\n }\n ],\n \"expires_in\": 900\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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))
}{
"success": true,
"message": "Batch signed URLs generated successfully.",
"urls": {
"ec883c70-f896-47c9-81b6-8d6ff0b5856a": {
"signed_url": "https://s3.us-east-1.amazonaws.com/cdn.legitmark.com/org/9d31b4b9-13c5-4db4-8893-a792736965ef/sr/8e61c991-553a-4a58-9eb6-561b64c11908/ec883c70-f896-47c9-81b6-8d6ff0b5856a.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=...&X-Amz-Expires=900&X-Amz-Signature=...",
"expires_at": "2026-09-01T08:15:00.000Z",
"is_multipart": false
}
},
"metadata": {
"total_urls": 1,
"failed_urls": 0,
"sr_uuid": "8e61c991-553a-4a58-9eb6-561b64c11908",
"expires_in": 900
}
}{
"success": false,
"error": {
"code": 123,
"timestamp": "2023-11-07T05:31:56Z",
"message": "<string>",
"details": "<string>"
}
}{
"success": false,
"error": {
"code": 123,
"timestamp": "2023-11-07T05:31:56Z",
"message": "<string>",
"details": "<string>"
}
}GET /intent. /intent always writes to the public bucket.Authorizations
Bearer token authentication. Use your API key in the format: Bearer leo_xxxxxxxx
Path Parameters
Service request UUID
Body
One entry per photo to upload
1Hide child attributes
Hide child attributes
Side UUID to upload
"ec883c70-f896-47c9-81b6-8d6ff0b5856a"
Object filename. Use {side_uuid}.jpg (or .png). The extension sets the upload content type.
"ec883c70-f896-47c9-81b6-8d6ff0b5856a.jpg"
Optional MIME type for the upload
"image/jpeg"
Upload-URL lifetime in seconds. Default 900 (15 minutes).
60 <= x <= 3600Response
Batch signed URLs generated successfully
true
"Batch signed URLs generated successfully."
Map of side UUID to signed upload URL
Hide child attributes
Hide child attributes