MagicSlides API
Generate presentations from any source
Turn a topic, text, PDF, YouTube video, website, or DOCX into a ready-to-present PowerPoint and PDF — with a single REST call. No slide-rendering code to maintain.
Global clean-energy capacity
Installed gigawatts, 2021–2025
Why the shift is accelerating
- ✓Solar costs fell 89% in a decade
- ✓Battery storage is now grid-viable
- ✓Policy incentives in 60+ countries
- ✓Corporate demand at record highs
Presentation
The Future of Renewable Energy
Solar, wind & storage over the next decade
Get started
Your first deck in 3 steps
Get your API key
Generate a key in your dashboard settings.
POST your content
Send your apiKey plus a topic, text, or URL to one endpoint.
Get your deck
The response returns a downloadable .pptx and .pdf.
Make the call
Authenticate with your apiKey and POST your content.
curl -X POST https://api.magicslides.app/public/api/ppt-from-text \
-H "Content-Type: application/json" \
-d '{
"apiKey": "ms-api-xxxxxxxx",
"topic": "The future of renewable energy",
"slideCount": 10,
"language": "en",
"aiImages": true,
"model": "gpt-4"
}'What you get back
{
"status": "success",
"url": "https://.../presentation.pptx",
"pdfUrl": "https://.../presentation.pdf",
"pptId": "presentation-id"
}Presentation
The Future of Renewable Energy
Solar, wind & storage over the next decade
Inputs
Send any source
One unified endpoint auto-detects the input type.
Topic
topicText
topicpdfURLYouTube
youtubeURLWebsite URL
websiteURLDOCX
docxURLUse cases
What people build with it
Embed in your product
Add one-click deck generation to your SaaS, LMS, or internal tools.
Automate reports
Turn recurring data or summaries into branded decks on a schedule.
Generate at scale
Produce one deck per client, dataset, or topic — in bulk.
AI agents & MCP
Let Claude, Cursor, or any agent build slides as a tool call.
Authentication
The API supports two authentication methods:
API Key Authentication (Recommended)
Use an API key for authentication. Get your API key from your dashboard settings.
Include the apiKey field in your request body. Format: ms-api-{base64-encoded-payload}.{secret}
Email and AccessId (Backward Compatibility)
For backward compatibility, you can use email and accessId instead of an API key. API key authentication takes precedence.
New
CLI API — Editable, HTML Template & Studio
A newer, more powerful API family lives directly on www.magicslides.app. It uses an x-api-key request header (not a body field) and returns richer outputs — a live editor, raw per-slide HTML, or a real-time SSE stream built by Claude.
CLI API (this section)
https://www.magicslides.appAuth via x-api-key header · Returns editor URLs, HTML, or SSE
Legacy API (below)
https://api.magicslides.appAuth via apiKey body field · Returns PPTX + PDF download URLs
x-api-key: YOUR_API_KEY. Get your key from dashboard → Settings → API.1. Editable Presentations
$0.50 / deckGenerates a presentation and returns a URL to the MagicSlides editor where it can be tweaked, downloaded as PPTX, or exported to PDF.
Endpoint
POST https://www.magicslides.app/api/cli/generate-presentationParameters
topicstringrequiredPresentation topic or contentslidesnumberSlide count (1–20). Default 5.languagestringLanguage code. Default "en".presentationTypestringe.g. "business", "educational"presentationTonestringe.g. "professional", "casual"presentationForstringTarget audience descriptionincludeImagesbooleanAdd stock images. Default false.webSearchbooleanEnhance with live web search. Default false.Response
{
"success": true,
"presentationId": "abc123",
"presentationUrl": "https://www.magicslides.app/editor/abc123",
"slug": "abc123",
"slideCount": 8
}Code examples
cURL
curl -X POST https://www.magicslides.app/api/cli/generate-presentation \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"topic": "The Future of AI in Healthcare",
"slides": 8,
"language": "en",
"presentationType": "business",
"presentationTone": "professional"
}'JavaScript / Node.js (fetch)
const res = await fetch(
'https://www.magicslides.app/api/cli/generate-presentation',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': 'YOUR_API_KEY',
},
body: JSON.stringify({
topic: 'The Future of AI in Healthcare',
slides: 8,
language: 'en',
presentationType: 'business',
presentationTone: 'professional',
}),
}
)
const data = await res.json()
console.log(data.presentationUrl)Python
import requests
data = requests.post(
'https://www.magicslides.app/api/cli/generate-presentation',
headers={'x-api-key': 'YOUR_API_KEY'},
json={
'topic': 'The Future of AI in Healthcare',
'slides': 8,
'language': 'en',
'presentationType': 'business',
'presentationTone': 'professional',
}
).json()
print(data['presentationUrl'])2. HTML Template
$0.50 / deckPick from 30+ professional templates. Returns per-slide HTML you can embed or host, plus PPTX and PDF download links. Call the templates list endpoint first to discover valid keys.
Step 1 — List templates
GET https://www.magicslides.app/api/cli/templatesAdd ?mode=proslides to filter to HTML-output templates only.
Step 2 — Generate
POST https://www.magicslides.app/api/cli/generate-html-templateParameters
topicstringrequiredPresentation topictemplateKeystringrequiredFrom GET /api/cli/templatesslidesnumberSlide count (3–20). Default 7.languagestringLanguage code. Default "en".presentationTypestringe.g. "business"presentationTonestringe.g. "professional"presentationForstringTarget audienceResponse
{
"success": true,
"mode": "proslides",
"templateKey": "editorial-magazine",
"slideCount": 8,
"presentUrl": "https://www.magicslides.app/s/{id}/index.html",
"pptxUrl": "https://…/presentation.pptx",
"pdfUrl": "https://…/presentation.pdf",
"slides": [
{ "index": 1, "html": "<!DOCTYPE html>..." },
{ "index": 2, "html": "<!DOCTYPE html>..." }
]
}Code examples
cURL
# 1. List templates
curl https://www.magicslides.app/api/cli/templates \
-H "x-api-key: YOUR_API_KEY"
# 2. Generate
curl -X POST https://www.magicslides.app/api/cli/generate-html-template \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"topic": "Sustainable Energy Trends 2025",
"templateKey": "editorial-magazine",
"slides": 8,
"language": "en"
}'JavaScript / Node.js (fetch)
const headers = {
'Content-Type': 'application/json',
'x-api-key': 'YOUR_API_KEY',
}
// 1. List templates
const templates = await fetch(
'https://www.magicslides.app/api/cli/templates',
{ headers }
).then(r => r.json())
// 2. Generate
const data = await fetch(
'https://www.magicslides.app/api/cli/generate-html-template',
{
method: 'POST',
headers,
body: JSON.stringify({
topic: 'Sustainable Energy Trends 2025',
templateKey: 'editorial-magazine',
slides: 8,
language: 'en',
}),
}
).then(r => r.json())
console.log(data.presentUrl)Python
import requests
headers = {'x-api-key': 'YOUR_API_KEY'}
# 1. List templates
templates = requests.get(
'https://www.magicslides.app/api/cli/templates',
headers=headers
).json()
# 2. Generate
data = requests.post(
'https://www.magicslides.app/api/cli/generate-html-template',
headers=headers,
json={
'topic': 'Sustainable Energy Trends 2025',
'templateKey': 'editorial-magazine',
'slides': 8,
'language': 'en',
}
).json()
print(data['presentUrl'])3. HTML Studio (Streaming)
$1.00 / deckSSE streamClaude AI builds a fully custom, animated HTML presentation from scratch — no template needed. Returns a Server-Sent Events (SSE) stream. Keep the connection open for 2–5 minutes. The final done event carries every URL you need.
{"type":"error","code":402} event is sent and the stream closes immediately.Endpoint
POST https://www.magicslides.app/api/cli/generate-html-studioParameters
topicstringrequiredWhat the presentation should be aboutstylestringVisual style — e.g. "dark, minimal, data-heavy"slidesnumberApproximate slide count (3–20). Default 8.languagestringLanguage code. Default "en".SSE event stream
data: {"type":"started","jobId":"…","credits":2}
data: {"type":"progress","message":"Sandbox ready. Planning slides…"}
data: {"type":"thinking","message":"Claude is writing slide 3…"}
data: {"type":"preview-url","url":"https://sb-xyz.vercel.run"}
data: {
"type": "done",
"previewUrl": "https://sb-xyz.vercel.run",
"shareUrl": "https://www.magicslides.app/s/{id}/index.html",
"chatUrl": "https://www.magicslides.app/en/studio/{id}",
"slideUrls": ["…/slide1.html", "…/slide2.html"],
"conversationId": "22f31f82-…"
}
# On credit exhaustion:
data: {"type":"error","code":402,"message":"Credits exhausted"}Code examples
cURL (pipe output to see events live)
curl -X POST https://www.magicslides.app/api/cli/generate-html-studio \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
--no-buffer \
-d '{
"topic": "Future of Remote Work",
"style": "modern dark with data visualizations",
"slides": 8,
"language": "en"
}'JavaScript / Node.js (fetch + ReadableStream)
const res = await fetch(
'https://www.magicslides.app/api/cli/generate-html-studio',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': 'YOUR_API_KEY',
},
body: JSON.stringify({
topic: 'Future of Remote Work',
style: 'modern dark with data visualizations',
slides: 8,
language: 'en',
}),
}
)
const reader = res.body.getReader()
const decoder = new TextDecoder()
while (true) {
const { done, value } = await reader.read()
if (done) break
for (const line of decoder.decode(value).split('\n')) {
if (!line.startsWith('data: ')) continue
const ev = JSON.parse(line.slice(6))
console.log(ev.type, ev.message ?? '')
if (ev.type === 'done') {
console.log('Share URL:', ev.shareUrl)
console.log('Slides:', ev.slideUrls)
}
}
}Python (requests streaming)
import json, requests
with requests.post(
'https://www.magicslides.app/api/cli/generate-html-studio',
headers={
'Content-Type': 'application/json',
'x-api-key': 'YOUR_API_KEY',
},
json={
'topic': 'Future of Remote Work',
'style': 'modern dark with data visualizations',
'slides': 8,
'language': 'en',
},
stream=True
) as res:
for line in res.iter_lines():
if not line.startswith(b'data: '):
continue
ev = json.loads(line[6:])
print(ev['type'], ev.get('message', ''))
if ev['type'] == 'done':
print('Share URL:', ev['shareUrl'])
print('Slides:', ev['slideUrls'])
breakLegacy
Legacy API Endpoints
These endpoints use api.magicslides.app as the base URL and authenticate via an apiKey body field. The unified endpoint is recommended for all new integrations.
PPT-from-Text (Unified API)
Unified endpoint that handles all input types: topics, summaries, YouTube videos, websites, PDFs, and DOCX documents. Automatically detects input type and processes accordingly. Recommended for all new integrations.
Endpoint URL
https://api.magicslides.app/public/api/ppt-from-textParameters
Example Usage
TypeScript/JavaScript
import axios from 'axios';
const generateFromTopic = async () => {
try {
const response = await axios.post(
'https://api.magicslides.app/public/api/ppt-from-text',
{
apiKey: 'ms-api-your-api-key-here',
topic: 'Introduction to Quantum Computing: Understanding quantum mechanics, qubits, superposition, and quantum algorithms.',
template: 'bullet-point1',
language: 'en',
slideCount: 10,
imageForEachSlide: true,
aiImages: false
}
);
console.log('Presentation URL:', response.data.url);
console.log('PPT ID:', response.data.pptId);
} catch (error) {
console.error('Error:', error);
}
};Python
import requests
def generate_from_topic():
try:
response = requests.post(
'https://api.magicslides.app/public/api/ppt-from-text',
json={
'apiKey': 'ms-api-your-api-key-here',
'topic': 'Introduction to Quantum Computing: Understanding quantum mechanics, qubits, superposition, and quantum algorithms.',
'template': 'bullet-point1',
'language': 'en',
'slideCount': 10,
'imageForEachSlide': True,
'aiImages': False
}
)
response.raise_for_status()
result = response.json()
print('Presentation URL:', result['url'])
print('PPT ID:', result['pptId'])
except requests.exceptions.RequestException as e:
print('Error:', e)cURL
curl -X POST \
'https://api.magicslides.app/public/api/ppt-from-text' \
-H 'Content-Type: application/json' \
-d '{
"apiKey": "ms-api-your-api-key-here",
"topic": "Introduction to Quantum Computing: Understanding quantum mechanics, qubits, superposition, and quantum algorithms.",
"template": "bullet-point1",
"language": "en",
"slideCount": 10,
"imageForEachSlide": true,
"aiImages": false
}'Topic to PPT
DEPRECATEDGenerate a customized presentation from any topic with AI. Control presentation style, length, language, and image options.
⚠️ This endpoint is deprecated but still functional. We recommend migrating to the unified PPT-from-Text API for all new integrations.
Endpoint URL
https://api.magicslides.app/public/api/ppt_from_topicParameters
Example Usage
TypeScript/JavaScript
import axios from 'axios';
const generateFromTopic = async () => {
try {
const response = await axios.post(
'https://api.magicslides.app/public/api/ppt_from_topic',
{
topic: 'Artificial Intelligence in Healthcare',
extraInfoSource: 'Focus on recent developments and future prospects',
email: 'your-email@example.com',
accessId: 'your-access-id',
template: 'bullet-point1',
language: 'en',
slideCount: 10,
aiImages: false,
imageForEachSlide: true,
googleImage: false,
googleText: false,
model: 'gpt-4',
presentationFor: 'healthcare professionals',
watermark: {
width: '48',
height: '48',
brandURL: 'https://djgurnpwsdoqjscwqbsj.supabase.co/storage/v1/object/public/watermarks/1712216042174_Sahoo.png',
position: 'BottomRight'
}
}
);
console.log('Presentation URL:', response.data.url);
} catch (error) {
console.error('Error:', error);
}
};Python
import requests
def generate_from_topic():
try:
response = requests.post(
'https://api.magicslides.app/public/api/ppt_from_topic',
json={
'topic': 'Artificial Intelligence in Healthcare',
'extraInfoSource': 'Focus on recent developments and future prospects',
'email': 'your-email@example.com',
'accessId': 'your-access-id',
'template': 'bullet-point1',
'language': 'en',
'slideCount': 10,
'aiImages': False,
'imageForEachSlide': True,
'googleImage': False,
'googleText': False,
'model': 'gpt-4',
'presentationFor': 'healthcare professionals',
'watermark': {
'width': '48',
'height': '48',
'brandURL': 'https://djgurnpwsdoqjscwqbsj.supabase.co/storage/v1/object/public/watermarks/1712216042174_Sahoo.png',
'position': 'BottomRight'
}
}
)
response.raise_for_status()
print('Presentation URL:', response.json()['url'])
except requests.exceptions.RequestException as e:
print('Error:', e)cURL
curl -X POST \
'https://api.magicslides.app/public/api/ppt_from_topic' \
-H 'Content-Type: application/json' \
-d '{
"topic": "Artificial Intelligence in Healthcare",
"extraInfoSource": "Focus on recent developments and future prospects",
"email": "your-email@example.com",
"accessId": "your-access-id",
"template": "bullet-point1",
"language": "en",
"slideCount": 10,
"aiImages": false,
"imageForEachSlide": true,
"googleImage": false,
"googleText": false,
"model": "gpt-4",
"presentationFor": "healthcare professionals",
"watermark": {
"width": "48",
"height": "48",
"brandURL": "https://djgurnpwsdoqjscwqbsj.supabase.co/storage/v1/object/public/watermarks/1712216042174_Sahoo.png",
"position": "BottomRight"
}
}'Summary to PPT
DEPRECATEDGenerate a presentation from a text summary.
⚠️ This endpoint is deprecated but still functional. We recommend migrating to the unified PPT-from-Text API for all new integrations.
Endpoint URL
https://api.magicslides.app/public/api/ppt_from_summeryParameters
Example Usage
TypeScript/JavaScript
import axios from 'axios';
const generateFromSummary = async () => {
try {
const response = await axios.post(
'https://api.magicslides.app/public/api/ppt_from_summery',
{
msSummaryText: 'Your detailed summary text here...',
email: 'your-email@example.com',
accessId: 'your-access-id',
template: 'bullet-point1',
language: 'en',
slideCount: 10,
aiImages: false,
imageForEachSlide: true,
googleImage: false,
googleText: false,
model: 'gpt-4',
presentationFor: 'general audience',
watermark: {
width: '48',
height: '48',
brandURL: 'https://djgurnpwsdoqjscwqbsj.supabase.co/storage/v1/object/public/watermarks/1712216042174_Sahoo.png',
position: 'BottomRight'
}
}
);
console.log('Presentation URL:', response.data.url);
} catch (error) {
console.error('Error:', error);
}
};Python
import requests
def generate_from_summary():
try:
response = requests.post(
'https://api.magicslides.app/public/api/ppt_from_summery',
json={
'msSummaryText': 'Your detailed summary text here...',
'email': 'your-email@example.com',
'accessId': 'your-access-id',
'template': 'bullet-point1',
'language': 'en',
'slideCount': 10,
'aiImages': False,
'imageForEachSlide': True,
'googleImage': False,
'googleText': False,
'model': 'gpt-4',
'presentationFor': 'general audience',
'watermark': {
'width': '48',
'height': '48',
'brandURL': 'https://djgurnpwsdoqjscwqbsj.supabase.co/storage/v1/object/public/watermarks/1712216042174_Sahoo.png',
'position': 'BottomRight'
}
}
)
response.raise_for_status()
print('Presentation URL:', response.json()['url'])
except requests.exceptions.RequestException as e:
print('Error:', e)cURL
curl -X POST \
'https://api.magicslides.app/public/api/ppt_from_summery' \
-H 'Content-Type: application/json' \
-d '{
"msSummaryText": "Your detailed summary text here...",
"email": "your-email@example.com",
"accessId": "your-access-id",
"template": "bullet-point1",
"language": "en",
"slideCount": 10,
"aiImages": false,
"imageForEachSlide": true,
"googleImage": false,
"googleText": false,
"model": "gpt-4",
"presentationFor": "general audience",
"watermark": {
"width": "48",
"height": "48",
"brandURL": "https://djgurnpwsdoqjscwqbsj.supabase.co/storage/v1/object/public/watermarks/1712216042174_Sahoo.png",
"position": "BottomRight"
}
}'YouTube to PPT
DEPRECATEDGenerate a presentation from a YouTube video.
⚠️ This endpoint is deprecated but still functional. We recommend migrating to the unified PPT-from-Text API for all new integrations.
Endpoint URL
https://api.magicslides.app/public/api/ppt_from_youtubeParameters
Example Usage
TypeScript/JavaScript
import axios from 'axios';
const generateFromYouTube = async () => {
try {
const response = await axios.post(
'https://api.magicslides.app/public/api/ppt_from_youtube',
{
youtubeURL: 'https://www.youtube.com/watch?v=example',
email: 'your-email@example.com',
accessId: 'your-access-id',
template: 'bullet-point1',
language: 'en',
slideCount: 10,
aiImages: false,
imageForEachSlide: true,
googleImage: false,
googleText: false,
model: 'gpt-4',
presentationFor: 'general audience',
watermark: {
width: '48',
height: '48',
brandURL: 'https://djgurnpwsdoqjscwqbsj.supabase.co/storage/v1/object/public/watermarks/1712216042174_Sahoo.png',
position: 'BottomRight'
}
}
);
console.log('Presentation URL:', response.data.url);
} catch (error) {
console.error('Error:', error);
}
};Python
import requests
def generate_from_youtube():
try:
response = requests.post(
'https://api.magicslides.app/public/api/ppt_from_youtube',
json={
'youtubeURL': 'https://www.youtube.com/watch?v=example',
'email': 'your-email@example.com',
'accessId': 'your-access-id',
'template': 'bullet-point1',
'language': 'en',
'slideCount': 10,
'aiImages': False,
'imageForEachSlide': True,
'googleImage': False,
'googleText': False,
'model': 'gpt-4',
'presentationFor': 'general audience',
'watermark': {
'width': '48',
'height': '48',
'brandURL': 'https://djgurnpwsdoqjscwqbsj.supabase.co/storage/v1/object/public/watermarks/1712216042174_Sahoo.png',
'position': 'BottomRight'
}
}
)
response.raise_for_status()
print('Presentation URL:', response.json()['url'])
except requests.exceptions.RequestException as e:
print('Error:', e)cURL
curl -X POST \
'https://api.magicslides.app/public/api/ppt_from_youtube' \
-H 'Content-Type: application/json' \
-d '{
"youtubeURL": "https://www.youtube.com/watch?v=example",
"email": "your-email@example.com",
"accessId": "your-access-id",
"template": "bullet-point1",
"language": "en",
"slideCount": 10,
"aiImages": false,
"imageForEachSlide": true,
"googleImage": false,
"googleText": false,
"model": "gpt-4",
"presentationFor": "general audience",
"watermark": {
"width": "48",
"height": "48",
"brandURL": "https://djgurnpwsdoqjscwqbsj.supabase.co/storage/v1/object/public/watermarks/1712216042174_Sahoo.png",
"position": "BottomRight"
}
}'Response Format
All API endpoints return a JSON response. The unified API returns:
{
"status": "success",
"message": "Presentation generated successfully",
"inputType": "topic",
"url": "https://example.com/path/to/presentation.pptx",
"pptId": "presentation-id",
"pdfUrl": "https://example.com/path/to/presentation.pdf",
"json": {
"presentationTitle": "Title",
"presentationSubtitle": "Subtitle",
"slides": [...]
},
"tokenUsed": 1234,
"openAICallTime": 5000
}Deprecated endpoints may return a slightly different format with success and data fields.
Error Handling
In case of an error, the API will return a JSON response with an error message:
{
"success": false,
"error": "Invalid access ID provided",
"code": "AUTH_ERROR"
}Rate Limits
The API is rate-limited to ensure fair usage. Please contact support for details about rate limits for your account.