How to build a social content engine with the Buffer API (2026)
Wire AI content generation into Buffer's new GraphQL API: get a key, query channels, draft per-platform posts, host media, and schedule across 11 networks with one mutation.
Buffer reopened a public API in 2026, and it changes what a solo builder can wire up over a weekend. The new API is a single GraphQL endpoint at https://api.buffer.com that creates, schedules, and deletes posts across 11 networks — Instagram, Facebook, TikTok, LinkedIn, X, YouTube, Threads, Pinterest, Google Business Profile, Bluesky, and Mastodon — through one createPost mutation. You do not learn 11 platform APIs or juggle 11 OAuth flows; you call one mutation with a channel ID and Buffer handles the publish.
That makes Buffer a clean publishing-and-scheduling backbone. What it is not is a content engine on its own: the API publishes what you hand it, but it does not write the copy, design the image, or cut the video — and it has no file upload, so every image and video has to live at a public URL before you reference it. A real engine is the AI generation layer you build in front of Buffer plus the durable media hosting underneath it.
This guide wires that engine end to end: authenticate, discover your channels, generate per-platform posts with a model, host the media durably, and schedule the batch through Buffer. It is specific about the parts that bite — the May 2026 assets-input change and the expiring-media-URL trap that ships blank posts.
The steps
Generate a Buffer API key and confirm the endpoint. In your Buffer account go to Settings → API and create a personal API key. Every request goes to https://api.buffer.com as a POST with an Authorization: Bearer YOUR_TOKEN header and a GraphQL body — no SDK is required; Postman, curl, or any GraphQL client works. Store the key as an environment variable, never in source. Personal keys reach all organizations you belong to but act as your account only; if you are building an app other people authorize, register it for OAuth 2.0 (Authorization Code flow with PKCE) at the same Settings → API screen instead.
Query your channels to get their IDs. createPost targets a channel by ID, not by name, so your first real call lists them. Query the channels query (see Buffer's Get Channels / Get Filtered Channels examples) to pull every connected channel with its id, service (instagram, linkedin, etc.), and name. Cache that map in your engine — channel IDs are the routing table for everything downstream. Connect the social accounts inside Buffer's UI first; the API publishes to channels Buffer is already authorized for, it does not add new account connections.
Build the generation layer in front of Buffer. Buffer publishes; it does not generate. This is the half you own. Take your source — a podcast, a long video, a blog, a list of prompts — and run a model to draft the posts: an LLM (Claude- or GPT-class) for captions, threads, and text; an image model for graphics; an avatar/video tool for shorts. Generate per platform, not one caption for all 11: X wants 280 characters, LinkedIn tolerates ~1,300, Instagram up to 2,200. Output a structured object per post — channelId, text, optional media URL, scheduled time — that maps straight onto the createPost input.
Host every image and video at a public URL first. The Buffer API has no file upload. The assets field on a post takes references to media that already lives at a publicly reachable URL — Buffer fetches it at create or publish time. So before you call createPost for any image or video post, upload the bytes to your own storage (S3, R2, Cloudflare, Supabase Storage) and get a stable public URL. Do not pass the raw URL your image or video model returned: those expire, and Buffer fetching a dead URL is how a post ships text-only or fails outright.
Create and schedule posts with the createPost mutation. A single createPost mutation serves all 11 platforms. The core inputs are text, channelId, and schedulingType (automatic). For timing you choose a mode: addToQueue drops the post into the next open slot from that channel's posting schedule, while customScheduled publishes at an exact moment you pass as dueAt in ISO 8601 UTC (e.g. 2026-03-10T15:00:00.000Z). For an engine, loop your generated batch and fire one mutation per post; stagger the dueAt values so the whole batch does not land at once.
Use the current assets input shape (post–May 2026). On 12 May 2026 Buffer changed how media is submitted: CreatePostInput.assets (and EditPostInput / ThreadedPostInput) moved from the old AssetsInput object to an array, [AssetInput!]!. Mutations using the legacy format now fail. If you are copying an older snippet or an LLM-generated example trained on the old schema, pass assets as a list of asset objects, not a single object. Threads on X, Bluesky, Threads, and Mastodon are built through channel-specific metadata in the same createPost input.
Respect rate limits and make every call idempotent. All Buffer plans include API access, but the limits scale with tier: 100 requests per 15 minutes on every plan; per 24 hours roughly 100 (Free) up to 500 (Team); per 30 days 3,000 (Free) up to 15,000 (Team). For a high-volume engine, batch and pace your createPost calls and back off on a 429. Tag each job with a unique key on your side and check it before firing, so a retry after a network blip never double-creates the same post. Partners needing higher limits email developersupport@buffer.com.
Add a review gate, or wire the MCP server for agent control. Do not run source-to-published with no human in the loop on day one. Land drafts in a review state in your own app, approve or edit, and only call createPost on approved items — feed every edit back into your generation prompt. If your interface is an AI assistant rather than a dashboard, Buffer ships an MCP server with native connections for Claude, Cursor, Raycast, ChatGPT, and Perplexity, so an agent can draft and queue posts through the same API. Keep a kill switch either way.
Common gotchas
No file upload in the API. Every image and video must be hosted at a public URL before you reference it in the assets field — Buffer fetches it, it does not accept a binary upload.
Passing an expiring provider URL as the asset. Image/video model URLs die in ~1-24h; if Buffer fetches a dead URL at publish time the post ships text-only or fails. Re-host to durable storage and pass that URL.
Using the legacy assets format. After 12 May 2026, CreatePostInput.assets is an array [AssetInput!]!, not the old AssetsInput object — old snippets and stale LLM examples silently break. Use the array shape.
Targeting a channel by name. createPost needs the channel ID, not the handle. Query channels first and build an ID map; channels must already be connected inside Buffer.
Ignoring per-plan rate limits. The 15-minute cap is 100 on every tier; a tight loop firing dozens of posts will hit it. Pace the batch and back off on 429.
Expecting Buffer to generate content. The API publishes and schedules only — it writes nothing. Brand voice, copy, images, and video are entirely your generation layer's job.
Writing one caption for all 11 platforms. The same string blows past X's 280 characters or reads flat on LinkedIn. Generate per platform and respect each ceiling.
Where Kompozy fits
The Buffer API gives you the cleanest possible publishing half of an engine — one mutation, 11 platforms, real scheduling. Steps 3 and 4 above are the half it leaves to you: generate the actual posts, and host the media durably so Buffer can fetch it. That is precisely the surface Kompozy fills. Kompozy generates the content the Buffer API will not — 18 formats spanning persona/avatar shorts, VFX hooks, clipped verticals, carousels, quote graphics, face-locked persona images, blogs, and newsletters — governed by a Persona Brief so 40 posts a week read as one voice. And it persists every generated image and video to durable storage at creation time, which is the exact fix for the expiring-URL trap that breaks Buffer's asset fetch: the URL you would hand Buffer is permanent, not a dead provider link.
Two honest ways to use them together. If you have standardized on Buffer's queue, use Kompozy as the generation-plus-durable-hosting layer and feed its permanent media URLs into your createPost calls. Or skip the glue entirely: Kompozy already publishes natively to 9 social platforms plus email and blog with per-platform limits, retries, and a review gate handled, so you do not maintain the channel-ID map, the rate-limit backoff, or the assets-input migration yourself. Creator tier ($49/mo for 2,500 credits) runs a solo single-source engine; Pro ($299/mo for 18,000 credits) covers multi-source, higher-volume operations; Enterprise is custom. Buffer wins if its queue and analytics are already your hub; Kompozy wins if you would rather not own the generation and media plumbing at all.
Frequently asked questions
Does Buffer have a public API in 2026?
Yes. Buffer reopened a public GraphQL API at https://api.buffer.com. It creates, schedules, and deletes posts and ideas and queries your channels and organization across 11 networks. Analytics is available in a limited, experimental form. You authenticate with a personal API key (Bearer token) or OAuth 2.0.
Can I publish images and videos through the Buffer API?
Yes, but there is no file upload. You host the image or video at a public URL yourself, then reference that URL in the post's assets field and Buffer fetches it. As of 12 May 2026 the assets input is an array ([AssetInput!]!), so make sure you are not using the older object format.
Does the Buffer API generate content for me?
No. The API is a publishing and scheduling backbone — it publishes exactly what you hand it. Generating the copy, images, and video, and keeping them on-brand, is a separate layer you build (or buy) in front of Buffer. That generation layer is what makes it a content engine rather than a scheduler.
How do I schedule a post for a specific time?
In createPost, set schedulingType to automatic and use mode customScheduled with dueAt as an ISO 8601 UTC timestamp like 2026-03-10T15:00:00.000Z. To instead drop the post into the channel's next open slot, use mode addToQueue and skip the explicit time.
What are the Buffer API rate limits?
All plans include API access. The 15-minute limit is 100 requests on every plan; the 24-hour limit runs from ~100 (Free) to 500 (Team); the 30-day limit from 3,000 (Free) to 15,000 (Team). Higher limits are available to partners by request via developersupport@buffer.com.
Buffer API or build my own per-platform integrations?
Buffer's one createPost mutation across 11 platforms saves you from maintaining 11 separate APIs, OAuth flows, and rate-limit regimes — a large amount of plumbing. The trade-off is you live inside Buffer's queue model and its media constraints. For most builders the single-mutation simplicity wins; build direct only if you need platform features Buffer does not expose.