Posts API Reference
The Posts API allows you to create, retrieve, update, and delete social media posts across multiple platforms.
Endpoints
Section titled “Endpoints”| Method | Endpoint | Description |
|---|---|---|
GET | /api/posts | List all posts |
GET | /api/posts/:id | Get a single post |
GET | /api/posts/stats | Get stats snapshots for posts |
POST | /api/posts | Create a new post |
PATCH | /api/posts/:id | Update an existing post |
POST | /api/posts/:id/publish | Publish a draft post |
DELETE | /api/posts/:id | Delete a post |
List posts
Section titled “List posts”GET /api/posts
Retrieves a paginated list of all posts in the current profile group. Thread children are not returned as top-level items — only parent posts appear. Use the Get Post endpoint to retrieve thread children for a specific post.
Query parameters
Section titled “Query parameters”| Name | Type | Required | Default | Description |
|---|---|---|---|---|
page | integer | No | 0 | Page number (zero-indexed) |
per_page | integer | No | 10 | Number of posts per page |
profile_group_id | string | No | - | Filter by profile group (id) |
status | string | No | - | Filter by status: draft, scheduled, published, failed |
platforms | array | No | - | Array of platforms (e.g., platforms[]=instagram&platforms[]=tiktok) |
scheduled_after | string | No | - | ISO 8601 date to filter posts scheduled after that date |
Example
Section titled “Example”curl -X GET "https://api.postproxy.dev/api/posts?page=0&per_page=10" \ -H "Authorization: Bearer YOUR_API_KEY"import PostProxy from "postproxy-sdk";
const client = new PostProxy("YOUR_API_KEY");const posts = await client.posts.list({ page: 0, perPage: 10 });console.log(posts);from postproxy import PostProxy
client = PostProxy("YOUR_API_KEY")posts = await client.posts.list(page=0, per_page=10)print(posts)package main
import ( "fmt" postproxy "github.com/postproxy/postproxy-go")
func main() { client := postproxy.New("YOUR_API_KEY") posts, _ := client.Posts.List(&postproxy.ListPostsOptions{ Page: 0, PerPage: 10, }) fmt.Println(posts)}require "postproxy"
client = PostProxy::Client.new("YOUR_API_KEY")posts = client.posts.list(page: 0, per_page: 10)puts postsuse PostProxy\PostProxy;
$client = new PostProxy("YOUR_API_KEY");$posts = $client->posts->list(["page" => 0, "per_page" => 10]);print_r($posts);import dev.postproxy.PostProxy;
PostProxy client = new PostProxy("YOUR_API_KEY");var posts = client.posts().list(new ListPostsOptions().page(0).perPage(10));System.out.println(posts);using PostProxy;
var client = new PostProxyClient("YOUR_API_KEY");var posts = await client.Posts.ListAsync(new ListPostsOptions { Page = 0, PerPage = 10 });Console.WriteLine(posts);Response:
{ "total": 42, "page": 0, "per_page": 10, "data": [ { "id": "abc123xyz", "body": "Check out our latest update!", "status": "processed", "scheduled_at": null, "created_at": "2024-01-15T10:30:00.000Z", "platforms": [ { "platform": "twitter", "status": "published", "params": null, "error": null, "attempted_at": "2024-01-15T10:30:01.000Z", "insights": { "impressions": 1523, "on": "2024-01-15T18:00:00.000Z" } }, { "platform": "instagram", "status": "published", "params": { "format": "post", "first_comment": "Link in bio!" }, "error": null, "attempted_at": "2024-01-15T10:30:02.000Z", "insights": { "impressions": 3842, "on": "2024-01-15T18:00:00.000Z" } } ] } ]}Response fields
Section titled “Response fields”| Field | Type | Description |
|---|---|---|
total | integer | Total number of posts |
page | integer | Current page number |
per_page | integer | Items per page |
data | array | Array of post objects |
Get post
Section titled “Get post”GET /api/posts/:id
Retrieves a single post by its ID.
Path parameters
Section titled “Path parameters”| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Post id |
Example
Section titled “Example”curl -X GET "https://api.postproxy.dev/api/posts/abc123xyz" \ -H "Authorization: Bearer YOUR_API_KEY"import PostProxy from "postproxy-sdk";
const client = new PostProxy("YOUR_API_KEY");const post = await client.posts.get("abc123xyz");console.log(post);from postproxy import PostProxy
client = PostProxy("YOUR_API_KEY")post = await client.posts.get("abc123xyz")print(post)package main
import ( "fmt" postproxy "github.com/postproxy/postproxy-go")
func main() { client := postproxy.New("YOUR_API_KEY") post, _ := client.Posts.Get("abc123xyz") fmt.Println(post)}require "postproxy"
client = PostProxy::Client.new("YOUR_API_KEY")post = client.posts.get("abc123xyz")puts postuse PostProxy\PostProxy;
$client = new PostProxy("YOUR_API_KEY");$post = $client->posts->get("abc123xyz");print_r($post);import dev.postproxy.PostProxy;
PostProxy client = new PostProxy("YOUR_API_KEY");var post = client.posts().get("abc123xyz");System.out.println(post);using PostProxy;
var client = new PostProxyClient("YOUR_API_KEY");var post = await client.Posts.GetAsync("abc123xyz");Console.WriteLine(post);Response:
{ "id": "abc123xyz", "body": "Check out our latest update!", "status": "processed", "scheduled_at": null, "created_at": "2024-01-15T10:30:00.000Z", "platforms": [ { "platform": "twitter", "status": "published", "params": null, "error": null, "attempted_at": "2024-01-15T10:30:01.000Z", "insights": { "impressions": 1523, "on": "2024-01-15T18:00:00.000Z" } } ]}Response fields
Section titled “Response fields”| Field | Type | Description |
|---|---|---|
id | string | Unique post identifier (id) |
body | string | Post body/text content |
status | string | Post status: processing, processed, scheduled |
scheduled_at | string|null | ISO 8601 timestamp if scheduled, null otherwise |
created_at | string | ISO 8601 timestamp of creation |
queue_id | string|null | Queue ID if the post belongs to a queue |
queue_priority | string|null | Priority level (high, medium, low) if in a queue |
media | array | Array of media attachment objects |
platforms | array | Array of platform-specific posting results |
thread | array | Array of thread child posts (only present for thread posts) |
Media object fields
Section titled “Media object fields”| Field | Type | Description |
|---|---|---|
id | string | Unique attachment identifier (id) |
status | string | Processing status: pending, processed, failed |
error_message | string|null | Error details if processing failed |
content_type | string | MIME type (e.g. image/jpeg, video/mp4) |
source_url | string|null | Original source URL if media was provided as a URL |
url | string|null | Hosted URL of the processed file (null if not yet processed) |
Thread child fields
Section titled “Thread child fields”| Field | Type | Description |
|---|---|---|
id | string | Unique identifier (id) of the child post |
body | string | Text content of the child post |
media | array | Array of media attachment objects (same structure as above) |
Platform object fields
Section titled “Platform object fields”| Field | Type | Description |
|---|---|---|
platform | string | Platform identifier: facebook, instagram, tiktok, linkedin, youtube, twitter, threads, pinterest |
status | string | Platform posting status: processing, published, failed, deleted |
params | object|null | Platform-specific parameters used for this post |
attempted_at | string|null | ISO 8601 timestamp of posting attempt |
insights | object | Engagement metrics (when available) |
insights.impressions | integer | Number of impressions/views |
insights.on | string | ISO 8601 timestamp when insights were captured |
Post stats
Section titled “Post stats”GET /api/posts/stats
Retrieves stats snapshots for one or more posts. Returns all matching snapshots (not just the latest) so you can see trends over time. Supports filtering by profiles/networks and timespan.
For thread posts, stats from all posts in the thread (parent + children) are included under the parent post’s ID. This means you get aggregated platform-level stats across the entire thread in a single request.
Query parameters
Section titled “Query parameters”| Name | Type | Required | Description |
|---|---|---|---|
post_ids | string | Yes | Comma-separated list of post ids (max 50) |
profiles | string | No | Comma-separated list of profile ids or platform names (e.g. instagram,twitter or abc123,def456 or mixed) |
from | string | No | ISO 8601 timestamp — only include snapshots recorded at or after this time |
to | string | No | ISO 8601 timestamp — only include snapshots recorded at or before this time |
Platform names are matched against known platforms (facebook, instagram, tiktok, linkedin, youtube, twitter, threads, pinterest). Anything else is treated as a profile id.
Example
Section titled “Example”curl -X GET "https://api.postproxy.dev/api/posts/stats?post_ids=abc123,def456&profiles=instagram,twitter&from=2026-02-01T00:00:00Z&to=2026-02-24T00:00:00Z" \ -H "Authorization: Bearer YOUR_API_KEY"import PostProxy from "postproxy-sdk";
const client = new PostProxy("YOUR_API_KEY");const stats = await client.posts.stats( ["abc123", "def456"], { profiles: ["instagram", "twitter"], from: "2026-02-01T00:00:00Z", to: "2026-02-24T00:00:00Z", },);console.log(stats);from postproxy import PostProxy
client = PostProxy("YOUR_API_KEY")stats = await client.posts.stats( post_ids=["abc123", "def456"], profiles=["instagram", "twitter"], from_date="2026-02-01T00:00:00Z", to_date="2026-02-24T00:00:00Z",)print(stats)package main
import ( "context" "fmt" postproxy "github.com/postproxy/postproxy-go")
func main() { client := postproxy.New("YOUR_API_KEY") from := "2026-02-01T00:00:00Z" to := "2026-02-24T00:00:00Z" stats, _ := client.Posts.Stats(context.Background(), []string{"abc123", "def456"}, &postproxy.PostStatsOptions{ Profiles: []string{"instagram", "twitter"}, From: &from, To: &to, }) fmt.Println(stats)}require "postproxy"
client = PostProxy::Client.new("YOUR_API_KEY")stats = client.posts.stats( ["abc123", "def456"], profiles: ["instagram", "twitter"], from: Time.now - 86400 * 30, to: Time.now)puts statsuse PostProxy\PostProxy;
$client = new PostProxy("YOUR_API_KEY");$stats = $client->posts()->stats( ['abc123', 'def456'], profiles: ['instagram', 'twitter'], from: '2026-02-01T00:00:00Z', to: '2026-02-24T00:00:00Z',);print_r($stats);import dev.postproxy.PostProxy;
PostProxy client = new PostProxy("YOUR_API_KEY");var stats = client.posts().stats(GetStatsParams.builder() .postIds(List.of("abc123", "def456")) .profiles(List.of("instagram", "twitter")) .from("2026-02-01T00:00:00Z") .to("2026-02-24T00:00:00Z") .build());System.out.println(stats);using PostProxy;
var client = new PostProxyClient("YOUR_API_KEY");var stats = await client.Posts.StatsAsync(new PostStatsOptions{ PostIds = new[] { "abc123", "def456" }, Profiles = new[] { "instagram", "twitter" }, From = "2026-02-01T00:00:00Z", To = "2026-02-24T00:00:00Z",});Console.WriteLine(stats);Response:
{ "data": { "abc123": { "platforms": [ { "profile_id": "prof_abc", "platform": "instagram", "records": [ { "stats": { "impressions": 1200, "likes": 85, "comments": 12, "saved": 8 }, "recorded_at": "2026-02-20T12:00:00Z" }, { "stats": { "impressions": 1523, "likes": 102, "comments": 15, "saved": 11 }, "recorded_at": "2026-02-21T04:00:00Z" } ] } ] }, "def456": { "platforms": [ { "profile_id": "prof_def", "platform": "twitter", "records": [ { "stats": { "impressions": 430, "likes": 22, "retweets": 5 }, "recorded_at": "2026-02-20T12:00:00Z" } ] } ] } }}Response fields
Section titled “Response fields”| Field | Type | Description |
|---|---|---|
data | object | Keyed by post id |
data.<post_id>.platforms | array | Array of platform objects for this post |
platforms[].profile_id | string | Profile id |
platforms[].platform | string | Platform name (instagram, twitter, etc.) |
platforms[].records | array | Snapshots ordered by recorded_at ascending |
records[].stats | object | Platform-specific metrics (varies by platform) |
records[].recorded_at | string | ISO 8601 timestamp when the snapshot was captured |
Stats fields by platform
Section titled “Stats fields by platform”| Platform | Fields |
|---|---|
impressions, likes, comments, saved, profile_visits, follows | |
impressions, clicks, likes | |
| Threads | impressions, likes, replies, reposts, quotes, shares |
impressions, likes, retweets, comments, quotes, saved | |
| YouTube | impressions, likes, comments, saved |
impressions | |
| TikTok | impressions, likes, comments, shares |
impressions, likes, comments, saved, outbound_clicks |
Error responses
Section titled “Error responses”Missing post_ids parameter (400):
{ "status": 400, "error": "Bad Request", "message": "param is missing or the value is empty: post_ids"}Create post
Section titled “Create post”POST /api/posts
Creates a new post and publishes it to the specified platforms.
Request body
Section titled “Request body”| Name | Type | Required | Description |
|---|---|---|---|
post[body] | string | No* | Text content of the post |
post[scheduled_at] | string | No | ISO 8601 timestamp to schedule the post |
post[draft] | boolean | No | If true, creates a draft that won’t publish until reviewed |
profiles | array | Yes | Array of profile IDs or platform names |
media | array | No* | Array of media URLs or file uploads |
platforms | object | No | Platform-specific parameters |
thread | array | No | Array of thread child posts (see Threads) |
profile_group_id | string | No | Profile group ID |
queue_id | string | No | Queue ID — adds the post to a queue (see Queues) |
queue_priority | string | No | Queue priority: high, medium (default), or low |
*Some platforms require media (Instagram, TikTok, YouTube). Some platforms require text content.
Draft posts
Section titled “Draft posts”Set draft: true to create a post that won’t be published automatically. Draft posts can be reviewed and then published using the Publish endpoint.
{ "post": { "body": "Content to review before posting", "draft": true }, "profiles": ["instagram"]}Profiles parameter
Section titled “Profiles parameter”The profiles array accepts either:
- Platform names:
"twitter","instagram","facebook", etc. - Uses the first connected profile for that platform - Profile IDs: Hashid of a specific profile
Media parameter
Section titled “Media parameter”You can provide media in two ways:
Option 1: URLs (JSON request)
Pass URLs to images or videos that Postproxy will download:
{ "media": [ "https://example.com/image1.jpg", "https://example.com/image2.png" ]}Option 2: File upload (multipart form)
Upload files directly using multipart/form-data:
curl -X POST "https://api.postproxy.dev/api/posts" \ -H "Authorization: Bearer YOUR_API_KEY" \ -F "post[body]=Check out this photo!" \ -F "profiles[]=instagram" \ -F "profiles[]=facebook" \ -F "media[]=@/path/to/image.jpg"import PostProxy from "postproxy-sdk";import fs from "fs";
const client = new PostProxy("YOUR_API_KEY");const post = await client.posts.create("Check out this photo!", ["instagram", "facebook"], { mediaFiles: [fs.createReadStream("/path/to/image.jpg")],});console.log(post);from postproxy import PostProxy
client = PostProxy("YOUR_API_KEY")post = await client.posts.create( "Check out this photo!", ["instagram", "facebook"], media_files=[open("/path/to/image.jpg", "rb")],)print(post)package main
import ( "fmt" "os" postproxy "github.com/postproxy/postproxy-go")
func main() { client := postproxy.New("YOUR_API_KEY") file, _ := os.Open("/path/to/image.jpg") defer file.Close()
post, _ := client.Posts.Create("Check out this photo!", []string{"instagram", "facebook"}, &postproxy.CreatePostOptions{ MediaFiles: []*os.File{file}, }) fmt.Println(post)}require "postproxy"
client = PostProxy::Client.new("YOUR_API_KEY")post = client.posts.create( "Check out this photo!", profiles: ["instagram", "facebook"], media_files: [File.open("/path/to/image.jpg")])puts postuse PostProxy\PostProxy;
$client = new PostProxy("YOUR_API_KEY");$post = $client->posts->create("Check out this photo!", ["instagram", "facebook"], [ "media_files" => ["/path/to/image.jpg"],]);print_r($post);import dev.postproxy.PostProxy;import java.io.File;import java.util.List;
PostProxy client = new PostProxy("YOUR_API_KEY");var post = client.posts().create( "Check out this photo!", List.of("instagram", "facebook"), new CreatePostOptions() .mediaFiles(List.of(new File("/path/to/image.jpg"))));System.out.println(post);using PostProxy;
var client = new PostProxyClient("YOUR_API_KEY");var post = await client.Posts.CreateAsync("Check out this photo!", ["instagram", "facebook"], new CreatePostOptions{ MediaFiles = [File.OpenRead("/path/to/image.jpg")],});Console.WriteLine(post);When using file upload, use form field names with brackets: post[body], profiles[], media[].
Platform-specific parameters
Section titled “Platform-specific parameters”Pass platform-specific options in the platforms object. See Platform Parameters for all available options.
{ "platforms": { "instagram": { "format": "reel", "first_comment": "Check the link in bio!" }, "youtube": { "title": "My Video Title", "privacy_status": "public" } }}Example
Section titled “Example”curl -X POST "https://api.postproxy.dev/api/posts" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "post": { "body": "Hello from the API!" }, "profiles": ["twitter", "linkedin", "threads"], "media": ["https://example.com/image.jpg"] }'import PostProxy from "postproxy-sdk";
const client = new PostProxy("YOUR_API_KEY");const post = await client.posts.create("Hello from the API!", ["twitter", "linkedin", "threads"], { media: ["https://example.com/image.jpg"],});console.log(post);from postproxy import PostProxy
client = PostProxy("YOUR_API_KEY")post = await client.posts.create( "Hello from the API!", ["twitter", "linkedin", "threads"], media=["https://example.com/image.jpg"],)print(post)package main
import ( "fmt" postproxy "github.com/postproxy/postproxy-go")
func main() { client := postproxy.New("YOUR_API_KEY") post, _ := client.Posts.Create("Hello from the API!", []string{"twitter", "linkedin", "threads"}, &postproxy.CreatePostOptions{ Media: []string{"https://example.com/image.jpg"}, }) fmt.Println(post)}require "postproxy"
client = PostProxy::Client.new("YOUR_API_KEY")post = client.posts.create( "Hello from the API!", profiles: ["twitter", "linkedin", "threads"], media: ["https://example.com/image.jpg"])puts postuse PostProxy\PostProxy;
$client = new PostProxy("YOUR_API_KEY");$post = $client->posts->create("Hello from the API!", ["twitter", "linkedin", "threads"], [ "media" => ["https://example.com/image.jpg"],]);print_r($post);import dev.postproxy.PostProxy;import java.util.List;
PostProxy client = new PostProxy("YOUR_API_KEY");var post = client.posts().create( "Hello from the API!", List.of("twitter", "linkedin", "threads"), new CreatePostOptions() .media(List.of("https://example.com/image.jpg")));System.out.println(post);using PostProxy;
var client = new PostProxyClient("YOUR_API_KEY");var post = await client.Posts.CreateAsync("Hello from the API!", ["twitter", "linkedin", "threads"], new CreatePostOptions{ Media = ["https://example.com/image.jpg"],});Console.WriteLine(post);Request body (JSON):
{ "post": { "body": "Hello from the API!" }, "profiles": [ "twitter", "linkedin", "threads" ], "media": [ "https://example.com/image.jpg" ]}Response (201 Created):
{ "id": "xyz789abc", "body": "Hello from the API!", "status": "processed", "scheduled_at": null, "created_at": "2024-01-15T10:30:00.000Z", "platforms": [ { "platform": "twitter", "status": "pending", "error": null, "params": null, "attempted_at": null }, { "platform": "linkedin", "status": "pending", "error": null, "params": null, "attempted_at": null }, { "platform": "threads", "status": "pending", "error": null, "params": null, "attempted_at": null } ]}Error responses
Section titled “Error responses”Missing profiles parameter (400):
{ "status": 400, "error": "Bad Request", "message": "param is missing or the value is empty: Missing profiles parameter"}Validation errors (422):
{ "errors": [ "Post profiles must have at least one profile selected", "Media is required for feed post on Instagram" ]}Update post
Section titled “Update post”PATCH /api/posts/:id
Updates an existing post. Only draft posts and scheduled posts (more than 5 minutes before their publish time) can be updated.
All parameters are optional — only send the fields you want to change. Fields you omit are left unchanged.
Path parameters
Section titled “Path parameters”| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Post id |
Request body
Section titled “Request body”| Name | Type | Required | Description |
|---|---|---|---|
post[body] | string | No | Updated text content |
post[scheduled_at] | string | No | Updated ISO 8601 schedule timestamp |
post[draft] | boolean | No | Set or unset draft status |
profiles | array | No | Replace all profiles (array of profile IDs or network names) |
platforms | object | No | Update platform-specific parameters |
media | array | No | Replace all media (array of media URLs or file uploads) |
thread | array | No | Replace all thread children |
queue_id | string | No | Assign the post to a queue |
queue_priority | string | No | Queue priority: high, medium, or low |
Update behavior
Section titled “Update behavior”Each parameter has specific update semantics:
post (body, scheduled_at, draft) — Merged with existing values. Only the fields you include are changed.
profiles — Full replace. When sent, all existing profile assignments are removed and replaced with the new set. If omitted, existing profiles are kept. Accepts the same values as create (profile IDs or network names).
platforms — Merged with existing params. When sent without profiles, the platform parameters are merged into the existing profile assignments. For example, sending {"platforms": {"youtube": {"privacy_status": "unlisted"}}} updates the YouTube privacy status without changing other params or profiles. When sent together with profiles, platform params are applied to the new profile set (same as create).
media — Full replace. When sent, all existing media attachments are destroyed and replaced with the new set. Send an empty array [] to remove all media. If omitted, existing media is kept.
thread — Full replace. When sent, all existing thread children are destroyed and rebuilt from the new array. Send an empty array [] to remove all thread children. If omitted, existing thread is kept. Thread children automatically inherit the parent’s profiles, scheduling, and draft status.
Example
Section titled “Example”curl -X PATCH "https://api.postproxy.dev/api/posts/abc123xyz" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "post": { "body": "Updated post content!" } }'import { PostProxy } from "postproxy-sdk";
const client = new PostProxy("YOUR_API_KEY");const post = await client.posts.update("abc123xyz", { body: "Updated post content!",});console.log(post);from postproxy import PostProxy
client = PostProxy("YOUR_API_KEY")post = await client.posts.update( "abc123xyz", body="Updated post content!",)print(post)package main
import ( "context" "fmt" "github.com/postproxy/postproxy-go")
func main() { client := postproxy.NewClient("YOUR_API_KEY") ctx := context.Background() body := "Updated post content!" post, _ := client.Posts.Update(ctx, "abc123xyz", &postproxy.PostUpdateOptions{ Body: &body, }) fmt.Println(post)}require "postproxy"
client = PostProxy::Client.new("YOUR_API_KEY")post = client.posts.update( "abc123xyz", body: "Updated post content!")puts postuse PostProxy\Client;
$client = new Client(apiKey: 'YOUR_API_KEY');$post = $client->posts()->update('abc123xyz', body: 'Updated post content!',);print_r($post);import dev.postproxy.sdk.PostProxy;import dev.postproxy.sdk.param.*;
var client = PostProxy.builder("YOUR_API_KEY").build();var post = client.posts().update("abc123xyz", UpdatePostParams.builder() .body("Updated post content!") .build());System.out.println(post);using PostProxy;using PostProxy.Parameters;
var client = PostProxyClient.Builder("YOUR_API_KEY").Build();var post = await client.Posts.UpdateAsync("abc123xyz", new UpdatePostParams{ Body = "Updated post content!",});Console.WriteLine(post);Request body (JSON):
{ "post": { "body": "Updated post content!" }}Response (200 OK):
{ "id": "abc123xyz", "body": "Updated post content!", "status": "scheduled", "draft": false, "scheduled_at": "2024-01-16T09:00:00.000Z", "created_at": "2024-01-15T10:30:00.000Z", "platforms": [ { "platform": "twitter", "status": "pending", "error": null, "params": { "format": "post" }, "attempted_at": null } ]}Error responses
Section titled “Error responses”Post not editable (422):
{ "error": "Post cannot be edited (only drafts or scheduled posts more than 5 minutes before publish time)"}Profile not found (422):
{ "error": "Profile not found for invalid_id"}Invalid platform params (422):
{ "error": "Invalid platform params for youtube: bad_key. Allowed: title, privacy_status, format"}Post not found (404):
{ "error": "Not found"}Delete post
Section titled “Delete post”DELETE /api/posts/:id
Deletes a post from the database. Note: This does not remove the post from social media platforms.
Path parameters
Section titled “Path parameters”| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Post id |
Example
Section titled “Example”curl -X DELETE "https://api.postproxy.dev/api/posts/abc123xyz" \ -H "Authorization: Bearer YOUR_API_KEY"import PostProxy from "postproxy-sdk";
const client = new PostProxy("YOUR_API_KEY");const result = await client.posts.delete("abc123xyz");console.log(result);from postproxy import PostProxy
client = PostProxy("YOUR_API_KEY")result = await client.posts.delete("abc123xyz")print(result)package main
import ( "fmt" postproxy "github.com/postproxy/postproxy-go")
func main() { client := postproxy.New("YOUR_API_KEY") result, _ := client.Posts.Delete("abc123xyz") fmt.Println(result)}require "postproxy"
client = PostProxy::Client.new("YOUR_API_KEY")result = client.posts.delete("abc123xyz")puts resultuse PostProxy\PostProxy;
$client = new PostProxy("YOUR_API_KEY");$result = $client->posts->delete("abc123xyz");print_r($result);import dev.postproxy.PostProxy;
PostProxy client = new PostProxy("YOUR_API_KEY");var result = client.posts().delete("abc123xyz");System.out.println(result);using PostProxy;
var client = new PostProxyClient("YOUR_API_KEY");var result = await client.Posts.DeleteAsync("abc123xyz");Console.WriteLine(result);Response:
{ "deleted": true}Publish post
Section titled “Publish post”POST /api/posts/:id/publish
Publishes a draft post. Only posts with status: "draft" can be published using this endpoint.
Path parameters
Section titled “Path parameters”| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Post id |
Example
Section titled “Example”curl -X POST "https://api.postproxy.dev/api/posts/abc123xyz/publish" \ -H "Authorization: Bearer YOUR_API_KEY"import PostProxy from "postproxy-sdk";
const client = new PostProxy("YOUR_API_KEY");const post = await client.posts.publishDraft("abc123xyz");console.log(post);from postproxy import PostProxy
client = PostProxy("YOUR_API_KEY")post = await client.posts.publish_draft("abc123xyz")print(post)package main
import ( "fmt" postproxy "github.com/postproxy/postproxy-go")
func main() { client := postproxy.New("YOUR_API_KEY") post, _ := client.Posts.PublishDraft("abc123xyz") fmt.Println(post)}require "postproxy"
client = PostProxy::Client.new("YOUR_API_KEY")post = client.posts.publish_draft("abc123xyz")puts postuse PostProxy\PostProxy;
$client = new PostProxy("YOUR_API_KEY");$post = $client->posts->publishDraft("abc123xyz");print_r($post);import dev.postproxy.PostProxy;
PostProxy client = new PostProxy("YOUR_API_KEY");var post = client.posts().publishDraft("abc123xyz");System.out.println(post);using PostProxy;
var client = new PostProxyClient("YOUR_API_KEY");var post = await client.Posts.PublishDraftAsync("abc123xyz");Console.WriteLine(post);Response:
{ "id": "abc123xyz", "body": "Hello World!", "status": "processing", "scheduled_at": null, "created_at": "2024-01-15T10:30:00.000Z", "platforms": [ { "platform": "instagram", "status": "processing", "params": { "format": "post" }, "attempted_at": null } ]}Error responses
Section titled “Error responses”Post not found (404):
{ "error": "Not found"}Post is not a draft (422):
{ "error": "Post is not a draft"}Post statuses
Section titled “Post statuses”Post-level status
Section titled “Post-level status”| Status | Description |
|---|---|
draft | Post is saved but not published, awaiting review |
processing | Post is being published to platforms |
processed | All platform publishing attempts completed |
scheduled | Post is scheduled for future publishing |
media_processing_failed | One or more media attachments failed to process |
Platform-level status
Section titled “Platform-level status”| Status | Description |
|---|---|
processing | Currently being published to this platform |
published | Successfully published |
failed | Publishing failed (check error message) |
deleted | Post was deleted on a platform |
Insights
Section titled “Insights”Insights (impressions/views) are collected periodically after a post is published. The insights object in the platform response contains:
| Field | Description |
|---|---|
impressions | Number of views/impressions on the platform |
on | Timestamp when the metrics were captured |
Insights are updated approximately every 8 hours for published posts.
Threads
Section titled “Threads”Threads allow you to create a sequence of posts that are published as replies to each other, forming a conversation thread on supported platforms.
Supported platforms
Section titled “Supported platforms”Threads are only supported on:
- X (Twitter) — each post is published as a reply to the previous tweet
- Threads — each post is published as a reply to the previous Threads post
Attempting to create a thread with other platforms (Instagram, Facebook, LinkedIn, etc.) will return a 422 error.
How threads work
Section titled “How threads work”- The parent post (
post[body]) is published first on each platform - Each child post in the
threadarray is published sequentially as a reply to the previous post - Per-platform chains are independent — the X chain and Threads chain run in parallel
- Position is determined by the array order (first item = first reply, etc.)
Thread parameter
Section titled “Thread parameter”| Field | Type | Required | Description |
|---|---|---|---|
body | string | Yes | Text content for this thread post |
media | array | No | Array of media URLs (same format as top-level media) |
Error handling
Section titled “Error handling”- If a post in the thread chain fails, subsequent posts in that chain will wait (they are not published)
- Each platform chain is independent — a failure on X does not block the Threads chain