Posts

List Posts

Get all posts for your account, including pending, published, and failed posts.

Endpoint

GET /posts

Request

curl https://api.postcore.dev/posts \
  -H "x-api-key: YOUR_API_KEY"
const response = await fetch('https://api.postcore.dev/posts', {
  headers: {
    'x-api-key': process.env.POSTCORE_API_KEY
  }
});

const { posts } = await response.json();
console.log(`You have ${posts.length} posts`);
import os
import requests

response = requests.get(
    'https://api.postcore.dev/posts',
    headers={'x-api-key': os.getenv('POSTCORE_API_KEY')}
)

posts = response.json()['posts']
print(f'You have {len(posts)} posts')

Response

{
  "posts": [
    {
      "postId": "post_abc123",
      "profileKey": "prof_abc123",
      "platform": "linkedin",
      "content": "Excited to announce our new feature! 🚀",
      "scheduledFor": "2025-01-15T14:00:00Z",
      "createdAt": "2025-01-08T12:00:00Z",
      "publishedAt": "2025-01-15T14:00:12Z",
      "status": "published",
      "platformUrl": "https://linkedin.com/feed/update/urn:li:share:123456789"
    },
    {
      "postId": "post_def456",
      "profileKey": "prof_abc123",
      "platform": "bluesky",
      "content": "Excited to announce our new feature! 🚀",
      "scheduledFor": "2025-01-15T14:00:00Z",
      "createdAt": "2025-01-08T12:00:00Z",
      "publishedAt": null,
      "status": "pending",
      "platformUrl": null
    }
  ]
}

Status Code: 200 OK

Response Fields

FieldTypeDescription
postIdstringUnique post identifier
profileKeystringAssociated profile
platformstringPlatform name (linkedin, bluesky)
contentstringPost content
scheduledForstringScheduled publish time
createdAtstringWhen post was created
publishedAtstring | nullWhen post was published (null if pending)
statusstring"pending", "published", or "failed"
platformUrlstring | nullURL to post on platform (null if pending)

Empty Response

If you haven't created any posts yet:

{
  "posts": []
}

Post Statuses

Posts can have three statuses:

pending - Post is scheduled but not yet published

  • publishedAt is null
  • platformUrl is null
  • Can be deleted

published - Post was successfully published

  • publishedAt has a timestamp
  • platformUrl contains link to post
  • Cannot be deleted via API

failed - Post failed to publish

  • publishedAt is null
  • platformUrl is null
  • Contains error information
  • Cannot be retried (must create new post)

Filtering Posts

By Status

const { posts } = await fetch("https://api.postcore.dev/posts", {
  headers: { "x-api-key": apiKey },
}).then((r) => r.json());

const pending = posts.filter((p) => p.status === "pending");
const published = posts.filter((p) => p.status === "published");
const failed = posts.filter((p) => p.status === "failed");

console.log(
  `Pending: ${pending.length}, Published: ${published.length}, Failed: ${failed.length}`
);

By Platform

const linkedInPosts = posts.filter((p) => p.platform === "linkedin");
const blueskyPosts = posts.filter((p) => p.platform === "bluesky");

By Profile

const userPosts = posts.filter((p) => p.profileKey === "prof_abc123");

By Date Range

const startDate = new Date("2025-01-01");
const endDate = new Date("2025-01-31");

const postsInJanuary = posts.filter((p) => {
  const scheduled = new Date(p.scheduledFor);
  return scheduled >= startDate && scheduled <= endDate;
});

Common Use Cases

Check Upcoming Posts

const now = new Date();

const upcoming = posts
  .filter((p) => {
    if (p.status !== "pending") return false;
    const scheduledDate = new Date(p.scheduledFor);
    return scheduledDate > now;
  })
  .sort((a, b) => new Date(a.scheduledFor) - new Date(b.scheduledFor));

console.log("Next 5 posts:");
upcoming.slice(0, 5).forEach((post) => {
  console.log(`- ${post.platform}: ${post.scheduledFor}`);
});

Find Posts Publishing Soon

const now = new Date();
const oneHourFromNow = new Date(now.getTime() + 60 * 60 * 1000);

const publishingSoon = posts.filter((p) => {
  if (p.status !== "pending") return false;
  const scheduled = new Date(p.scheduledFor);
  return scheduled > now && scheduled <= oneHourFromNow;
});

if (publishingSoon.length > 0) {
  console.log(`${publishingSoon.length} posts publishing in the next hour`);
}

Get Monthly Statistics

const thisMonth = new Date().getMonth();
const thisYear = new Date().getFullYear();

const monthlyPosts = posts.filter((p) => {
  const created = new Date(p.createdAt);
  return created.getMonth() === thisMonth && created.getFullYear() === thisYear;
});

const stats = {
  total: monthlyPosts.length,
  pending: monthlyPosts.filter((p) => p.status === "pending").length,
  published: monthlyPosts.filter((p) => p.status === "published").length,
  failed: monthlyPosts.filter((p) => p.status === "failed").length,
};

console.log("This month:", stats);

Sorting Posts

Posts are returned ordered by scheduledFor (newest first). You can re-sort as needed:

// Oldest first
posts.sort((a, b) => new Date(a.scheduledFor) - new Date(b.scheduledFor));

// By creation date
posts.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));

// By platform, then date
posts.sort((a, b) => {
  if (a.platform !== b.platform) {
    return a.platform.localeCompare(b.platform);
  }
  return new Date(a.scheduledFor) - new Date(b.scheduledFor);
});

Error Responses

Invalid API Key

{
  "error": "INVALID_API_KEY",
  "message": "Invalid API key"
}

Status: 401 Unauthorized