API Reference

v1

Schedule, update, publish, and manage posts programmatically across Threads, TikTok, YouTube, X, LinkedIn, Bluesky, Pinterest, Instagram, Facebook, and Reddit.

Authentication

All API requests require an authenticated session. Sign in at viral-cat.com with your Google account. Requests use cookie-based session authentication (NextAuth).

// All requests must include your session cookie.
// Use the same browser session or forward cookies from your client.
//
// Unauthenticated requests return:
{ "error": "Unauthorized" }   // 401

Base URL: https://viral-cat.com/api

Posts

Create, read, update, and delete scheduled posts. Each post targets one platform.

GET/api/posts

List scheduled posts. Optionally filter by month/year and brand. Add ?summary=true for count + next-scheduled-date only.

Query Parameters

month   number   optional   1-12
year    number   optional   e.g. 2026
brandId string   optional   filter by brand
summary boolean  optional   returns count aggregates only

Response

{
  "success": true,
  "scheduledVideos": [
    {
      "id": 42,
      "platform": "youtube",
      "caption": "Check this out!",
      "scheduledDate": "2026-06-15T07:00:00.000Z",
      "status": "scheduled",
      "videoFileName": "promo.mp4",
      "googleDriveFileId": "1abc...",
      "brandId": "brand_123",
      "ctaUrl": "https://example.com",
      "hashtags": ["#viral", "#ai"]
    }
  ]
}
POST/api/posts

Schedule a new post. Creates one row per platform. Platforms that already have a scheduled post for the same brand + day are skipped (dedup). Incompatible media/platform combos are filtered automatically.

Request Body

{
  "caption": "My awesome post",
  "scheduledDate": "2026-06-15T07:00:00.000Z",
  "scheduledTime": "07:00",
  "platforms": ["youtube", "twitter", "threads"],
  "googleDriveFileId": "1abc...",
  "videoFileName": "promo.mp4",
  "ctaUrl": "https://example.com",
  "hashtags": ["#viral"],
  "brandId": "brand_123"
}

Response

{
  "success": true,
  "posts": [
    { "id": 43, "platform": "youtube", "status": "scheduled" },
    { "id": 44, "platform": "threads", "status": "scheduled" }
  ]
}

// 402 when monthly post limit reached (includes upgrade URL)
PUT/api/posts

Update a scheduled post. Only posts with status 'scheduled' can be edited. Returns 409 if the post has already been published or is currently posting.

Request Body

{
  "id": 43,
  "caption": "Updated caption",
  "scheduledDate": "2026-06-16T09:00:00.000Z",
  "scheduledTime": "09:00",
  "platform": "youtube",
  "ctaUrl": "https://example.com",
  "hashtags": ["#updated"],
  "videoFileName": "promo.mp4",
  "googleDriveFileId": "1abc..."
}

Response

{
  "success": true,
  "scheduledVideo": { "id": 43, "status": "scheduled" }
}

// 409 if post is not in "scheduled" status
DELETE/api/posts?id=43

Delete a scheduled post by ID. Drive files are never deleted; only the DB row is removed.

Response

{
  "success": true,
  "message": "Scheduled video deleted successfully"
}
PATCH/api/posts

Batch assign a brand to multiple posts (up to 500).

Request Body

{
  "ids": [43, 44, 45],
  "brandId": "brand_123"
}

Response

{ "success": true, "updated": 3 }

Publishing

Trigger immediate publishing. Server-side rate limiting (5s per platform) is enforced automatically.

POST/api/posts/publish

Publish a post immediately. Accepts scheduled, posting (resume), and failed (retry) statuses. Returns 422 on publish failure with error details.

Request Body

{ "videoId": 43 }

Response

// Success
{
  "success": true,
  "result": { "success": true, "postUrl": "https://..." }
}

// Failure (422)
{
  "success": false,
  "result": { "success": false, "error": "Token expired" }
}

Skip / Restore Days

Skip auto-posting for a brand on a specific day, or restore a previously skipped day.

POST/api/posts/skip

Skip a brand's auto-post for a given day. Idempotent: re-skipping the same day is a no-op.

Request Body

{
  "brandId": "brand_123",
  "date": "2026-06-15"
}

Response

{ "success": true, "created": 1 }
DELETE/api/posts/skip

Restore a skipped day. Cancelled posts are re-scheduled; skip markers are removed.

Request Body

{
  "brandId": "brand_123",
  "date": "2026-06-15"
}

Response

{ "success": true, "restored": 1, "deleted": 0 }

Post Bundles

Manage multi-platform post bundles. A bundle is a group of posts sharing the same content, scheduled for the same day across different platforms.

PUT/api/posts/bundle

Update a bundle. Provide the full desired state: existing posts are updated, new platforms are added, and removed platforms are deleted. Orphan rows from race conditions are cleaned up automatically.

Request Body

{
  "postIds": [43, 44],
  "caption": "Shared caption across platforms",
  "ctaUrl": "https://example.com",
  "platforms": [
    { "postId": 43, "platform": "youtube", "scheduledDate": "2026-06-15T07:00:00Z" },
    { "postId": 44, "platform": "threads", "scheduledDate": "2026-06-15T07:00:00Z" },
    { "platform": "twitter", "scheduledDate": "2026-06-15T07:00:00Z" }
  ]
}

Response

{ "success": true }
DELETE/api/posts/bundle

Delete all posts in a bundle.

Request Body

{ "postIds": [43, 44, 45] }

Response

{ "success": true, "deleted": 3 }

Platforms

Check connection status for all linked platforms.

GET/api/platforms/status

Get connection status for all platforms. Returns which platforms are connected, token validity, and last-checked timestamps.

Response

{
  "statuses": {
    "youtube": { "connected": true, "valid": true },
    "tiktok": { "connected": true, "valid": true },
    "twitter": { "connected": false }
  }
}
POST/api/platforms/status

Run a health check across all connected platforms. Validates tokens and refreshes expired ones.

Response

{
  "health_check": {
    "youtube": { "healthy": true },
    "tiktok": { "healthy": true, "refreshed": true }
  }
}

TikTok Draft Status

TikTok posts are published as inbox drafts. Poll for approval status.

POST/api/posts/tiktok-status

Check the status of pending TikTok drafts. Updates post URLs when drafts are approved and published. Marks posts as failed if TikTok rejects them.

Response

{
  "updated": 1,
  "pending": 2,
  "results": [
    { "id": 50, "status": "PUBLISHED", "url": "https://tiktok.com/..." },
    { "id": 51, "status": "PROCESSING_DOWNLOAD" }
  ]
}

Supported Platforms

YouTube

Video

TikTok

Video (draft)

Instagram

Image, Video

Threads

Image, Video, Text

X

Text (OG card)

LinkedIn

Image, Video

Bluesky

Image, Text

Pinterest

Image

Facebook

Image, Video

Reddit

Text, Link

Rate Limits & Errors

Publishing cooldown

5-second per-platform delay enforced server-side. No client-side throttling needed.

Post limits

Monthly post limits are enforced per subscription tier. A 402 response includes an upgradeUrl.

Error codes

400Bad request / missing fields401Not authenticated402Plan limit reached404Post not found409Post not editable (already published / posting)422Publish failed (platform error)500Internal error