Gamma APIgamma.app ↗
Generate AI-powered presentations, documents, and webpages via Gamma.app's API. Create from scratch or templates, poll generation status, and export to PDF or PPTX.
What is the Gamma API?
This API provides 6 endpoints for creating and managing AI-generated content on Gamma.app, covering presentations, documents, and webpages. The generate_content endpoint kicks off a new generation job and returns an id and status for async tracking, while get_export_urls delivers both pdfUrl and pptxUrl download links once a job completes. Workspace organization utilities for themes and folders are also included.
curl -X POST 'https://api.parse.bot/scraper/e7bdebeb-3e3e-4708-a3b2-68d721909cd5/generate_content' \
-H 'X-API-Key: $PARSE_API_KEY' \
-H 'Content-Type: application/json' \
-d '{}'Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace gamma-app-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
"""
Gamma API Client via Parse.bot
AI-powered presentation generation with Gamma.app
Get your API key from: https://gamma.app/settings/api
"""
import os
import time
import requests
from typing import Optional, Any, Dict, List
class ParseClient:
"""Client for interacting with Gamma API through Parse.bot scraper."""
def __init__(self, api_key: Optional[str] = None):
"""
Initialize the Parse API client.
Args:
api_key: Parse API key. Defaults to PARSE_API_KEY environment variable.
"""
self.base_url = "https://api.parse.bot"
self.scraper_id = "e7bdebeb-3e3e-4708-a3b2-68d721909cd5"
self.api_key = api_key or os.getenv("PARSE_API_KEY")
if not self.api_key:
raise ValueError("API key required. Set PARSE_API_KEY or pass api_key parameter.")
def _call(self, endpoint: str, method: str = "POST", **params) -> Dict[str, Any]:
"""
Make a request to the Parse API endpoint.
Args:
endpoint: The endpoint name (e.g., 'generate_content')
method: HTTP method ('GET' or 'POST')
**params: Query/body parameters
Returns:
Response JSON as dictionary
"""
url = f"{self.base_url}/scraper/{self.scraper_id}/{endpoint}"
headers = {
"X-API-Key": self.api_key,
"Content-Type": "application/json"
}
if method.upper() == "GET":
response = requests.get(url, headers=headers, params=params)
elif method.upper() == "POST":
response = requests.post(url, headers=headers, json=params)
else:
raise ValueError(f"Unsupported method: {method}")
response.raise_for_status()
return response.json()
def generate_content(
self,
input_text: str,
text_mode: str = "generate",
format: Optional[str] = None,
num_cards: Optional[int] = None,
theme_id: Optional[str] = None,
export_as: Optional[str] = None,
additional_instructions: Optional[str] = None,
image_options: Optional[Dict] = None,
text_options: Optional[Dict] = None,
card_options: Optional[Dict] = None,
sharing_options: Optional[Dict] = None,
folder_ids: Optional[str] = None,
card_split: Optional[str] = None,
) -> str:
"""
Generate a new AI-powered gamma (presentation, document, or webpage).
Args:
input_text: The content or topic to generate from
text_mode: How to process input ('generate', 'condense', 'preserve')
format: Type of content ('presentation', 'document', 'social', 'webpage')
num_cards: Number of cards to generate
theme_id: ID of the theme to apply
export_as: Auto-export as 'pdf' or 'pptx'
additional_instructions: Extra AI instructions
image_options: JSON object for image settings
text_options: JSON object for text settings
card_options: JSON object for card settings
sharing_options: JSON object for sharing settings
folder_ids: Folder ID or comma-separated string
card_split: How to split content into cards
Returns:
Generation ID string
"""
params = {
"input_text": input_text,
"text_mode": text_mode,
"api_key": self.api_key
}
if format:
params["format"] = format
if num_cards:
params["numCards"] = num_cards
if theme_id:
params["themeId"] = theme_id
if export_as:
params["exportAs"] = export_as
if additional_instructions:
params["additionalInstructions"] = additional_instructions
if image_options:
params["imageOptions"] = image_options
if text_options:
params["textOptions"] = text_options
if card_options:
params["cardOptions"] = card_options
if sharing_options:
params["sharingOptions"] = sharing_options
if folder_ids:
params["folderIds"] = folder_ids
if card_split:
params["cardSplit"] = card_split
response = self._call("generate_content", method="POST", **params)
return response["data"]["id"]
def get_generation_status(self, generation_id: str) -> Dict[str, Any]:
"""
Poll the status of an async generation job.
Args:
generation_id: The ID of the generation to check
Returns:
Status response with 'status', 'gammaId', 'id'
"""
params = {
"generation_id": generation_id,
"api_key": self.api_key
}
response = self._call("get_generation_status", method="GET", **params)
return response["data"]
def get_export_urls(self, generation_id: str) -> Dict[str, str]:
"""
Retrieve PDF and PPTX export URLs for a generation.
Args:
generation_id: The ID of the generation
Returns:
Dictionary with 'pdfUrl' and 'pptxUrl' download URLs
"""
params = {
"generation_id": generation_id,
"api_key": self.api_key
}
response = self._call("get_export_urls", method="GET", **params)
return response["data"]
def create_from_template(
self,
template_gamma_id: str,
prompt: str,
theme_id: Optional[str] = None,
export_as: Optional[str] = None,
image_options: Optional[Dict] = None,
sharing_options: Optional[Dict] = None,
folder_ids: Optional[str] = None,
) -> str:
"""
Create a new gamma based on an existing template.
Args:
template_gamma_id: The ID of the template gamma to use
prompt: Instructions for creating from the template
theme_id: ID of the theme to apply
export_as: Auto-export as 'pdf' or 'pptx'
image_options: JSON object for image settings
sharing_options: JSON object for sharing settings
folder_ids: Folder ID or comma-separated string
Returns:
Generation ID string
"""
params = {
"template_gamma_id": template_gamma_id,
"prompt": prompt,
"api_key": self.api_key
}
if theme_id:
params["themeId"] = theme_id
if export_as:
params["exportAs"] = export_as
if image_options:
params["imageOptions"] = image_options
if sharing_options:
params["sharingOptions"] = sharing_options
if folder_ids:
params["folderIds"] = folder_ids
response = self._call("create_from_template", method="POST", **params)
return response["data"]["id"]
def list_themes(
self,
query: Optional[str] = None,
limit: Optional[int] = None,
after: Optional[str] = None
) -> Dict[str, Any]:
"""
List themes available in the workspace.
Args:
query: Search for themes by name
limit: Max results to return
after: Cursor token for pagination
Returns:
Dictionary with 'data', 'hasMore', and pagination info
"""
params = {"api_key": self.api_key}
if query:
params["query"] = query
if limit:
params["limit"] = limit
if after:
params["after"] = after
response = self._call("list_themes", method="GET", **params)
return response["data"]
def list_folders(
self,
query: Optional[str] = None,
limit: Optional[int] = None,
after: Optional[str] = None
) -> Dict[str, Any]:
"""
List folders in the workspace.
Args:
query: Search for folders by name
limit: Max results to return
after: Cursor token for pagination
Returns:
Dictionary with 'data', 'hasMore', and pagination info
"""
params = {"api_key": self.api_key}
if query:
params["query"] = query
if limit:
params["limit"] = limit
if after:
params["after"] = after
response = self._call("list_folders", method="GET", **params)
return response["data"]
def poll_until_complete(
client: ParseClient,
generation_id: str,
max_wait_seconds: int = 600,
poll_interval: int = 5
) -> Optional[Dict[str, Any]]:
"""
Poll until a generation completes.
Args:
client: ParseClient instance
generation_id: ID of the generation to monitor
max_wait_seconds: Maximum time to wait in seconds
poll_interval: Seconds between polls
Returns:
Final status response if completed, None if timeout
"""
start_time = time.time()
while time.time() - start_time < max_wait_seconds:
status_data = client.get_generation_status(generation_id)
status = status_data.get("status")
if status == "completed":
return status_data
elif status == "failed":
print(f" ✗ Generation failed")
return None
print(f" ⏳ Status: {status}")
time.sleep(poll_interval)
print(f" ⚠ Timeout waiting for generation")
return None
if __name__ == "__main__":
client = ParseClient()
print("\n" + "=" * 70)
print("GAMMA API: COMPLETE WORKFLOW")
print("=" * 70)
# Step 1: Discover themes and folders
print("\n[Step 1] Discovering themes and folders in workspace...")
themes_data = client.list_themes(limit=5)
themes = themes_data.get("data", [])
print(f" Found {len(themes)} available themes")
selected_theme_id = None
if themes:
selected_theme = themes[0]
selected_theme_id = selected_theme.get("id")
print(f" → Selected theme: {selected_theme.get('name', 'Unknown')}")
folders_data = client.list_folders(limit=5)
folders = folders_data.get("data", [])
print(f" Found {len(folders)} available folders")
selected_folder_id = None
if folders:
selected_folder = folders[0]
selected_folder_id = selected_folder.get("id")
print(f" → Selected folder: {selected_folder.get('name', 'Unknown')}")
# Step 2: Generate presentations on different topics
print("\n[Step 2] Generating presentations from topics...")
topics = [
{
"title": "AI in Healthcare",
"description": "Medical applications and patient care innovations"
},
{
"title": "Sustainable Energy",
"description": "Renewable sources and environmental impact"
}
]
generations = {}
for topic in topics:
title = topic["title"]
description = topic["description"]
prompt = f"{title}: {description}"
print(f"\n Generating: '{title}'")
try:
gen_id = client.generate_content(
input_text=prompt,
text_mode="generate",
format="presentation",
num_cards=6,
theme_id=selected_theme_id,
folder_ids=selected_folder_id,
additional_instructions="Include real-world examples and statistics"
)
generations[title] = {
"generation_id": gen_id,
"status": "pending",
"gamma_id": None,
"export_urls": None
}
print(f" ✓ Started: {gen_id}")
except Exception as e:
print(f" ✗ Error: {str(e)}")
# Step 3: Monitor all generations
print("\n[Step 3] Monitoring generation progress...")
for title, gen_info in generations.items():
gen_id = gen_info["generation_id"]
print(f"\n '{title}' ({gen_id}):")
status_response = poll_until_complete(client, gen_id, max_wait_seconds=120)
if status_response:
gen_info["status"] = status_response.get("status")
gen_info["gamma_id"] = status_response.get("gammaId")
print(f" ✓ Complete! Gamma ID: {gen_info['gamma_id']}")
else:
gen_info["status"] = "failed"
print(f" ✗ Generation did not complete")
# Step 4: Retrieve export URLs for completed generations
print("\n[Step 4] Retrieving export URLs...")
completed_count = 0
for title, gen_info in generations.items():
if gen_info["status"] != "completed":
continue
gen_id = gen_info["generation_id"]
print(f"\n '{title}':")
try:
export_urls = client.get_export_urls(gen_id)
gen_info["export_urls"] = export_urls
completed_count += 1
pdf_url = export_urls.get("pdfUrl", "N/A")
pptx_url = export_urls.get("pptxUrl", "N/A")
if pdf_url != "N/A":
print(f" 📄 PDF: {pdf_url[:50]}...")
if pptx_url != "N/A":
print(f" 📊 PPTX: {pptx_url[:50]}...")
except Exception as e:
print(f" ✗ Error retrieving URLs: {str(e)}")
# Summary
print("\n" + "=" * 70)
print(f"SUMMARY: {completed_count}/{len(generations)} presentations ready")
print("=" * 70)
for title, gen_info in generations.items():
status_symbol = "✓" if gen_info["status"] == "completed" else "✗"
gamma_id = gen_info.get("gamma_id", "N/A")
print(f" {status_symbol} {title:<25} → {gamma_id}")
print()Creates a new AI-generated gamma (presentation, document, or webpage) from scratch. Sends the request to Gamma's generation API and returns the generation object with an ID for tracking progress. Requires a valid Gamma API key.
| Param | Type | Description |
|---|---|---|
| format | string | Output format such as presentation, document, or webpage |
| api_keyrequired | string | Gamma API key obtained from https://gamma.app/settings/api |
| themeId | string | Theme ID to apply to the generated content |
| exportAs | string | Export format |
| numCards | integer | Number of cards/slides to generate |
| cardSplit | string | Card split preference |
| folderIds | string | Comma-separated folder IDs or JSON array of folder IDs to organize the generated content |
| text_mode | string | Text generation mode |
| input_textrequired | string | The text prompt or content to generate from |
| cardOptions | object | Card layout options as a JSON object |
| textOptions | object | Text generation options as a JSON object |
| imageOptions | object | Image generation options as a JSON object |
| sharingOptions | object | Sharing settings as a JSON object |
| additionalInstructions | string | Additional instructions for AI generation |
{
"type": "object",
"fields": {
"id": "string - generation ID for tracking progress",
"status": "string - current status of the generation"
},
"sample": {
"data": {
"id": "gen_abc123",
"status": "pending"
},
"status": "success"
}
}About the Gamma API
Generating Content
The generate_content endpoint accepts parameters including format (presentation, document, or webpage), numCards for controlling slide count, themeId for applying a workspace theme, and folderIds for organizing output. It returns a generation id and initial status. Because generation is asynchronous, you follow up with get_generation_status, polling until status reaches completed or failed. On completion, the response includes a gammaId referencing the created asset.
Template-Based Creation
create_from_template takes a template_gamma_id and a prompt, and accepts the same optional fields as generate_content—themeId, exportAs, folderIds, plus imageOptions and sharingOptions objects for finer control over the generated output. It returns the same generation object shape, so the same get_generation_status polling flow applies.
Exporting Completed Generations
Once a generation is complete, get_export_urls accepts a generation_id and returns pdfUrl and pptxUrl—direct download links for the finished presentation or document. No additional processing steps are required between completion and export.
Workspace Utilities
list_themes and list_folders both return paginated arrays via cursor-based pagination: each response includes a data array, an after cursor string, and a hasMore boolean. Both endpoints support a query parameter for name-based filtering and a limit parameter to control page size. These endpoints let you resolve valid themeId and folderIds values before triggering a generation.
The Gamma API is a managed, monitored endpoint for gamma.app — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when gamma.app changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official gamma.app API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Automate creation of branded sales decks by passing a product brief to
generate_contentwith a fixedthemeId - Build a report generation pipeline that polls
get_generation_statusand emails thepdfUrlon completion - Populate a content library by creating multiple gammas from a common
template_gamma_idwith varied prompts - Programmatically organize generated assets into workspace folders using
folderIdsreturned bylist_folders - Enumerate available themes with
list_themesto let users pick a style before triggering generation - Export completed presentations to PPTX via
get_export_urlsfor downstream editing in PowerPoint - Generate client-facing documents at scale by integrating
create_from_templateinto a CRM workflow
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 100 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
One credit = one API call regardless of which marketplace API you call. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.
Does Gamma.app have an official developer API?+
What does `get_generation_status` return and when is it safe to call `get_export_urls`?+
get_generation_status returns a status field with values pending, processing, completed, or failed, alongside the id and a gammaId field that is populated once the job is complete. Call get_export_urls only after status is completed; the gammaId confirms the asset exists and the export URLs will be valid.Can I list existing gammas in my workspace or delete a generated gamma through this API?+
How does pagination work across `list_themes` and `list_folders`?+
after string and a hasMore boolean. Pass the after value from one response as the after input on the next request to advance through pages. When hasMore is false, you have reached the last page.Can I control sharing permissions or image generation behavior when creating from a template?+
create_from_template accepts an imageOptions object and a sharingOptions object as optional inputs, giving you control over image behavior and sharing settings for that specific generation. generate_content does not currently expose those same objects; you can fork the API on Parse and revise it to add that support.