> ## Documentation Index
> Fetch the complete documentation index at: https://heygen-1fa696a7.mintlify.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Automated Broadcast

> Run scheduled video broadcasts - news roundups, daily briefings, market updates. The HeyGen API generates each clip on a cron schedule from fresh data inputs.

## The Problem

Publishing regular video content — daily news roundups, weekly company updates, recurring educational series — is unsustainable without a production team. But consistency is what builds an audience.

## How It Works

```
Schedule triggers → Aggregate content → LLM writes script → Video Agent renders → Auto-distribute
```

A fully automated pipeline that runs on a schedule, collects fresh content from your sources, generates a video, and delivers it to your audience — no human in the loop.

## Build It

<Steps>
  <Step title="Set up content aggregation">
    Pull content from whatever sources feed your broadcast.

    ```python theme={null}
    import requests
    from datetime import datetime

    def aggregate_content():
        stories = []

        # RSS feeds
        import feedparser
        feed = feedparser.parse("https://news.ycombinator.com/rss")
        for entry in feed.entries[:5]:
            stories.append({
                "title": entry.title,
                "summary": entry.get("summary", ""),
                "source": "Hacker News",
                "url": entry.link,
            })

        # APIs (example: your internal metrics)
        metrics = requests.get("https://api.yourapp.com/weekly-stats").json()
        stories.append({
            "title": f"This week: {metrics['new_users']} new users, {metrics['revenue']} revenue",
            "summary": f"Growth of {metrics['growth_pct']}% week over week",
            "source": "Internal",
        })

        return stories

    stories = aggregate_content()
    ```
  </Step>

  <Step title="Generate a video script with an LLM">
    ```python theme={null}
    import anthropic

    client = anthropic.Anthropic()

    story_text = "\n".join(
        f"- {s['title']} ({s['source']}): {s['summary']}"
        for s in stories
    )

    message = client.messages.create(
        model="claude-sonnet-4-20250514",
        max_tokens=1500,
        messages=[{
            "role": "user",
            "content": f"""Create a HeyGen Video Agent prompt for a 60-second
    news/update video.

    Date: {datetime.now().strftime('%B %d, %Y')}

    Stories to cover:
    {story_text}

    Structure:
    - Intro (5s): "Here's your [daily/weekly] update for [date]"
    - Stories (45s): Cover the top 3 stories with text overlays for key stats
    - Sign-off (10s): "That's your update. See you [tomorrow/next week]."

    Tone: Authoritative but approachable. Clean, news-desk style background.
    Keep pacing brisk — one story every 15 seconds."""
        }],
    )
    video_prompt = message.content[0].text
    ```
  </Step>

  <Step title="Generate the video">
    ```python theme={null}
    resp = requests.post(
        "https://api.heygen.com/v3/video-agents",
        headers={
            "X-Api-Key": HEYGEN_API_KEY,
            "Content-Type": "application/json",
        },
        json={"prompt": video_prompt},
    )
    video_id = resp.json()["data"]["video_id"]

    # Poll until complete
    import time
    while True:
        status = requests.get(
            f"https://api.heygen.com/v3/videos/{video_id}",
            headers={"X-Api-Key": HEYGEN_API_KEY},
        ).json()["data"]

        if status["status"] == "completed":
            video_url = status["video_url"]
            break
        elif status["status"] == "failed":
            raise Exception(f"Video failed: {status.get('failure_message')}")

        time.sleep(15)
    ```
  </Step>

  <Step title="Distribute automatically">
    Deliver the video to your audience wherever they are.

    ```python theme={null}
    # Telegram
    import telegram
    bot = telegram.Bot(token=TELEGRAM_TOKEN)
    bot.send_video(chat_id=CHANNEL_ID, video=video_url, caption="Daily Update")

    # Slack
    requests.post(SLACK_WEBHOOK, json={
        "text": f"Daily update is ready: {video_url}",
    })

    # Email (via your ESP)
    send_email(
        to=subscriber_list,
        subject=f"Your Daily Update — {datetime.now().strftime('%B %d')}",
        html=f'<a href="{video_url}"><img src="{thumbnail_url}"></a>',
    )
    ```
  </Step>

  <Step title="Schedule it">
    Run the pipeline on a schedule using cron, GitHub Actions, or a cloud function.

    ```yaml theme={null}
    # .github/workflows/daily-broadcast.yml
    name: Daily Video Broadcast
    on:
      schedule:
        - cron: '0 17 * * 1-5'  # 5 PM UTC, weekdays
    jobs:
      broadcast:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - run: pip install -r requirements.txt
          - run: python broadcast.py
            env:
              HEYGEN_API_KEY: ${{ secrets.HEYGEN_API_KEY }}
              ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
              TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }}
    ```
  </Step>
</Steps>

## Real-World Example

STUDIO 47, a German broadcaster, reported these results after adopting HeyGen for automated video production (via [HeyGen customer stories](https://www.heygen.com/customer-stories/studio-47)):

* Significantly faster content creation
* 24/7 production capability
* Substantial cost reduction vs traditional production
* Expanded into multilingual content that wasn't feasible before

## Resilient Delivery

Build fallbacks for when things go wrong:

```python theme={null}
def deliver(video_url, caption):
    try:
        # Try primary: send video by URL
        bot.send_video(chat_id=CHANNEL_ID, video=video_url, caption=caption)
    except Exception:
        try:
            # Fallback: download and upload as file
            video_data = requests.get(video_url).content
            bot.send_video(chat_id=CHANNEL_ID, video=video_data, caption=caption)
        except Exception:
            # Last resort: send text with link
            bot.send_message(chat_id=CHANNEL_ID, text=f"{caption}\n\n{video_url}")
```

## Broadcast Types

| Type                  | Schedule       | Content source                   | Duration |
| --------------------- | -------------- | -------------------------------- | -------- |
| **Daily news**        | Every morning  | RSS, APIs, web scrape            | 45–60s   |
| **Weekly roundup**    | Monday morning | Internal metrics + industry news | 90s      |
| **Product changelog** | Each release   | Git commits, release notes       | 30–45s   |
| **Company all-hands** | Weekly/monthly | Meeting notes, updates           | 60–90s   |
| **Social digest**     | Daily          | Trending topics in your niche    | 30s      |

## Variations

* **Multi-language:** Generate once, [translate](/cookbook/video-agent/multilingual-content) for regional audiences
* **Different avatars per topic:** Use different presenters for different content categories
* **Audience segmentation:** Generate different versions for different subscriber segments

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Content Repurposing" icon="recycle" href="/cookbook/video-agent/content-repurposing">
    Repurpose existing content instead of aggregating new content.
  </Card>

  <Card title="Docs to Video" icon="file-lines" href="/cookbook/video-agent/docs-to-video">
    Trigger video generation from code changes instead of a schedule.
  </Card>
</CardGroup>
