curl --request POST \
--url https://app.trypost.it/api/posts/{post}/media/from-url \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"urls": [
{
"url": "https://example.com/launch.jpg",
"alt": "Product launch banner"
},
{
"url": "https://example.com/teaser.mp4"
}
]
}
'import requests
url = "https://app.trypost.it/api/posts/{post}/media/from-url"
payload = { "urls": [{
"url": "https://example.com/launch.jpg",
"alt": "Product launch banner"
}, { "url": "https://example.com/teaser.mp4" }] }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
urls: [
{url: 'https://example.com/launch.jpg', alt: 'Product launch banner'},
{url: 'https://example.com/teaser.mp4'}
]
})
};
fetch('https://app.trypost.it/api/posts/{post}/media/from-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://app.trypost.it/api/posts/{post}/media/from-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 => json_encode([
'urls' => [
[
'url' => 'https://example.com/launch.jpg',
'alt' => 'Product launch banner'
],
[
'url' => 'https://example.com/teaser.mp4'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"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://app.trypost.it/api/posts/{post}/media/from-url"
payload := strings.NewReader("{\n \"urls\": [\n {\n \"url\": \"https://example.com/launch.jpg\",\n \"alt\": \"Product launch banner\"\n },\n {\n \"url\": \"https://example.com/teaser.mp4\"\n }\n ]\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))
}HttpResponse<String> response = Unirest.post("https://app.trypost.it/api/posts/{post}/media/from-url")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"urls\": [\n {\n \"url\": \"https://example.com/launch.jpg\",\n \"alt\": \"Product launch banner\"\n },\n {\n \"url\": \"https://example.com/teaser.mp4\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.trypost.it/api/posts/{post}/media/from-url")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"urls\": [\n {\n \"url\": \"https://example.com/launch.jpg\",\n \"alt\": \"Product launch banner\"\n },\n {\n \"url\": \"https://example.com/teaser.mp4\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"post": {
"id": "9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41",
"post_group_id": "9d3c1f29-e0a1-4b7c-8d2e-5f6a7b8c9d03",
"author": {
"id": "9b1e2d3c-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
"name": "Ana Souza"
},
"content": "We just shipped scheduled threads. Here is how they work.",
"media": [
{
"id": "9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f",
"path": "medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
"url": "https://media.trypost.it/medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
"type": "image",
"mime_type": "image/jpeg",
"original_filename": "launch.jpg",
"size": 482113,
"meta": {
"width": 1080,
"height": 1350,
"alt_text": "Product launch banner"
}
}
],
"status": "scheduled",
"schedule_mode": "custom",
"scheduled_at": "2026-10-12 14:00:00",
"published_at": null,
"approval_requested_by": null,
"approval_requested_at": null,
"approved_by": null,
"approved_at": null,
"recurrence": null,
"origin": "trypost",
"platforms": [
{
"id": "9d3c1f2b-1a2b-4c3d-8e4f-5a6b7c8d9e10",
"platform": "x",
"content_type": "x_post",
"meta": {
"thread_replies": [
{
"text": "2/ Replies publish under the first post.",
"media": []
}
]
},
"status": "pending",
"enabled": true,
"platform_url": null,
"published_at": null,
"error_message": null,
"display_name": "TryPost",
"display_username": "trypostit",
"display_avatar": "https://pbs.twimg.com/profile_images/1790000000000000000/avatar_400x400.jpg",
"social_account": {
"id": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
"platform": "x",
"display_name": "TryPost",
"username": "trypostit",
"status": "connected",
"has_posting_schedule": true,
"timezone": "America/Sao_Paulo",
"posting_goal": 5,
"max_content_length": 280,
"long_posts": false,
"verified_badge": null
}
}
],
"labels": [
{
"id": "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f",
"name": "Launch",
"color": "#2563EB",
"created_at": "2026-09-01 10:00:00",
"updated_at": "2026-09-01 10:00:00"
}
],
"created_at": "2026-10-08 13:20:11",
"updated_at": "2026-10-08 13:20:11"
},
"attached_count": 1,
"failed_urls": [
"https://example.com/teaser.mp4"
],
"failures": [
{
"url": "https://example.com/teaser.mp4",
"reason": "unreachable",
"message": "Could not fetch media from https://example.com/teaser.mp4."
}
]
}{
"message": "Unauthenticated."
}{
"message": "Active subscription required."
}{
"message": "<string>"
}{
"message": "<string>"
}{
"message": "<string>"
}{
"message": "<string>",
"errors": {}
}{
"name": "rate_limit_exceeded",
"message": "Rate limit exceeded. Please retry after 30 seconds."
}Attach media from URL
Downloads up to 10 public files and appends them to the post’s media. Each URL must serve the file itself: redirects are not followed, and web pages, private-network hosts and files over the type’s size cap are refused. Each download must finish within 20 seconds. Only the types the post’s channel accepts are kept. URLs that could not be attached are listed in failed_urls, and failures gives the reason of each. Posts that are publishing, published, partially published or failed cannot take media: when a file was downloaded, the request fails with 422 on post with This post has already been processed and cannot be re-published. Duplicate it to try again. Accepted files: JPEG, PNG, GIF and WebP images (HEIC and HEIF too when the server can convert them, stored as JPEG), MP4 and MOV videos, and PDF documents. Size caps: 10 MB per image (and at most about 67 megapixels, 8192 × 8192 pixels in total), 1 GB per video, 100 MB per PDF. Each network enforces its own, usually smaller, caps when the post is scheduled or published (GET /content-types). On Pinterest and TikTok the content type is chosen again from the post’s media, as on create.
curl --request POST \
--url https://app.trypost.it/api/posts/{post}/media/from-url \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"urls": [
{
"url": "https://example.com/launch.jpg",
"alt": "Product launch banner"
},
{
"url": "https://example.com/teaser.mp4"
}
]
}
'import requests
url = "https://app.trypost.it/api/posts/{post}/media/from-url"
payload = { "urls": [{
"url": "https://example.com/launch.jpg",
"alt": "Product launch banner"
}, { "url": "https://example.com/teaser.mp4" }] }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
urls: [
{url: 'https://example.com/launch.jpg', alt: 'Product launch banner'},
{url: 'https://example.com/teaser.mp4'}
]
})
};
fetch('https://app.trypost.it/api/posts/{post}/media/from-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://app.trypost.it/api/posts/{post}/media/from-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 => json_encode([
'urls' => [
[
'url' => 'https://example.com/launch.jpg',
'alt' => 'Product launch banner'
],
[
'url' => 'https://example.com/teaser.mp4'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"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://app.trypost.it/api/posts/{post}/media/from-url"
payload := strings.NewReader("{\n \"urls\": [\n {\n \"url\": \"https://example.com/launch.jpg\",\n \"alt\": \"Product launch banner\"\n },\n {\n \"url\": \"https://example.com/teaser.mp4\"\n }\n ]\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))
}HttpResponse<String> response = Unirest.post("https://app.trypost.it/api/posts/{post}/media/from-url")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"urls\": [\n {\n \"url\": \"https://example.com/launch.jpg\",\n \"alt\": \"Product launch banner\"\n },\n {\n \"url\": \"https://example.com/teaser.mp4\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.trypost.it/api/posts/{post}/media/from-url")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"urls\": [\n {\n \"url\": \"https://example.com/launch.jpg\",\n \"alt\": \"Product launch banner\"\n },\n {\n \"url\": \"https://example.com/teaser.mp4\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"post": {
"id": "9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41",
"post_group_id": "9d3c1f29-e0a1-4b7c-8d2e-5f6a7b8c9d03",
"author": {
"id": "9b1e2d3c-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
"name": "Ana Souza"
},
"content": "We just shipped scheduled threads. Here is how they work.",
"media": [
{
"id": "9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f",
"path": "medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
"url": "https://media.trypost.it/medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
"type": "image",
"mime_type": "image/jpeg",
"original_filename": "launch.jpg",
"size": 482113,
"meta": {
"width": 1080,
"height": 1350,
"alt_text": "Product launch banner"
}
}
],
"status": "scheduled",
"schedule_mode": "custom",
"scheduled_at": "2026-10-12 14:00:00",
"published_at": null,
"approval_requested_by": null,
"approval_requested_at": null,
"approved_by": null,
"approved_at": null,
"recurrence": null,
"origin": "trypost",
"platforms": [
{
"id": "9d3c1f2b-1a2b-4c3d-8e4f-5a6b7c8d9e10",
"platform": "x",
"content_type": "x_post",
"meta": {
"thread_replies": [
{
"text": "2/ Replies publish under the first post.",
"media": []
}
]
},
"status": "pending",
"enabled": true,
"platform_url": null,
"published_at": null,
"error_message": null,
"display_name": "TryPost",
"display_username": "trypostit",
"display_avatar": "https://pbs.twimg.com/profile_images/1790000000000000000/avatar_400x400.jpg",
"social_account": {
"id": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
"platform": "x",
"display_name": "TryPost",
"username": "trypostit",
"status": "connected",
"has_posting_schedule": true,
"timezone": "America/Sao_Paulo",
"posting_goal": 5,
"max_content_length": 280,
"long_posts": false,
"verified_badge": null
}
}
],
"labels": [
{
"id": "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f",
"name": "Launch",
"color": "#2563EB",
"created_at": "2026-09-01 10:00:00",
"updated_at": "2026-09-01 10:00:00"
}
],
"created_at": "2026-10-08 13:20:11",
"updated_at": "2026-10-08 13:20:11"
},
"attached_count": 1,
"failed_urls": [
"https://example.com/teaser.mp4"
],
"failures": [
{
"url": "https://example.com/teaser.mp4",
"reason": "unreachable",
"message": "Could not fetch media from https://example.com/teaser.mp4."
}
]
}{
"message": "Unauthenticated."
}{
"message": "Active subscription required."
}{
"message": "<string>"
}{
"message": "<string>"
}{
"message": "<string>"
}{
"message": "<string>",
"errors": {}
}{
"name": "rate_limit_exceeded",
"message": "Rate limit exceeded. Please retry after 30 seconds."
}Authorizations
Workspace API key from Settings → API Keys.
Path Parameters
Post id. A post of another workspace returns 404.
Body
1 - 10 elementsShow child attributes
Show child attributes
Response
The post and the result of each URL.
A post on one channel. Posts created together from several channels are independent posts that share a post_group_id.
Show child attributes
Show child attributes
{
"id": "9d3c1f2a-6b4e-4c8a-9f1e-2a7b5c8d0e41",
"post_group_id": "9d3c1f29-e0a1-4b7c-8d2e-5f6a7b8c9d03",
"author": {
"id": "9b1e2d3c-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
"name": "Ana Souza"
},
"content": "We just shipped scheduled threads. Here is how they work.",
"media": [
{
"id": "9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f",
"path": "medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
"url": "https://media.trypost.it/medias/9d3c1f30-8a9b-4c0d-9e1f-2a3b4c5d6e7f.jpg",
"type": "image",
"mime_type": "image/jpeg",
"original_filename": "launch.jpg",
"size": 482113,
"meta": {
"width": 1080,
"height": 1350,
"alt_text": "Product launch banner"
}
}
],
"status": "scheduled",
"schedule_mode": "custom",
"scheduled_at": "2026-10-12 14:00:00",
"published_at": null,
"approval_requested_by": null,
"approval_requested_at": null,
"approved_by": null,
"approved_at": null,
"recurrence": null,
"origin": "trypost",
"platforms": [
{
"id": "9d3c1f2b-1a2b-4c3d-8e4f-5a6b7c8d9e10",
"platform": "x",
"content_type": "x_post",
"meta": {
"thread_replies": [
{
"text": "2/ Replies publish under the first post.",
"media": []
}
]
},
"status": "pending",
"enabled": true,
"platform_url": null,
"published_at": null,
"error_message": null,
"display_name": "TryPost",
"display_username": "trypostit",
"display_avatar": "https://pbs.twimg.com/profile_images/1790000000000000000/avatar_400x400.jpg",
"social_account": {
"id": "9c8b7a65-4d3e-4f2a-8b1c-0d9e8f7a6b54",
"platform": "x",
"display_name": "TryPost",
"username": "trypostit",
"status": "connected",
"has_posting_schedule": true,
"timezone": "America/Sao_Paulo",
"posting_goal": 5,
"max_content_length": 280,
"long_posts": false,
"verified_badge": null
}
}
],
"labels": [
{
"id": "9c0d1e2f-3a4b-4c5d-8e6f-7a8b9c0d1e2f",
"name": "Launch",
"color": "#2563EB",
"created_at": "2026-09-01 10:00:00",
"updated_at": "2026-09-01 10:00:00"
}
],
"created_at": "2026-10-08 13:20:11",
"updated_at": "2026-10-08 13:20:11"
}
Show child attributes
Show child attributes

