Buffer API Integration
This is a member-only chapter. Log in with your Signal Over Noise membership email to continue.
Log in to readModule 2: Buffer API Integration
Buffer’s API is GraphQL, not REST. That’s worth stating upfront because most Buffer tutorials written before 2022 describe a different API entirely — one that no longer exists in the same form. If you’ve tried to integrate with Buffer before and hit strange errors, that’s probably why.
The GraphQL API is cleaner. One endpoint, one query language, typed responses. Once you understand the shape of it, adding a new channel or changing what gets queued is straightforward.
Setting Up Buffer
You need a Buffer account with at least one channel connected. The free tier allows one channel; the Essentials plan allows three. For the terminal workflow to be useful you want at least LinkedIn and one other platform.
Once your channels are connected, you need an API token. Buffer calls this an “access token” and it lives under Settings > Apps. Create a new app, give it a sensible name, and note the token. This is what the post-to-buffer skill uses.
Store it as an environment variable:
export BUFFER_ACCESS_TOKEN="your-token-here"
Add that to your .zshrc or equivalent so it persists between sessions.
How Buffer’s GraphQL API Works
Every request goes to https://api.bufferapp.com/graphql. You send a POST with a JSON body containing your query (or mutation) and any variables.
To queue a post, you use the createPost mutation. The key fields are:
channelId— the ID of the connected channel you’re posting totext— the post contentscheduledAt— optional ISO timestamp; if omitted, Buffer adds it to the queue
To find your channel IDs, query the channels field on the current user:
query {
currentUser {
channels {
id
name
service
}
}
}
Run that once, save the IDs, and you’re set. They don’t change.
How the post-to-buffer Skill Works
The post-to-buffer skill wraps the Buffer GraphQL API into a consistent interface. You give it the post content and the target platform; it handles the API call.
The skill’s YAML header looks roughly like:
---
name: post-to-buffer
description: Queue a social media post to Buffer via GraphQL API.
tools: Bash
---
The body contains instructions for constructing the GraphQL mutation and executing it via curl — or via a small Node script if you prefer. The Bash tool does the actual HTTP call.
When the social-media agent calls this skill, it passes:
- The formatted post text for each platform
- The channel ID for that platform
- Optionally a scheduled time (or nothing, to use the queue order)
Per-Platform Formatting
Each platform has different norms. The skill applies these automatically, but it helps to understand why.
LinkedIn — Professional context expected. Posts can be longer (up to around 3,000 characters for personal posts). Line breaks read well. Leading with a hook sentence, then context, then the point, works consistently. Hashtags go at the end if at all.
Threads — Reads like a conversation. Shorter works better — not because of a strict limit but because long blocks of text feel out of place. Write like you’re telling someone in passing, not presenting at a conference.
X — 280 characters is the hard limit for standard posts. The skill trims aggressively and prompts you if the content can’t be shortened without losing meaning. Threads (the X kind, not the app) are available for longer content but the skill defaults to single posts unless you ask for a thread.
The skill drafts all three versions from your single description. You review them together, edit individually if needed, and approve the ones you want to queue.
Handling Multiple Channels
If you have the same platform connected twice (say, a personal LinkedIn and a company LinkedIn), the skill needs to know which one you mean. You configure this in the skill itself — a small mapping of friendly names to channel IDs:
personal-linkedin → ch_xxxx
company-linkedin → ch_yyyy
threads → ch_zzzz
x → ch_aaaa
Then you reference channels by name rather than ID. The skill resolves it.
Testing the Integration
Before wiring it into your full workflow, test the API directly. A basic curl call to the channels query confirms your token works and shows you the IDs you need:
curl -s -X POST https://api.bufferapp.com/graphql \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $BUFFER_ACCESS_TOKEN" \
-d '{"query":"{ currentUser { channels { id name service } } }"}'
If that returns your channels, you’re ready. If it returns an auth error, check that the token is exported and that you copied it correctly from Buffer’s settings.
The next module covers the content extraction pattern — how to turn work sessions into queued posts without switching context.
Check Your Understanding
Answer all questions correctly to complete this module.
1. What type of API does Buffer use?
2. How does post-to-buffer handle per-platform formatting differences?
3. What should you do if the channels query returns an auth error?
Pass the quiz above to unlock
Save failed. Please try again.