Buffer API: What It Can Do, Its Limits, and Alternatives
Buffer API guide for October 2026: the new GraphQL endpoint, rate limits by plan, API keys and OAuth, the MCP server, and the gaps. See where PostZen fits.
TLDR: The Buffer API relaunched on May 27, 2026 as a GraphQL endpoint with an MCP server, a CLI, and OAuth, on every plan including Free. Each request posts to one channel, media must be a public URL, and daily caps run 250 to 500 requests. It fits teams already in Buffer; products posting for their users need a different API.
Does Buffer have an API?
Yes. The Buffer API has been public again since May 27, 2026, and it is not the API older tutorials describe. After a beta program, Buffer announced in its launch post that the API was open for building and shipped three things: a public GraphQL API, a remote MCP server for AI assistants, and a command-line tool. OAuth app clients came with it, so third-party tools can act for other Buffer users.
The Buffer API lives at one endpoint, https://api.buffer.com. Every call is a POST with a GraphQL document in the body and an Authorization: Bearer header carrying your key, and Buffer says it runs on the same GraphQL stack as its own apps. The data model is short: an account holds organizations, an organization holds channels (one connected social profile each), and a channel holds posts.
If you have seen Buffer code before, it probably targeted api.bufferapp.com/1/, Buffer’s older REST API, which older tutorials and several competitor comparison pages still describe. Any page that calls the Buffer API closed predates the May 27, 2026 launch. For code written against the old API, Buffer publishes a REST-to-GraphQL migration guide: updates are now called posts, the platform configuration endpoints are gone, and platform constraints such as character limits and media types are now enforced server side. The rest of the developer documentation lives at developers.buffer.com.
What can the Buffer API do?
As of October 1, 2026, the Buffer API covers a large share of what the composer does, plus a slice of the planning side:
- Posts. Create, edit, and delete posts with text and media, add a first comment, build threaded posts, and set channel-specific fields. Media is attached by public link, not uploaded.
- Ideas and tags. Create and list ideas, and create, update, and delete tags.
- Reads. List organizations, channels, scheduled posts, and sent posts.
Scheduling has two documented modes on createPost. addToQueue drops the post into the next free slot of the channel’s posting schedule. customScheduled takes a dueAt timestamp in ISO 8601 UTC. A separate schedulingType decides who presses publish: automatic means Buffer posts for you, and notification means Buffer sends a reminder and you post by hand.
Each createPost call targets exactly one channel through channelId. Sending one announcement to five networks is five mutations, which matters for the rate limits below. API posts also respect channel permissions: on a channel set to require approval, a post created through the Buffer API lands as a draft awaiting approval instead of entering the queue. For an agency or any team with a review step, that is a feature.
Channel features follow the platforms:
- Instagram post type (post, story, or reel) and user tags on images
- Threads on X, Bluesky, Threads, and Mastodon
- First comment on LinkedIn, Facebook, and Instagram
- Pinterest board selection
Buffer’s help article on the API lists 11 supported platforms: Instagram, Threads, LinkedIn, X, Facebook, TikTok, Google Business Profiles, Mastodon, YouTube, Pinterest, and Bluesky. Start Page posts cannot be created through the API. For no-code automation, Buffer also connects to Zapier, Make, n8n, and IFTTT.
Is the Buffer API free, and what are its rate limits?
There is no separate Buffer API pricing. API access is included on every plan, Free included, and what you pay for is channels. As of October 1, 2026, Buffer’s pricing, last updated in November 2025, is:
- Free: up to 3 channels, with 10 scheduled posts per channel at a time
- Essentials: $5 per channel per month, or $60 per channel per year on annual billing
- Team: $10 per channel per month, or $120 per channel per year on annual billing
- Channels above 10 get a volume discount
The plan also sets how many API keys and app clients you can register, and your Buffer API rate limits:
| Plan | API keys | App clients | Per 15 minutes | Per 24 hours | Per 30 days |
|---|---|---|---|---|---|
| Free | 1 | 1 | 100 | 250 | 3,000 |
| Essentials | 3 | 3 | 100 | 250 | 7,500 |
| Team | 5 | 5 | 100 | 500 | 15,000 |
Limits apply per client, meaning per API key or app client, over rolling windows. Every response carries structured RateLimit and RateLimit-Policy headers, one per window. A header like RateLimit: "100-in-15min";r=98;t=897 means 98 requests remain in the 15-minute window and it resets in 897 seconds. Cross a limit and you get HTTP 429 with a Retry-After header in seconds and an error body carrying code: "RATE_LIMIT_EXCEEDED" and the exhausted window. The API limits guide has the full policy.
The numbers look generous until you do the per-channel math. Because each createPost targets one channel, sharing one announcement to five channels costs five requests. On Free or Essentials, the 250-a-day cap allows about 50 of those five-channel posts a day, before you spend requests listing channels, checking whether a post went out, or retrying. A team scheduling its own content will rarely get close. A product posting for many users will, which is why Buffer tells developers building for multiple users to email developersupport@buffer.com for higher limits.
How do you get a Buffer API key and make your first request?
A Buffer API key is created in the Buffer dashboard under Settings, then API. Three things about keys matter before you create one, all from Buffer’s authentication guide:
- A key acts as you, reaching every organization and channel your account can see; there is no per-organization scoping.
- Keys are personal: they belong to the user who created them, not the organization.
- Only an organization owner can create keys.
Send the key as Authorization: Bearer YOUR_API_KEY on every request. A first session with the Buffer API follows the data model down: find the organization, list its channels, then create a post on one of them. Here is that sequence in Node.js 18 or newer, which has fetch built in. The helper checks for GraphQL errors, which arrive inside a normal HTTP 200, and surfaces a 429 with its Retry-After value. A failed mutation comes back as a MutationError object rather than an exception, so the last step checks for that too.
const BUFFER_API = 'https://api.buffer.com'
async function buffer(query, variables = {}) {
const response = await fetch(BUFFER_API, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${process.env.BUFFER_API_KEY}`,
},
body: JSON.stringify({ query, variables }),
})
if (response.status === 429) {
// Retry-After is in seconds; the body names the exhausted window
const retryAfter = response.headers.get('Retry-After')
throw new Error(`Rate limited, retry in ${retryAfter}s`)
}
const { data, errors } = await response.json()
if (errors?.length) throw new Error(errors.map((e) => e.message).join('; '))
return data
}
// 1. Which organizations can this key see?
const { account } = await buffer(`
query GetOrganizations {
account {
organizations { id name }
}
}
`)
console.log(account.organizations)
// 2. Which channels are in the organization? (paste an id from step 1)
const { channels } = await buffer(`
query GetChannels {
channels(input: { organizationId: "some_organization_id" }) {
id
name
displayName
service
}
}
`)
console.log(channels)
// 3. Schedule one post on one channel (paste a channel id from step 2)
const { createPost } = await buffer(`
mutation CreatePost {
createPost(input: {
text: "Version 2.4 is out: faster sync and a new calendar view.",
channelId: "some_channel_id",
schedulingType: automatic,
mode: customScheduled,
dueAt: "2026-10-08T15:00:00.000Z",
assets: [{ image: { url: "https://cdn.example.com/release-2-4.png" } }]
}) {
... on PostActionSuccess { post { id text dueAt } }
... on MutationError { message }
}
}
`)
// A failed mutation is still HTTP 200: it arrives as a MutationError
if (createPost.message) throw new Error(createPost.message)
console.log(createPost.post.id, createPost.post.dueAt)
The same three calls in Python with requests:
import os
import requests
BUFFER_API = "https://api.buffer.com"
HEADERS = {
"Content-Type": "application/json",
"Authorization": f"Bearer {os.environ['BUFFER_API_KEY']}",
}
def buffer(query, variables=None):
response = requests.post(
BUFFER_API,
headers=HEADERS,
json={"query": query, "variables": variables or {}},
timeout=30,
)
if response.status_code == 429:
# Retry-After is in seconds; the body names the exhausted window
raise RuntimeError(f"Rate limited, retry in {response.headers['Retry-After']}s")
body = response.json()
if body.get("errors"):
raise RuntimeError(body["errors"][0]["message"])
return body["data"]
# 1. Which organizations can this key see?
data = buffer("""
query GetOrganizations {
account {
organizations { id name }
}
}
""")
print(data["account"]["organizations"])
# 2. Which channels are in the organization? (paste an id from step 1)
data = buffer("""
query GetChannels {
channels(input: { organizationId: "some_organization_id" }) {
id
name
displayName
service
}
}
""")
print(data["channels"])
# 3. Schedule one post on one channel (paste a channel id from step 2)
data = buffer("""
mutation CreatePost {
createPost(input: {
text: "Version 2.4 is out: faster sync and a new calendar view.",
channelId: "some_channel_id",
schedulingType: automatic,
mode: customScheduled,
dueAt: "2026-10-08T15:00:00.000Z",
assets: [{ image: { url: "https://cdn.example.com/release-2-4.png" } }]
}) {
... on PostActionSuccess { post { id text dueAt } }
... on MutationError { message }
}
}
""")
result = data["createPost"]
if "message" in result: # a MutationError arrives inside an HTTP 200
raise RuntimeError(result["message"])
print(result["post"]["id"], result["post"]["dueAt"])
Buffer’s own examples inline the IDs, as these do: run the first query, paste an organization ID into the second, paste a channel ID into the third. In real code, pass IDs through the variables field the helpers already send rather than splicing strings into the query text.
How does the Buffer MCP server work?
The Buffer MCP server is a remote server at https://mcp.buffer.com/mcp that puts the Buffer API in front of an AI assistant. Any MCP client connects with the same personal API key, sent as Authorization: Bearer YOUR_API_KEY from the client’s configuration; Buffer’s MCP guide has the details. As of October 1, 2026, the help article linked above lists ready-made setups for Claude and Claude Code, ChatGPT and Codex, Cursor, Notion, Perplexity, Manus, Antigravity, Grok, Raycast, n8n, and Zapier.
The tools mirror the API: get_account, list_channels, get_channel, list_posts with an optional includeMetrics flag, get_post, create_post, delete_post, and create_idea, plus two generic tools that reach the rest of the GraphQL schema. create_post keeps the one-channel-per-call rule, so an agent asked to post to five channels makes five tool calls. MCP traffic counts against the same per-client rate limits, and every successful tool response reports the remaining quota so an agent can pace itself.
Buffer’s own security notes apply to any MCP server that uses a static key:
- The connection covers your whole account, every organization and every channel in it.
- The key sits in your MCP client’s config file, often in plain text.
create_postcan publish immediately anddelete_postcannot be undone, so Buffer recommends keeping your client’s approval prompts on for write tools.
For the terminal and CI, Buffer ships a CLI for Node.js 18 or newer:
npm install -g @bufferapp/cli
buffer init
buffer doctor
buffer account
buffer channels list
buffer init stores a key and buffer doctor checks the setup. The commands are generated from the public GraphQL schema, the package includes markdown skill files for Claude Code and Codex, and a BUFFER_API_KEY environment variable covers headless runs. Our own MCP server takes a different route: clients sign in with OAuth 2.1, so no long-lived key is pasted into a config file. The agents page covers the setup.
What can’t the Buffer API do?
Everything below holds for the Buffer API as of October 1, 2026, most of it stated plainly in Buffer’s own docs.
- Comments and engagement. No reading or replying to comments through the API; engagement stays in Buffer’s app.
- File uploads. There is no upload endpoint. Images, videos, and documents go in the
assetsarray as public URLs, and each URL has to stay reachable until the post publishes, because Buffer fetches media at publish time, hours or days later. The hosting media guide warns specifically against expiring or signed links such as S3 pre-signed URLs. - Analytics. Post metrics exist but are labelled experimental, and Buffer advises against relying on them for reporting or production tools. There is no analytics CSV export through the API, and reading metrics needs a personal key with the
insightsReadscope, which an OAuth app client cannot request. - Video thumbnails. No custom thumbnail image; on Instagram, TikTok, and Pinterest you pick a frame with
metadata.thumbnailOffset, in milliseconds. - Key scoping. No per-organization scoping. A key reaches everything its owner can.
- Webhooks. The developer docs document no webhooks, so finding out whether a post went out means polling the posts queries.
- Start Page. Not available through the API.
- Fan-out. One channel per
createPost, so a multi-network post is several requests.
Buffer’s public roadmap shows which of these might change. Under Exploring, meaning requested but not committed, it lists image and asset uploads, a Community API for automating comment replies, copying media into Buffer’s own storage, more analytics in the MCP server, API key permissions and scopes, and link shortening parity. As of October 1, 2026, the Planned and In Progress columns are both empty.
Can you build a product for your users on the Buffer API?
Technically yes, with one caveat that decides it for most products.
The Buffer API supports OAuth 2.0 for apps acting on behalf of other Buffer users: Authorization Code flow with PKCE, required for every client; app registration on the same Settings, then API screen as keys; authorization at https://auth.buffer.com/auth; and the scopes posts:read, posts:write, ideas:read, ideas:write, account:read, account:write, and offline_access. Access tokens last 3,600 seconds, and refresh tokens are single use and rotate on every refresh.
The caveat: every one of your users needs a Buffer account, and they connect their social channels inside Buffer, not inside your product. That is a sensible shape for a tool that extends Buffer for Buffer customers, say a CMS plugin that pushes drafts into a customer’s queue. It is the wrong shape for a product whose users have never heard of Buffer.
Three more limits point the same way:
- App clients cannot request
insightsRead, so your product cannot show your users their post metrics. - Buffer applies rate limits per client, so the users of one app client share its 250 or 500 requests a day, and a plan allows one, three, or five app clients.
- Higher limits for multi-user apps are granted by email, not by plan.
This separates two product categories that get lumped together. An integration adds to Buffer. A social media API replaces it: your users connect Instagram or LinkedIn through a link your product shows, the API holds the tokens, and your users never see a third brand. That second category is what white-label social media APIs are for, and the Buffer API is not built for it.
Buffer API vs PostZen: which one fits?
We built PostZen for the second category, so this comparison is not neutral, but every row is checkable against the Buffer docs above and our API reference.
| Buffer API | PostZen API | |
|---|---|---|
| Who connects social accounts | Each end user, inside their own Buffer account | Your users, through a hosted connect link inside your product |
| Platforms | 11, including Mastodon and Google Business Profiles | 10, including Telegram; no Mastodon or Google Business Profiles |
| One post to several networks | One createPost per channel |
One request with a platforms array |
| Media | Public URLs that must stay live until publish time | Upload up to 5 GB, or a URL that PostZen re-hosts |
| Webhooks | None documented | Post published, partially failed, or failed; account needs reauth or disconnected |
| Analytics | Experimental, personal key only | 8 platforms through the API |
| Comments and DMs | Not in the API | Comments on Instagram, Facebook, and Threads; Instagram DMs |
| Rate limits | 100 per 15 minutes; 250 to 500 a day; 3,000 to 15,000 per 30 days | 60 to 2,000 per minute by plan |
| AI agents | MCP server with a pasted API key | MCP server with OAuth 2.1 sign-in |
| Pricing model | Per channel, API included on every plan | Plans from Free to Scale on the pricing page |
Use the Buffer API if:
- Your team already runs its channels in Buffer and you want to automate your own posting from a CMS, a release pipeline, or a spreadsheet.
- You need Mastodon or Google Business Profiles, which PostZen does not support.
- You want Buffer’s approval step, ideas board, or notification-style reminders behind your automation.
- You are automating one account and 250 requests a day is plenty; the Free plan costs nothing.
- You want an AI assistant to draft into your own Buffer queue.
Use a developer API like PostZen if:
- Your users are not Buffer customers and should not have to become one.
- You post to several networks per item and want a webhook, not a poll, to tell you what happened.
- You need file uploads, analytics you can build on, or comments and DMs from the same API.
- Your request volume scales with your user count rather than your team size.
Two honest notes on our side of the table. PostZen has no ideas board and no equivalent of Buffer’s Start Page. And X posts carry X’s own per-request API charges, which we pass through. Our Buffer alternatives page covers the dashboard side of the comparison, and the best social media APIs for developers roundup puts us next to the other API-first options.
The shorter path: one request to every platform
Here is the release announcement from the Buffer example, going to four networks in one request:
curl -X POST https://api.postzen.dev/v1/posts \
-H "Authorization: Bearer $POSTZEN_API_KEY" \
-H "Content-Type: application/json" \
-H "x-request-id: release-2-4" \
-d '{
"content": "Version 2.4 is out: faster sync and a new calendar view.",
"scheduledFor": "2026-10-08T15:00:00Z",
"mediaItems": [{ "url": "https://cdn.example.com/release-2-4.png" }],
"platforms": [
{ "platform": "linkedin", "accountId": "acc_linkedin" },
{ "platform": "threads", "accountId": "acc_threads" },
{ "platform": "bluesky", "accountId": "acc_bluesky" },
{ "platform": "instagram", "accountId": "acc_instagram", "settings": { "postType": "feed" } }
]
}'
Line by line:
platformscarries one target per network, each with its ownaccountIdand optionalsettings, like the InstagrampostType; the result is one post with per-platform results.mediaItemstakes a URL that PostZen downloads and re-hosts, up to 100 MB, so the original link does not have to stay up until publish time. For larger files,POST /v1/media/presignaccepts direct uploads up to 5 GB.x-request-idmakes the create idempotent: a retried request returns the original post instead of a duplicate.scheduledForis the publish time. The scheduling API guide explains which platforms schedule natively and why the rest need a layer like this.
When the post goes out, a post.published webhook fires; if a platform rejects it, post.partially_failed or post.failed arrives with the detail; and account.needs_reauth or account.disconnected flags a connection that needs attention, so nothing polls. Your users connect their accounts through a hosted link: GET /v1/connect/{platform} returns an authUrl, the user approves on the platform, and the account is ready for your API calls without a PostZen account. Analytics come through the same API for Instagram, Facebook, X, YouTube, TikTok, Threads, Pinterest, and Bluesky (LinkedIn is pending LinkedIn’s review, and Telegram has no metrics); the analytics API guide shows the queries. Comments on Instagram, Facebook Page, and Threads posts, and Instagram direct messages, are there too.
Rate limits are per minute rather than per day: 60 requests a minute on Free, 120 on Starter, 600 on Pro, and 2,000 on Scale, with the plans on the pricing page. Two SDKs, @postzen/node and postzen-sdk for Python, wrap the same endpoints.
If you came here looking for a Buffer API alternative, check the reason first. If the reason is that Buffer closed its API, that is out of date: it is open, documented, and free to start with. If the reason is that your users should never have to open Buffer, that has not changed, and it is the case we built for.
Frequently asked questions
Does Buffer have an API?
Yes. Buffer launched a public GraphQL API on May 27, 2026, at a single endpoint, api.buffer.com, together with a remote MCP server, a CLI, and OAuth app clients. The older REST API at api.bufferapp.com is the one most older tutorials describe, and Buffer now publishes a REST-to-GraphQL migration guide for code written against it.
Is the Buffer API free?
API access is included on every Buffer plan, including the Free plan, which allows up to 3 channels and 10 scheduled posts per channel at a time. Paid plans are priced per channel: Essentials is $5 per channel per month and Team is $10 per channel per month, as of October 1, 2026. There is no separate API tier; your plan sets how many API keys you can create and your rate limits.
What are the Buffer API rate limits?
Every plan allows 100 requests per 15 minutes per API key or app client. The 24-hour limit is 250 requests on Free and Essentials and 500 on Team, and the 30-day limit is 3,000, 7,500, and 15,000 respectively. Each response includes RateLimit headers with the remaining count and the seconds until reset, and crossing a limit returns HTTP 429 with a Retry-After header.
How do I get a Buffer API key?
Open Buffer, go to Settings, then API, and create a key; only an organization owner can do this. Send it as a Bearer token in the Authorization header on every request to api.buffer.com. A key is personal, acts for your whole account, and cannot be scoped to one organization.
Does Buffer have an MCP server?
Yes. Buffer runs a remote MCP server at mcp.buffer.com/mcp that any MCP client can connect to with a Buffer API key, with setup guides for Claude, ChatGPT, Cursor, and others. Its tools list channels, create and delete posts, read posts with metrics, and create ideas, and every call counts against the same rate limits as the API.
Can I build an app for my users on the Buffer API?
Buffer supports OAuth 2.0 app clients with PKCE, so your app can act for other Buffer users. Every one of those users needs a Buffer account and connects their social channels inside Buffer, app clients cannot read post metrics, and rate limits are shared per app client. Products whose users should not need a Buffer account use a social media API such as PostZen, where users connect accounts through a hosted link inside your product.



