Back to PPT Agent

PPT Agent API Documentation

Complete REST API documentation for creating, managing, and retrieving presentations programmatically

API Overview

PPT Agent provides a comprehensive REST API for programmatic access to presentation management. All endpoints include rate limiting for optimal performance and are publicly accessible.

RESTfulPublicRate LimitedJSON

Base URL & Authentication

Base URL

Development:
http://localhost:3000/api
Production:
https://your-domain.com/api

Authentication

All endpoints are publicly accessible. No authentication required.

Note:
No authentication headers required

Rate Limiting

100
GET Requests
per minute
20
POST Requests
per minute
30
PUT Requests
per minute
10
DELETE Requests
per minute
Rate Limit Response:
When rate limits are exceeded, you'll receive a 429 status code with a retry-after header.
Best Practices:
Implement exponential backoff and respect retry-after headers for optimal API usage.

API Endpoints

List Presentations

GET/presentations
Description:

Retrieve all presentations for the authenticated user, sorted by modification date.

Response Format:
[
  {
    "id": "my-presentation",
    "name": "My Presentation",
    "description": "A sample presentation",
    "theme": "default",
    "created": "2024-01-12T23:17:31.000Z",
    "updated": "2024-01-12T23:17:31.000Z",
    "slideCount": 5
  }
]
Example Request:
curl -X GET http://localhost:3000/api/presentations
Success Response (200):

Array of presentation objects

Error Response (429):

Rate limit exceeded

Create Presentation

POST/presentations
Description:

Create a new presentation with the specified configuration.

Request Body:
{
  "name": "My New Presentation",
  "description": "A presentation created via API",
  "theme": "dark"
}
Required Fields:
  • name (string) - Presentation name
Optional Fields:
  • description (string) - Presentation description
  • theme (string) - Theme name
Validation Rules:
  • • Name must be 1-100 characters
  • • Name can only contain letters, numbers, spaces, hyphens, underscores, and basic punctuation
  • • Description must be 500 characters or less
  • • Theme must be 50 characters or less
  • • Maximum 20 presentations per user
Example Request:
curl -X POST http://localhost:3000/api/presentations \
  -H "Content-Type: application/json" \
  -d '{
    "name": "API Presentation",
    "description": "Created via REST API",
    "theme": "dark"
  }'
Success Response (201):

Created presentation object

Error Response (400):

Validation failed

Error Response (409):

Presentation already exists

Update Presentation

PUT/presentations
Description:

Update an existing presentation's metadata.

Request Body:
{
  "id": "my-presentation",
  "name": "Updated Presentation Name",
  "description": "Updated description",
  "theme": "light",
  "slideCount": 10
}
Required Fields:
  • id (string) - Presentation ID
Optional Fields:
  • name (string) - Updated name
  • description (string) - Updated description
  • theme (string) - Updated theme
  • slideCount (number) - Updated slide count
Example Request:
curl -X PUT http://localhost:3000/api/presentations \
  -H "Content-Type: application/json" \
  -d '{
    "id": "my-presentation",
    "name": "Updated Name",
    "description": "Updated description"
  }'
Success Response (200):

Updated presentation object

Error Response (400):

Validation failed

Error Response (403):

Access denied - not owner

Delete Presentation

DELETE/presentations
Description:

Delete a presentation by ID. Requires ownership verification.

Query Parameters:
  • id (string, required) - Presentation ID to delete
Example Request:
curl -X DELETE "http://localhost:3000/api/presentations?id=my-presentation"
Success Response (200):

{ success: true }

Error Response (400):

Missing presentation ID

Error Response (403):

Access denied - not owner

List Slides

GET/slides
Description:

Retrieve all slides for a specific presentation.

Query Parameters:
  • presentationId (string, required) - Presentation ID
Example Request:
curl -X GET "http://localhost:3000/api/slides?presentationId=my-presentation"
Success Response (200):

Array of slide objects with id, filename, and content

Error Response (400):

Missing presentationId

Create Slide

POST/slides
Description:

Create a new slide in a presentation. Supports all slide types including timeline, hero, stats, infographic, and more.

Request Body:
{
  "presentationId": "my-presentation",
  "type": "timeline",
  "title": "2026 Roadmap",
  "subtitle": "Strategic Plan",
  "points": [
    { "date": "Q1 2026", "title": "Foundation" },
    { "date": "Q2 2026", "title": "Launch" }
  ]
}
Supported Slide Types:
hero - Title slide
timeline - Roadmap
stats - Statistics
infographic - Visual cards
bullets - Bullet points
quote - Quote slide
split - Split layout
gallery - Image gallery
+18 more
Example - Timeline from Google Sheets:
curl -X POST http://localhost:3000/api/slides \
  -H "Content-Type: application/json" \
  -d '{
    "presentationId": "roadmap-2026",
    "type": "timeline",
    "title": "Product Roadmap",
    "subtitle": "2026 Strategic Plan",
    "points": [
      {"date": "Q1", "title": "Foundation"},
      {"date": "Q2", "title": "Launch"},
      {"date": "Q3", "title": "Scale"},
      {"date": "Q4", "title": "Expand"}
    ]
  }'
Example - Stats Slide:
curl -X POST http://localhost:3000/api/slides \
  -H "Content-Type: application/json" \
  -d '{
    "presentationId": "my-presentation",
    "type": "stats",
    "title": "Key Metrics",
    "stats": [
      {"value": "150+", "label": "Customers"},
      {"value": "99.9%", "label": "Uptime"},
      {"value": "50ms", "label": "Latency"}
    ]
  }'
Example - Infographic:
curl -X POST http://localhost:3000/api/slides \
  -H "Content-Type: application/json" \
  -d '{
    "presentationId": "my-presentation",
    "type": "infographic",
    "title": "Our Values",
    "items": [
      {"icon": "users", "value": "Team", "label": "50+ Engineers", "color": "#3b82f6"},
      {"icon": "zap", "value": "Speed", "label": "10x Faster", "color": "#10b981"}
    ],
    "layout": "horizontal"
  }'
Success Response (201):

Created slide object

Error Response (400):

Validation failed

Error Response (404):

Presentation not found

Delete Slide

DELETE/slides
Description:

Delete a slide from a presentation by slide ID.

Query Parameters:
  • presentationId (string, required) - Presentation ID
  • slideId (string, required) - Slide ID to delete
Example Request:
curl -X DELETE "http://localhost:3000/api/slides?presentationId=my-presentation&slideId=01-my-slide"
Success Response (200):

{ success: true }

Error Response (400):

Missing parameters

Error Response (404):

Slide not found

Error Handling

HTTP Status Codes

200Success
Request completed successfully
201Created
Resource created successfully
400Bad Request
Invalid request format or validation failed
401Unauthorized
Authentication required or invalid token
403Forbidden
Access denied - not owner of resource
404Not Found
Resource not found
409Conflict
Resource already exists
429Too Many Requests
Rate limit exceeded
500Internal Server Error
Server error occurred

Error Response Format

{
  "error": "Validation failed",
  "details": [
    "name: Name is required",
    "description: Description must be 500 characters or less"
  ]
}
{
  "error": "Unauthorized"
}

Code Examples

JavaScript/Node.js

import fetch from 'node-fetch';

class VisionDeckAPI {
  constructor(baseUrl) {
    this.baseUrl = baseUrl;
    this.headers = {
      'Content-Type': 'application/json'
    };
  }

  async listPresentations() {
    const response = await fetch(`${this.baseUrl}/presentations`, {
      headers: this.headers
    });
    return response.json();
  }

  async createPresentation(data) {
    const response = await fetch(`${this.baseUrl}/presentations`, {
      method: 'POST',
      headers: this.headers,
      body: JSON.stringify(data)
    });
    return response.json();
  }

  async updatePresentation(id, data) {
    const response = await fetch(`${this.baseUrl}/presentations`, {
      method: 'PUT',
      headers: this.headers,
      body: JSON.stringify({ id, ...data })
    });
    return response.json();
  }

  async deletePresentation(id) {
    const response = await fetch(`${this.baseUrl}/presentations?id=${id}`, {
      method: 'DELETE',
      headers: this.headers
    });
    return response.json();
  }
}

// Usage
const api = new VisionDeckAPI('http://localhost:3000/api');

// Create a presentation
const presentation = await api.createPresentation({
  name: 'My API Presentation',
  description: 'Created via JavaScript API'
});

console.log('Created:', presentation);

// --- Slides API ---
async listSlides(presentationId) {
  const response = await fetch(`${this.baseUrl}/slides?presentationId=${presentationId}`, {
    headers: this.headers
  });
  return response.json();
}

async createSlide(data) {
  const response = await fetch(`${this.baseUrl}/slides`, {
    method: 'POST',
    headers: this.headers,
    body: JSON.stringify(data)
  });
  return response.json();
}

async deleteSlide(presentationId, slideId) {
  const response = await fetch(`${this.baseUrl}/slides?presentationId=${presentationId}&slideId=${slideId}`, {
    method: 'DELETE',
    headers: this.headers
  });
  return response.json();
}

// Create a timeline slide (great for roadmaps from Google Sheets!)
const timelineSlide = await api.createSlide({
  presentationId: 'my-roadmap',
  type: 'timeline',
  title: '2026 Product Roadmap',
  subtitle: 'Strategic Plan',
  points: [
    { date: 'Q1 2026', title: 'Foundation' },
    { date: 'Q2 2026', title: 'Launch' },
    { date: 'Q3 2026', title: 'Scale' },
    { date: 'Q4 2026', title: 'Expand' }
  ]
});

console.log('Created slide:', timelineSlide.id);

Python

import requests
import json

class VisionDeckAPI:
    def __init__(self, base_url):
        self.base_url = base_url
        self.headers = {
            'Content-Type': 'application/json'
        }

    def list_presentations(self):
        response = requests.get(f'{self.base_url}/presentations', headers=self.headers)
        response.raise_for_status()
        return response.json()

    def create_presentation(self, name, description=None, theme=None):
        data = {'name': name}
        if description:
            data['description'] = description
        if theme:
            data['theme'] = theme

        response = requests.post(f'{self.base_url}/presentations', 
                               headers=self.headers, 
                               json=data)
        response.raise_for_status()
        return response.json()

    def update_presentation(self, presentation_id, **kwargs):
        data = {'id': presentation_id, **kwargs}
        response = requests.put(f'{self.base_url}/presentations', 
                              headers=self.headers, 
                              json=data)
        response.raise_for_status()
        return response.json()

    def delete_presentation(self, presentation_id):
        response = requests.delete(f'{self.base_url}/presentations?id={presentation_id}', 
                                 headers=self.headers)
        response.raise_for_status()
        return response.json()

# Usage
api = VisionDeckAPI('http://localhost:3000/api')

# Create a presentation
presentation = api.create_presentation(
    name='Python API Presentation',
    description='Created via Python API',
    theme='dark'
)

print(f"Created: {presentation['id']}")

# --- Slides API ---
def list_slides(self, presentation_id):
    response = requests.get(f'{self.base_url}/slides?presentation_id={presentation_id}', 
                             headers=self.headers)
    response.raise_for_status()
    return response.json()

def create_slide(self, presentation_id, slide_type, title, **kwargs):
    data = {
        'presentationId': presentation_id,
        'type': slide_type,
        'title': title
    }
    data.update(kwargs)
    
    response = requests.post(f'{self.base_url}/slides', 
                           headers=self.headers, 
                           json=data)
    response.raise_for_status()
    return response.json()

def delete_slide(self, presentation_id, slide_id):
    response = requests.delete(f'{self.base_url}/slides?presentation_id={presentation_id}&slide_id={slide_id}', 
                             headers=self.headers)
    response.raise_for_status()
    return response.json()

# Create a timeline slide from Google Sheets data
timeline_slide = api.create_slide(
    presentation_id='my-roadmap',
    slide_type='timeline',
    title='2026 Product Roadmap',
    subtitle='Strategic Plan',
    points=[
        {'date': 'Q1 2026', 'title': 'Foundation'},
        {'date': 'Q2 2026', 'title': 'Launch'},
        {'date': 'Q3 2026', 'title': 'Scale'},
        {'date': 'Q4 2026', 'title': 'Expand'}
    ]
)

print(f"Created slide: {timeline_slide['id']}")

cURL Examples

# List presentations
curl -X GET http://localhost:3000/api/presentations

# Create presentation
curl -X POST http://localhost:3000/api/presentations \
  -H "Content-Type: application/json" \
  -d '{
    "name": "cURL Presentation",
    "description": "Created via cURL"
  }'

# Update presentation
curl -X PUT http://localhost:3000/api/presentations \
  -H "Content-Type: application/json" \
  -d '{
    "id": "curl-presentation",
    "name": "Updated cURL Presentation"
  }'

# Delete presentation
curl -X DELETE "http://localhost:3000/api/presentations?id=curl-presentation"

# --- Slides API ---

# List slides in a presentation
curl -X GET "http://localhost:3000/api/slides?presentationId=my-presentation"

# Create a timeline slide (roadmap from Google Sheets!)
curl -X POST http://localhost:3000/api/slides \
  -H "Content-Type: application/json" \
  -d '{
    "presentationId": "my-roadmap",
    "type": "timeline",
    "title": "2026 Product Roadmap",
    "subtitle": "Strategic Plan",
    "points": [
      {"date": "Q1 2026", "title": "Foundation"},
      {"date": "Q2 2026", "title": "Launch"},
      {"date": "Q3 2026", "title": "Scale"},
      {"date": "Q4 2026", "title": "Expand"}
    ]
  }'

# Create a stats slide
curl -X POST http://localhost:3000/api/slides \
  -H "Content-Type: application/json" \
  -d '{
    "presentationId": "my-presentation",
    "type": "stats",
    "title": "Key Metrics",
    "stats": [
      {"value": "150+", "label": "Customers"},
      {"value": "99.9%", "label": "Uptime"},
      {"value": "50ms", "label": "Latency"}
    ]
  }'

# Delete a slide
curl -X DELETE "http://localhost:3000/api/slides?presentationId=my-presentation&slideId=01-my-slide"

Best Practices

API Usage

  • Authentication: Store tokens securely and refresh as needed
  • Error Handling: Always check response status codes
  • Rate Limiting: Implement exponential backoff for retries
  • Validation: Validate input data before sending requests
  • Caching: Cache GET responses when appropriate

Security

  • HTTPS: Always use HTTPS in production
  • Token Storage: Never expose tokens in client-side code
  • Input Sanitization: Sanitize all user inputs
  • CORS: Configure CORS policies appropriately
  • Logging: Log API calls for monitoring and debugging

Common Patterns

CRUD Operations

Use standard HTTP methods: GET (read), POST (create), PUT (update), DELETE (delete)

Error Handling

Always handle 4xx and 5xx responses gracefully with appropriate user feedback

Rate Limiting

Implement retry logic with exponential backoff when hitting rate limits

Troubleshooting

Authentication Issues

  • Problem: Getting 401 Unauthorized errors
  • Solution: Verify your token is valid and not expired
  • Check: Token format, expiration, and proper header inclusion

Rate Limiting

  • Problem: Getting 429 Too Many Requests
  • Solution: Implement exponential backoff and respect retry-after headers
  • Check: Your request frequency and implement caching where appropriate

Validation Errors

  • Problem: Getting 400 Bad Request with validation errors
  • Solution: Check the error details and validate your input data
  • Check: Required fields, data types, and length restrictions

CORS Issues

  • Problem: CORS errors in browser
  • Solution: Configure CORS settings in your application
  • Check: Allowed origins, methods, and headers

For more information, visit our user guide or check out the GitHub repository for additional examples and documentation.