How to Automate Social Media Posting with an API (Step-by-Step)


Clicking "publish" across Instagram, TikTok, LinkedIn, Facebook, X, YouTube, and Threads every time you have a new post is not a workflow. It is a waste of engineering hours. If you are building a content pipeline, an AI agent, a CMS integration, or anything that produces social content at scale — you need an API.
This guide walks you through automating social media posting with a REST API, step by step. Every code example uses PostEverywhere's API because it is the fastest way to go from zero to publishing across all 7 platforms with a single HTTP request.
Table of Contents
- Why Automate with an API Instead of a Dashboard
- What You Need Before Starting
- Step 1: Get Your API Key
- Step 2: List Your Connected Accounts
- Step 3: Create and Schedule a Post
- Step 4: Upload Media
- Step 5: Schedule with AI-Generated Content
- Step 6: Check Post Status
- Common Automation Patterns
- Error Handling and Rate Limits
- FAQs
Why Automate with an API Instead of a Dashboard
A dashboard is fine when one person manages one brand. But the moment any of these apply, you need an API:
- CI/CD pipelines — push a blog post to your CMS and automatically distribute it across social platforms
- AI content agents — let your LLM generate content and publish it without human intervention
- Bulk operations — schedule 500 posts from a CSV in seconds instead of clicking through a calendar
- Multi-tenant apps — agencies and SaaS products that manage posting for dozens of clients
- Event-driven publishing — trigger posts when a product launches, a price drops, or a webhook fires
The PostEverywhere API gives you a single REST endpoint for all 7 platforms. One auth token, one request format, one response structure. No juggling the Meta Graph API, Twitter API v2, LinkedIn Marketing API, and TikTok Content Posting API separately.
What You Need Before Starting
Before writing any code, you need three things:
- A PostEverywhere account — any plan works, including the 14-day free trial. API access is included on Starter ($19/mo), Growth ($39/mo), and Pro ($79/mo) plans.
- Connected social accounts — link your Instagram, TikTok, LinkedIn, Facebook, X, YouTube, and/or Threads accounts from the dashboard.
- An API key — generated from your developer settings.
That is it. No OAuth app registration, no developer portal applications, no approval processes. You get your key and start making requests immediately.
Step 1: Get Your API Key
Head to your PostEverywhere developer settings and generate an API key. Your key looks like this:
pe_live_a1b2c3d4e5f6g7h8i9j0...
All requests use Bearer token authentication. Add this header to every request:
Authorization: Bearer pe_live_a1b2c3d4e5f6g7h8i9j0...
Store your API key securely. Use environment variables — never hardcode it.
Ready to automate your social media? Start your free 14-day trial — API access included on every plan. No credit card required.
Step 2: List Your Connected Accounts
Before scheduling posts, you need the account IDs for each connected platform. Here is how to fetch them.
cURL:
curl -X GET https://app.posteverywhere.ai/api/v1/accounts \
-H "Authorization: Bearer $PE_API_KEY" \
-H "Content-Type: application/json"
Python:
import requests
import os
api_key = os.environ["PE_API_KEY"]
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
response = requests.get(
"https://app.posteverywhere.ai/api/v1/accounts",
headers=headers
)
accounts = response.json()["data"]
for account in accounts:
print(f"{account['platform']}: {account['id']} ({account['name']})")
Node.js:
const response = await fetch("https://app.posteverywhere.ai/api/v1/accounts", {
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.PE_API_KEY}`,
"Content-Type": "application/json"
}
});
const { data: accounts } = await response.json();
accounts.forEach(account => {
console.log(`${account.platform}: ${account.id} (${account.name})`);
});
Example response:
{
"data": [
{ "id": "acc_123", "platform": "instagram", "name": "@yourbrand" },
{ "id": "acc_456", "platform": "linkedin", "name": "Your Company" },
{ "id": "acc_789", "platform": "tiktok", "name": "@yourbrand" },
{ "id": "acc_012", "platform": "facebook", "name": "Your Page" },
{ "id": "acc_345", "platform": "x", "name": "@yourbrand" },
{ "id": "acc_678", "platform": "youtube", "name": "Your Channel" },
{ "id": "acc_901", "platform": "threads", "name": "@yourbrand" }
]
}
Save those account IDs. You will reference them in every post request. See the full Accounts endpoint documentation for filtering and pagination options.
Step 3: Create and Schedule a Post
This is the core of the API. One request creates a post and schedules it to one or more platforms at a specific time. No need to make 7 separate API calls.
cURL:
curl -X POST https://app.posteverywhere.ai/api/v1/posts \
-H "Authorization: Bearer $PE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "Just shipped our new API docs. Automate your social media posting with a single endpoint.\n\nCheck it out: https://posteverywhere.ai/developers",
"platforms": ["instagram", "linkedin", "x", "facebook", "threads"],
"account_ids": ["acc_123", "acc_456", "acc_345", "acc_012", "acc_901"],
"scheduled_at": "2026-03-24T09:00:00Z"
}'
Python:
import requests
import os
payload = {
"content": (
"Just shipped our new API docs. Automate your social media "
"posting with a single endpoint.\n\n"
"Check it out: https://posteverywhere.ai/developers"
),
"platforms": ["instagram", "linkedin", "x", "facebook", "threads"],
"account_ids": ["acc_123", "acc_456", "acc_345", "acc_012", "acc_901"],
"scheduled_at": "2026-03-24T09:00:00Z"
}
response = requests.post(
"https://app.posteverywhere.ai/api/v1/posts",
headers={
"Authorization": f"Bearer {os.environ['PE_API_KEY']}",
"Content-Type": "application/json"
},
json=payload
)
post = response.json()["data"]
print(f"Post {post['id']} scheduled for {post['scheduled_at']}")
Node.js:
const response = await fetch("https://app.posteverywhere.ai/api/v1/posts", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.PE_API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
content: "Just shipped our new API docs. Automate your social media posting with a single endpoint.\n\nCheck it out: https://posteverywhere.ai/developers",
platforms: ["instagram", "linkedin", "x", "facebook", "threads"],
account_ids: ["acc_123", "acc_456", "acc_345", "acc_012", "acc_901"],
scheduled_at: "2026-03-24T09:00:00Z"
})
});
const { data: post } = await response.json();
console.log(`Post ${post.id} scheduled for ${post.scheduled_at}`);
That is a single request to schedule across 5 platforms. The API handles platform-specific formatting, character limits, and publishing. Check the full Posts endpoint documentation for all available fields including hashtags, first comments, and link previews.
Step 4: Upload Media
Most social posts need images or video. PostEverywhere uses a presigned URL flow — you request an upload URL, push your file directly to storage, then attach the media ID to your post.
Step 4a: Get a presigned upload URL
curl -X POST https://app.posteverywhere.ai/api/v1/media/upload \
-H "Authorization: Bearer $PE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"filename": "product-launch.jpg",
"content_type": "image/jpeg"
}'
Response:
{
"data": {
"media_id": "med_abc123",
"upload_url": "https://storage.posteverywhere.ai/uploads/...",
"expires_at": "2026-03-23T12:30:00Z"
}
}
Step 4b: Upload the file to the presigned URL
curl -X PUT "https://storage.posteverywhere.ai/uploads/..." \
-H "Content-Type: image/jpeg" \
--data-binary @product-launch.jpg
Step 4c: Attach the media to a post
payload = {
"content": "Our new product just dropped. Link in bio.",
"platforms": ["instagram", "tiktok", "facebook", "linkedin", "x", "youtube", "threads"],
"account_ids": ["acc_123", "acc_789", "acc_012", "acc_456", "acc_345", "acc_678", "acc_901"],
"media_ids": ["med_abc123"],
"scheduled_at": "2026-03-25T14:00:00Z"
}
response = requests.post(
"https://app.posteverywhere.ai/api/v1/posts",
headers=headers,
json=payload
)
You can attach multiple media IDs for carousel posts on Instagram and LinkedIn. See the full Media endpoint documentation for supported file types, size limits, and video processing details.
Step 5: Schedule with AI-Generated Content
If you want the API to generate your captions, images, or both — use the AI endpoint. This is especially useful for bulk automation where writing unique captions for every post is not practical.
Python example — generate a caption and schedule it:
# Step 1: Generate AI content
ai_response = requests.post(
"https://app.posteverywhere.ai/api/v1/ai/generate",
headers=headers,
json={
"prompt": "Write an engaging social media post about our new API documentation launch",
"tone": "professional",
"platforms": ["linkedin", "x", "instagram"]
}
)
generated = ai_response.json()["data"]
# Step 2: Schedule the generated content
for platform, content in generated["content"].items():
requests.post(
"https://app.posteverywhere.ai/api/v1/posts",
headers=headers,
json={
"content": content["text"],
"platforms": [platform],
"account_ids": [account_map[platform]],
"scheduled_at": "2026-03-26T10:00:00Z"
}
)
The AI endpoint generates platform-optimized content. A LinkedIn post gets a professional tone with line breaks. An X post stays under 280 characters. An Instagram caption includes relevant hashtags. This is the same AI content generator that powers the dashboard — available programmatically.
Building an AI content pipeline? PostEverywhere's API handles generation, scheduling, and publishing in one workflow. See the developer docs to get started.
Step 6: Check Post Status
After scheduling, you can poll for status updates to confirm your posts published successfully.
cURL:
curl -X GET https://app.posteverywhere.ai/api/v1/posts/post_xyz789 \
-H "Authorization: Bearer $PE_API_KEY"
Response:
{
"data": {
"id": "post_xyz789",
"status": "published",
"platforms": [
{ "platform": "instagram", "status": "published", "published_at": "2026-03-24T09:00:03Z", "url": "https://instagram.com/p/..." },
{ "platform": "linkedin", "status": "published", "published_at": "2026-03-24T09:00:01Z", "url": "https://linkedin.com/feed/update/..." },
{ "platform": "x", "status": "published", "published_at": "2026-03-24T09:00:02Z", "url": "https://x.com/.../status/..." }
]
}
}
Possible status values: draft, scheduled, publishing, published, failed. If a post fails on one platform but succeeds on others, you get per-platform status so you can retry only the failures.
Common Automation Patterns
Once you have the basics working, these are the patterns that save the most time.
Daily Scheduler (Cron Job)
Run a script every morning that pulls content from your CMS and schedules it across platforms:
# cron: 0 6 * * * python schedule_daily.py
import requests, os
from datetime import datetime, timedelta
headers = {"Authorization": f"Bearer {os.environ['PE_API_KEY']}"}
# Fetch today's content from your CMS
posts = fetch_from_cms(date=datetime.today())
for i, post in enumerate(posts):
scheduled_time = datetime.now().replace(hour=9) + timedelta(hours=i * 3)
requests.post(
"https://app.posteverywhere.ai/api/v1/posts",
headers=headers,
json={
"content": post["caption"],
"platforms": post["platforms"],
"account_ids": post["account_ids"],
"media_ids": post.get("media_ids", []),
"scheduled_at": scheduled_time.isoformat() + "Z"
}
)
RSS-to-Social Pipeline
Automatically share new blog posts as social content using a webhook or polling approach. Pair this with PostEverywhere's AI content generator to create unique captions for each platform instead of just sharing the title and link.
AI Content Pipeline
Build an end-to-end pipeline: generate content with your LLM, generate images with the AI image endpoint, format for each platform, schedule at optimal times, and monitor results — all without touching the dashboard.
Bulk CSV Upload
Have a spreadsheet of 200 posts? Parse the CSV and loop through the Posts endpoint:
import csv
with open("posts.csv") as f:
reader = csv.DictReader(f)
for row in reader:
requests.post(
"https://app.posteverywhere.ai/api/v1/posts",
headers=headers,
json={
"content": row["caption"],
"platforms": row["platforms"].split(","),
"account_ids": row["account_ids"].split(","),
"scheduled_at": row["scheduled_at"]
}
)
This replaces hours of manual scheduling with seconds of execution. PostEverywhere's social media scheduler handles the rest — formatting, publishing, and error recovery.
Error Handling and Rate Limits
The API enforces rate limits to keep things stable for everyone. See the full rate limits documentation for details.
| Limit | Threshold |
|---|---|
| Per minute | 60 requests |
| Per hour | 1,000 requests |
| Per day | 10,000 requests |
When you hit a rate limit, you get a 429 Too Many Requests response with a Retry-After header. Handle it gracefully:
import time
def api_request(method, url, **kwargs):
response = requests.request(method, url, headers=headers, **kwargs)
if response.status_code == 429:
retry_after = int(response.headers.get("Retry-After", 60))
time.sleep(retry_after)
return api_request(method, url, **kwargs)
response.raise_for_status()
return response.json()
Common error codes:
| Code | Meaning | Fix |
|---|---|---|
| 400 | Bad request | Check your payload format |
| 401 | Unauthorized | Verify your API key |
| 403 | Forbidden | Account not connected or insufficient permissions |
| 404 | Not found | Post or account ID does not exist |
| 429 | Rate limited | Back off and retry after the specified interval |
| 500 | Server error | Retry with exponential backoff |
For production systems, implement exponential backoff, log failures, and set up alerts for persistent errors. The PostEverywhere developer quickstart includes a production-ready client wrapper with retry logic built in.
Need higher rate limits? Pro plans support up to 10,000 requests per day. Talk to us about enterprise limits if you are building an agency tool or SaaS integration.
What About Social Media Automation Without Code?
Not every team has developers. If you want to automate posting without writing code, PostEverywhere's dashboard includes auto-scheduling, AI caption generation, cross-posting, and bulk scheduling — all from a visual interface. The API and dashboard work together, so you can mix both approaches. Use the API for programmatic workflows and the dashboard for one-off posts and manual adjustments.
FAQs
Do I need a paid plan to use the PostEverywhere API?
API access is included on every plan. The Starter plan at $19/mo includes 60 requests per minute and 10,000 per day. You can start with the 14-day free trial — no credit card required — and make API calls immediately.
Can I post to all 7 platforms in a single API call?
Yes. Include all platform names in the platforms array and the corresponding account IDs. One request handles Instagram, TikTok, LinkedIn, Facebook, X, YouTube, and Threads simultaneously.
How do I handle different content formats per platform?
You can either send a single content field and let the API adapt it per platform, or use the AI generation endpoint to create platform-specific versions. The AI understands character limits, hashtag conventions, and tone differences between platforms.
Is the API suitable for agencies managing multiple clients?
Yes. Each connected account has a unique ID, so you can manage hundreds of client accounts from a single API key. The multi-account management features work the same way via API as they do in the dashboard.
What happens if a post fails on one platform but succeeds on others?
The API returns per-platform status. A post can be published on LinkedIn and failed on Instagram. You get the specific error message for the failed platform so you can fix the issue and retry just that one — no need to re-publish everywhere.

Founder & CEO of PostEverywhere. Writing about social media strategy, publishing workflows, and analytics that help brands grow faster.