skills/buffer-api/SKILL.md
Schedule, create, and manage social media posts via the Buffer GraphQL API. Use this skill when the user wants to post to social media through Buffer, schedule posts, create ideas, list channels, retrieve posts, or manage their Buffer queue. Triggers on: Buffer, schedule a post, publish to social media, Buffer API, social media queue, Buffer channels, create Buffer post, Buffer idea, or any mention of posting to LinkedIn/Twitter/Instagram/Facebook/Bluesky/Threads/Pinterest/Mastodon/YouTube/TikTok via Buffer.
npx skillsauth add baphomet480/claude-skills buffer-apiInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Schedule, create, and manage social media posts through Buffer's GraphQL API.
BUFFER_API_KEY environment variablePaid accounts can generate up to 5 API keys. Free accounts get 1. TikTok is not supported via the API at this time.
POST https://api.buffer.com
Content-Type: application/json
Authorization: Bearer $BUFFER_API_KEY
All requests are GraphQL POST requests to this single endpoint.
Every request needs the Authorization: Bearer header:
curl -X POST 'https://api.buffer.com' \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $BUFFER_API_KEY" \
-d '{"query": "{ account { organizations { id } } }"}'
| Operation | Type | Description |
|-----------|------|-------------|
| account | Query | Get authenticated user info |
| channel | Query | Fetch single channel by ID |
| channels | Query | Fetch all channels for an org |
| post | Query | Fetch single post by ID |
| posts | Query | Fetch posts with filters, sorting, pagination |
| dailyPostingLimits | Query | Check posting limits per channel per date |
| createPost | Mutation | Create and schedule a post |
| deletePost | Mutation | Delete a post by ID |
| createIdea | Mutation | Save an idea to the ideas board |
Before creating posts, you need your organization ID and channel IDs. Run these queries in order:
query GetOrganizations {
account {
organizations {
id
}
}
}
query GetChannels {
channels(input: { organizationId: "YOUR_ORG_ID" }) {
id
name
service
type
}
}
Filter by service type:
query GetFilteredChannels {
channels(
input: {
organizationId: "YOUR_ORG_ID"
filter: { services: [linkedin] }
}
) {
id
name
service
type
}
}
Service enum values: facebook, twitter, instagram, linkedin, pinterest, googlebusiness, mastodon, tiktok, bluesky, youtube, threads, startpage
query GetChannel {
channel(input: { channelId: "YOUR_CHANNEL_ID" }) {
id
name
service
type
metadata {
... on LinkedInMetadata { handle }
... on TwitterMetadata { handle }
... on FacebookMetadata { facebookPageName }
... on InstagramMetadata { handle }
}
}
}
mutation CreatePost {
createPost(input: {
text: "Hello from the Buffer API!",
channelId: "YOUR_CHANNEL_ID",
schedulingType: automatic,
mode: addToQueue
}) {
... on PostActionSuccess {
post {
id
text
status
}
}
... on MutationError {
message
}
}
}
Same as text post, with assets.images:
mutation CreateImagePost {
createPost(input: {
text: "Check out this image!",
channelId: "YOUR_CHANNEL_ID",
schedulingType: automatic,
mode: addToQueue,
assets: {
images: [
{ url: "https://example.com/image.jpg" }
]
}
}) {
... on PostActionSuccess {
post {
id
text
assets { id mimeType }
}
}
... on MutationError {
message
}
}
}
Use mode: customSchedule with a dueAt ISO 8601 timestamp:
mutation CreateScheduledPost {
createPost(input: {
text: "Posting at a specific time",
channelId: "YOUR_CHANNEL_ID",
schedulingType: automatic,
mode: customSchedule,
dueAt: "2026-04-01T14:00:00.000Z"
}) {
... on PostActionSuccess {
post { id text status }
}
... on MutationError { message }
}
}
Use mode: shareNow:
mutation ShareNow {
createPost(input: {
text: "Publishing immediately!",
channelId: "YOUR_CHANNEL_ID",
schedulingType: automatic,
mode: shareNow
}) {
... on PostActionSuccess {
post { id text status }
}
... on MutationError { message }
}
}
Use mode: shareNext to push the post to the front of the queue:
mutation ShareNext {
createPost(input: {
text: "This goes next in the queue",
channelId: "YOUR_CHANNEL_ID",
schedulingType: automatic,
mode: shareNext
}) {
... on PostActionSuccess {
post { id text status }
}
... on MutationError { message }
}
}
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| text | String | Yes | Post content |
| channelId | ChannelId | Yes | Target channel |
| schedulingType | Enum | Yes | automatic or notification |
| mode | Enum | Yes | addToQueue, shareNow, shareNext, customSchedule |
| dueAt | DateTime | For customSchedule | ISO 8601 timestamp |
| assets | AssetsInput | No | Images, videos, documents, links |
assets: {
images: [{ url: "https://..." }]
videos: [{ url: "https://...", title: "My Video" }]
documents: [{ url: "https://..." }]
link: { url: "https://..." }
}
Save content ideas to the Buffer ideas board:
mutation CreateIdea {
createIdea(input: {
organizationId: "YOUR_ORG_ID",
content: {
title: "Blog post idea"
text: "Write about the new GraphQL API features"
}
}) {
... on Idea {
id
content { title text }
}
}
}
query GetScheduledPosts {
posts(
input: {
organizationId: "YOUR_ORG_ID",
filter: { status: [scheduled] },
sort: [{ field: dueAt, direction: asc }]
}
) {
totalCount
edges {
node {
id
text
status
createdAt
dueAt
channelId
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
query GetSentPosts {
posts(
input: {
organizationId: "YOUR_ORG_ID",
filter: {
status: [sent],
channelIds: ["YOUR_CHANNEL_ID"]
}
}
) {
edges {
node {
id
text
createdAt
channelId
}
}
}
}
query GetPostsWithAssets {
posts(
input: {
organizationId: "YOUR_ORG_ID",
filter: { status: [sent], channelIds: ["YOUR_CHANNEL_ID"] }
}
) {
edges {
node {
id
text
assets {
thumbnail
mimeType
source
... on ImageAsset {
image { altText width height }
}
}
}
}
}
}
Use first and after for cursor-based pagination:
query GetPaginatedPosts {
posts(
input: { organizationId: "YOUR_ORG_ID" },
first: 10,
after: "CURSOR_FROM_PREVIOUS_PAGE"
) {
edges {
node { id text status }
}
pageInfo {
hasNextPage
endCursor
}
totalCount
}
}
draft, scheduled, sent, error, deleted, approval_pending, approval_rejected
dueAt, createdAt
mutation DeletePost {
deletePost(input: { postId: "POST_ID" }) {
... on DeletePostSuccess {
post { id status }
}
... on MutationError { message }
}
}
curl -X POST 'https://api.buffer.com' \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $BUFFER_API_KEY" \
-d "$(jq -n --arg text "Hello from the API" --arg ch "$BUFFER_CHANNEL_ID" '{
query: "mutation CreatePost($input: CreatePostInput!) { createPost(input: $input) { ... on PostActionSuccess { post { id text } } ... on MutationError { message } } }",
variables: { input: { text: $text, channelId: $ch, schedulingType: "automatic", mode: "addToQueue" } }
}')"
curl -X POST 'https://api.buffer.com' \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $BUFFER_API_KEY" \
-d "$(jq -n --arg org "$BUFFER_ORG_ID" '{
query: "query($input: PostsInput!) { posts(input: $input, first: 20) { edges { node { id text dueAt channelId } } } }",
variables: { input: { organizationId: $org, filter: { status: ["scheduled"] }, sort: [{ field: "dueAt", direction: "asc" }] } }
}')"
Returned as typed union members. Always include ... on MutationError { message } in mutations:
... on PostActionSuccess { post { id } }
... on MutationError { message }
Specific error types: QueueLimitError, PostAlreadyExistsError, ValidationError, LimitReachedError, InvalidInputError, UnauthorizedError, VoidMutationError
Returned in the standard GraphQL errors array with extension codes:
| Code | Meaning |
|------|---------|
| NOT_FOUND | Resource does not exist |
| FORBIDDEN | No permission |
| UNAUTHORIZED | Auth required or invalid |
| UNEXPECTED | Server error |
| RATE_LIMIT_EXCEEDED | Too many requests |
| Client Type | Limit | |-------------|-------| | Third-party clients | 100 requests / 15 min | | Unknown/unauthenticated | 50 requests / 15 min | | Account overall (all clients) | 2,000 requests / 15 min |
Response headers: RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset
On 429, use the retryAfter value (seconds) from the error response.
| Limit | Value | |-------|-------| | Max query complexity | 175,000 points | | Max query depth | 25 levels | | Max aliases | 30 | | Max directives | 50 | | Max tokens | 15,000 |
Facebook, Twitter/X, Instagram, LinkedIn, Pinterest, Google Business, Mastodon, TikTok (not via API), Bluesky, YouTube, Threads, Start Page
If the current project root contains an .agent/ directory, this skill MUST participate in the Agentic OS shared-memory model.
At the end of your execution, check for .agent/state/last-run.json. If it exists, append or update the file using its required schema to log your run. Ensure you capture your runtime (agent_runtime), skill_executed, a concise summary, decisions, and next_steps.
development
Sets up, configures, and optimizes Google Analytics 4 (GA4) properties. Evaluates websites for proper GA4 implementation, tracking codes, and configuration improvements. Uses the Google Analytics Admin API for programmatic setup or provides manual integration paths via gtag.js or Next.js Third Parties.
development
Open-source intelligence on people, companies, domains, and B2B accounts. Use when the user wants to investigate, vet, research, or build a dossier on a target — phrases like "OSINT", "due diligence", "background check", "research this person", "look into [company/domain]", "vet this prospect/vendor", "what does X do", "is this account worth pursuing", "find me a contact at", "who's the buyer for", or any open-source investigation task. Disambiguates identities before reporting and grades every claim by independent source count.
development
Generate, edit, describe, restyle, restore, thumbnail, and batch-process images using xAI (Grok) or OpenAI image APIs and GPT-4o vision. Default provider is xAI ($0.02/image flat rate). Use this skill whenever the user asks to generate, create, make, draw, or design an image or picture using AI, or wants to edit, modify, transform, restyle, composite, or inpaint an existing image. Also handles image description and alt-text generation, background removal, style transfer, photo restoration, thumbnail creation, and batch generation from JSON manifests. Trigger when the user mentions DALL-E, gpt-image, Grok image, xAI image, OpenAI image generation, or wants AI-generated visuals for any purpose (logos, mockups, illustrations, thumbnails, icons, concept art, memes). Also trigger for batch image generation, generating a set or series of images, processing multiple images from a manifest, or creating consistent image collections. If the user says "make me an image of...", "generate a picture", "edit this photo to...", "describe this image", "remove the background", "make this look like watercolor", "restore this old photo", "create a thumbnail", "generate a batch of images", or "process this image manifest", this is the skill to use.
testing
Agentic OS Orchestrator. Process and execute tasks from the shared .agent/state/tasks.json queue. Use when the user asks to 'check the queue', 'process tasks', or run the heartbeat.