Skip to main content
POST
/
publish
/
:contentId
Publish Content
curl --request POST \
  --url https://api.example.com/publish/:contentId
{
  "success": true,
  "result": {
    "result.videoId": "<string>",
    "result.url": "<string>",
    "result.status": "<string>",
    "result.publishedAt": "<string>"
  },
  "error": "<string>"
}

Endpoint

POST /publish/:contentId

Description

Manually publishes previously generated content to YouTube, bypassing the automated schedule. This is useful for immediate publishing or when you want to control the exact timing of content release.

Path Parameters

contentId
string
required
The unique identifier of the content to publish. This ID is returned from the /generate endpoint or can be retrieved from the /schedule endpoint.

Request Body

No request body required. All content details (title, description, tags, thumbnail) are retrieved from the database using the contentId.

Headers

Content-Type: application/json

Response

success
boolean
required
Indicates whether publishing succeeded.
result
object
Publishing result details.
result.videoId
string
YouTube video ID of the published content.
result.url
string
Full YouTube URL of the published video.
result.status
string
Publishing status: "published", "uploading", "processing".
result.publishedAt
string
ISO 8601 timestamp when the video was published.
error
string
Error message if success is false.

Example Requests

curl -X POST http://localhost:3456/publish/content_1234567890abcdef \
  -H "Content-Type: application/json"

Example Response

Success

{
  "success": true,
  "result": {
    "videoId": "dQw4w9WgXcQ",
    "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
    "status": "published",
    "publishedAt": "2026-03-05T10:45:30.123Z",
    "title": "Master React Hooks in 10 Minutes - Complete Guide for Beginners",
    "visibility": "public"
  }
}

Error - Content Not Found

{
  "success": false,
  "error": "Content not found: content_invalid123"
}

Error - Already Published

{
  "success": false,
  "error": "Content already published: https://www.youtube.com/watch?v=dQw4w9WgXcQ"
}

Error - API Failure

{
  "success": false,
  "error": "YouTube API error: Daily upload limit exceeded"
}

Response Codes

Status CodeDescription
200Publishing request processed (check success field)
500Server error during publishing

Publishing Process

When you call this endpoint, the Publishing & Scheduling Agent:
  1. Retrieves Content - Fetches content data from the database
  2. Prepares Upload - Packages video file, thumbnail, and metadata
  3. Authenticates - Uses YouTube API credentials
  4. Uploads Video - Transfers video file to YouTube
  5. Sets Metadata - Applies title, description, tags, and thumbnail
  6. Publishes - Makes the video public (or scheduled visibility)
  7. Updates Database - Marks content as published with video ID
Video upload and processing can take several minutes depending on file size and YouTube’s processing queue. The endpoint returns once the upload is initiated, but the video may still be processing on YouTube’s end.

Use Cases

Immediate Publishing

Publish breaking news or time-sensitive content immediately:
# Generate content
RESPONSE=$(curl -s -X POST http://localhost:3456/generate \
  -H "Content-Type: application/json" \
  -d '{"topic": "Breaking: Major Tech Announcement"}')

# Extract content ID
CONTENT_ID=$(echo $RESPONSE | jq -r '.result.contentId')

# Publish immediately
curl -X POST http://localhost:3456/publish/$CONTENT_ID \
  -H "Content-Type: application/json"

Workflow Integration

Integrate with content approval workflows:
async function approvalWorkflow(contentId) {
  // Get content details
  const scheduleResponse = await fetch('http://localhost:3456/schedule');
  const schedule = await scheduleResponse.json();
  const content = schedule.find(item => item.contentId === contentId);
  
  // Show to human reviewer
  console.log('Review content:', content.title);
  const approved = await getUserApproval(); // Your approval UI
  
  if (approved) {
    // Publish immediately
    const publishResponse = await fetch(
      `http://localhost:3456/publish/${contentId}`,
      { method: 'POST', headers: { 'Content-Type': 'application/json' } }
    );
    
    const result = await publishResponse.json();
    
    if (result.success) {
      console.log('✅ Published:', result.result.url);
      // Notify team, update CMS, etc.
    }
  }
}

Batch Publishing

Publish multiple pieces of content at once:
import requests
import time

def batch_publish(content_ids):
    results = []
    
    for content_id in content_ids:
        response = requests.post(
            f'http://localhost:3456/publish/{content_id}',
            headers={'Content-Type': 'application/json'}
        )
        
        result = response.json()
        results.append(result)
        
        if result['success']:
            print(f"✅ Published: {result['result']['title']}")
        else:
            print(f"❌ Failed: {result['error']}")
        
        # Wait between uploads to avoid rate limits
        time.sleep(60)
    
    return results

# Publish 3 videos
batch_publish([
    'content_abc123',
    'content_def456',
    'content_ghi789'
])

Scheduled Publishing Override

Publish content earlier than scheduled:
async function publishEarly(contentId) {
  // Check current schedule
  const scheduleResponse = await fetch('http://localhost:3456/schedule');
  const schedule = await scheduleResponse.json();
  const content = schedule.find(item => item.contentId === contentId);
  
  const scheduledTime = new Date(content.scheduledPublishTime);
  console.log(`Originally scheduled for: ${scheduledTime}`);
  
  // Publish now
  const publishResponse = await fetch(
    `http://localhost:3456/publish/${contentId}`,
    { method: 'POST', headers: { 'Content-Type': 'application/json' } }
  );
  
  const result = await publishResponse.json();
  console.log(`Published early: ${result.result.url}`);
}

Error Handling

Common errors and solutions:
ErrorCauseSolution
Content not foundInvalid contentIdVerify ID from /schedule or /generate
Already publishedContent was previously publishedCheck database or use different content
Invalid credentialsYouTube API credentials missing/expiredRun npm run credentials:setup
Upload limit exceededDaily YouTube upload quota reachedWait 24 hours or upgrade quota
File not foundVideo file missing from storageRegenerate content
Thumbnail upload failedThumbnail file corruptedRegenerate thumbnail

Important Notes

Manually publishing content will bypass the automated scheduling system. The content will be removed from the schedule and marked as published in the database.
Make sure your YouTube channel is properly verified and has no strikes. Channels with restrictions may experience publishing failures.

Rate Limits

YouTube API has the following limits:
  • Daily upload quota: Varies by channel (typically 6-50 videos/day)
  • API quota: 10,000 units/day (publishing uses ~1,600 units)
  • Concurrent uploads: 1 at a time recommended
The agent automatically handles rate limiting and will queue uploads if necessary.