API Reference
Generate purposeful presentations programmatically with the Linedot API.
Base URL: https://api.linedot.ai/api/v1
Authentication
All API requests require an API key.
/api/v1/templates
List all available presentation templates.
const response = await fetch('https://api.linedot.ai/api/v1/templates', {
headers: { 'X-API-KEY': '{your-api-key}' }
});
const data = await response.json();
console.log(data.templates);Available Templates
| ID | Name | Description |
|---|---|---|
linedot | Linedot | Grid-based balanced perfection |
goldman | Goldman | Corporate institutional with navy blues |
editorial | Editorial | Bold typography with magazine feel |
swiss | Swiss | Clean and modern with subtle accents |
venture_capital | Venture Capital | Modern minimalist industrial style |
institutional | Institutional | Warm minimalist earth tones |
custom_* | Custom |
Response
{
"templates": [
{
"id": "linedot",
"name": "Linedot",
"description": "Grid-based balanced perfection"
},
{
"id": "goldman",
"name": "Goldman",
"description": "Corporate institutional with navy blues"
},
...
],
"customTemplates": [
{
"id": "custom_blue_goldman_abc123",
"name": "Blue Corporate Theme",
"description": "Custom color preset based on Goldman",
"isCustom": true,
"baseThemeId": "goldman"
}
],
"total": 7
}/api/v1/generate
Generate a presentation from PDF or image sources. Returns a job ID for tracking.
Request Body
| Parameter | Type | Default | Description |
|---|---|---|---|
sourcesrequired | SourceFile[] | — | Array of source files (see structure below) |
deliveryMethod | DeliveryMethod | {"type": "jobId"} | How to deliver the presentation (see Email Delivery section) |
templateId | string | "goldman" | Template ID (e.g., "goldman") or custom template ID |
intendedFor | string | auto-detected | Target audience. Auto-detected from documents if not provided |
focus | string | "All Documents" | What to focus on from source documents (e.g., "Revenue growth metrics") |
options.length | string | number | "standard" | Preset: "executive" | "standard" | "detailed" | "comprehensive", or exact number (1-24) |
SourceFile Structure
| Field | Type | Default | Description |
|---|---|---|---|
typerequired | "pdf" | "image" | — | File type |
datarequired | string | — | Base64 encoded file content |
name | string | — | Optional filename for reference |
Length Presets
"executive"— 3-5 slides"standard"— 6-8 slides"detailed"— 9-16 slides"comprehensive"— 17-24 slides10— Exact number (1-24)
Example Request (Email Delivery)
Fire and forget — the presentation is automatically emailed when ready:
const fs = require('fs');
const pdfBase64 = fs.readFileSync('document.pdf').toString('base64');
const response = await fetch('https://api.linedot.ai/api/v1/generate', {
method: 'POST',
headers: {
'X-API-KEY': '{your-api-key}',
'Content-Type': 'application/json'
},
body: JSON.stringify({
sources: [{ type: 'pdf', data: pdfBase64 }],
deliveryMethod: {
type: 'email',
emails: ['team@example.com'],
content: 'Here is your presentation.'
}
})
});
const { jobId } = await response.json();
console.log('Submitted! Presentation will be emailed when ready.');Response
{
"jobId": "{your-job-id}",
"status": "queued"
}Timing: Generation typically takes 4-6 minutes. We recommend polling the job status every 5 minutes. 99% of presentations complete within 10 minutes.
/api/v1/generate/detailed
Generate a presentation with per-slide control. Specify content and visuals for each slide. Optionally provide source PDFs/images to enrich AI-generated content with additional context.
Request Body
| Parameter | Type | Default | Description |
|---|---|---|---|
titlerequired | string | — | Presentation title |
slidesrequired | SlideDefinition[] | — | Array of slide definitions (see structure below) |
deliveryMethod | DeliveryMethod | {"type": "jobId"} | How to deliver the presentation (see Email Delivery section) |
templateId | string | "goldman" | Template ID (e.g., "goldman") or custom template ID |
intendedFor | string | auto-detected | Target audience. Auto-detected from content if not provided |
focus | string | "All Documents" | What to focus on from source documents or slide content |
subtitle | string | — | Optional presentation subtitle |
sources | SourceFile[] | — | Source PDFs/images to provide context for AI content generation |
SourceFile Structure (for sources)
| Field | Type | Default | Description |
|---|---|---|---|
typerequired | "pdf" | "image" | — | Source file type |
datarequired | string | — | Base64 encoded file content |
name | string | — | Optional filename for reference |
SlideDefinition Structure
| Field | Type | Default | Description |
|---|---|---|---|
titlerequired | string | — | Slide title |
contentrequired | string[] | — | Array of content points/bullet points |
textMode | "preserve" | "generate" | "generate" | Per-slide text mode. "preserve" uses exact text, "generate" uses AI |
visual | VisualItem[] | [] | Array of visual specifications (see below) |
VisualItem Types
| Format | Description |
|---|---|
"chart" | Auto-generate a chart from slide content |
"table" | Auto-generate a table from slide content |
{"type": "chart", "description": "..."} | Chart with data description. Include numbers for best results (e.g., "Bar chart: Q1 $32M, Q2 $36M, Q3 $41M") |
{"type": "table", "description": "..."} | Table with structure description (e.g., "3 columns: Region, Revenue, Growth") |
{"type": "image", "data": "base64..."} | Custom image (base64 encoded PNG/JPEG) |
Example Request
const response = await fetch('https://api.linedot.ai/api/v1/generate/detailed', {
method: 'POST',
headers: {
'X-API-KEY': '{your-api-key}',
'Content-Type': 'application/json'
},
body: JSON.stringify({
deliveryMethod: { type: 'jobId' },
title: 'Q4 Business Review',
slides: [
{
title: 'Revenue Overview',
content: ['Q4 revenue reached $45M', '15% growth YoY'],
visual: [{ type: 'chart', description: 'Bar chart: Q1 $32M, Q2 $36M, Q3 $41M, Q4 $45M' }]
},
{
title: 'Key Metrics',
content: ['Customer retention: 94%', 'NPS: 72', 'ARR: $180M'],
visual: ['table']
}
],
templateId: 'goldman',
intendedFor: 'Executive leadership team',
subtitle: 'Financial Performance'
})
});
const { jobId } = await response.json();
console.log('Job started:', jobId);Example with textMode: "preserve"
Use "preserve" on specific slides when you want exact text without AI enhancement:
{
"deliveryMethod": {"type": "jobId"},
"title": "Brand Guidelines",
"slides": [
{
"title": "Mission Statement",
"textMode": "preserve",
"content": [
"To empower creators with tools that amplify their vision.",
"Founded in 2020. Trusted by 10,000+ teams."
]
},
{
"title": "Brand Values",
"textMode": "preserve",
"content": ["Integrity", "Innovation", "Inclusivity"]
},
{
"title": "Market Overview",
"content": ["TAM is growing", "Strong competitive position"],
"visual": ["chart"]
}
],
"templateId": "swiss",
"intendedFor": "Marketing team",
"subtitle": "Official Copy - Do Not Modify"
}Response
{
"jobId": "{your-job-id}",
"status": "queued"
}Timing: Generation typically takes 4-6 minutes. We recommend polling the job status every 5 minutes. 99% of presentations complete within 10 minutes.
/api/v1/jobs/:jobId
Check the status of a presentation generation job.
const jobId = '{your-job-id}';
const response = await fetch(`https://api.linedot.ai/api/v1/jobs/${jobId}`, {
headers: { 'X-API-KEY': '{your-api-key}' }
});
const status = await response.json();
console.log(status);Response (Processing)
{
"jobId": "{your-job-id}",
"status": "processing",
"createdAt": "2025-01-07T10:30:00Z"
}Response (Completed)
{
"jobId": "{your-job-id}",
"status": "completed",
"createdAt": "2025-01-07T10:30:00Z",
"completedAt": "2025-01-07T10:32:15Z"
}Status Values
queued— Job is waiting to be processedprocessing— Generation in progresscompleted— Ready for downloadfailed— Generation failed (error field included)
/api/v1/jobs/:jobId/download
Get a signed download URL for the completed PPTX file. Valid for 10 minutes.
const jobId = '{your-job-id}';
// Get download URL
const response = await fetch(`https://api.linedot.ai/api/v1/jobs/${jobId}/download`, {
headers: { 'X-API-KEY': '{your-api-key}' }
});
const { url } = await response.json();
// Download the file
const pptxRes = await fetch(url);
const buffer = await pptxRes.arrayBuffer();
// Save buffer to file or process as neededResponse
{
"url": "..."
}Generated URL expires after 10 minutes. Calling this endpoint results in a fresh URL every time.
Full Example
Two complete examples demonstrating both delivery methods: email (fire-and-forget) and polling.
Email Delivery (Fire and Forget)
The simplest approach: submit once, and the presentation is emailed automatically when ready.
const fs = require('fs');
const API_KEY = '{your-api-key}';
const API_BASE = 'https://api.linedot.ai/api/v1';
async function sendPresentation() {
const pdfBuffer = fs.readFileSync('document.pdf');
const pdfBase64 = pdfBuffer.toString('base64');
const response = await fetch(`${API_BASE}/generate`, {
method: 'POST',
headers: {
'X-API-KEY': API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
deliveryMethod: {
type: 'email',
emails: ['team@example.com', 'boss@example.com'],
content: "Here's the Q4 report.\nPlease review by Friday.",
},
sources: [{ type: 'pdf', data: pdfBase64 }],
templateId: 'goldman',
}),
});
const { jobId } = await response.json();
console.log(`Submitted! Job ID: ${jobId}`);
console.log('Recipients will receive the presentation by email.');
}
sendPresentation();Polling Method (Manual Download)
Traditional approach: poll for completion and download the presentation yourself.
const fs = require('fs');
const API_KEY = '{your-api-key}';
const API_BASE = 'https://api.linedot.ai/api/v1';
async function generatePresentation() {
// Step 1: Read PDF and submit for generation
console.log('Submitting PDF for generation...');
const pdfBuffer = fs.readFileSync('document.pdf');
const pdfBase64 = pdfBuffer.toString('base64');
const generateResponse = await fetch(`${API_BASE}/generate`, {
method: 'POST',
headers: {
'X-API-KEY': API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
deliveryMethod: { type: 'jobId' },
sources: [{ type: 'pdf', data: pdfBase64 }],
templateId: 'goldman',
intendedFor: 'Board of directors',
options: { length: 'standard' },
}),
});
const { jobId } = await generateResponse.json();
console.log(`Job ID: ${jobId}`);
// Step 2: Poll for completion (every 60 seconds)
console.log('Polling for completion...');
while (true) {
const statusResponse = await fetch(`${API_BASE}/jobs/${jobId}`, {
headers: { 'X-API-KEY': API_KEY },
});
const { status } = await statusResponse.json();
console.log(`Status: ${status}`);
if (status === 'completed') {
console.log('Generation complete!');
break;
} else if (status === 'failed') {
throw new Error('Generation failed');
}
console.log('Waiting 60 seconds...');
await new Promise((resolve) => setTimeout(resolve, 60000));
}
// Step 3: Get download URL and save file
console.log('Downloading presentation...');
const downloadResponse = await fetch(`${API_BASE}/jobs/${jobId}/download`, {
headers: { 'X-API-KEY': API_KEY },
});
const { url } = await downloadResponse.json();
const pptxResponse = await fetch(url);
const pptxBuffer = Buffer.from(await pptxResponse.arrayBuffer());
fs.writeFileSync('presentation.pptx', pptxBuffer);
console.log('Saved to presentation.pptx');
}
generatePresentation().catch(console.error);Tip: For production use, consider implementing exponential backoff and a maximum retry count. Generation typically completes in 4-6 minutes, with 99% completing within 10 minutes.
Email Delivery
Fire and Forget
With email delivery, simply submit your request and the presentation will be automatically sent to the specified recipients when ready. No polling required!
The deliveryMethod field controls how your presentation is delivered. If not specified, it defaults to jobId. You can choose between two options:
Option 1: Job ID (Polling) — Default
Returns a job ID for you to poll and download the presentation manually. This is the default if deliveryMethod is not specified.
{
"deliveryMethod": {
"type": "jobId"
}
}Option 2: Email (Fire and Forget)
Automatically sends the presentation to specified email addresses when complete.
{
"deliveryMethod": {
"type": "email",
"emails": ["recipient@example.com", "team@example.com"],
"content": "Here's the Q4 report.\nPlease review by Friday."
}
}Email delivery options:
- •
emails(required): Array of up to 10 email addresses - •
content(optional): Custom message, max 500 chars. Use\nfor new lines
Note: The API always returns a jobId regardless of delivery method. You can use this to check status or download the presentation later via the/jobs/:id endpoints.
Email Preview
Type a message below to see how it will appear in the recipient's inbox:
29/500 characters
Paste this value into the "content" field of your API request
Preview
Q4 Financial Report.pptx(2.4 MB)What to Expect
A real-world example showing the input document and the generated presentation output.
Rate Limits
API requests are rate limited to ensure fair usage and system stability.
| Limit Type | Default | Description |
|---|---|---|
| Per minute | 50 requests | Maximum requests per minute per API key |
| Per day | 1,000 requests | Maximum requests per 24-hour period per API key |
| Free tier | 20 requests | Lifetime limit for free accounts |
Need higher limits? Rate limits can be increased for enterprise customers. Schedule a call to discuss your needs.
Error Codes
| Code | Description |
|---|---|
| 400 | Bad Request — Missing or invalid parameters |
| 401 | Unauthorized — Missing or invalid API key |
| 403 | Forbidden — API key inactive, expired, or quota exceeded |
| 404 | Not Found — Job or template doesn't exist |
| 500 | Internal Server Error |
| 503 | Service Unavailable — Generation service offline |
Pricing
Free Trial
20 requests
Try the API with 20 free lifetime requests. No credit card required.
Startup Plan
$100/month
+ pay as you go
1,250 slides included. Perfect for teams and automation.
Enterprise plans available. Contact us for custom pricing.
Support
Need help with the API?
Get help