Media Upload
curl --request POST \
--url http://localhost:8080/api/v1/media \
--header 'Authorization: Basic <encoded-value>' \
--header 'Content-Type: multipart/form-data' \
--form files=@example-file \
--form 'inline=<string>' \
--form linked_model=messagesimport requests
url = "http://localhost:8080/api/v1/media"
files = { "files": ("example-file", open("example-file", "rb")) }
payload = {
"inline": "<string>",
"linked_model": "messages"
}
headers = {"Authorization": "Basic <encoded-value>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('files', '<string>');
form.append('inline', '<string>');
form.append('linked_model', 'messages');
const options = {method: 'POST', headers: {Authorization: 'Basic <encoded-value>'}};
options.body = form;
fetch('http://localhost:8080/api/v1/media', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_PORT => "8080",
CURLOPT_URL => "http://localhost:8080/api/v1/media",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"files\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"inline\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"linked_model\"\r\n\r\nmessages\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Authorization: Basic <encoded-value>",
"Content-Type: multipart/form-data"
],
]);
$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 := "http://localhost:8080/api/v1/media"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"files\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"inline\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"linked_model\"\r\n\r\nmessages\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Basic <encoded-value>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("http://localhost:8080/api/v1/media")
.header("Authorization", "Basic <encoded-value>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"files\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"inline\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"linked_model\"\r\n\r\nmessages\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("http://localhost:8080/api/v1/media")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Basic <encoded-value>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"files\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"inline\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"linked_model\"\r\n\r\nmessages\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"status": "success",
"data": {
"id": 123,
"created_at": "2025-08-28T10:00:00Z",
"updated_at": "2025-08-28T10:00:00Z",
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"store": "fs",
"filename": "example.jpg",
"content_type": "image/jpeg",
"content_id": "",
"model_id": 456,
"model_type": "messages",
"disposition": "attachment",
"size": 102400,
"meta": {
"width": 800,
"height": 600
},
"private": true,
"url": "/uploads/550e8400-e29b-41d4-a716-446655440000"
}
}{
"status": "error",
"message": "Invalid request",
"data": "<unknown>",
"error_type": "GeneralException"
}{
"status": "error",
"message": "Invalid request",
"data": "<unknown>",
"error_type": "GeneralException"
}{
"status": "error",
"message": "Invalid request",
"data": "<unknown>",
"error_type": "GeneralException"
}{
"status": "error",
"message": "Invalid request",
"data": "<unknown>",
"error_type": "GeneralException"
}{
"status": "error",
"message": "Invalid request",
"data": "<unknown>",
"error_type": "GeneralException"
}Media
Media Upload
POST
/
api
/
v1
/
media
Media Upload
curl --request POST \
--url http://localhost:8080/api/v1/media \
--header 'Authorization: Basic <encoded-value>' \
--header 'Content-Type: multipart/form-data' \
--form files=@example-file \
--form 'inline=<string>' \
--form linked_model=messagesimport requests
url = "http://localhost:8080/api/v1/media"
files = { "files": ("example-file", open("example-file", "rb")) }
payload = {
"inline": "<string>",
"linked_model": "messages"
}
headers = {"Authorization": "Basic <encoded-value>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('files', '<string>');
form.append('inline', '<string>');
form.append('linked_model', 'messages');
const options = {method: 'POST', headers: {Authorization: 'Basic <encoded-value>'}};
options.body = form;
fetch('http://localhost:8080/api/v1/media', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_PORT => "8080",
CURLOPT_URL => "http://localhost:8080/api/v1/media",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"files\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"inline\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"linked_model\"\r\n\r\nmessages\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Authorization: Basic <encoded-value>",
"Content-Type: multipart/form-data"
],
]);
$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 := "http://localhost:8080/api/v1/media"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"files\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"inline\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"linked_model\"\r\n\r\nmessages\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Basic <encoded-value>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("http://localhost:8080/api/v1/media")
.header("Authorization", "Basic <encoded-value>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"files\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"inline\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"linked_model\"\r\n\r\nmessages\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("http://localhost:8080/api/v1/media")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Basic <encoded-value>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"files\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"inline\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"linked_model\"\r\n\r\nmessages\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"status": "success",
"data": {
"id": 123,
"created_at": "2025-08-28T10:00:00Z",
"updated_at": "2025-08-28T10:00:00Z",
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"store": "fs",
"filename": "example.jpg",
"content_type": "image/jpeg",
"content_id": "",
"model_id": 456,
"model_type": "messages",
"disposition": "attachment",
"size": 102400,
"meta": {
"width": 800,
"height": 600
},
"private": true,
"url": "/uploads/550e8400-e29b-41d4-a716-446655440000"
}
}{
"status": "error",
"message": "Invalid request",
"data": "<unknown>",
"error_type": "GeneralException"
}{
"status": "error",
"message": "Invalid request",
"data": "<unknown>",
"error_type": "GeneralException"
}{
"status": "error",
"message": "Invalid request",
"data": "<unknown>",
"error_type": "GeneralException"
}{
"status": "error",
"message": "Invalid request",
"data": "<unknown>",
"error_type": "GeneralException"
}{
"status": "error",
"message": "Invalid request",
"data": "<unknown>",
"error_type": "GeneralException"
}Authorizations
basicAuthtokenAuth
Basic authentication using base64 encoded API key and secret. Format: Authorization: Basic <base64(api_key:api_secret)>
Body
multipart/form-data
Media upload
File to upload. Only the first file is used. Size and extension limits come from the upload settings.
Set to 'true' to store the file with an inline disposition (e.g. an inline image) instead of as an attachment.
Name of the model the uploaded media is linked to, e.g. messages. help_articles stores the file as publicly served media and requires the help_center:manage permission.
Example:
"messages"
Was this page helpful?

