gamma-sdk-patterns
Learn idiomatic Gamma SDK patterns and best practices. Use when implementing complex presentation workflows, handling async operations, or structuring Gamma code. Trigger with phrases like "gamma patterns", "gamma best practices", "gamma SDK usage", "gamma async", "gamma code structure".
Install
mkdir -p .claude/skills/gamma-sdk-patterns && curl -L -o skill.zip "https://mcp.directory/api/skills/download/4240" && unzip -o skill.zip -d .claude/skills/gamma-sdk-patterns && rm skill.zipInstalls to .claude/skills/gamma-sdk-patterns
About this skill
Gamma API Patterns
Overview
Gamma has no published SDK — all interaction is via REST at https://public-api.gamma.app/v1.0/. This skill provides production-grade patterns for typed clients, generation helpers, polling, template workflows, and error handling.
Prerequisites
- Completed
gamma-install-authsetup - TypeScript project with
fetch(Node.js 18+) - Understanding of the generate-poll-retrieve workflow
Instructions
Step 1: Typed Client Singleton
// lib/gamma.ts
const GAMMA_BASE = "https://public-api.gamma.app/v1.0";
interface GammaConfig {
apiKey: string;
baseUrl?: string;
timeoutMs?: number;
}
// Types based on actual API responses
interface GenerateRequest {
content: string;
outputFormat?: "presentation" | "document" | "webpage" | "social_post";
themeId?: string;
exportAs?: "pdf" | "pptx" | "png";
textMode?: "generate" | "condense" | "preserve";
textAmount?: "brief" | "medium" | "detailed" | "extensive";
imageOptions?: { style?: string };
sharingOptions?: {
workspaceAccess?: "noAccess" | "view" | "comment" | "edit" | "fullAccess";
externalAccess?: "noAccess" | "view" | "comment" | "edit" | "fullAccess";
};
folderIds?: string[];
}
interface GenerateResult {
generationId: string;
status: "in_progress" | "completed" | "failed";
gammaUrl?: string;
exportUrl?: string;
creditsUsed?: number;
}
let instance: ReturnType<typeof createGammaClient> | null = null;
export function getGamma() {
if (!instance) {
instance = createGammaClient({
apiKey: process.env.GAMMA_API_KEY!,
});
}
return instance;
}
export function createGammaClient(config: GammaConfig) {
const base = config.baseUrl ?? GAMMA_BASE;
const headers: Record<string, string> = {
"X-API-KEY": config.apiKey,
"Content-Type": "application/json",
};
async function request<T>(method: string, path: string, body?: unknown): Promise<T> {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), config.timeoutMs ?? 30000);
try {
const res = await fetch(`${base}${path}`, {
method,
headers,
body: body ? JSON.stringify(body) : undefined,
signal: controller.signal,
});
if (!res.ok) {
const text = await res.text();
throw new GammaApiError(res.status, text, path);
}
return res.json() as T;
} finally {
clearTimeout(timeout);
}
}
return {
generate: (body: GenerateRequest) =>
request<{ generationId: string }>("POST", "/generations", body),
generateFromTemplate: (body: TemplateRequest) =>
request<{ generationId: string }>("POST", "/generations/from-template", body),
poll: (id: string) =>
request<GenerateResult>("GET", `/generations/${id}`),
getFileUrls: (id: string) =>
request<{ exportUrl: string }>("GET", `/generations/${id}/files`),
listThemes: () => request<Theme[]>("GET", "/themes"),
listFolders: () => request<Folder[]>("GET", "/folders"),
};
}
Step 2: Custom Error Class
// lib/errors.ts
export class GammaApiError extends Error {
constructor(
public status: number,
public body: string,
public path: string
) {
super(`Gamma API ${status} on ${path}: ${body}`);
this.name = "GammaApiError";
}
get isRateLimit() { return this.status === 429; }
get isAuth() { return this.status === 401 || this.status === 403; }
get isServerError() { return this.status >= 500; }
}
Step 3: Poll-Until-Done Helper
// lib/poll.ts
export async function pollUntilDone(
gamma: ReturnType<typeof createGammaClient>,
generationId: string,
opts = { intervalMs: 5000, timeoutMs: 180000 }
): Promise<GenerateResult> {
const deadline = Date.now() + opts.timeoutMs;
while (Date.now() < deadline) {
const result = await gamma.poll(generationId);
if (result.status === "completed") return result;
if (result.status === "failed") {
throw new Error(`Generation ${generationId} failed`);
}
await new Promise((r) => setTimeout(r, opts.intervalMs));
}
throw new Error(`Poll timeout for ${generationId} after ${opts.timeoutMs}ms`);
}
Step 4: Generate-and-Wait Convenience
// lib/generate.ts
export async function generateAndWait(
gamma: ReturnType<typeof createGammaClient>,
request: GenerateRequest
): Promise<GenerateResult> {
const { generationId } = await gamma.generate(request);
console.log(`Generation started: ${generationId}`);
return pollUntilDone(gamma, generationId);
}
// Usage
const gamma = getGamma();
const result = await generateAndWait(gamma, {
content: "Quarterly business review for Q1 2026",
outputFormat: "presentation",
themeId: "theme_abc123",
exportAs: "pptx",
textAmount: "medium",
imageOptions: { style: "photorealistic corporate" },
});
console.log(`View: ${result.gammaUrl}`);
console.log(`Download: ${result.exportUrl}`);
Step 5: Template-Based Generation
// lib/templates.ts
// Uses POST /v1.0/generations/from-template
// The template gamma must contain exactly one page
interface TemplateRequest {
gammaId: string; // Template gamma ID (one-page template)
prompt: string; // Content + instructions for the template
themeId?: string;
exportAs?: "pdf" | "pptx" | "png";
imageOptions?: { style?: string };
sharingOptions?: object;
folderIds?: string[];
}
export async function generateFromTemplate(
gamma: ReturnType<typeof createGammaClient>,
templateId: string,
prompt: string,
options: Partial<TemplateRequest> = {}
): Promise<GenerateResult> {
const { generationId } = await gamma.generateFromTemplate({
gammaId: templateId,
prompt,
...options,
});
return pollUntilDone(gamma, generationId);
}
Step 6: Retry with Backoff
// lib/retry.ts
export async function withRetry<T>(
fn: () => Promise<T>,
maxRetries = 3,
baseDelayMs = 1000
): Promise<T> {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
return await fn();
} catch (err) {
if (attempt === maxRetries) throw err;
if (err instanceof GammaApiError && !err.isRateLimit && !err.isServerError) {
throw err; // Don't retry auth errors or 4xx
}
const delay = baseDelayMs * Math.pow(2, attempt);
console.warn(`Retry ${attempt + 1}/${maxRetries} in ${delay}ms`);
await new Promise((r) => setTimeout(r, delay));
}
}
throw new Error("Unreachable");
}
// Usage
const result = await withRetry(() =>
generateAndWait(gamma, { content: "My deck", outputFormat: "presentation" })
);
API Endpoints Reference
| Method | Endpoint | Purpose |
|---|---|---|
| POST | /v1.0/generations | Generate from text content |
| POST | /v1.0/generations/from-template | Generate from a template gamma |
| GET | /v1.0/generations/{id} | Poll generation status |
| GET | /v1.0/generations/{id}/files | Get export file URLs |
| GET | /v1.0/themes | List workspace themes |
| GET | /v1.0/folders | List workspace folders |
Error Handling
| Pattern | Use Case |
|---|---|
GammaApiError class | Typed error handling with isRateLimit, isAuth, isServerError |
withRetry() | Auto-retry on 429/5xx with exponential backoff |
pollUntilDone() | Timeout-aware polling with configurable interval |
Singleton getGamma() | Consistent config across modules |
Resources
Next Steps
Proceed to gamma-core-workflow-a for content generation workflows.
More by jeremylongshore
View all skills by jeremylongshore →You might also like
flutter-development
aj-geddes
Build beautiful cross-platform mobile apps with Flutter and Dart. Covers widgets, state management with Provider/BLoC, navigation, API integration, and material design.
drawio-diagrams-enhanced
jgtolentino
Create professional draw.io (diagrams.net) diagrams in XML format (.drawio files) with integrated PMP/PMBOK methodologies, extensive visual asset libraries, and industry-standard professional templates. Use this skill when users ask to create flowcharts, swimlane diagrams, cross-functional flowcharts, org charts, network diagrams, UML diagrams, BPMN, project management diagrams (WBS, Gantt, PERT, RACI), risk matrices, stakeholder maps, or any other visual diagram in draw.io format. This skill includes access to custom shape libraries for icons, clipart, and professional symbols.
ui-ux-pro-max
nextlevelbuilder
"UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 8 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient."
godot
bfollington
This skill should be used when working on Godot Engine projects. It provides specialized knowledge of Godot's file formats (.gd, .tscn, .tres), architecture patterns (component-based, signal-driven, resource-based), common pitfalls, validation tools, code templates, and CLI workflows. The `godot` command is available for running the game, validating scripts, importing resources, and exporting builds. Use this skill for tasks involving Godot game development, debugging scene/resource files, implementing game systems, or creating new Godot components.
nano-banana-pro
garg-aayush
Generate and edit images using Google's Nano Banana Pro (Gemini 3 Pro Image) API. Use when the user asks to generate, create, edit, modify, change, alter, or update images. Also use when user references an existing image file and asks to modify it in any way (e.g., "modify this image", "change the background", "replace X with Y"). Supports both text-to-image generation and image-to-image editing with configurable resolution (1K default, 2K, or 4K for high resolution). DO NOT read the image file first - use this skill directly with the --input-image parameter.
fastapi-templates
wshobson
Create production-ready FastAPI projects with async patterns, dependency injection, and comprehensive error handling. Use when building new FastAPI applications or setting up backend API projects.
Related MCP Servers
Browse all serversAnalyze your Cursor Chat History for coding insights, development patterns, and best practices with powerful search and
Learn how to create a server in Minecraft efficiently. Use npx tool to scaffold an MCP server with templates and best pr
Learn how to use Python to read a file and manipulate local files safely through the Filesystem API.
Boost productivity with Task Master: an AI-powered tool for project management and agile development workflows, integrat
Boost Postgres performance with Postgres MCP Pro—AI-driven index tuning, health checks, and safe, intelligent SQL optimi
pg-aiguide — Version-aware PostgreSQL docs and best practices tailored for AI coding assistants. Improve queries, migrat
Stay ahead of the MCP ecosystem
Get weekly updates on new skills and servers.