Skill: javainthinking/2slides-skills (version 1.0.0)

--- name: 2slides description: AI-powered presentation generation using 2slides API. Create slides from text content, match reference image styles, or summarize documents into presentations. Use when users request to "create a presentation", "make slides", "generate a deck", "create slides from this content/document/image", or any presentation creation task. Supports theme selection, multiple languages, and both synchronous and asynchronous generation modes. --- # 2slides Presentation Generation Generate professional presentations using the 2slides AI API. Supports content-based generation, style matching from reference images, and document summarization. ## Setup Requirements Users must have a 2slides API key and credits: 1. **Get API Key:** Visit https://2slides.com/api to create an account and API key - New users receive **500 free credits** (~50 Fast PPT pages) 2. **Purchase Credits (Optional):** Visit https://2slides.com/pricing to buy additional credits - Pay-as-you-go, no subscriptions - Credits never expire - Up to 20% off on larger packages 3. **Set API Key:** Store the key in environment variable: `SLIDES_2SLIDES_API_KEY` ```bash export SLIDES_2SLIDES_API_KEY="your_api_key_here" ``` **Credit Costs:** - Fast PPT: 10 credits/page - Nano Banana 1K/2K: 100 credits/page - Nano Banana 4K: 200 credits/page - Voice Narration: 210 credits/page - Download Export: FREE See [references/pricing.md](references/pricing.md) for detailed pricing information. ## Workflow Decision Tree Choose the appropriate approach based on the user's request: ``` User Request │ ├─ "Create slides from this content/text" │ └─> Use Content-Based Generation (Section 1) │ ├─ "Create slides like this image" │ └─> Use Reference Image Generation (Section 2) │ ├─ "Create custom designed slides" or "Create PDF slides" │ └─> Use Custom PDF Generation (Section 3) │ ├─ "Create slides from this document" │ └─> Use Document Summarization (Section 4) │ ├─ "Add voice narration" or "Generate audio for slides" │ └─> Use Voice Narration (Section 5) │ ├─ "Download slides as images" or "Export slides and voices" │ └─> Use Download Export (Section 6) │ └─ "Search for themes" or "What themes are available?" └─> Use Theme Search (Section 7) ``` --- ## 1. Content-Based Generation Generate slides from user-provided text content. ### When to Use - User provides content directly in their message - User says "create a presentation about X" - User provides structured outline or bullet points ### Workflow **Step 1: Prepare Content** Structure the content clearly for best results: ``` Title: [Main Topic] Section 1: [Subtopic] - Key point 1 - Key point 2 - Key point 3 Section 2: [Subtopic] - Key point 1 - Key point 2 ``` **Step 2: Choose Theme (Required)** Search for an appropriate theme (themeId is required): ```bash python scripts/search_themes.py --query "business" python scripts/search_themes.py --query "professional" python scripts/search_themes.py --query "creative" ``` Pick a theme ID from the results. **Step 3: Generate Slides** Use the `generate_slides.py` script with the theme ID: ```bash # Basic generation (theme ID required) python scripts/generate_slides.py --content "Your content here" --theme-id "theme123" # In different language python scripts/generate_slides.py --content "Your content" --theme-id "theme123" --language "Spanish" # Async mode for longer presentations python scripts/generate_slides.py --content "Your content" --theme-id "theme123" --mode async ``` **Step 4: Handle Results** **Sync mode response:** ```json { "slideUrl": "https://2slides.com/slides/abc123", "pdfUrl": "https://2slides.com/slides/abc123/download", "status": "completed" } ``` Provide both URLs to the user: - `slideUrl`: Interactive online slides - `pdfUrl`: Downloadable PDF version **Async mode response:** ```json { "jobId": "job123", "status": "pending" } ``` Poll for results: ```bash python scripts/get_job_status.py --job-id "job123" ``` --- ## 2. Reference Image Generation Generate slides that match the style of a reference image. ### When to Use - User provides an image URL and says "create slides like this" - User wants to match existing brand/design style - User has a template image they want to emulate ### Workflow **Step 1: Verify Image URL** Ensure the reference image is: - Publicly accessible URL - Valid image format (PNG, JPG, etc.) - Represents the desired slide style **Step 2: Generate Slides** Use the `generate_slides.py` script with `--reference-image`: ```bash python scripts/generate_slides.py \ --content "Your presentation content" \ --reference-image "https://example.com/template.jpg" \ --language "Auto" ``` **Optional parameters:** ```bash --aspect-ratio "16:9" # width:height format (e.g., "16:9", "4:3") --resolution "2K" # "1K", "2K" (default), or "4K" --page 5 # Number of slides (0 for auto-detection, max 100) --content-detail "concise" # "concise" (brief) or "standard" (detailed) ``` **Note:** This uses Nano Banana Pro mode with credit costs: - 1K/2K: 100 credits per page - 4K: 200 credits per page **Step 3: Handle Results** This mode always runs synchronously and returns: ```json { "slideUrl": "https://2slides.com/workspace?jobId=...", "pdfUrl": "https://...pdf...", "status": "completed", "message": "Successfully generated N slides", "slidePageCount": N } ``` Provide both URLs to the user: - `slideUrl`: View slides in 2slides workspace - `pdfUrl`: Direct PDF download (expires in 1 hour) **Processing time:** ~30 seconds per page (30-60 seconds typical for 1-2 pages) --- ## 3. Custom PDF Generation Generate custom-designed slides from text without needing a reference image. ### When to Use - User wants custom design without providing a reference image - User requests "create PDF slides" - User wants to specify design characteristics - Alternative to theme-based generation with more design flexibility ### Workflow **Step 1: Prepare Content** Structure the content clearly: ``` Title: [Main Topic] Section 1: [Subtopic] - Key point 1 - Key point 2 Section 2: [Subtopic] - Key point 1 - Key point 2 ``` **Step 2: Generate Slides** Use the `create_pdf_slides.py` script: ```bash # Basic generation python scripts/create_pdf_slides.py --content "Your content here" # With design specifications python scripts/create_pdf_slides.py \ --content "Sales Report Q4 2025" \ --design-spec "modern minimalist, blue color scheme" # High resolution with auto page detection python scripts/create_pdf_slides.py \ --content "Marketing Plan" \ --resolution "4K" \ --page 0 \ --content-detail "standard" ``` **Optional parameters:** ```bash --design-spec "text" # Design specifications (e.g., "corporate professional") --aspect-ratio "16:9" # width:height format --resolution "2K" # "1K", "2K" (default), or "4K" --page 5 # Number of slides (0 for auto-detection, max 100) --content-detail "concise" # "concise" (brief) or "standard" (detailed) --language "Auto" # Language for content ``` **Step 3: Handle Results** Returns same structure as create-like-this: ```json { "slideUrl": "https://2slides.com/workspace?jobId=...", "pdfUrl": "https://...pdf...", "status": "completed", "message": "Successfully generated N slides", "slidePageCount": N } ``` **Notes:** - Same credit costs as create-like-this (100 credits/page for 1K/2K, 200 for 4K) - Processing time: ~30 seconds per page - Automatically generates PDF - Uses AI to create custom design based on content and specs --- ## 4. Document Summarization Generate slides from document content. ### When to Use - User uploads a document (PDF, DOCX, TXT, etc.) - User says "create slides from this document" - User wants to summarize long content into presentation format ### Workflow **Step 1: Read Document** Use appropriate tool to read the document content: - PDF: Use PDF reading tools - DOCX: Use DOCX reading tools - TXT/MD: Use Read tool **Step 2: Extract Key Points** Analyze the document and extract: - Main topics and themes - Key points for each section - Important data, quotes, or examples - Logical flow and structure **Step 3: Structure Content** Format extracted information into presentation structure: ``` Title: [Document Main Topic] Introduction - Context - Purpose - Overview [Section 1 from document] - Key point 1 - Key point 2 - Supporting detail [Section 2 from document] - Key point 1 - Key point 2 - Supporting detail Conclusion - Summary - Key takeaways - Next steps ``` **Step 4: Generate Slides** Use content-based generation workflow (Section 1). First search for a theme, then generate: ```bash # Search for appropriate theme python scripts/search_themes.py --query "business" # Generate with theme ID python scripts/generate_slides.py --content "[Structured content from step 3]" --theme-id "theme123" ``` **Tips:** - Keep slides concise (3-5 points per slide) - Focus on key insights, not full text - Use document headings as slide titles - Include important statistics or quotes - Ask user if they want specific sections highlighted --- ## 5. Voice Narration Add AI-generated voice narration to slides. ### When to Use - User wants to add audio to slides - User requests "add voice narration" or "generate audio" - User wants presentations with spoken content - User needs multi-speaker narration ### Prerequisites **IMPORTANT:** The slide generation job must be completed before adding narration. 1. Generate slides first using any method (Section 1, 2, 3, or 4) 2. Get the job ID from the generation result 3. Ensure job status is "completed" before requesting narration ### Workflow **Step 1: Choose Voice** 30 voices available including: - Puck (default) - Aoede - Charon - Kore - Fenrir - Phoebe - And 24 more... List all voices: ```bash python scripts/generate_narration.py --list-voices ``` **Step 2: Generate Narration** Use the `generate_narration.py` script with the job ID: ```bash # Basic narration with default voice python scripts/generate_narration.py --job-id "abc-123-def-456" # With specific voice python scripts/generate_narration.py --job-id "abc-123-def-456" --voice "Aoede" # Multi-speaker mode python scripts/generate_narration.py --job-id "abc-123-def-456" --multi-speaker # In specific language python scripts/generate_narration.py \ --job-id "abc-123-def-456" \ --language "Spanish" \ --voice "Charon" ``` **Parameters:** - `--job-id`: Job ID from slide generation (required, must be UUID format for Nano Banana) - `--voice`: Voice name (default: "Puck") - `--multi-speaker`: Enable multi-speaker mode (default: off) - `--language`: Language for narration (default: "Auto") **Step 3: Check Status** Narration generation runs asynchronously: ```bash python scripts/get_job_status.py --job-id "abc-123-def-456" ``` **Step 4: Handle Results** Once completed, the job will include narration files. Use download endpoint (Section 6) to get audio files. **Notes:** - **Cost:** 210 credits per page (10 for text, 200 for audio) - Processing time varies by slide count - 30 voice options available - Supports 19 languages plus auto-detection - Multi-speaker mode uses different voices for variety --- ## 6. Download Export Download slides as PNG images and voice narrations as WAV files. ### When to Use - User wants to download slides as images - User needs voice files separately - User wants transcripts - User needs slides in image format for other tools ### Workflow **Step 1: Verify Job Complete** Ensure slides (and optionally narration) are generated and job is completed. **Step 2: Download Archive** Use the `download_slides_pages_voices.py` script: ```bash # Download with default filename (<job_id>.zip) python scripts/download_slides_pages_voices.py --job-id "abc-123-def-456" # Download to specific path python scripts/download_slides_pages_voices.py \ --job-id "abc-123-def-456" \ --output "my-presentation.zip" ``` **Step 3: Extract Contents** The ZIP archive contains: - **Pages:** PNG files for each slide - **Voices:** WAV audio files (if narration was generated) - **Transcripts:** Text transcripts of narration **Notes:** - **Cost:** Completely FREE (no credits used) - Download URLs valid for **1 hour only** - Includes all pages and voice files - High quality PNG export - WAV format for audio --- ## 7. Theme Search Find appropriate themes for presentations. ### When to Use - Before generating slides with specific styling - User asks "what themes are available?" - User wants professional or branded appearance ### Workflow **Search themes:** ```bash # Search for specific style (query is required) python scripts/search_themes.py --query "business" python scripts/search_themes.py --query "creative" python scripts/search_themes.py --query "education" python scripts/search_themes.py --query "professional" # Get more results python scripts/search_themes.py --query "modern" --limit 50 ``` **Theme selection:** 1. Show user available themes with names and descriptions 2. Ask user to choose or let them use default 3. Use the theme ID in generation request --- ## Using the MCP Server If the 2slides MCP server is configured in Claude Desktop, use the integrated tools instead of scripts. **Two Configuration Modes:** 1. **Streamable HTTP Protocol (Recommended)** - Simplest setup, no local installation - Configure: `"url": "https://2slides.com/api/mcp?[REDACTED_SECRET]"` 2. **NPM Package (stdio)** - Uses local npm package - Configure: `"command": "npx", "args": ["2slides-mcp"]` **Available MCP tools:** - `slides_generate` - Generate slides from content - `slides_create_like_this` - Generate from reference image - `themes_search` - Search themes - `jobs_get` - Check job status See [mcp-integration.md](references/mcp-integration.md) for complete setup instructions and detailed tool documentation. **When to use MCP vs scripts:** - **Use MCP** in Claude Desktop when configured - **Use scripts** in Claude Code CLI or when MCP not available --- ## Advanced Features ### Sync vs Async Mode **Sync Mode (default):** - Waits for generation to complete (30-60 seconds) - Returns results immediately - Best for quick presentations **Async Mode:** - Returns job ID immediately - Poll for results with `get_job_status.py` - Best for large presentations or batch processing - **Recommended polling:** Check every 20-30 seconds to avoid server strain ### Rate Limits Different endpoints have different rate limits: - **Fast PPT (generate):** 10 requests per minute - **Nano Banana (create-like-this, create-pdf-slides):** 6 requests per minute If rate limited, wait before retrying or check plan limits. ### Credit Costs - **Fast PPT (generate endpoint):** 10 credits per page - **Nano Banana 1K/2K (create-like-this, create-pdf-slides):** 100 credits per page - **Nano Banana 4K:** 200 credits per page - **Voice Narration:** 210 credits per page (10 for text, 200 for audio) - **Download Export:** FREE (no credits) ### Purchasing Credits 2slides uses a pay-as-you-go credit system with no subscriptions required. **Credit Packages:** (Current promotion: up to 20% off) - 2,000 credits: $5.00 - 4,000 credits: $9.50 (5% off) - 10,000 credits: $22.50 (10% off) - 20,000 credits: $42.50 (15% off) - 40,000 credits: $80.00 (20% off) **New users receive 500 free credits** for onboarding (~50 Fast PPT pages). **Credits never expire** - use them at your own pace. **Purchase credits at:** https://2slides.com/pricing ### Download URL Expiration All download URLs (PDF, ZIP archives) are valid for **1 hour only**. Download files promptly after generation. ### Language Support Generate slides in multiple languages (use full language name): ```bash --language "Auto" # Automatic detection (default) --language "English" # English --language "Simplified Chinese" # 简体中文 --language "Traditional Chinese" # 繁體中文 --language "Spanish" # Español --language "French" # Français --language "German" # Deutsch --language "Japanese" # 日本語 --language "Korean" # 한국어 ``` And more: Arabic, Portuguese, Indonesian, Russian, Hindi, Vietnamese, Turkish, Polish, Italian ### Error Handling **Common error codes:** 1. **Missing API key** ``` Error: API key not found Solution: Set SLIDES_2SLIDES_API_KEY environment variable ``` 2. **RATE_LIMIT_EXCEEDED** ``` Error: 429 Too Many Requests Solution: Wait 20-30 seconds before retrying Rate limits: Fast PPT (10/min), Nano Banana (6/min) ``` 3. **INSUFFICIENT_CREDITS** ``` Error: Not enough credits Solution: Add credits at https://2slides.com/api ``` 4. **INVALID_JOB_ID** ``` Error: Job ID not found or invalid Solution: Verify job ID format (must be UUID for Nano Banana) ``` 5. **Invalid content** ``` Error: 400 Bad Request Solution: Verify content format and parameters ``` --- ## Additional Documentation ### API Reference See [api-reference.md](references/api-reference.md) for: - All endpoints and parameters - Request/response formats - Authentication details - Rate limits and best practices - Error codes and handling ### Pricing Information See [pricing.md](references/pricing.md) for: - Credit packages and pricing - Cost examples and calculations - Free trial details - Refund policy - Enterprise options --- ## Tips for Best Results **Content Structure:** - Use clear headings and subheadings - Keep bullet points concise - Limit to 3-5 points per section - Include relevant examples or data **Theme Selection:** - Theme ID is required for standard generation - Search with keywords matching presentation purpose - Common searches: "business", "professional", "creative", "education", "modern" - Each theme has unique styling and layout **Reference Images:** - Use high-quality images for best results - Can use URL or base64 encoded image - Public URL must be accessible - Consider resolution setting (1K/2K/4K) based on quality needs - Use page=0 for automatic slide count detection **Document Processing:** - Extract only key information - Don't try to fit entire document in slides - Focus on main insights and takeaways - Ask user which sections to emphasize

path: UPDATE_SUMMARY.md
content: # 2slides Skills Update Summary

Complete summary of updates based on https://2slides.com/api.md and https://2slides.com/pricing

## Update Overview

**Version:** 2.0.0
**Date:** 2026-02-10
**Sources:**
- API Documentation: https://2slides.com/api.md
- Pricing Information: https://2slides.com/pricing

---

## Major Updates

### 1. Three New Features Added

#### a) Custom PDF Slides Generation
**Script:** `scripts/create_pdf_slides.py`
- Generate custom-designed slides without reference images
- AI creates design based on content and optional design specifications
- Same quality options as image-based generation (1K/2K/4K)
- **Cost:** 100 credits/page (1K/2K), 200 credits/page (4K)

```bash
python scripts/create_pdf_slides.py --content "Sales Report" --design-spec "modern minimalist"
```

#### b) AI Voice Narration
**Script:** `scripts/generate_narration.py`
- 30 voice options (Puck, Aoede, Charon, and 27 more)
- Single and multi-speaker modes
- 19 languages supported
- **Cost:** 210 credits/page (10 for text, 200 for audio)

```bash
python scripts/generate_narration.py --job-id "abc-123" --voice "Aoede" --multi-speaker
```

#### c) Free Download Export
**Script:** `scripts/download_slides_pages_voices.py`
- Export slides as PNG images
- Export voice files as WAV format
- Includes transcripts
- **Cost:** FREE (0 credits)

```bash
python scripts/download_slides_pages_voices.py --job-id "abc-123" --output slides.zip
```

### 2. Comprehensive Pricing Information Added

#### New Pricing Documentation
Created `references/pricing.md` with complete pricing details:
- Credit packages and discounts
- Detailed cost breakdowns
- Example calculations for common scenarios
- Free trial information
- Refund policy
- Payment methods

#### Credit Packages (Current Promotion)

| Credits | Price | Discount | Cost per 1,000 |
|---------|-------|----------|----------------|
| 2,000 | $5.00 | — | $2.50 |
| 4,000 | $9.50 | 5% off | $2.38 |
| 10,000 | $22.50 | 10% off | $2.25 |
| 20,000 | $42.50 | 15% off | $2.13 |
| 40,000 | $80.00 | 20% off | $2.00 |

**Key Benefits:**
- ✅ 500 free credits for new users
- ✅ Credits never expire
- ✅ No subscriptions required
- ✅ 3-day refund window

#### Credit Costs per Feature

| Feature | Credits per Page |
|---------|-----------------|
| Fast PPT | 10 |
| Nano Banana 1K/2K | 100 |
| Nano Banana 4K | 200 |
| Voice Narration | 210 |
| Download Export | FREE |

### 3. Updated All Documentation

#### SKILL.md Updates
- ✅ Added Setup Requirements section with pricing links
- ✅ Added Purchasing Credits section
- ✅ Updated credit costs throughout
- ✅ Added 3 new workflow sections (PDF, Narration, Download)
- ✅ Enhanced error handling with credit-related errors
- ✅ Added references to pricing.md

#### api-reference.md Updates
- ✅ Added 3 new endpoint documentations
- ✅ Added Purchasing Credits section with pricing table
- ✅ Added example cost calculations
- ✅ Corrected Fast PPT cost to 10 credits/page
- ✅ Enhanced error codes

#### README.md Updates
- ✅ Added "Pricing & Credits" section
- ✅ Added free trial information (500 credits)
- ✅ Added Step 3 in "Before You Begin" for purchasing credits
- ✅ Added pricing table with examples
- ✅ Added INSUFFICIENT_CREDITS troubleshooting
- ✅ Updated version to 2.0.0

#### mcp-integration.md Updates
- ✅ Added 3 new MCP tool documentations
- ✅ Added voice options list
- ✅ Enhanced tool descriptions

#### CHANGELOG.md Updates
- ✅ Documented all new features
- ✅ Added pricing information section
- ✅ Added credit cost correction note
- ✅ Listed all modified and new files

#### New Files Created
- ✅ `references/pricing.md` - Comprehensive pricing guide
- ✅ `CHANGELOG.md` - Version history
- ✅ `UPDATE_SUMMARY.md` - This file

---

## Example Cost Calculations

### Scenario 1: Quick Business Presentation
- **Need:** 15-slide Fast PPT
- **Credits:** 150 (15 × 10)
- **Cost with largest package:** $0.30

### Scenario 2: Branded Marketing Deck
- **Need:** 20-slide Nano Banana 2K with brand image
- **Credits:** 2,000 (20 × 100)
- **Cost with largest package:** $4.00

### Scenario 3: Training Presentation with Audio
- **Need:** 30-slide 2K with voice narration
- **Credits:** 6,300
  - Slides: 3,000 (30 × 100)
  - Narration: 3,300 (30 × 110 voice-only)
- **Cost with largest package:** $12.60

### Scenario 4: Complete Package
- **Need:** 25-slide 2K + narration + PNG/WAV export
- **Credits:** 5,250
  - Slides: 2,500 (25 × 100)
  - Narration: 2,750 (25 × 110)
  - Export: 0 (FREE)
- **Cost with largest package:** $10.50

---

## Free Trial Details

**New users get 500 free credits:**
- ~50 Fast PPT slide pages
- ~5 Nano Banana 2K pages
- ~2 Nano Banana 2K pages with full narration
- Mix and match as needed

---

## Technical Summary

### Scripts Created
1. `scripts/create_pdf_slides.py` (5.5KB) - Custom PDF generation
2. `scripts/generate_narration.py` (5.4KB) - Voice narration
3. `scripts/download_slides_pages_voices.py` (3.7KB) - Export download

### Documentation Files

| File | Status | Size | Description |
|------|--------|------|-------------|
| SKILL.md | Updated | ~500 lines | Main skill guide |
| README.md | Updated | ~370 lines | Project overview |
| references/api-reference.md | Updated | ~310 lines | API documentation |
| references/mcp-integration.md | Updated | ~210 lines | MCP setup |
| references/pricing.md | **NEW** | ~300 lines | Pricing guide |
| CHANGELOG.md | **NEW** | ~200 lines | Version history |

### Testing Results

✅ All scripts executable and tested:
- `create_pdf_slides.py --help` - Working
- `generate_narration.py --list-voices` - Working (30 voices)
- `download_slides_pages_voices.py --help` - Working
- All existing scripts still working

---

## Key Links

- **Purchase Credits:** https://2slides.com/pricing
- **API Access:** https://2slides.com/api
- **Main Website:** https://2slides.com
- **API Documentation:** https://2slides.com/api.md

---

## Migration Notes

**No breaking changes** - All existing functionality remains compatible.

**Credit Cost Correction:**
- Fast PPT was initially documented as 1 credit/slide
- Corrected to 10 credits/page based on official pricing
- This affects cost estimates but not functionality

**For existing users:**
- Continue using existing scripts as before
- New features are optional additions
- Check credit balance at https://2slides.com/api
- Purchase additional credits at https://2slides.com/pricing if needed

---

## What's Next

Users can now:
1. ✅ Generate slides with themes (Fast PPT)
2. ✅ Match reference image styles (Nano Banana)
3. ✅ Create custom PDF slides (NEW)
4. ✅ Add AI voice narration (NEW)
5. ✅ Download as PNG/WAV (NEW)
6. ✅ Search themes
7. ✅ Track job status

All with transparent, pay-as-you-go pricing and 500 free credits to start!

---

**Last Updated:** 2026-02-10
**Version:** 2.0.0


path: CHANGELOG.md
content: # Changelog - 2slides Skills Update

## Version 2.0.0 - 2026-02-10

Based on the updated API documentation from https://2slides.com/api.md

### New Features

#### 1. Custom PDF Slides Generation
- **New Script**: `scripts/create_pdf_slides.py`
- Generate custom-designed slides without needing a reference image
- AI creates design based on content and optional design specifications
- Same credit costs as create-like-this (100/200 credits per page)
- Supports all resolution options (1K, 2K, 4K)

**Usage:**
```bash
python scripts/create_pdf_slides.py --content "Sales Report" --design-spec "modern minimalist"
```

#### 2. AI Voice Narration
- **New Script**: `scripts/generate_narration.py`
- Add AI-generated voice narration to completed slides
- 30 voice options available (Puck, Aoede, Charon, and 27 more)
- Multi-speaker mode support
- 19 languages supported
- Cost: 210 credits per page (10 for text, 200 for audio)

**Usage:**
```bash
# List voices
python scripts/generate_narration.py --list-voices

# Generate narration
python scripts/generate_narration.py --job-id "abc-123" --voice "Aoede" --multi-speaker
```

#### 3. Download Export (Free)
- **New Script**: `scripts/download_slides_pages_voices.py`
- Download slides as PNG images
- Download voice narrations as WAV files
- Includes transcripts
- **Completely FREE** - no credit cost
- Download URLs valid for 1 hour

**Usage:**
```bash
python scripts/download_slides_pages_voices.py --job-id "abc-123" --output slides.zip
```

### Documentation Updates

#### SKILL.md
- Added Section 3: Custom PDF Generation workflow
- Added Section 5: Voice Narration workflow with voice options
- Added Section 6: Download Export workflow
- Updated workflow decision tree with new features
- Added rate limits section (Fast PPT: 10/min, Nano Banana: 6/min)
- Updated credit costs across all endpoints
- Added download URL expiration notice (1 hour)
- Enhanced error handling with specific error codes (INSUFFICIENT_CREDITS, INVALID_JOB_ID, RATE_LIMIT_EXCEEDED)
- Added polling recommendations (20-30 seconds)

#### api-reference.md
- Added Section 3: Create PDF Slides endpoint documentation
- Added Section 4: Generate Narration endpoint documentation
- Added Section 5: Download Slides Pages and Voices endpoint documentation
- Updated credit costs:
  - Fast PPT: 1 credit per slide (was 10)
  - Voice narration: 210 credits per page
  - Download: FREE
- Added rate limits per endpoint
- Added download URL expiration notice
- Enhanced error codes section
- Updated job status response to include narration status

#### mcp-integration.md
- Added documentation for 3 new MCP tools:
  - `slides_create_pdf_slides`
  - `slides_generate_narration`
  - `slides_download_pages_voices`
- Added note about requiring MCP server update
- Added voice options list
- Updated job status response format

#### README.md
- Updated Features section with 3 new features
- Added new scripts to Command Reference
- Expanded Generation Modes section
- Updated rate limits documentation
- Updated version to 2.0.0 with What's New section
- Enhanced Quick Start examples

### Technical Improvements

#### New Scripts (All Executable)
1. **create_pdf_slides.py** (5.5KB)
   - Custom PDF slide generation
   - Design specification support
   - Full parameter validation
   - Dynamic timeout calculation

2. **generate_narration.py** (5.4KB)
   - 30 voice options with --list-voices
   - Multi-speaker mode
   - Language selection
   - Job ID validation

3. **download_slides_pages_voices.py** (3.7KB)
   - ZIP download with progress
   - File size reporting
   - Custom output path support
   - Error handling

#### Enhanced Error Handling
- Added specific error codes from API
- Better rate limit messages
- UUID format validation for Nano Banana jobs
- Download URL expiration warnings

### Breaking Changes
None - all existing functionality remains backward compatible.

### Migration Guide
No migration needed. All new features are additive. Existing scripts and workflows continue to work as before.

### Credits & Costs Summary

| Feature | Cost |
|---------|------|
| Fast PPT (theme-based) | 10 credits/page |
| Nano Banana 1K/2K (image/custom) | 100 credits/page |
| Nano Banana 4K | 200 credits/page |
| Voice Narration | 210 credits/page |
| Download Export | **FREE** |

### Purchasing Credits

**Credit Packages** (up to 20% off promotion):
- 2,000 credits: $5.00
- 4,000 credits: $9.50 (5% off)
- 10,000 credits: $22.50 (10% off)
- 20,000 credits: $42.50 (15% off)
- 40,000 credits: $80.00 (20% off)

**Key Benefits:**
- 500 free credits for new users
- Credits never expire
- No subscriptions required
- Purchase at: https://2slides.com/pricing

### Rate Limits

| Endpoint | Limit |
|----------|-------|
| Fast PPT (generate) | 10 requests/min |
| Nano Banana (create-like-this, create-pdf-slides) | 6 requests/min |
| Voice Narration | 6 requests/min |
| Download | No limit |

### Files Modified

#### Updated Files
- `SKILL.md` - Major update with 3 new sections
- `references/api-reference.md` - Added 3 new endpoints
- `references/mcp-integration.md` - Added 3 new MCP tools
- `README.md` - Updated features, commands, examples

#### New Files
- `scripts/create_pdf_slides.py` - Custom PDF generation
- `scripts/generate_narration.py` - Voice narration
- `scripts/download_slides_pages_voices.py` - Export download
- `CHANGELOG.md` - This file

#### Unchanged Files
- `scripts/generate_slides.py` - No changes needed
- `scripts/search_themes.py` - No changes needed
- `scripts/get_job_status.py` - No changes needed (works with narration status)
- `.gitignore` - No changes needed

### Testing

All scripts tested and verified:
- ✅ `create_pdf_slides.py --help` - Working
- ✅ `generate_narration.py --list-voices` - Working (30 voices listed)
- ✅ `download_slides_pages_voices.py --help` - Working
- ✅ All scripts executable with proper permissions
- ✅ Help output formatted correctly

### Next Steps

To use the new features:

1. **Custom PDF Slides**: No additional setup needed
2. **Voice Narration**:
   - Generate slides first
   - Get job ID
   - Run narration script with job ID
   - Poll for completion
3. **Download Export**:
   - Complete slides (and optionally narration)
   - Run download script with job ID
   - Extract ZIP archive

### Support

- API Documentation: https://2slides.com/api
- Pricing & Credits: https://2slides.com/pricing
- Skill Documentation: See SKILL.md
- API Reference: See references/api-reference.md
- MCP Setup: See references/mcp-integration.md

### Important Notes

**Credit Cost Correction:** The Fast PPT endpoint costs **10 credits per page** (not 1 credit per slide as initially documented). This has been corrected throughout all documentation based on official pricing at https://2slides.com/pricing.


path: README.md
content: # 2slides Skills for Claude Code

AI-powered presentation generation using the [2slides API](https://2slides.com). This Claude Code skill enables you to create professional presentations from text content, match reference image styles, or summarize documents into slides.

## Important Links

**🌐 [2slides Website](https://2slides.com)** - Learn about 2slides features, pricing, and create presentations online

**🔑 [Get API Access](https://2slides.com/api)** - Sign up for API access, get your API key, and view API documentation

**📚 [API Documentation](https://2slides.com/api)** - Complete API reference with endpoints, parameters, and examples

> **New to 2slides?** Start at [2slides.com](https://2slides.com) to explore features, then visit [2slides.com/api](https://2slides.com/api) to get your API key and enable this skill.

## Overview

This skill provides integrated access to 2slides presentation generation capabilities within Claude Code. Generate slides in multiple languages, choose from various themes, and create presentations using several different methods.

## Features

- **Content-Based Generation**: Create slides from text, outlines, or bullet points with themes
- **Reference Image Matching**: Generate slides that match the style of an existing image
- **Custom PDF Generation**: Create custom-designed slides without reference images (NEW)
- **Voice Narration**: Add AI voice narration with 30 voice options and multi-speaker support (NEW)
- **Export & Download**: Download slides as PNG images and voice files as WAV (FREE) (NEW)
- **Document Summarization**: Convert documents (PDF, DOCX, TXT) into presentation format
- **Theme Search**: Browse and select from professional themes
- **Multi-Language Support**: Generate presentations in 19+ languages
- **Sync & Async Modes**: Choose immediate results or batch processing
- **MCP Integration**: Use native tools in Claude Desktop

## Before You Begin

This skill requires a 2slides API account and API key.

**Free Trial:** New users receive **500 free credits** (~50 Fast PPT pages) to get started.

Follow these steps:

### Step 1: Explore 2slides
Visit **[2slides.com](https://2slides.com)** to:
- See examples of AI-generated presentations
- Understand available features and capabilities
- Review pricing plans and credit system
- Try the web interface to see what's possible

### Step 2: Get API Access
Visit **[2slides.com/api](https://2slides.com/api)** to:
- Sign up for an API account (receive 500 free credits)
- Generate your API key
- View API documentation and usage limits
- Check your credit balance and usage
- Access API endpoints reference

### Step 3: Purchase Credits (Optional)
Visit **[2slides.com/pricing](https://2slides.com/pricing)** to:
- Purchase additional credits (pay-as-you-go, no subscriptions)
- View current promotions (up to 20% off)
- Review pricing tiers
- **Credits never expire** - buy what you need

Once you have your API key, proceed with installation below.

## Installation

### 1. Set Up API Key

**First time using 2slides?**

1. **Visit [2slides.com](https://2slides.com)** to learn about the platform and features
2. **Go to [2slides.com/api](https://2slides.com/api)** to access the API portal
3. **Create an account** if you don't have one
4. **Generate your API key** from the API dashboard
5. **Set the environment variable** with your API key:

```bash
export SLIDES_2SLIDES_API_KEY="your_api_key_here"
```

To make this permanent, add it to your shell configuration file (`~/.bashrc`, `~/.zshrc`, etc.):

```bash
echo 'export SLIDES_2SLIDES_API_KEY="your_api_key_here"' >> ~/.zshrc
source ~/.zshrc
```

### 2. Install the Skill

Copy this skill directory to your Claude Code skills location or invoke it directly using the skill name when it's available in your environment.

### 3. (Optional) Configure MCP Server

For Claude Desktop integration, add the 2slides MCP server to your Claude configuration. See [references/mcp-integration.md](references/mcp-integration.md) for complete setup instructions.

## Quick Start

### Create Slides from Text

```
Create a presentation about machine learning with these sections:
- Introduction to ML
- Types of Learning
- Applications
- Future Trends
```

### Create Slides from a Document

```
Create slides from this research paper [attach PDF]
```

### Match a Reference Style

```
Create slides about our Q4 results matching the style of this image: https://example.com/template.jpg
```

### Search for Themes

```
Search for professional business themes
```

## Usage Examples

### Example 1: Quick Presentation

```
User: Create a 5-slide presentation about climate change

Claude: [Searches for appropriate theme]
        [Generates structured content]
        [Creates presentation with generate_slides.py]

        Your presentation is ready!
        View online: https://2slides.com/slides/abc123
        Download PDF: https://2slides.com/slides/abc123/download
```

### Example 2: Document Summary

```
User: [Uploads 20-page research paper]
      Summarize this into slides

Claude: [Reads document]
        [Extracts key points]
        [Structures content for slides]
        [Generates presentation]

        Created a 12-slide summary of your research paper.
```

### Example 3: Style Matching

```
User: Create slides about our product launch using this design
      [provides reference image URL]

Claude: [Generates slides matching the reference style]

        Slides created matching your design template.
```

## Command Reference

The skill includes six Python scripts for API interaction:

### Generate Slides

```bash
# Basic generation with theme
python scripts/generate_slides.py --content "Your content" --theme-id "theme123"

# With language
python scripts/generate_slides.py --content "Content" --theme-id "theme123" --language "Spanish"

# From reference image
python scripts/generate_slides.py --content "Content" --reference-image "https://example.com/img.jpg"

# Async mode
python scripts/generate_slides.py --content "Content" --theme-id "theme123" --mode async
```

### Create PDF Slides (NEW)

```bash
# Custom-designed slides without reference image
python scripts/create_pdf_slides.py --content "Sales Report Q4 2025"

# With design specifications
python scripts/create_pdf_slides.py \
  --content "Marketing Plan" \
  --design-spec "modern minimalist, blue color scheme"

# High resolution with auto page detection
python scripts/create_pdf_slides.py --content "Product Launch" --resolution "4K" --page 0
```

### Generate Narration (NEW)

```bash
# List available voices (30 options)
python scripts/generate_narration.py --list-voices

# Add narration with default voice
python scripts/generate_narration.py --job-id "abc-123-def-456"

# With specific voice and multi-speaker
python scripts/generate_narration.py \
  --job-id "abc-123-def-456" \
  --voice "Aoede" \
  --multi-speaker

# In different language
python scripts/generate_narration.py \
  --job-id "abc-123-def-456" \
  --language "Spanish" \
  --voice "Charon"
```

### Download Export (NEW)

```bash
# Download slides as PNG and voices as WAV (FREE)
python scripts/download_slides_pages_voices.py --job-id "abc-123-def-456"

# Download to specific path
python scripts/download_slides_pages_voices.py \
  --job-id "abc-123-def-456" \
  --output "my-presentation.zip"
```

### Search Themes

```bash
# Search for themes
python scripts/search_themes.py --query "business"
python scripts/search_themes.py --query "creative" --limit 50
```

### Check Job Status

```bash
# For async jobs (also shows narration status)
python scripts/get_job_status.py --job-id "job123"
```

## Documentation

- **[SKILL.md](SKILL.md)**: Complete skill documentation with workflows and examples
- **[api-reference.md](references/api-reference.md)**: Detailed API documentation
- **[pricing.md](references/pricing.md)**: Pricing, credits, and cost calculations
- **[mcp-integration.md](references/mcp-integration.md)**: MCP server setup and configuration
- **[CHANGELOG.md](CHANGELOG.md)**: Version history and updates

## Supported Languages

Auto, English, Simplified Chinese, Traditional Chinese, Spanish, French, German, Japanese, Korean, Arabic, Portuguese, Indonesian, Russian, Hindi, Vietnamese, Turkish, Polish, Italian, and more.

## Generation Modes

### Content-Based Generation

Generate slides from text content using pre-designed themes.

**Requirements:**
- Text content (can be structured or unstructured)
- Theme ID (search themes first)

**Best for:**
- Quick presentations
- Structured outlines
- Bullet-point content

**Credit cost:** 10 credits per page

### Reference Image Generation

Create slides matching the style of a reference image.

**Requirements:**
- Text content
- Reference image URL (public or base64)

**Best for:**
- Matching existing brand guidelines
- Replicating design templates
- Consistent visual style

**Credit costs:**
- 1K/2K resolution: 100 credits per page
- 4K resolution: 200 credits per page

### Custom PDF Generation (NEW)

Create custom-designed slides from text without a reference image.

**Requirements:**
- Text content
- Optional design specifications

**Best for:**
- Custom designs without templates
- AI-generated layouts
- Flexible design requirements

**Credit costs:**
- 1K/2K resolution: 100 credits per page
- 4K resolution: 200 credits per page

### Voice Narration (NEW)

Add AI-generated voice narration to slides.

**Requirements:**
- Completed slide generation job ID
- Voice selection (30 options)

**Best for:**
- Presentations with audio
- Multi-speaker presentations
- Accessible content

**Credit cost:** 210 credits per page (10 for text, 200 for audio)

### Download Export (NEW)

Export slides as PNG images and voice files as WAV.

**Best for:**
- Using slides in other tools
- Extracting individual slide images
- Getting audio files separately

**Credit cost:** FREE (no credits)

### Document Summarization

Convert documents into presentation format.

**Supported formats:**
- PDF documents
- Microsoft Word (DOCX)
- Plain text (TXT, MD)

**Best for:**
- Research papers
- Reports
- Long-form content

## Tips for Best Results

1. **Structure Your Content**
   - Use clear headings and subheadings
   - Keep bullet points concise (3-5 per slide)
   - Include relevant examples or data

2. **Choose Appropriate Themes**
   - Search with keywords matching your purpose
   - Common searches: "business", "professional", "creative", "education"
   - Preview themes before selecting

3. **Reference Images**
   - Use high-quality images for better matching
   - Ensure images are publicly accessible
   - Consider resolution settings based on quality needs

4. **Document Processing**
   - Focus on key insights, not full text
   - Use document headings as slide titles
   - Ask user which sections to emphasize

## Troubleshooting

### API Key Issues

```
Error: API key not found
Solution: Set SLIDES_2SLIDES_API_KEY environment variable
```

**To get your API key:**
- Go to [2slides.com/api](https://2slides.com/api)
- Log in to your account
- Navigate to API Keys section
- Generate a new key if needed

### Rate Limiting

```
Error: 429 Too Many Requests
Solution: Wait 20-30 seconds before retrying
```

**Rate limits by endpoint:**
- Fast PPT (theme-based): 10 requests per minute
- Nano Banana (image-based/custom): 6 requests per minute

**To check your usage and limits:**
- Visit [2slides.com/api](https://2slides.com/api)
- Check your current plan and credit balance
- Review API rate limits for your tier
- Consider upgrading your plan at [2slides.com](https://2slides.com)

### Insufficient Credits

```
Error: INSUFFICIENT_CREDITS
Solution: Purchase more credits at https://2slides.com/pricing
```

**To check your credit balance:**
- Visit [2slides.com/api](https://2slides.com/api)
- View your API dashboard
- See current credit balance and usage history

### Invalid Content

```
Error: 400 Bad Request
Solution: Verify content format and required parameters (theme-id or reference-image)
```

**For API support:**
- Visit [2slides.com/api](https://2slides.com/api) for API documentation
- Check the API reference for correct parameter formats
- Contact 2slides support through [2slides.com](https://2slides.com)

## Pricing & Credits

2slides uses a **pay-as-you-go credit system** with no monthly subscriptions.

### Credit Packages

Current promotion: **Up to 20% off credits**

| Credits | Price | Cost per 1,000 | Savings | Fast PPT Pages |
|---------|-------|---------------|---------|----------------|
| 2,000 | $5.00 | $2.50 | — | ~200 pages |
| 4,000 | $9.50 | $2.38 | 5% | ~400 pages |
| 10,000 | $22.50 | $2.25 | 10% | ~1,000 pages |
| 20,000 | $42.50 | $2.13 | 15% | ~2,000 pages |
| 40,000 | $80.00 | $2.00 | 20% | ~4,000 pages |

**Purchase at:** https://2slides.com/pricing

### Free Trial

New users receive **500 free credits** for onboarding:
- ~50 Fast PPT slide pages
- ~5 Nano Banana 2K pages
- ~2 Nano Banana 2K pages with narration

### Credit Costs Summary

| Feature | Credits per Page | Example (10 pages) |
|---------|-----------------|-------------------|
| Fast PPT | 10 | 100 credits |
| Nano Banana 1K/2K | 100 | 1,000 credits |
| Nano Banana 4K | 200 | 2,000 credits |
| Voice Narration | +210 | +2,100 credits |
| Download Export | FREE | 0 credits |

### Key Benefits

- ✅ **Credits never expire** - use at your own pace
- ✅ **No subscriptions** - pay only for what you use
- ✅ **Volume discounts** - up to 20% off
- ✅ **3-day refund window** - risk-free purchase
- ✅ **500 free credits** for new users

### Example Costs

With the 40,000 credit package ($80, $2.00 per 1,000):

- **10-slide Fast PPT presentation:** 100 credits = **$0.20**
- **10-slide Nano Banana 2K:** 1,000 credits = **$2.00**
- **10-slide with 4K resolution:** 2,000 credits = **$4.00**
- **10-slide with narration (2K + voice):** 2,100 credits = **$4.20**

## Advanced Configuration

### Async vs Sync Mode

**Sync Mode (default):**
- Waits for generation (30-60 seconds)
- Returns results immediately
- Best for interactive use

**Async Mode:**
- Returns job ID immediately
- Poll for results with `get_job_status.py`
- Best for batch processing or large presentations

### Custom Settings

You can customize generation with additional parameters:

```bash
--aspect-ratio "16:9"          # Slide dimensions
--resolution "2K"              # Output quality (1K, 2K, 4K)
--page 10                      # Number of slides
--content-detail "concise"     # Brief or detailed content
```

See [SKILL.md](SKILL.md) for complete parameter documentation.

## Contributing

This skill is designed to work with the official 2slides API. For API issues or feature requests, contact 2slides support at [https://2slides.com](https://2slides.com).

For skill-related improvements, ensure all changes maintain compatibility with the 2slides API specification.

## License

This skill integrates with the 2slides API service. Usage is subject to 2slides terms of service and API usage limits.

## Resources

### 2slides Platform
- **[2slides.com](https://2slides.com)** - Main website
  - Product features and demos
  - Pricing and plans
  - Web-based presentation creation
  - Account management
  - Support and contact information

### API & Development
- **[2slides.com/api](https://2slides.com/api)** - API Portal
  - Get your API key
  - API documentation and reference
  - Usage limits and credit information
  - Code examples and guides
  - API status and updates

### Claude Code
- **[Claude Code](https://claude.ai/claude-code)** - Official Claude Code documentation
- **Skill Documentation** - See [SKILL.md](SKILL.md) for complete usage guide

### Getting Help
- **API Issues**: Visit [2slides.com/api](https://2slides.com/api) for documentation
- **Pricing & Credits**: Visit [2slides.com/pricing](https://2slides.com/pricing) or see [pricing.md](references/pricing.md)
- **Account Questions**: Contact support through [2slides.com](https://2slides.com)
- **Skill Usage**: Refer to [SKILL.md](SKILL.md) and [api-reference.md](references/api-reference.md)

## Version

Current version: 2.0.0

**What's New in 2.0:**
- ✨ Custom PDF slides generation without reference images
- 🎙️ AI voice narration with 30 voices and multi-speaker support
- 📥 Free download export for slides as PNG and voices as WAV
- 📊 Updated rate limits and credit costs
- 🔄 Enhanced job status tracking with narration support

---

Made with Claude Code


path: scripts/generate_narration.py
content: #!/usr/bin/env python3
"""
Generate AI voice narration for slides using the 2slides API.
Supports single and multi-speaker modes with 30 voice options.
"""

import os
import sys
import json
import argparse
import requests
from typing import Optional, Dict, Any, List


API_BASE_URL = "https://2slides.com/api/v1"

# Available voice options (30 voices)
AVAILABLE_VOICES = [
    "Puck", "Aoede", "Charon", "Kore", "Fenrir", "Phoebe", "Asteria",
    "Luna", "Stella", "Theia", "Helios", "Atlas", "Clio", "Melpomene",
    "Calliope", "Erato", "Euterpe", "Polyhymnia", "Terpsichore", "Thalia",
    "Urania", "Zeus", "Hera", "Poseidon", "Athena", "Apollo", "Artemis",
    "Ares", "Aphrodite", "Hephaestus"
]


def get_api_key() -> str:
    """Get API key from environment variable."""
    [REDACTED_SECRET]"SLIDES_2SLIDES_API_KEY")
    if not api_key:
        raise ValueError(
            "API key not found. Set SLIDES_2SLIDES_API_KEY environment variable.\n"
            "Get your API key from: https://2slides.com/api"
        )
    return api_key


def generate_narration(
    job_id: str,
    language: str = "Auto",
    voice: str = "Puck",
    multi_speaker: bool = False,
    [REDACTED_SECRET] = None
) -> Dict[str, Any]:
    """
    Generate AI voice narration for slides.

    Args:
        job_id: Job ID from slide generation (must be UUID format for Nano Banana)
        language: Language for narration (default: "Auto")
            Options: Auto, English, Simplified Chinese, Traditional Chinese, Spanish,
            Arabic, Portuguese, Indonesian, Japanese, Russian, Hindi, French, German,
            Vietnamese, Turkish, Polish, Italian, Korean
        voice: Voice name (default: "Puck")
            Options: Puck, Aoede, Charon, Kore, Fenrir, Phoebe, Asteria, Luna, Stella,
            Theia, Helios, Atlas, Clio, Melpomene, Calliope, Erato, Euterpe, Polyhymnia,
            Terpsichore, Thalia, Urania, Zeus, Hera, Poseidon, Athena, Apollo, Artemis,
            Ares, Aphrodite, Hephaestus
        multi_speaker: Enable multi-speaker mode (default: False)
        api_key: API key (uses env var if not provided)

    Returns:
        Dict with narration generation result

    Notes:
        - Job must be completed before adding narration
        - Cost: 210 credits per page (10 for text, 200 for audio)
        - Processing time: Varies by slide count
    """
    if api_key is None:
        [REDACTED_SECRET])

    if voice not in AVAILABLE_VOICES:
        print(f"Warning: Voice '{voice}' not in known voices list", file=sys.stderr)
        print(f"Available voices: {', '.join(AVAILABLE_VOICES)}", file=sys.stderr)

    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json"
    }

    payload = {
        "jobId": job_id,
        "language": language,
        "voice": voice,
        "multiSpeaker": multi_speaker
    }

    url = f"{API_BASE_URL}/slides/generate-narration"

    print("Generating voice narration...", file=sys.stderr)
    print(f"Voice: {voice}, Multi-speaker: {multi_speaker}", file=sys.stderr)

    # Set reasonable timeout for narration generation
    timeout = 120

    response = requests.post(url, headers=headers, json=payload, timeout=timeout)
    response.raise_for_status()

    result = response.json()

    # Check API response structure
    if not result.get("success"):
        # Common error example:
        # {"error":"Job is not completed","code":"JOB_NOT_COMPLETED",...}
        error_msg = result.get("error", "Unknown error")
        code = result.get("code")
        details = result.get("details")
        extra = f" (code={code})" if code else ""
        raise ValueError(f"API error: {error_msg}{extra}{f' details={details}' if details else ''}")

    # API may return either:
    # - { success:true, data:{...} }
    # - { success:true, jobId:"...", message:"..." }  (no data field)
    data = result.get("data")
    if not data:
        data = {
            "jobId": result.get("jobId") or job_id,
            "status": result.get("status") or "pending",
            "message": result.get("message") or "Narration generation started"
        }

    print("✓ Narration generation started!", file=sys.stderr)
    print(f"  Job ID: {data.get('jobId')}", file=sys.stderr)
    print("Use get_job_status.py to check progress", file=sys.stderr)

    return data


def list_voices():
    """Print available voices."""
    print("Available voices (30 total):")
    print("-" * 40)
    for i, voice in enumerate(AVAILABLE_VOICES, 1):
        print(f"{i:2d}. {voice}")
    print("-" * 40)
    print("\nPopular choices: Puck, Aoede, Charon")


def main():
    parser = argparse.ArgumentParser(
        description="Generate AI voice narration for 2slides presentations",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Examples:
  # List available voices
  %(prog)s --list-voices

  # Generate narration with default voice
  %(prog)s --job-id "abc-123-def-456"

  # Generate with specific voice
  %(prog)s --job-id "abc-123-def-456" --voice "Aoede"

  # Generate with multi-speaker mode
  %(prog)s --job-id "abc-123-def-456" --multi-speaker

  # Generate in Spanish
  %(prog)s --job-id "abc-123-def-456" --language "Spanish" --voice "Charon"

Credit Cost: 210 credits per page (10 for text, 200 for audio)
        """
    )

    parser.add_argument("--job-id", help="Job ID from slide generation (UUID format)")
    parser.add_argument("--language", default="Auto", help="Narration language (default: Auto)")
    parser.add_argument("--voice", default="Puck", help="Voice name (default: Puck)")
    parser.add_argument("--multi-speaker", action="store_true", help="Enable multi-speaker mode")
    parser.add_argument("--list-voices", action="store_true", help="List available voices and exit")

    args = parser.parse_args()

    if args.list_voices:
        list_voices()
        return

    if not args.job_id:
        print("Error: --job-id is required (or use --list-voices)", file=sys.stderr)
        sys.exit(1)

    try:
        result = generate_narration(
            job_id=args.job_id,
            language=args.language,
            voice=args.voice,
            multi_speaker=args.multi_speaker
        )

        print(json.dumps(result, indent=2))

    except Exception as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)


if __name__ == "__main__":
    main()


path: scripts/get_job_status.py
content: #!/usr/bin/env python3
"""
Check the status of an async slide generation job.
"""

import os
import sys
import json
import argparse
import requests
from typing import Optional, Dict, Any


API_BASE_URL = "https://2slides.com/api/v1"


def get_api_key() -> str:
    """Get API key from environment variable."""
    [REDACTED_SECRET]"SLIDES_2SLIDES_API_KEY")
    if not api_key:
        raise ValueError(
            "API key not found. Set SLIDES_2SLIDES_API_KEY environment variable.\n"
            "Get your API key from: https://2slides.com/api"
        )
    return api_key


def get_job_status(
    job_id: str,
    [REDACTED_SECRET] = None
) -> Dict[str, Any]:
    """
    Get the status of a slide generation job.

    Args:
        job_id: Job ID from async generation
        api_key: API key (uses env var if not provided)

    Returns:
        Dict with job status and result
    """
    if api_key is None:
        [REDACTED_SECRET])

    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json"
    }

    url = f"{API_BASE_URL}/jobs/{job_id}"

    print(f"Checking job status: {job_id}...", file=sys.stderr)
    response = requests.get(url, headers=headers)
    response.raise_for_status()

    result = response.json()

    # Check API response structure
    if not result.get("success"):
        error_msg = result.get("error", "Unknown error")
        raise ValueError(f"API error: {error_msg}")

    # Extract data from response
    data = result.get("data")
    if not data:
        raise ValueError("No data in API response")

    status = data.get("status", "unknown")

    print(f"✓ Job status: {status}", file=sys.stderr)
    if data.get("message"):
        print(f"  Message: {data.get('message')}", file=sys.stderr)
    if data.get("slidePageCount"):
        print(f"  Pages: {data.get('slidePageCount')}", file=sys.stderr)
    if data.get("downloadUrl"):
        print(f"  Download URL: {data.get('downloadUrl')}", file=sys.stderr)

    return data


def main():
    parser = argparse.ArgumentParser(
        description="Check 2slides job status",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Examples:
  # Check job status
  %(prog)s --job-id abc123
        """
    )

    parser.add_argument("--job-id", required=True, help="Job ID to check")

    args = parser.parse_args()

    try:
        result = get_job_status(job_id=args.job_id)
        print(json.dumps(result, indent=2))

    except Exception as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)


if __name__ == "__main__":
    main()


path: scripts/create_pdf_slides.py
content: #!/usr/bin/env python3
"""
Generate custom-designed slides from text using the 2slides API.
Similar to create-like-this but without needing a reference image.
"""

import os
import sys
import json
import argparse
import requests
from typing import Optional, Dict, Any


API_BASE_URL = "https://2slides.com/api/v1"


def get_api_key() -> str:
    """Get API key from environment variable."""
    [REDACTED_SECRET]"SLIDES_2SLIDES_API_KEY")
    if not api_key:
        raise ValueError(
            "API key not found. Set SLIDES_2SLIDES_API_KEY environment variable.\n"
            "Get your API key from: https://2slides.com/api"
        )
    return api_key


def create_pdf_slides(
    user_input: str,
    response_language: str = "Auto",
    aspect_ratio: str = "16:9",
    resolution: str = "2K",
    page: int = 1,
    content_detail: str = "concise",
    design_spec: Optional[str] = None,
    [REDACTED_SECRET] = None
) -> Dict[str, Any]:
    """
    Generate custom-designed slides from text with optional design specifications.

    Args:
        user_input: Content to convert into slides
        response_language: Language (default: "Auto")
            Options: Auto, English, Simplified Chinese, Traditional Chinese, Spanish,
            Arabic, Portuguese, Indonesian, Japanese, Russian, Hindi, French, German,
            Vietnamese, Turkish, Polish, Italian, Korean
        aspect_ratio: Aspect ratio in width:height format (default: "16:9")
        resolution: Output quality - "1K", "2K", or "4K" (default: "2K")
        page: Number of slides, 0 for auto-detection, max 100 (default: 1)
        content_detail: "concise" (brief) or "standard" (detailed) (default: "concise")
        design_spec: Optional design specifications (e.g., "modern minimalist", "corporate blue")
        api_key: API key (uses env var if not provided)

    Returns:
        Dict with generation result
    """
    if api_key is None:
        [REDACTED_SECRET])

    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json"
    }

    payload = {
        "userInput": user_input,
        "responseLanguage": response_language,
        "aspectRatio": aspect_ratio,
        "resolution": resolution,
        "page": page,
        "contentDetail": content_detail
    }

    if design_spec:
        payload["designSpec"] = design_spec

    url = f"{API_BASE_URL}/slides/create-pdf-slides"

    # Calculate dynamic timeout: ~30s per page, minimum 120s
    timeout = max(120, page * 40)

    print("Generating custom-designed slides...", file=sys.stderr)
    print(f"(Timeout set to {timeout}s for {page} page(s))", file=sys.stderr)
    response = requests.post(url, headers=headers, json=payload, timeout=timeout)
    response.raise_for_status()

    result = response.json()

    # Handle the actual API response structure
    if result.get("success") and "data" in result:
        data = result["data"]
        # Transform to expected format for consistency
        normalized_result = {
            "slideUrl": data.get("jobUrl"),
            "pdfUrl": data.get("downloadUrl"),
            "status": "completed" if data.get("status") == "success" else data.get("status"),
            "message": data.get("message"),
            "slidePageCount": data.get("slidePageCount"),
            "jobId": data.get("jobId")
        }
        print("✓ Slides generated successfully!", file=sys.stderr)
        print(f"  Pages: {data.get('slidePageCount')}", file=sys.stderr)
        return normalized_result
    else:
        # Fallback to raw result if structure is unexpected
        print("✓ Request completed!", file=sys.stderr)
        return result


def main():
    parser = argparse.ArgumentParser(
        description="Generate custom-designed slides using 2slides API",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Examples:
  # Generate slides with auto design
  %(prog)s --content "Sales Report Q4 2025"

  # Generate with specific design
  %(prog)s --content "Marketing Plan" --design-spec "modern minimalist, blue color scheme"

  # Generate in 4K resolution
  %(prog)s --content "Product Launch" --resolution 4K --page 5
        """
    )

    parser.add_argument("--content", required=True, help="Content for slides")
    parser.add_argument("--design-spec", help="Optional design specifications")
    parser.add_argument("--language", default="Auto", help="Response language (default: Auto)")
    parser.add_argument("--aspect-ratio", default="16:9", help="Aspect ratio in width:height format (default: 16:9)")
    parser.add_argument("--resolution", choices=["1K", "2K", "4K"], default="2K",
                       help="Output quality (default: 2K)")
    parser.add_argument("--page", type=int, default=1, help="Number of slides, 0 for auto (default: 1, max: 100)")
    parser.add_argument("--content-detail", choices=["concise", "standard"], default="concise",
                       help="Content detail level (default: concise)")

    args = parser.parse_args()

    try:
        result = create_pdf_slides(
            user_input=args.content,
            response_language=args.language,
            aspect_ratio=args.aspect_ratio,
            resolution=args.resolution,
            page=args.page,
            content_detail=args.content_detail,
            design_spec=args.design_spec
        )

        print(json.dumps(result, indent=2))

    except Exception as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)


if __name__ == "__main__":
    main()


path: scripts/download_slides_pages_voices.py
content: #!/usr/bin/env python3
"""
Download slides pages as PNG files and voice narrations as WAV files.
Exports everything as a ZIP archive (completely free).
"""

import os
import sys
import json
import argparse
import requests
from typing import Optional, Dict, Any


API_BASE_URL = "https://2slides.com/api/v1"


def get_api_key() -> str:
    """Get API key from environment variable."""
    [REDACTED_SECRET]"SLIDES_2SLIDES_API_KEY")
    if not api_key:
        raise ValueError(
            "API key not found. Set SLIDES_2SLIDES_API_KEY environment variable.\n"
            "Get your API key from: https://2slides.com/api"
        )
    return api_key


def download_slides_pages_voices(
    job_id: str,
    output_path: Optional[str] = None,
    [REDACTED_SECRET] = None
) -> str:
    """
    Download slides pages and voice narrations as a ZIP archive.

    Args:
        job_id: Job ID from slide generation
        output_path: Optional path to save the ZIP file (default: <job_id>.zip)
        api_key: API key (uses env var if not provided)

    Returns:
        Path to the downloaded ZIP file

    Notes:
        - Exports pages as PNG files
        - Exports voices as WAV files
        - Includes transcripts
        - Completely free (no credit cost)
        - Download URL valid for 1 hour
    """
    if api_key is None:
        [REDACTED_SECRET])

    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json"
    }

    payload = {
        "jobId": job_id
    }

    url = f"{API_BASE_URL}/slides/download-slides-pages-voices"

    print(f"Requesting download for job: {job_id}...", file=sys.stderr)

    response = requests.post(url, headers=headers, json=payload, timeout=30)
    response.raise_for_status()

    result = response.json()

    # Check API response structure
    if not result.get("success"):
        error_msg = result.get("error", "Unknown error")
        raise ValueError(f"API error: {error_msg}")

    # Get download URL from data field
    data = result.get("data")
    if not data:
        raise ValueError("No data in API response")

    download_url = data.get("downloadUrl")
    if not download_url:
        raise ValueError("No download URL in response")

    # Optional: log additional info
    file_name = data.get("fileName", "unknown.zip")
    expires_in = data.get("expiresIn", 3600)
    print(f"  Filename: {file_name}", file=sys.stderr)
    print(f"  Expires in: {expires_in} seconds", file=sys.stderr)

    # Download the ZIP file
    if output_path is None:
        output_path = f"{job_id}.zip"

    print(f"Downloading ZIP archive to: {output_path}...", file=sys.stderr)

    zip_response = requests.get(download_url, stream=True, timeout=120)
    zip_response.raise_for_status()

    # Save to file
    with open(output_path, 'wb') as f:
        for chunk in zip_response.iter_content(chunk_size=8192):
            f.write(chunk)

    file_size = os.path.getsize(output_path)
    print(f"✓ Downloaded successfully!", file=sys.stderr)
    print(f"  File: {output_path}", file=sys.stderr)
    print(f"  Size: {file_size:,} bytes", file=sys.stderr)

    return output_path


def main():
    parser = argparse.ArgumentParser(
        description="Download 2slides pages and voices as ZIP archive (FREE)",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Examples:
  # Download with default filename
  %(prog)s --job-id "abc-123-def-456"

  # Download to specific path
  %(prog)s --job-id "abc-123-def-456" --output slides.zip

Archive Contents:
  - Pages as PNG files
  - Voice files as WAV
  - Transcripts

Note: Download URLs are valid for 1 hour only
Cost: Completely FREE (no credits used)
        """
    )

    parser.add_argument("--job-id", required=True, help="Job ID from slide generation")
    parser.add_argument("--output", help="Output ZIP file path (default: <job_id>.zip)")

    args = parser.parse_args()

    try:
        output_path = download_slides_pages_voices(
            job_id=args.job_id,
            output_path=args.output
        )

        # Output path for easy parsing
        print(json.dumps({"success": True, "output": output_path}, indent=2))

    except Exception as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)


if __name__ == "__main__":
    main()


path: scripts/generate_slides.py
content: #!/usr/bin/env python3
"""
Generate slides using the 2slides API.
Supports both content-based and reference image-based generation.
"""

import os
import sys
import json
import time
import argparse
import requests
from typing import Optional, Dict, Any


API_BASE_URL = "https://2slides.com/api/v1"


def get_api_key() -> str:
    """Get API key from environment variable."""
    [REDACTED_SECRET]"SLIDES_2SLIDES_API_KEY")
    if not api_key:
        raise ValueError(
            "API key not found. Set SLIDES_2SLIDES_API_KEY environment variable.\n"
            "Get your API key from: https://2slides.com/api"
        )
    return api_key


def generate_slides(
    user_input: str,
    theme_id: str,
    response_language: str = "Auto",
    mode: str = "sync",
    [REDACTED_SECRET] = None
) -> Dict[str, Any]:
    """
    Generate slides from user input.

    Args:
        user_input: Content to convert into slides
        theme_id: Theme ID (required, use search_themes.py to find themes)
        response_language: Language (default: "Auto")
            Options: Auto, English, Simplified Chinese, Traditional Chinese, Spanish,
            Arabic, Portuguese, Indonesian, Japanese, Russian, Hindi, French, German,
            Vietnamese, Turkish, Polish, Italian, Korean
        mode: "sync" or "async" (default: "sync")
        api_key: API key (uses env var if not provided)

    Returns:
        Dict with generation result or job ID
    """
    if api_key is None:
        [REDACTED_SECRET])

    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json"
    }

    payload = {
        "userInput": user_input,
        "themeId": theme_id,
        "responseLanguage": response_language,
        "mode": mode
    }

    url = f"{API_BASE_URL}/slides/generate"

    # Set timeout: 90s for sync (waits for completion), 30s for async (just creates job)
    timeout = 90 if mode == "sync" else 30

    print(f"Generating slides in {mode} mode...", file=sys.stderr)
    response = requests.post(url, headers=headers, json=payload, timeout=timeout)
    response.raise_for_status()

    result = response.json()

    # Check API response structure
    if not result.get("success"):
        error_msg = result.get("error", "Unknown error")
        raise ValueError(f"API error: {error_msg}")

    # Extract data from response
    data = result.get("data")
    if not data:
        raise ValueError("No data in API response")

    if mode == "sync":
        print("✓ Slides generated successfully!", file=sys.stderr)
        print(f"  Pages: {data.get('slidePageCount', 'N/A')}", file=sys.stderr)
        if data.get("downloadUrl"):
            print(f"  Download URL: {data.get('downloadUrl')}", file=sys.stderr)
    else:
        print(f"✓ Job created: {data.get('jobId')}", file=sys.stderr)
        print("Use get_job_status.py to check status", file=sys.stderr)

    return data


def create_like_this(
    user_input: str,
    reference_image_url: str,
    response_language: str = "Auto",
    aspect_ratio: str = "16:9",
    resolution: str = "2K",
    page: int = 1,
    content_detail: str = "concise",
    [REDACTED_SECRET] = None
) -> Dict[str, Any]:
    """
    Generate slides matching a reference image style (Nano Banana Pro).

    Args:
        user_input: Content to convert into slides
        reference_image_url: URL or base64 of reference image to match style
        response_language: Language (default: "Auto")
            Options: Auto, English, Simplified Chinese, Traditional Chinese, Spanish,
            Arabic, Portuguese, Indonesian, Japanese, Russian, Hindi, French, German,
            Vietnamese, Turkish, Polish, Italian, Korean
        aspect_ratio: Aspect ratio in width:height format (default: "16:9")
        resolution: Output quality - "1K", "2K", or "4K" (default: "2K")
        page: Number of slides, 0 for auto-detection, max 100 (default: 1)
        content_detail: "concise" (brief, keyword-focused) or "standard" (comprehensive) (default: "concise")
        api_key: API key (uses env var if not provided)

    Returns:
        Dict with generation result
    """
    if api_key is None:
        [REDACTED_SECRET])

    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json"
    }

    payload = {
        "userInput": user_input,
        "referenceImageUrl": reference_image_url,
        "responseLanguage": response_language,
        "aspectRatio": aspect_ratio,
        "resolution": resolution,
        "page": page,
        "contentDetail": content_detail
    }

    url = f"{API_BASE_URL}/slides/create-like-this"

    # Calculate dynamic timeout: ~30s per page, minimum 120s
    timeout = max(120, page * 40)

    print("Generating slides from reference image...", file=sys.stderr)
    print(f"(Timeout set to {timeout}s for {page} page(s))", file=sys.stderr)
    response = requests.post(url, headers=headers, json=payload, timeout=timeout)
    response.raise_for_status()

    result = response.json()

    # Handle the actual API response structure
    if result.get("success") and "data" in result:
        data = result["data"]
        # Transform to expected format for consistency
        normalized_result = {
            "slideUrl": data.get("jobUrl"),
            "pdfUrl": data.get("downloadUrl"),
            "status": "completed" if data.get("status") == "success" else data.get("status"),
            "message": data.get("message"),
            "slidePageCount": data.get("slidePageCount"),
            "jobId": data.get("jobId")
        }
        print("✓ Slides generated successfully!", file=sys.stderr)
        print(f"  Pages: {data.get('slidePageCount')}", file=sys.stderr)
        return normalized_result
    else:
        # Fallback to raw result if structure is unexpected
        print("✓ Request completed!", file=sys.stderr)
        return result


def main():
    parser = argparse.ArgumentParser(
        description="Generate slides using 2slides API",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Examples:
  # Generate slides from content
  %(prog)s --content "Intro to AI: ML, Deep Learning, Neural Networks"

  # Generate with specific theme
  %(prog)s --content "Business Plan" --theme-id "theme123"

  # Generate in async mode
  %(prog)s --content "Long presentation" --mode async

  # Generate from reference image
  %(prog)s --content "Sales Report" --reference-image "https://example.com/image.jpg"
        """
    )

    parser.add_argument("--content", required=True, help="Content for slides")
    parser.add_argument("--theme-id", help="Theme ID (required for standard generation)")
    parser.add_argument("--reference-image", help="Reference image URL (use this OR theme-id)")
    parser.add_argument("--language", default="Auto", help="Response language (default: Auto)")
    parser.add_argument("--mode", choices=["sync", "async"], default="sync",
                       help="Generation mode (default: sync)")
    parser.add_argument("--aspect-ratio", default="16:9", help="Aspect ratio in width:height format (default: 16:9)")
    parser.add_argument("--resolution", choices=["1K", "2K", "4K"], default="2K",
                       help="Output quality (default: 2K)")
    parser.add_argument("--page", type=int, default=1, help="Number of slides, 0 for auto (default: 1, max: 100)")
    parser.add_argument("--content-detail", choices=["concise", "standard"], default="concise",
                       help="Content detail level (default: concise)")

    args = parser.parse_args()

    try:
        if args.reference_image:
            result = create_like_this(
                user_input=args.content,
                reference_image_url=args.reference_image,
                response_language=args.language,
                aspect_ratio=args.aspect_ratio,
                resolution=args.resolution,
                page=args.page,
                content_detail=args.content_detail
            )
        else:
            if not args.theme_id:
                print("Error: --theme-id is required for standard generation", file=sys.stderr)
                print("Use --reference-image for style-based generation instead", file=sys.stderr)
                sys.exit(1)
            result = generate_slides(
                user_input=args.content,
                theme_id=args.theme_id,
                response_language=args.language,
                mode=args.mode
            )

        print(json.dumps(result, indent=2))

    except Exception as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)


if __name__ == "__main__":
    main()


path: scripts/search_themes.py
content: #!/usr/bin/env python3
"""
Search for available themes in the 2slides catalog.
"""

import os
import sys
import json
import argparse
import requests
from typing import Optional, List, Dict, Any


API_BASE_URL = "https://2slides.com/api/v1"


def get_api_key() -> str:
    """Get API key from environment variable."""
    [REDACTED_SECRET]"SLIDES_2SLIDES_API_KEY")
    if not api_key:
        raise ValueError(
            "API key not found. Set SLIDES_2SLIDES_API_KEY environment variable.\n"
            "Get your API key from: https://2slides.com/api"
        )
    return api_key


def search_themes(
    query: str,
    limit: int = 20,
    [REDACTED_SECRET] = None
) -> List[Dict[str, Any]]:
    """
    Search for themes.

    Args:
        query: Search query (required keyword)
        limit: Maximum number of results (max 100, default 20)
        api_key: API key (uses env var if not provided)

    Returns:
        List of theme objects
    """
    if api_key is None:
        [REDACTED_SECRET])

    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json"
    }

    params = {
        "query": query,
        "limit": min(limit, 100)
    }

    url = f"{API_BASE_URL}/themes/search"

    print(f"Searching themes{f': {query}' if query else ''}...", file=sys.stderr)
    response = requests.get(url, headers=headers, params=params)
    response.raise_for_status()

    result = response.json()

    # Check API response structure
    if not result.get("success"):
        error_msg = result.get("error", "Unknown error")
        raise ValueError(f"API error: {error_msg}")

    # Extract data from response
    data = result.get("data")
    if not data:
        raise ValueError("No data in API response")

    themes = data.get("themes", [])

    print(f"✓ Found {len(themes)} theme(s)", file=sys.stderr)

    return themes


def format_theme(theme: Dict[str, Any]) -> str:
    """Format a theme object for display."""
    theme_id = theme.get("id", "N/A")
    name = theme.get("name", "Unnamed")
    description = theme.get("description", "No description")

    return f"ID: {theme_id}\nName: {name}\nDescription: {description}\n"


def main():
    parser = argparse.ArgumentParser(
        description="Search for 2slides themes",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Examples:
  # Search for business themes
  %(prog)s --query "business"

  # Search for creative themes
  %(prog)s --query "creative"

  # Get more results
  %(prog)s --query "professional" --limit 50
        """
    )

    parser.add_argument("--query", required=True, help="Search query (required keyword)")
    parser.add_argument("--limit", type=int, default=20,
                       help="Maximum results (max 100, default 20)")
    parser.add_argument("--json", action="store_true",
                       help="Output raw JSON")

    args = parser.parse_args()

    try:
        themes = search_themes(
            query=args.query,
            limit=args.limit
        )

        if args.json:
            print(json.dumps(themes, indent=2))
        else:
            print()
            for i, theme in enumerate(themes, 1):
                print(f"Theme {i}:")
                print(format_theme(theme))
                print("-" * 60)

    except Exception as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)


if __name__ == "__main__":
    main()


path: references/pricing.md
content: # 2slides Pricing & Credit Information

Complete pricing details and credit system information.

## Credit System Overview

2slides operates on a **pay-as-you-go credit system** with no monthly subscriptions or recurring charges.

### Key Benefits

- ✅ **Credits never expire** - Use them at your own pace
- ✅ **No subscriptions** - Pay only for what you use
- ✅ **Volume discounts** - Save up to 20% on larger packages
- ✅ **3-day refund window** - Risk-free purchase
- ✅ **500 free credits** - Free trial for new users

## Credit Packages

**Current Promotion:** Up to 20% off credits for a limited time.

| Credits | Original Price | Current Price | Discount | Cost per 1,000 |
|---------|----------------|---------------|----------|----------------|
| 2,000 | $5.00 | $5.00 | — | $2.50 |
| 4,000 | $10.00 | $9.50 | 5% | $2.38 |
| 10,000 | $25.00 | $22.50 | 10% | $2.25 |
| 20,000 | $50.00 | $42.50 | 15% | $2.13 |
| 40,000 | $100.00 | $80.00 | 20% | $2.00 |

**Purchase at:** https://2slides.com/pricing

## Credit Costs by Feature

| Feature | Credits per Page | Example (10 pages) |
|---------|-----------------|-------------------|
| Fast PPT (theme-based) | 10 | 100 credits |
| Nano Banana 1K/2K (image/custom) | 100 | 1,000 credits |
| Nano Banana 4K | 200 | 2,000 credits |
| Voice Narration | +210 | +2,100 credits |
| Download Export | FREE | 0 credits |

### Detailed Cost Breakdown

**Fast PPT Generation (Theme-Based)**
- 10 credits per page
- Uses pre-designed themes
- Fastest generation mode
- Cost example: 20-page presentation = 200 credits

**Nano Banana (Image Matching / Custom PDF)**
- **1K/2K resolution:** 100 credits per page
- **4K resolution:** 200 credits per page
- Matches reference image style or generates custom design
- Higher quality output
- Cost example: 10-page 2K presentation = 1,000 credits

**Voice Narration**
- 210 credits per page total
  - 10 credits for text processing
  - 200 credits for audio generation
- 30 voice options available
- Multi-speaker mode included
- Cost example: 5-page narration = 1,050 credits

**Download Export**
- Completely FREE (0 credits)
- Export slides as PNG images
- Export voice files as WAV
- Includes transcripts

## Free Trial

**New users receive 500 free credits** upon account creation.

**What you can do with 500 credits:**
- Create ~50 Fast PPT slide pages
- Create ~5 Nano Banana 2K pages
- Create ~2 Nano Banana 2K pages with full narration
- Mix and match features as needed

## Example Cost Calculations

### Scenario 1: Quick Business Presentation
- **Need:** 15-slide Fast PPT presentation
- **Credits required:** 150 credits (15 pages × 10 credits)
- **Cost with 2,000 package:** $0.38
- **Cost with 40,000 package:** $0.30

### Scenario 2: Branded Marketing Deck
- **Need:** 20-slide Nano Banana 2K matching brand image
- **Credits required:** 2,000 credits (20 pages × 100 credits)
- **Cost with 4,000 package:** $4.75
- **Cost with 40,000 package:** $4.00

### Scenario 3: Training Presentation with Audio
- **Need:** 30-slide 2K presentation with voice narration
- **Credits required:** 6,300 credits
  - Slides: 3,000 credits (30 pages × 100 credits)
  - Narration: 3,300 credits (30 pages × 110 credits - voice only)
- **Cost with 10,000 package:** $14.18
- **Cost with 40,000 package:** $12.60

### Scenario 4: High-Resolution Portfolio
- **Need:** 10-slide 4K Nano Banana presentation
- **Credits required:** 2,000 credits (10 pages × 200 credits)
- **Cost with 4,000 package:** $4.75
- **Cost with 40,000 package:** $4.00

### Scenario 5: Complete Package
- **Need:** 25-slide 2K presentation with narration, exported as PNG/WAV
- **Credits required:** 5,250 credits
  - Slides: 2,500 credits (25 pages × 100 credits)
  - Narration: 2,750 credits (25 pages × 110 credits - voice only)
  - Export: 0 credits (FREE)
- **Cost with 10,000 package:** $11.81
- **Cost with 40,000 package:** $10.50

## Payment Methods

Accepted payment methods via Stripe:
- Major credit cards (Visa, Mastercard, American Express, Discover)
- Apple Pay
- Google Pay

## Refund Policy

- **3-day refund window** after purchase
- Contact support through https://2slides.com for refund requests
- Credits must not have been substantially used

## Enterprise & Team Plans

Currently in development. For high-volume or team needs, contact 2slides support through https://2slides.com.

## Checking Your Credit Balance

**Via Web:**
1. Visit https://2slides.com/api
2. Log in to your account
3. View your dashboard for current credit balance and usage history

**Via API:**
- Credit balance is returned in API error responses when insufficient
- Check account page for detailed usage tracking

## Credit Expiration

**Credits NEVER expire.** Purchase credits and use them at your own pace without time pressure.

## Best Practices for Credit Management

1. **Start with free credits** - Use your 500 free credits to test features
2. **Calculate needs** - Estimate your typical usage before purchasing
3. **Buy in bulk** - Larger packages offer better value (up to 20% off)
4. **Monitor usage** - Check your dashboard regularly to track consumption
5. **Plan ahead** - Buy credits before you need them to take advantage of promotions

## Rate Limits

Credit purchases do not affect API rate limits:
- Fast PPT: 10 requests per minute
- Nano Banana: 6 requests per minute

Rate limits are based on API tier, not credit balance.

## Common Questions

**Q: Do credits expire?**
A: No, credits never expire.

**Q: Can I get a refund?**
A: Yes, within 3 days of purchase if credits haven't been substantially used.

**Q: What happens if I run out of credits?**
A: API requests will return an INSUFFICIENT_CREDITS error. Purchase more credits to continue.

**Q: Can I share credits with my team?**
A: Currently, credits are tied to individual API keys. Team plans are in development.

**Q: Are there discounts for students or nonprofits?**
A: Contact 2slides support for special pricing inquiries.

**Q: How do I know how many credits I have left?**
A: Check your dashboard at https://2slides.com/api

## Resources

- **Purchase Credits:** https://2slides.com/pricing
- **API Dashboard:** https://2slides.com/api
- **Main Website:** https://2slides.com
- **API Documentation:** See api-reference.md
- **Skill Guide:** See SKILL.md

---

*Pricing information last updated: 2026-02-10*


path: references/mcp-integration.md
content: # MCP Integration Guide

2slides provides an MCP (Model Context Protocol) server for seamless integration with Claude Desktop and other MCP-compatible AI agents.

## What is the MCP Server?

The 2slides MCP server exposes the same API functionality as direct API calls, but through a standardized tool interface that Claude can use directly without requiring script execution.

**Available Tools:**
1. `slides_generate` - Generate slides from content
2. `slides_create_like_this` - Generate slides from reference image
3. `slides_create_pdf_slides` - Generate custom-designed slides (NEW)
4. `slides_generate_narration` - Add AI voice narration (NEW)
5. `slides_download_pages_voices` - Export slides and voices as ZIP (NEW)
6. `themes_search` - Search available themes
7. `jobs_get` - Check job status

**Note:** New tools (3-5) may require MCP server update to latest version.

## Installation & Configuration

2slides MCP server supports two integration modes:

### Mode 1: Streamable HTTP Protocol (Recommended)

Simplest setup using HTTP endpoint. No local installation required.

**Step 1:** Get your API key from https://2slides.com/api

**Step 2:** Configure Claude Desktop

Edit: `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS)

```json
{
  "mcpServers": {
    "2slides": {
      "url": "https://2slides.com/api/mcp?[REDACTED_SECRET]"
    }
  }
}
```

**Step 3:** Restart Claude Desktop completely

**Advantages:**
- ✅ No Node.js or npm required
- ✅ Always uses latest version
- ✅ Faster setup
- ✅ No local dependencies

---

### Mode 2: NPM Package (stdio)

Uses local npm package for MCP server.

**Step 1:** Get your API key from https://2slides.com/api

**Step 2:** Configure Claude Desktop

Edit: `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS)

```json
{
  "mcpServers": {
    "2slides": {
      "command": "npx",
      "args": ["2slides-mcp"],
      "env": {
        "API_KEY": "YOUR_2SLIDES_API_KEY"
      }
    }
  }
}
```

**Step 3:** Restart Claude Desktop completely

**Requirements:**
- Node.js and npm installed
- Internet connection for first-time package download

---

### Verify Installation

After restart, the 2slides tools should be available. Test by asking:
"Search for business themes using 2slides"

## When to Use MCP vs Direct API

### Use MCP Server When:
- Working in Claude Desktop or other MCP-compatible environments
- Want seamless tool integration without script management
- Prefer Claude to handle API calls directly
- Need real-time interaction and feedback

### Use Direct API Scripts When:
- Working in Claude Code CLI
- MCP server is not configured or available
- Need more control over parameters and error handling
- Integrating into custom workflows or automation
- Need to batch process multiple requests

## MCP Tool Details

### slides_generate

Generate slides from user content.

**Parameters:**
- `userInput` (string, required): Content to convert
- `themeId` (string, required): Theme ID from themes_search
- `responseLanguage` (string, optional, default: "Auto"): Language name
- `mode` (string, optional, default: "sync"): "sync" or "async"

**Example:**
```
First search for a theme:
Use themes_search with:
- query: "business"

Then generate with the theme ID:
Use slides_generate with:
- userInput: "Introduction to Python: Variables, Functions, Classes"
- themeId: "theme_abc123"
- mode: "sync"
```

### slides_create_like_this

Generate slides matching a reference image.

**Parameters:**
- `userInput` (string, required): Content for slides
- `referenceImageUrl` (string, required): URL or base64 of reference image
- `responseLanguage` (string, optional, default: "Auto"): Language name
- `aspectRatio` (string, optional, default: "16:9"): width:height format
- `resolution` (string, optional, default: "2K"): "1K", "2K", or "4K"
- `page` (number, optional, default: 1): Number of slides (0 for auto-detection, max 100)
- `contentDetail` (string, optional, default: "concise"): "concise" or "standard"

**Example:**
```
Use slides_create_like_this with:
- userInput: "Sales Report Q4 2025"
- referenceImageUrl: "https://example.com/template.jpg"
- resolution: "2K"
- page: 0  # Auto-detect slide count
- contentDetail: "standard"
```

### themes_search

Search for available themes.

**Parameters:**
- `query` (string, required): Search keyword
- `limit` (number, optional, default: 20, max: 100): Max results

**Example:**
```
Use themes_search with:
- query: "business"
- limit: 10
```

**Note:** Query parameter is required. Search with keywords like "business", "professional", "creative", "education", "modern" to find appropriate themes.

### slides_create_pdf_slides

Generate custom-designed slides from text without a reference image.

**Parameters:**
- `userInput` (string, required): Content for slides
- `responseLanguage` (string, optional, default: "Auto"): Language name
- `aspectRatio` (string, optional, default: "16:9"): width:height format
- `resolution` (string, optional, default: "2K"): "1K", "2K", or "4K"
- `page` (number, optional, default: 1): Number of slides (0 for auto-detection, max 100)
- `contentDetail` (string, optional, default: "concise"): "concise" or "standard"
- `designSpec` (string, optional): Design specifications

**Example:**
```
Use slides_create_pdf_slides with:
- userInput: "Sales Report Q4 2025"
- designSpec: "modern minimalist, blue color scheme"
- resolution: "2K"
- page: 0  # Auto-detect slide count
```

### slides_generate_narration

Add AI voice narration to completed slides.

**Parameters:**
- `jobId` (string, required): Job ID from slide generation (UUID format)
- `language` (string, optional, default: "Auto"): Language for narration
- `voice` (string, optional, default: "Puck"): Voice name (30 options available)
- `multiSpeaker` (boolean, optional, default: false): Enable multi-speaker mode

**Available Voices:**
Puck, Aoede, Charon, Kore, Fenrir, Phoebe, Asteria, Luna, Stella, Theia, Helios, Atlas, Clio, Melpomene, Calliope, Erato, Euterpe, Polyhymnia, Terpsichore, Thalia, Urania, Zeus, Hera, Poseidon, Athena, Apollo, Artemis, Ares, Aphrodite, Hephaestus

**Example:**
```
Use slides_generate_narration with:
- jobId: "abc-123-def-456"
- voice: "Aoede"
- multiSpeaker: true
- language: "English"
```

**Note:** Job must be completed before adding narration. Cost: 210 credits per page.

### slides_download_pages_voices

Download slides as PNG images and voice files as WAV in a ZIP archive.

**Parameters:**
- `jobId` (string, required): Job ID from slide generation

**Example:**
```
Use slides_download_pages_voices with:
- jobId: "abc-123-def-456"
```

**Note:** Completely FREE (no credits). Download URL valid for 1 hour.

### jobs_get

Check status of async job.

**Parameters:**
- `jobId` (string, required): Job ID from async generation

**Response includes:**
- Slide generation status
- Narration status (if applicable)
- Download URLs (when completed)

**Example:**
```
Use jobs_get with:
- jobId: "abc123..."
```

## Troubleshooting

### Tools Not Appearing

1. Verify configuration file syntax is valid JSON
2. For HTTP mode: Check API key is correctly in the URL
3. For npm mode: Ensure API key is correctly set in the `env` section
4. Restart Claude Desktop completely (quit fully, not just close window)
5. Check for error messages in Claude Desktop console

### API Key Issues

- Verify API key is active at https://2slides.com/api
- Check for typos in the configuration
- Ensure no extra quotes or spaces around the key
- For HTTP mode: API key must be in the URL query parameter

### HTTP Mode Issues

- Verify URL format: `https://2slides.com/api/mcp?[REDACTED_SECRET]`
- Check internet connectivity
- Ensure API key has no special characters that need URL encoding

### NPM Mode Issues

- Ensure `npx` is available (requires Node.js)
- Try running `npx 2slides-mcp` manually to check for errors
- Verify internet connection for package download
- Check Node.js version compatibility

## GitHub Repository

For more information, visit: https://github.com/2slides/mcp-2slides


path: references/api-reference.md
content: # 2slides API Reference

Complete API documentation for 2slides slide generation service.

## Base URL

```
https://2slides.com/api/v1
```

## Authentication

All API requests require authentication using a Bearer token in the Authorization header:

```
[REDACTED_SECRET]
```

Get your API key from: https://2slides.com/api

Store the API key in environment variable: `SLIDES_2SLIDES_API_KEY`

## Endpoints

### 1. Generate Slides

Generate slides from user input with optional theme selection.

**Endpoint:** `POST /slides/generate`

**Headers:**
```
[REDACTED_SECRET]
Content-Type: application/json
```

**Request Body:**
```json
{
  "userInput": "string (required) - Content to convert into slides",
  "themeId": "string (required) - Theme ID from themes/search",
  "responseLanguage": "string (optional, default: 'Auto') - Language code",
  "mode": "string (optional, default: 'sync') - 'sync' or 'async'"
}
```

**Supported Languages:**
Auto, English, Simplified Chinese (简体中文), Traditional Chinese (繁體中文), Spanish, Arabic, Portuguese, Indonesian, Japanese, Russian, Hindi, French, German, Vietnamese, Turkish, Polish, Italian, Korean

**Response (sync mode):**
```json
{
  "slideUrl": "https://2slides.com/slides/...",
  "pdfUrl": "https://2slides.com/slides/.../download",
  "status": "completed"
}
```

**Response (async mode):**
```json
{
  "jobId": "abc123...",
  "status": "pending"
}
```

**Notes:**
- **Sync mode**: Waits for generation to complete and returns the result directly (may take 30-60 seconds)
- **Async mode**: Returns immediately with a jobId to poll for results using `/jobs/{jobId}`

---

### 2. Create Like This (Reference Image)

Generate slides matching a reference image style (Nano Banana Pro mode).

**Endpoint:** `POST /slides/create-like-this`

**Headers:**
```
[REDACTED_SECRET]
Content-Type: application/json
```

**Request Body:**
```json
{
  "userInput": "string (required) - Content for slides",
  "referenceImageUrl": "string (required) - URL or base64 of reference image",
  "responseLanguage": "string (optional, default: 'Auto')",
  "aspectRatio": "string (optional, default: '16:9') - width:height format",
  "resolution": "string (optional, default: '2K') - '1K', '2K', or '4K'",
  "page": "number (optional, default: 1) - 0 for auto-detection, max 100",
  "contentDetail": "string (optional, default: 'concise') - 'concise' or 'standard'"
}
```

**Resolution Options:**
- **1K**: Standard quality
- **2K**: High quality (default)
- **4K**: Ultra high quality

**Content Detail Options:**
- **concise**: Brief, keyword-focused content
- **standard**: Comprehensive, detailed content

**Page Parameter:**
- Set to `0` to enable automatic slide count detection
- Set to specific number (1-100) for exact slide count

**Response:**
```json
{
  "success": true,
  "data": {
    "jobId": "608f8997-5207-480c-9ff2-d2475cba6b9d",
    "status": "success",
    "message": "Successfully generated N slides",
    "downloadUrl": "https://...pdf...",
    "jobUrl": "https://2slides.com/workspace?jobId=...",
    "createdAt": 1770108913384,
    "updatedAt": 1770108934015,
    "slidePageCount": 3,
    "successCount": 3,
    "failedCount": 0
  }
}
```

**Response Fields:**
- `success`: Boolean indicating if request succeeded
- `data.jobId`: Unique job identifier
- `data.status`: Generation status ("success" or "failed")
- `data.message`: Human-readable status message
- `data.downloadUrl`: Direct PDF download URL (temporary, expires in 1 hour)
- `data.jobUrl`: View slides in 2slides workspace
- `data.slidePageCount`: Number of slides generated
- `data.successCount`: Number of successfully generated slides
- `data.failedCount`: Number of failed slides

**Notes:**
- This endpoint always runs synchronously
- Processing time: ~30 seconds per page
- Typical response time: 30-60 seconds for 1-2 pages
- Automatically generates PDF
- Matches the style and design of the reference image
- **Timeout recommendation**: Set timeout to `max(120, pages * 40)` seconds

---

### 3. Create PDF Slides

Generate custom-designed slides from text with optional design specifications.

**Endpoint:** `POST /slides/create-pdf-slides`

**Headers:**
```
[REDACTED_SECRET]
Content-Type: application/json
```

**Request Body:**
```json
{
  "userInput": "string (required) - Content for slides",
  "responseLanguage": "string (optional, default: 'Auto')",
  "aspectRatio": "string (optional, default: '16:9') - width:height format",
  "resolution": "string (optional, default: '2K') - '1K', '2K', or '4K'",
  "page": "number (optional, default: 1) - 0 for auto-detection, max 100",
  "contentDetail": "string (optional, default: 'concise') - 'concise' or 'standard'",
  "designSpec": "string (optional) - Design specifications (e.g., 'modern minimalist')"
}
```

**Response:**
```json
{
  "success": true,
  "data": {
    "jobId": "608f8997-5207-480c-9ff2-d2475cba6b9d",
    "status": "success",
    "message": "Successfully generated N slides",
    "downloadUrl": "https://...pdf...",
    "jobUrl": "https://2slides.com/workspace?jobId=...",
    "slidePageCount": 3,
    "successCount": 3,
    "failedCount": 0
  }
}
```

**Notes:**
- Similar to create-like-this but without reference image
- Uses AI to generate custom design based on content and design specs
- Same credit costs: 100 credits/page (1K/2K), 200 credits/page (4K)
- Processing time: ~30 seconds per page
- Always runs synchronously

---

### 4. Generate Narration

Add AI voice narration to slides in single or multi-speaker mode.

**Endpoint:** `POST /slides/generate-narration`

**Headers:**
```
[REDACTED_SECRET]
Content-Type: application/json
```

**Request Body:**
```json
{
  "jobId": "string (required) - Job ID from slide generation (UUID format)",
  "language": "string (optional, default: 'Auto') - Language for narration",
  "voice": "string (optional, default: 'Puck') - Voice name from available voices",
  "multiSpeaker": "boolean (optional, default: false) - Enable multi-speaker mode"
}
```

**Available Voices (30 total):**
Puck, Aoede, Charon, Kore, Fenrir, Phoebe, Asteria, Luna, Stella, Theia, Helios, Atlas, Clio, Melpomene, Calliope, Erato, Euterpe, Polyhymnia, Terpsichore, Thalia, Urania, Zeus, Hera, Poseidon, Athena, Apollo, Artemis, Ares, Aphrodite, Hephaestus

**Response:**
```json
{
  "success": true,
  "jobId": "abc123...",
  "status": "pending",
  "message": "Narration generation started"
}
```

**Notes:**
- Job must be completed before adding narration
- Job ID must be UUID format for Nano Banana jobs
- Cost: 210 credits per page (10 for text, 200 for audio)
- Runs asynchronously - poll with /jobs/{jobId}
- Multi-speaker mode uses different voices for variety
- 19 languages supported plus auto-detection

---

### 5. Download Slides Pages and Voices

Export slides as PNG files and voice narrations as WAV files in a ZIP archive.

**Endpoint:** `POST /slides/download-slides-pages-voices`

**Headers:**
```
[REDACTED_SECRET]
Content-Type: application/json
```

**Request Body:**
```json
{
  "jobId": "string (required) - Job ID from slide generation"
}
```

**Response:**
```json
{
  "success": true,
  "downloadUrl": "https://...zip...",
  "message": "Download ready"
}
```

**Archive Contents:**
- Pages: PNG files for each slide
- Voices: WAV audio files (if narration generated)
- Transcripts: Text files with narration transcripts

**Notes:**
- **Cost: Completely FREE** (no credits used)
- Download URL valid for **1 hour only**
- High quality PNG export
- WAV format for audio
- Includes all slides and voice files

---

### 6. Search Themes

Search for available presentation themes.

**Endpoint:** `GET /themes/search`

**Headers:**
```
[REDACTED_SECRET]
```

**Query Parameters:**
```
query: string (required) - Search keyword
limit: number (optional, default: 20, max: 100)
```

**Response:**
```json
{
  "themes": [
    {
      "id": "theme_id_123",
      "name": "Professional Blue",
      "description": "Clean professional theme with blue accents",
      "previewUrl": "https://..."
    }
  ],
  "count": 1
}
```

---

### 7. Get Job Status

Retrieve the status and results of an async generation job.

**Endpoint:** `GET /jobs/{jobId}`

**Headers:**
```
[REDACTED_SECRET]
```

**Path Parameters:**
```
jobId: string (required) - Job ID from async generation
```

**Response:**
```json
{
  "jobId": "abc123",
  "status": "completed|pending|failed",
  "slideUrl": "https://2slides.com/slides/...",
  "pdfUrl": "https://2slides.com/slides/.../download",
  "narrationStatus": "completed|pending|not_started",
  "error": "error message if failed"
}
```

**Status Values:**
- `pending`: Job is still processing
- `completed`: Slides are ready
- `failed`: Generation failed (see error field)

**Narration Status Values:**
- `not_started`: No narration requested
- `pending`: Narration is being generated
- `completed`: Narration is ready

**Polling Recommendation:**
Poll every 20-30 seconds to avoid server strain

---

## Error Handling

All endpoints return standard HTTP status codes:

- `200 OK`: Request succeeded
- `400 Bad Request`: Invalid parameters
- `401 Unauthorized`: Missing or invalid API key
- `404 Not Found`: Resource not found
- `429 Too Many Requests`: Rate limit exceeded
- `500 Internal Server Error`: Server error

**Error Response Format:**
```json
{
  "error": "Error message",
  "code": "ERROR_CODE"
}
```

**Common Error Codes:**
- `INSUFFICIENT_CREDITS`: Account has insufficient credits
- `INVALID_JOB_ID`: Job ID not found or invalid format
- `RATE_LIMIT_EXCEEDED`: Too many requests (see rate limits below)
- `JOB_NOT_COMPLETED`: Job must complete before adding narration
- `INVALID_UUID`: Job ID must be UUID format (for Nano Banana jobs)

---

## Credit Costs

- **Fast PPT (generate endpoint)**: 10 credits per page
- **Nano Banana 1K/2K (create-like-this, create-pdf-slides)**: 100 credits per page
- **Nano Banana 4K**: 200 credits per page
- **Voice Narration**: 210 credits per page (10 for text, 200 for audio)
- **Download Export**: FREE (no credits)

## Purchasing Credits

2slides operates on a **pay-as-you-go credit system** with no subscriptions.

**Credit Packages** (Current promotion: up to 20% off):

| Credits | Price | Cost per 1,000 | Savings |
|---------|-------|---------------|---------|
| 2,000 | $5.00 | $2.50 | — |
| 4,000 | $9.50 | $2.38 | 5% |
| 10,000 | $22.50 | $2.25 | 10% |
| 20,000 | $42.50 | $2.13 | 15% |
| 40,000 | $80.00 | $2.00 | 20% |

**Key Benefits:**
- New users get **500 free credits** (~50 Fast PPT pages)
- **Credits never expire**
- No monthly subscriptions
- 3-day refund window
- Purchase at: https://2slides.com/pricing

**Example Costs:**
- 10-slide Fast PPT presentation: 100 credits ($0.25 with largest package)
- 10-slide Nano Banana 2K presentation: 1,000 credits ($2.00 with largest package)
- 10-slide presentation with narration: 2,100 credits ($4.20 with largest package)

## Rate Limits

Different endpoints have different rate limits:

- **Fast PPT (generate)**: 10 requests per minute
- **Nano Banana (create-like-this, create-pdf-slides)**: 6 requests per minute

**Best Practices:**
- Poll async jobs every 20-30 seconds to avoid server strain
- If rate limited (429 error), wait before retrying
- Check your plan's rate limits at https://2slides.com/api

## Download URL Expiration

All download URLs (PDF, ZIP archives) remain valid for **1 hour only**. Download files promptly after generation.

---

## Best Practices

### Content Formatting

**For best results, structure content clearly:**

```
Title: Introduction to AI

Section 1: Machine Learning
- Definition
- Key concepts
- Applications

Section 2: Deep Learning
- Neural networks
- Training process
- Use cases
```

### Choosing Sync vs Async Mode

- **Use sync** for quick generations (<5 slides)
- **Use async** for larger presentations (>5 slides)
- **Use async** when integrating into workflows that can poll

### Theme Selection

1. Search themes with relevant keywords
2. Preview themes if URLs available
3. Use theme ID in generation request
4. Leave theme blank for default styling

### Language Support

Specify `responseLanguage` to generate slides in different languages:
- `"Auto"` - Automatic language detection (default)
- `"English"` - English
- `"Simplified Chinese"` - 简体中文
- `"Traditional Chinese"` - 繁體中文
- `"Spanish"` - Español
- `"Arabic"` - العربية
- `"Portuguese"` - Português
- `"Indonesian"` - Bahasa Indonesia
- `"Japanese"` - 日本語
- `"Russian"` - Русский
- `"Hindi"` - हिन्दी
- `"French"` - Français
- `"German"` - Deutsch
- `"Vietnamese"` - Tiếng Việt
- `"Turkish"` - Türkçe
- `"Polish"` - Polski
- `"Italian"` - Italiano
- `"Korean"` - 한국어


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: suspicious | SkillSpector: suspicious (CRITICAL)