> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/darkzOGx/youtube-automation-agent/llms.txt
> Use this file to discover all available pages before exploring further.

# Publish Content

> Manually publish content to YouTube

## 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

<ParamField path="contentId" type="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.
</ParamField>

## 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

<ResponseField name="success" type="boolean" required>
  Indicates whether publishing succeeded.
</ResponseField>

<ResponseField name="result" type="object">
  Publishing result details.

  <ResponseField name="result.videoId" type="string">
    YouTube video ID of the published content.
  </ResponseField>

  <ResponseField name="result.url" type="string">
    Full YouTube URL of the published video.
  </ResponseField>

  <ResponseField name="result.status" type="string">
    Publishing status: `"published"`, `"uploading"`, `"processing"`.
  </ResponseField>

  <ResponseField name="result.publishedAt" type="string">
    ISO 8601 timestamp when the video was published.
  </ResponseField>
</ResponseField>

<ResponseField name="error" type="string">
  Error message if `success` is `false`.
</ResponseField>

## Example Requests

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST http://localhost:3456/publish/content_1234567890abcdef \
    -H "Content-Type: application/json"
  ```

  ```javascript JavaScript (Fetch) theme={null}
  const contentId = 'content_1234567890abcdef';

  const response = await fetch(`http://localhost:3456/publish/${contentId}`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    }
  });

  const result = await response.json();

  if (result.success) {
    console.log('Published:', result.result.url);
  } else {
    console.error('Error:', result.error);
  }
  ```

  ```python Python theme={null}
  import requests

  content_id = 'content_1234567890abcdef'

  response = requests.post(
      f'http://localhost:3456/publish/{content_id}',
      headers={'Content-Type': 'application/json'}
  )

  result = response.json()

  if result['success']:
      print(f"Video published: {result['result']['url']}")
  else:
      print(f"Error: {result['error']}")
  ```
</CodeGroup>

## Example Response

### Success

```json theme={null}
{
  "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

```json theme={null}
{
  "success": false,
  "error": "Content not found: content_invalid123"
}
```

### Error - Already Published

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

### Error - API Failure

```json theme={null}
{
  "success": false,
  "error": "YouTube API error: Daily upload limit exceeded"
}
```

## Response Codes

| Status Code | Description                                          |
| ----------- | ---------------------------------------------------- |
| 200         | Publishing request processed (check `success` field) |
| 500         | Server 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

<Note>
  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.
</Note>

## Use Cases

### Immediate Publishing

Publish breaking news or time-sensitive content immediately:

```bash theme={null}
# 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:

```javascript theme={null}
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:

```python theme={null}
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:

```javascript theme={null}
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:

| Error                   | Cause                                   | Solution                                  |
| ----------------------- | --------------------------------------- | ----------------------------------------- |
| Content not found       | Invalid `contentId`                     | Verify ID from `/schedule` or `/generate` |
| Already published       | Content was previously published        | Check database or use different content   |
| Invalid credentials     | YouTube API credentials missing/expired | Run `npm run credentials:setup`           |
| Upload limit exceeded   | Daily YouTube upload quota reached      | Wait 24 hours or upgrade quota            |
| File not found          | Video file missing from storage         | Regenerate content                        |
| Thumbnail upload failed | Thumbnail file corrupted                | Regenerate thumbnail                      |

## Important Notes

<Warning>
  Manually publishing content will bypass the automated scheduling system. The content will be removed from the schedule and marked as published in the database.
</Warning>

<Note>
  Make sure your YouTube channel is properly verified and has no strikes. Channels with restrictions may experience publishing failures.
</Note>

## 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.
