Public API and agent guides
Start trial
Install This Skill for Your AI Agent

Add Creagency skill, CLI, and local MCP workflows to Claude Code, Codex, OpenClaw, or any local AI agent

Option 1: Terminal / Command Line
Run this in your terminal
# Quick install for Bash/Zsh/Terminal mkdir -p ~/.agents/skills/creagency-api && curl -fsSL https://creagency.ai/.agents/skills/creagency-api/SKILL.md \ -o ~/.agents/skills/creagency-api/SKILL.md && echo "✓ Creagency skill installed to ~/.agents/skills/creagency-api/SKILL.md"
Option 2: Copy-Paste Prompt (Easiest!)
Copy this and paste to your AI agent
I need you to install the Creagency API skill so you can help me manage social media posts. Please follow these steps: 1. First, create the skill directory structure: mkdir -p ~/.agents/skills/creagency-api 2. Download the skill file from Creagency's docs: curl -fsSL https://creagency.ai/.agents/skills/creagency-api/SKILL.md \ -o ~/.agents/skills/creagency-api/SKILL.md 3. Once downloaded, confirm the skill is installed by listing the file: ls -la ~/.agents/skills/creagency-api/ 4. Now you can use the skill! Try saying: "Use the creagency-api skill to help me schedule a post" The skill file contains: - Complete API workflow patterns for TypeScript & Python - Error handling decision trees for all HTTP status codes - Rate limiting strategies and best practices - Platform-specific constraints (X, Instagram, LinkedIn, etc.) - Ready-to-use tool definitions for agent integration

Use the skill for rules, the CLI for terminal workflows, and local stdio MCP for guarded tool calls. Hosted remote MCP is planned separately.

What's Inside This Skill

  • ✓Complete API workflow recipes (TypeScript & Python)
  • ✓Error handling decision trees for all HTTP codes
  • ✓Rate limiting patterns & proactive monitoring
  • ✓Advanced workflows: AI captions, cross-posting, bulk
  • ✓Platform constraints (X, Instagram, LinkedIn, etc.)
  • ✓Ready-to-use tool definitions for agent integration
Requirements

This skill requires a Creagency API key to make actual API calls. The skill provides the patterns and code, but you'll need to authenticate.

Get Your API Key →
AI Agent Skill Guide

Creagency Agent Skill Reference

Once you've installed the skill above, this guide provides complete documentation for using Creagency's public API, CLI, and local MCP tools. Includes workflow recipes, error handling patterns, rate limit strategies, and production-ready code.

Core Principles

API-Contract First
Always read the OpenAPI spec at /api/open-api. Don't invent endpoints—discover them from the contract.
Bearer Authentication
Use "Authorization: Bearer <api_key>" on every request. Falls back to x-api-key header if needed.
Graceful Degradation
Handle 403 (scope missing), 429 (rate limited), and 401 (auth failed) with clear user messages.
Progress Reporting
Report progress after each step in multi-step workflows (upload → create → schedule).
Human Confirmation
Confirm destructive actions (delete, publish) and expensive operations (bulk uploads).
Rate Limit Awareness
Monitor ratelimit-remaining headers. Implement backoff with jitter on 429 responses.

Authentication

All API calls must include an API key in the Authorization header. The key resolves to your organization automatically—no need to specify workspace IDs.

# Primary method (recommended)
Authorization: Bearer <your_api_key>
# Fallback method
x-api-key: <your_api_key>

Store API keys in environment variables—never hardcode them. Required scopes vary by endpoint; check the Scopes reference.

Workflow Recipes

Step-by-step patterns for the most common agent workflows. Each workflow shows the exact API call sequence with error handling.

Workflow 1: Create and Schedule a Post

Steps:

  1. Verify connected social accounts (GET /api/integrations/social/accounts)
  2. Validate platform selection against available accounts
  3. Create post draft (POST /api/posts)
  4. If scheduledAt provided: post is scheduled automatically
  5. If no scheduledAt: queue for publish (POST /api/posts/{id}/publish)

Agent Note: Always verify the platform account is connected before creating the post. If missing, ask the user to connect the account in the dashboard first.

Workflow 2: Upload Media and Attach to Post

Steps:

  1. Request signed upload URL (POST /api/media/uploads/sign)
  2. Upload file directly to object storage (R2/S3)
  3. Create asset metadata (POST /api/assets)
  4. Pass asset IDs when creating post (assetIds array)

Optimization: Upload media in parallel if multiple files. Each upload is independent and can proceed concurrently.

Workflow 3: List and Manage Scheduled Posts

Steps:

  1. Query posts with filters (GET /api/posts?platform=x&limit=50)
  2. Check scheduledAt field to identify scheduled posts
  3. For rescheduling: PATCH /api/posts/{id} with new scheduledAt
  4. For unscheduling: POST /api/posts/{id}/unschedule
Workflow 4: Bulk Post Creation

Steps:

  1. Validate post count against rate limits (max 10 posts/minute)
  2. Create posts sequentially with rate limit checks
  3. Report progress after each successful creation
  4. If rate limited (429): wait for reset window and continue

Warning: Posts creation is rate-limited to 10/minute. For large batches, implement progress saving to resume after interruptions.

Complete Implementations

Production-ready client implementations with error handling, retries, and rate limit management.

import { CreagencyClient } from './creagency-client';

// Initialize with API key from environment
const client = new CreagencyClient({
  apiKey: process.env.CREAGENCY_API_KEY,
  baseUrl: 'https://api.creagency.ai'
});

// Complete workflow: Create post with media
async function createAndSchedulePost(workflow: {
  content: string;
  platform: 'x' | 'linkedin' | 'instagram' | 'youtube';
  mediaFiles: string[]; // local file paths
  scheduledAt?: Date;
}) {
  try {
    // Step 1: Best-effort account preflight when integrations:read is available
    try {
      const accounts = await client.listConnectedAccounts();
      const targetAccount = accounts.find(a => a.platform === workflow.platform);

      if (!targetAccount) {
        return {
          success: false,
          error: `No connected ${workflow.platform} account. Please connect in dashboard.`
        };
      }
    } catch (error: any) {
      if (error?.status !== 403) {
        throw error;
      }
    }

    // Step 2: Upload media (parallel)
    const mediaAssets = await Promise.all(
      workflow.mediaFiles.map(file => client.uploadMedia(file))
    );

    // Step 3: Create asset metadata
    const assets = await Promise.all(
      mediaAssets.map(media => 
        client.createAsset({
          name: media.filename,
          mimeType: media.contentType,
          sizeBytes: media.size
        })
      )
    );

    // Step 4: Create post
    const post = await client.createPost({
      content: workflow.content,
      platforms: [workflow.platform],
      assetIds: assets.map(a => a.id),
      scheduledAt: workflow.scheduledAt?.toISOString()
    });

    // Step 5: If immediate publish requested
    if (!workflow.scheduledAt) {
      await client.publishPost(post.id);
    }

    return {
      success: true,
      postId: post.id,
      status: workflow.scheduledAt ? 'scheduled' : 'publishing',
      url: `https://app.creagency.ai/dashboard/posts/${post.id}`
    };

  } catch (error) {
    return client.handleError(error);
  }
}

Error Handling Decision Tree

Agents must handle errors gracefully. Here's the complete decision pattern:

// Error handling decision tree for agents
class CreagencyErrorHandler {
  handle(error: ApiError): AgentAction {
    const { status, code, message } = error;

    // 401: Authentication failure
    if (status === 401) {
      return {
        type: 'STOP',
        userMessage: 
          'API key is invalid, expired, or revoked. ' +
          'Please check your CREAGENCY_API_KEY environment variable ' +
          'or generate a new key in the dashboard.'
      };
    }

    // 403: Scope/permission issue
    if (status === 403) {
      if (code === 'UPGRADE_REQUIRED') {
        return {
          type: 'ASK_USER',
          userMessage: 
            'This operation requires a higher plan. ' +
            'Current plan: Starter. Required: Growth+. ' +
            'Would you like me to open the billing page?'
        };
      }
      
      return {
        type: 'STOP',
        userMessage: 
          'API key lacks required scope for this operation. ' +
          'This key is missing a required scope for the attempted workflow. ' +
          'Continue with a reduced workflow or create a key with the exact scope needed.'
      };
    }

    // 429: Rate limited
    if (status === 429) {
      const resetSeconds = error.headers['ratelimit-reset'];
      
      return {
        type: 'WAIT',
        waitSeconds: parseInt(resetSeconds) + 1,
        userMessage: 
          `Rate limit hit. Waiting ${resetSeconds} seconds before retry...`
      };
    }

    // 400: Validation error
    if (status === 400) {
      // Extract field-specific errors
      const fieldErrors = error.details?.fields;
      
      if (fieldErrors) {
        const fields = Object.keys(fieldErrors).join(', ');
        return {
          type: 'ASK_USER',
          userMessage: 
            `Validation failed for fields: ${fields}. ` +
            'Please correct the input and try again.'
        };
      }
      
      return {
        type: 'ASK_USER',
        userMessage: 
          `Request validation failed: ${message}. ` +
          'Please check the data format and try again.'
      };
    }

    // 500+: Server errors
    if (status >= 500) {
      return {
        type: 'RETRY',
        maxRetries: 3,
        backoffMs: 1000,
        userMessage: 
          'Server error occurred. Will retry with exponential backoff...'
      };
    }

    // Default: Unknown error
    return {
      type: 'STOP',
      userMessage: 
        `Unexpected error (${status}): ${message}. ` +
        'Please try again or contact support.'
    };
  }
}
Retryable Errors

429 RATE_LIMITED - Wait and retry

503 SERVICE_UNAVAILABLE - Retry with backoff

504 GATEWAY_TIMEOUT - Retry with backoff

Network errors - Retry with backoff

Non-Retryable Errors

401 UNAUTHORIZED - Stop, notify user

403 FORBIDDEN - Stop, check scopes/plan

400 VALIDATION_ERROR - Fix input, retry

404 NOT_FOUND - Stop, verify ID

Rate Limiting Pattern

Implement proactive rate limit management to avoid hitting limits:

// Rate limit handling pattern
class RateLimitManager {
  private remaining: number = 60;
  private resetTime: Date = new Date();
  private minRemaining: number = 5;

  async executeWithRateLimit<T>(
    operation: () => Promise<{ headers: Headers; data: T }>
  ): Promise<T> {
    // Pre-check: If running low, wait proactively
    if (this.remaining <= this.minRemaining) {
      const waitMs = this.resetTime.getTime() - Date.now();
      if (waitMs > 0) {
        console.log('Rate limit buffer low. Pausing for ' + waitMs + 'ms...');
        await sleep(waitMs);
      }
    }

    try {
      const response = await operation();
      
      // Update rate limit tracking from headers
      this.remaining = parseInt(response.headers['ratelimit-remaining'] || '0');
      const resetSeconds = parseInt(response.headers['ratelimit-reset'] || '60');
      this.resetTime = new Date(Date.now() + resetSeconds * 1000);
      
      return response.data;
    } catch (error) {
      if (error.status === 429) {
        const retryAfter = parseInt(error.headers['retry-after'] || '60');
        console.log('Rate limited. Waiting ' + retryAfter + 's...');
        await sleep(retryAfter * 1000);
        
        // Retry once
        const retry = await operation();
        return retry.data;
      }
      throw error;
    }
  }
}
Plan-Specific Limits
PlanRequests/MinPosts/MinMedia/Min
Starter601020
Growth1801020
Scale6001020
Enterprise1,2001020

Tool Definition Pattern

When integrating Creagency into your agent's tool system, define tools with these schemas:

// Tool definition pattern for AI agents
// Use this when integrating Creagency into your agent's tool system

const creagencyTools = [
  {
    name: 'creagency_list_posts',
    description: 'List posts for the organization with optional filtering',
    parameters: {
      type: 'object',
      properties: {
        platform: {
          type: 'string',
          enum: ['x', 'linkedin', 'instagram', 'youtube', 'tiktok', 'facebook', 'threads'],
          description: 'Filter by social platform'
        },
        q: {
          type: 'string',
          description: 'Search term for post content'
        },
        limit: {
          type: 'integer',
          minimum: 1,
          maximum: 100,
          default: 20,
          description: 'Number of posts to return'
        },
        favoriteOnly: {
          type: 'boolean',
          description: 'Return only favorited posts'
        }
      }
    },
    requiredScopes: ['posts:read']
  },
  {
    name: 'creagency_create_post',
    description: 'Create a new post draft or scheduled post',
    parameters: {
      type: 'object',
      properties: {
        content: {
          type: 'string',
          maxLength: 63206,
          description: 'Post content/caption'
        },
        platforms: {
          type: 'array',
          items: { type: 'string' },
          minItems: 1,
          description: 'Target platforms (e.g., ["x", "linkedin"])'
        },
        scheduledAt: {
          type: 'string',
          format: 'date-time',
          description: 'ISO 8601 datetime for scheduling. Omit for draft.'
        },
        assetIds: {
          type: 'array',
          items: { type: 'string' },
          description: 'Media asset IDs to attach'
        }
      },
      required: ['content', 'platforms']
    },
    requiredScopes: ['posts:write']
  },
  {
    name: 'creagency_upload_media',
    description: 'Upload media file and create asset',
    parameters: {
      type: 'object',
      properties: {
        filePath: {
          type: 'string',
          description: 'Local path to media file'
        },
        filename: {
          type: 'string',
          description: 'Desired filename for the asset'
        }
      },
      required: ['filePath']
    },
    requiredScopes: ['assets:write']
  },
  {
    name: 'creagency_publish_post',
    description: 'Queue an existing post for immediate publishing',
    parameters: {
      type: 'object',
      properties: {
        postId: {
          type: 'string',
          description: 'ID of the post to publish'
        }
      },
      required: ['postId']
    },
    requiredScopes: ['posts:write']
  },
  {
    name: 'creagency_list_connected_accounts',
    description: 'List connected social media accounts',
    parameters: {
      type: 'object',
      properties: {}
    },
    requiredScopes: ['integrations:read']
  }
];

Advanced Workflows

Complex multi-step workflows for production use cases. These patterns handle AI generation, cross-platform posting, failure recovery, and bulk operations.

Workflow: AI-Generated Caption

Use AI to generate a platform-optimized caption, then create the post with it. Includes polling for job completion.

// POST /api/posts/ai/caption-jobs
const job = await api.caption.generate({
  content: "product launch announcement",
  platform: "linkedin",
  tone: "professional"
});

// Poll GET /api/posts/ai/caption-jobs/{id}
const caption = await pollForCompletion(job.id, 30000);

// Create post with generated caption
const post = await api.posts.create({
  content: caption,
  platforms: ["linkedin"]
});

Quota Limits: AI captions have daily limits by plan (Starter: 15/day, Growth: 50/day, Scale: 125/day, Enterprise: Unlimited).

Workflow: Cross-Post to Multiple Platforms

Create a single post that publishes to multiple platforms simultaneously. Validates that all platforms are connected first.

// Verify all platforms connected
const accounts = await api.accounts.list();
const connected = new Set(accounts.map(a => a.platform));

const requested = ["x", "linkedin", "instagram"];
const missing = requested.filter(p => !connected.has(p));

if (missing.length > 0) {
  throw new Error(
    'Not connected to: ' + missing.join(', ')
  );
}

// Create single post for all platforms
const post = await api.posts.create({
  content: "Big announcement! ",
  platforms: requested,
  assetIds: ["asset_123"] // Same media for all
});
Workflow: Reschedule Failed Posts

Automatically find posts that failed to publish and reschedule them for retry. Useful for handling temporary platform issues.

// List posts with status filter (if available)
const posts = await api.posts.list({ limit: 100 });
const failed = posts.filter(p => p.status === 'failed');

console.log('Found ' + failed.length + ' failed posts');

for (const post of failed) {
  // Reschedule 1 hour from now
  await api.posts.update(post.id, {
    scheduledAt: new Date(Date.now() + 3600000).toISOString()
  });
  
  console.log('Rescheduled post ' + post.id);
}
Workflow: Bulk Create with Rate Limiting

Create multiple posts in sequence with built-in rate limit safety. Pauses every 5 posts to avoid hitting the 10 posts/minute limit.

const postsToCreate = [
  { content: "Post 1", platform: "x" },
  { content: "Post 2", platform: "x" },
  // ... 20 more
];

for (let i = 0; i < postsToCreate.length; i++) {
  const data = postsToCreate[i];
  
  await api.posts.create(data);
  console.log('Created ' + (i + 1) + '/' + postsToCreate.length);
  
  // Pause every 5 posts to stay under 10/min limit
  if (i > 0 && i % 5 === 0) {
    console.log('Pausing 10s for rate limit...');
    await sleep(10000);
  }
}

Pro Tip: For large batches, save progress to disk so you can resume if interrupted. Track created post IDs in a log file.

Complete Advanced Workflows (TypeScript)
// Advanced Workflow 1: Create Post with AI-Generated Caption
async function createPostWithAiCaption(params: {
  topic: string;
  platform: 'x' | 'linkedin' | 'instagram';
  tone?: 'professional' | 'casual' | 'witty';
  scheduledAt?: string;
}) {
  console.log('[Workflow] Generating AI caption...');
  
  // Step 1: Generate caption
  const captionJob = await apiPost('/api/posts/ai/caption-jobs', {
    content: params.topic,
    platform: params.platform,
    tone: params.tone || 'professional'
  });
  
  // Step 2: Poll for completion (max 30s)
  let caption: string | null = null;
  const startTime = Date.now();
  
  while (Date.now() - startTime < 30000) {
    const status = await apiGet('/api/posts/ai/caption-jobs/' + captionJob.id);
    
    if (status.status === 'completed') {
      caption = status.result;
      break;
    }
    if (status.status === 'failed') {
      throw new Error('Caption generation failed: ' + status.error);
    }
    
    await sleep(2000); // Poll every 2s
  }
  
  if (!caption) {
    throw new Error('Caption generation timed out');
  }
  
  console.log('[Workflow] Caption generated, creating post...');
  
  // Step 3: Create post with generated caption
  const post = await apiPost('/api/posts', {
    content: caption,
    platforms: [params.platform],
    scheduledAt: params.scheduledAt
  });
  
  return {
    success: true,
    postId: post.id,
    caption: caption,
    url: 'https://app.creagency.ai/dashboard/posts/' + post.id
  };
}

// Advanced Workflow 2: Cross-Post to Multiple Platforms
async function crossPostToMultiplePlatforms(params: {
  content: string;
  platforms: string[];
  scheduledAt?: string;
  assetIds?: string[];
}) {
  console.log('[Workflow] Cross-posting to ' + params.platforms.length + ' platforms...');
  
  // Step 1: Verify all platforms connected when integrations:read is available
  try {
    const accounts = await apiGet('/api/integrations/social/accounts');
    const connectedPlatforms = new Set(accounts.map((a: any) => a.platform));

    const missing = params.platforms.filter(p => !connectedPlatforms.has(p));
    if (missing.length > 0) {
      throw new Error(
        'Not connected to: ' + missing.join(', ') + '. ' +
        'Connect accounts in dashboard first.'
      );
    }
  } catch (error: any) {
    if (error?.status !== 403) {
      throw error;
    }
  }
  
  // Step 2: Create single post targeting all platforms
  const post = await apiPost('/api/posts', {
    content: params.content,
    platforms: params.platforms,
    scheduledAt: params.scheduledAt,
    assetIds: params.assetIds
  });
  
  console.log('Created cross-post: ' + post.id);
  
  return {
    success: true,
    postId: post.id,
    platforms: params.platforms,
    url: 'https://app.creagency.ai/dashboard/posts/' + post.id
  };
}

// Advanced Workflow 3: Reschedule Failed Posts
async function rescheduleFailedPosts(options?: {
  newScheduledAt?: string;
  platform?: string;
}) {
  console.log('[Workflow] Finding failed posts...');
  
  // Get all posts
  const posts = await apiGet('/api/posts?limit=100');
  
  // Filter for failed posts
  const failedPosts = posts.filter((p: any) => 
    p.status === 'failed' &&
    (!options?.platform || p.platforms.includes(options.platform))
  );

  console.log('Found ' + failedPosts.length + ' failed posts');

  let rescheduled = 0;
  let failed = 0;

  for (const post of failedPosts) {
    try {
      const newTime = options?.newScheduledAt || 
        new Date(Date.now() + 3600000).toISOString();

      await apiPatch('/api/posts/' + post.id, {
        scheduledAt: newTime
      });
      
      console.log('Rescheduled post ' + post.id);
      rescheduled++;
    } catch (err) {
      console.log('Failed to reschedule ' + post.id + ': ' + err);
      failed++;
    }
  }
  
  return { rescheduled, failed };
}

// Advanced Workflow 4: Bulk Create with Rate Limiting
async function bulkCreatePosts(postsData: Array<{
  content: string;
  platform: string;
  scheduledAt?: string;
}>) {
  console.log('[Workflow] Bulk creating ' + postsData.length + ' posts...');

  let created = 0;
  let failed = 0;
  const results: any[] = [];

  for (let i = 0; i < postsData.length; i++) {
    const data = postsData[i];
    console.log('  [' + (i + 1) + '/' + postsData.length + '] Creating post...');

    try {
      const post = await apiPost('/api/posts', {
        content: data.content,
        platforms: [data.platform],
        scheduledAt: data.scheduledAt
      });
      results.push(post);
      created++;

      // Rate limiting safety: posts limited to 10/minute
      if (i > 0 && i % 5 === 0 && i < postsData.length - 1) {
        console.log('  [Rate limit safety: pausing 10s...]');
        await sleep(10000);
      }
    } catch (err) {
      console.log('  Failed: ' + err);
      failed++;
    }
  }
  
  return { created, failed, results };
}

// Helper functions
const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
const apiGet = (path: string) => { /* ... */ return {} as any; };
const apiPost = (path: string, data: any) => { /* ... */ return {} as any; };
const apiPatch = (path: string, data: any) => { /* ... */ return {} as any; };

Platform-Specific Constraints

Validate content before sending to avoid platform rejections:

X (Twitter)

Max text: 280 characters

Max images: 4 per post

Video: 512MB max, 140s max

Images: JPEG, PNG, GIF, WebP

Instagram

Max caption: 2,200 characters

Max images: 10 per post

Video: 650MB max (feed: 60s, reels: 90s)

Images: JPEG, PNG only

LinkedIn

Max text: 3,000 characters

Max images: 20 per post

Video: 200MB max, 10 min max

Images: JPEG, PNG

YouTube

Title: 100 characters max

Description: 5,000 characters max

Video: 256GB max, 12 hours max

Formats: MP4, MOV, AVI

Quick Reference

Base URL
https://api.creagency.ai
Auth Header
Authorization: Bearer <key>
OpenAPI Spec
GET /api/open-api

Reference Implementation

Download complete, runnable reference clients to test your API key and explore all endpoints. Includes built-in test suite that verifies connectivity and demonstrates all workflows.

TypeScript Reference Client

Complete TypeScript implementation with all endpoints, workflows, and test suite. Works with Node.js 18+ or Deno.

# Install and run tests
export CREAGENCY_API_KEY=your_key
npx ts-node reference-client.ts

Location: docs/api/reference-client.ts

Python Reference Client

Complete Python implementation with dataclasses, type hints, and comprehensive test suite. Works with Python 3.9+.

# Install and run tests
export CREAGENCY_API_KEY=your_key
python reference_client.py

Location: docs/api/reference_client.py

What's Included
✓All API endpoints (Posts, Assets, Media, AI, Integrations)
✓Built-in test suite (5 automated tests)
✓Rate limit tracking and handling
✓Error handling with retry logic
✓All 4 advanced workflows (AI, cross-post, bulk, reschedule)
✓File upload with direct-to-storage pattern
✓Progress reporting helpers
✓Type-safe request/response models

Changelog

Track updates to the Creagency API and this agent skill documentation.

v1.0.02026-04-10

Initial Release

  • Complete public API coverage (Posts, Assets, Media, AI, Integrations)
  • 4 basic workflow recipes (create post, upload media, schedule, bulk)
  • 4 advanced workflows (AI caption, cross-post, reschedule failed, bulk with rate limiting)
  • Error handling decision tree with retry logic
  • Rate limiting patterns with proactive monitoring
  • Tool definition patterns for agent integration
  • Platform-specific constraints (X, Instagram, LinkedIn, YouTube)
  • Reference implementations in TypeScript and Python
  • Built-in test suites for both languages
  • Rate limits documentation by subscription plan

Planned Future Updates

  • Analytics API endpoints (post metrics, account insights)
  • Team management endpoints (invitations, role changes)
  • Advanced scheduling (recurring posts, best-time recommendations)
  • Webhook integration patterns for real-time updates
  • Batch operations API (when available)

Related Documentation