PodPDF - Transform Your Content into Professional PDFs
PodPDF Documentation & Product Guide
Transform Your Content into Professional PDFs
PodPDF is a powerful PDF generation platform that converts HTML, Markdown, and images into high-quality PDFs in seconds. Use our intuitive web application for instant conversions, or integrate our API into your applications for automated PDF generation.
We operate globally using cloud infrastructure. Built on Amazon Web Services (AWS) with worldwide availability, PodPDF serves customers in all countries with industry-leading reliability and scale.
đŻ Two Ways to Use PodPDF
Web Application (No Coding Required)
Perfect for business users, designers, and anyone who needs to convert documents to PDF without technical knowledge.
Access: Log in at https://app.podpdf.com and use the Convert page
Features: - â Visual drag-and-drop interface - â Upload HTML, Markdown, or image files - â Real-time preview - â Instant download - â No programming knowledge needed - â Perfect for one-off conversions
Ideal for: - Creating invoices and receipts manually - Converting documents for personal use - Testing layouts and formatting - Non-technical team members - Quick ad-hoc PDF generation
API (For Developers)
Perfect for developers who need to integrate PDF generation into applications, automate workflows, or process documents at scale.
Access: Create API keys in Settings and integrate into your application
Features: - â RESTful API with comprehensive documentation - â Support for multiple programming languages - â Webhook notifications for long jobs - â Batch processing capabilities - â Automated PDF generation - â Full programmatic control
Ideal for: - Automated invoice/receipt generation - Bulk document processing - Integration into web/mobile apps - Workflow automation - SaaS product features - High-volume PDF generation
Both methods use the same infrastructure and count toward your quota, so you can mix and match based on your needs!
đ Why Choose PodPDF?
Key Benefits
- ⥠Fast & Reliable - Generate PDFs in under 30 seconds using our web app or API
- đ Global Availability - We operate globally using cloud infrastructure, serving customers worldwide
- đ 99.9% Uptime SLA - Guaranteed availability for paid plans with SLA credits
- đ„ïž Two Ways to Use - Interactive web application for manual conversions OR powerful API for automation
- đš Flexible Input - Support for HTML, Markdown, and images (PNG/JPEG)
- đŻ Precise Control - Customize page size, margins, orientation, scaling, and more
- đ° Cost-Effective - Start free with 100 PDFs, then pay only $0.01 per PDF with credit-based billing
- đ Secure - Built on AWS with Cognito authentication and API key support
- đ Full Visibility - Monitor all jobs through our dashboard with webhook notifications
- đ No Infrastructure - Fully serverless, no servers to manage
- đ€ User-Friendly - No coding required when using the web application
Common Use Cases
For Non-Technical Users (Web Application): - Quick Document Conversion - Convert HTML, Markdown files, or images to PDF instantly - Manual Invoice Creation - Create one-off invoices and receipts using the visual editor - Document Formatting - Style and format documents before converting to PDF - Photo Albums - Upload and arrange photos into beautiful PDF albums - Content Archiving - Save web content as PDFs for personal records
For Developers (API Integration): - Automated Invoice Generation - Generate invoices programmatically from your app - Report Creation - Automatically convert analytics data and reports into PDFs - Bulk Processing - Convert large batches of documents to PDF - Receipt & Ticket Generation - Create printable tickets and receipts on demand - Marketing Automation - Generate personalized PDFs from templates at scale - Workflow Integration - Add PDF generation to your existing business processes
đ Pricing & Plans
Free Tier
Perfect for testing and small projects
- 100 PDFs - Lifetime quota (one-time, non-renewable, cumulative)
- 20 requests/minute - Rate limit
- $0/PDF - Completely free
- Full API Access - All features included (subject to conversion type restrictions)
- Dashboard Access - Monitor jobs and usage
- 1 Webhook - Maximum webhook configuration
- Upgrade Path - Purchase credits to automatically upgrade to paid plan
Paid Standard
For production applications and high-volume needs
- Unlimited PDFs - No quota limit (subject to credit balance)
- Unlimited Requests - No rate limiting
- $0.01/PDF - Just one cent per PDF (credit-based billing)
- Credit System - Purchase credits upfront, deducted per PDF
- Automatic Upgrade - Free tier users automatically upgraded when purchasing credits
- Full API Access - All features included (subject to conversion type restrictions)
- 99.9% Uptime SLA - Guaranteed availability with SLA credits
- Priority Support - Get help when you need it
- 5 Webhooks - Multiple webhook configurations with event subscriptions
- Webhook Delivery History - Permanent retention of delivery records
Plan Comparison
| Feature | Free Tier | Paid Standard |
|---|---|---|
| Quota | 100 PDFs (lifetime) | Unlimited (credit-based) |
| Rate Limit | 20 req/min | Unlimited |
| Price per PDF | $0 | $0.01 |
| Billing Model | Free | Credit-based (purchase upfront) |
| Upgrade | Purchase credits to upgrade | Automatic when purchasing credits |
| Uptime SLA | Best-effort | 99.9% guaranteed |
| HTML to PDF | â (if enabled) | â (if enabled) |
| Markdown to PDF | â (if enabled) | â (if enabled) |
| Images to PDF | â (if enabled) | â (if enabled) |
| Conversion Types | Plan-dependent | Plan-dependent |
| Custom Styling | â | â |
| API Keys | â | â |
| Dashboard | â | â |
| Webhooks | 1 webhook | 5 webhooks (default) |
| Webhook Events | â | â (event subscriptions) |
| Job History | â | â |
Credit Purchase & Billing
How It Works: - Free Tier: Start with 100 free PDFs. Once exhausted, purchase credits to continue. - Automatic Upgrade: When you purchase credits for the first time, your account automatically upgrades to the paid plan ($0.01 per PDF). - Credit-Based Billing: Paid plans use a credit system - purchase credits upfront, and theyâre deducted after each PDF generation. - Credit Balance: You must have sufficient credits (or free credits) to generate PDFs. Requests are rejected if balance is insufficient. - Transaction History: All credit purchases and deductions are logged for audit purposes.
Purchasing Credits: - Credits can be purchased at any time through your account dashboard - Credits are added to your balance immediately upon successful payment - Credits do not expire (unless otherwise specified) - Unused credits remain in your account until consumed
Important Notes: - Plan upgrade is permanent - you cannot revert to free tier after upgrading - Credits are forfeited upon account deletion - Credit purchase automatically clears quota exceeded flags - Free credits (if included in your plan) are consumed before purchased credits
đŻ Features & Capabilities
Input Formats
1. HTML to PDF
Convert any HTML content into PDFs with full CSS support.
Features: - Complete HTML5 and CSS3 support - Custom fonts and web fonts - Background graphics and colors - Responsive layouts - Print media queries
Example Use Cases: - Invoices and receipts - Reports and dashboards - Email templates - Web pages for archiving
2. Markdown to PDF
Transform Markdown documents into professional PDFs.
Features: - GitHub-flavored Markdown - Tables, lists, and code blocks - Automatic styling - Syntax highlighting - Headings and formatting
Example Use Cases: - Technical documentation - Blog posts - README files - Meeting notes and reports
3. Images to PDF
Combine multiple images into organized PDF documents.
Features: - PNG and JPEG support - Multiple images per PDF - Fit modes: contain, cover, fill - Custom page sizes - Configurable margins
Example Use Cases: - Photo albums - Scanned documents - Image catalogs - Product sheets
Conversion Type Restrictions
Plan-Based Restrictions:
- Plans may have restrictions on which conversion types are enabled
- Enabled Conversion Types: Plans may specify which input types are allowed:
- html - HTML to PDF conversion
- markdown - Markdown to PDF conversion
- image - Image to PDF conversion
- If your plan has enabled_conversion_types configured, only those types are allowed
- If your plan does not specify restrictions, all types are enabled (backward compatible)
- Requests for disabled conversion types will be rejected with 403 CONVERSION_TYPE_NOT_ENABLED error
- Check your plan details via GET /plans or GET /accounts/me to see which conversion types are enabled
Customization Options
Page Settings
- Formats: A4, Letter, Legal, Tabloid, A3, A5
- Orientation: Portrait or Landscape
- Margins: Customizable (top, right, bottom, left)
- Scale: 0.5x to 2.0x zoom control
Advanced Options
- Print Background: Include/exclude background graphics
- Fit Mode (Images): Control how images fit on pages
- Page Limits: Up to 100 pages per document (production)
Output Features
- High-quality PDF output
- Configurable page size and orientation
- Searchable text (HTML/Markdown)
- Embedded fonts and images
đ Getting Started
Step 1: Sign Up
- Visit the PodPDF dashboard at
https://app.podpdf.com - Sign up with your email
- Confirm your email address
- Start generating PDFs immediately
Step 2: Choose Your Method
Option A: Web Application (No Coding Required)
Perfect for: Non-technical users, one-off conversions, quick testing
- Log in to the dashboard
- Navigate to Convert page
- Choose your input method:
- HTML - Write or paste HTML code directly
- Markdown - Write or paste Markdown content
- File Upload - Upload .html or .md files
- Images - Upload and arrange multiple images
- Configure PDF options (page size, margins, orientation)
- Click Generate PDF and download instantly
No API key needed! Your login session handles everything.
Option B: API Integration (For Developers)
Perfect for: Automated workflows, bulk processing, app integration
- Log in to the dashboard
- Navigate to Settings â API Keys
- Click Create New API Key
- Give it a name (e.g., âProductionâ, âDevelopmentâ)
- Copy and securely store your API key
- Use it in your API requests
Step 3: Make Your First Request (API Users)
Quick Example: HTML to PDF
bash
curl -X POST https://api.podpdf.com/quickjob \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"input_type": "html",
"html": "<!DOCTYPE html><html><head><title>Invoice</title></head><body><h1>Invoice #1234</h1><p>Thank you for your business!</p></body></html>",
"options": {
"format": "A4",
"margin": {
"top": "20mm",
"right": "20mm",
"bottom": "20mm",
"left": "20mm"
}
}
}' \
--output invoice.pdf
Quick Example: Markdown to PDF
bash
curl -X POST https://api.podpdf.com/quickjob \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"input_type": "markdown",
"markdown": "# Monthly Report\n\n## Summary\n\nThis is a **bold** statement.\n\n| Metric | Value |\n|--------|-------|\n| Sales | $1,000 |\n| Costs | $500 |",
"options": {
"format": "A4",
"margin": {
"top": "20mm",
"right": "20mm",
"bottom": "20mm",
"left": "20mm"
}
}
}' \
--output report.pdf
Quick Example: Images to PDF
bash
curl -X POST https://api.podpdf.com/quickjob \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "input_type=image" \
-F "images=@photo1.jpg" \
-F "images=@photo2.jpg" \
-F 'options={"format":"A4","fit":"contain","margin":{"top":"10mm","right":"10mm","bottom":"10mm","left":"10mm"}}' \
--output photos.pdf
đ API Reference
Note: This section is for developers integrating PodPDF into their applications. If youâre looking to convert documents manually, use our web application instead - no coding required!
Base URL
https://api.podpdf.com
Authentication
All API requests require authentication using one of these methods:
Method 1: API Key (Recommended for programmatic access)
http
Authorization: Bearer YOUR_API_KEY
or
http
X-API-Key: YOUR_API_KEY
Method 2: JWT Token (For web dashboard)
http
Authorization: Bearer YOUR_JWT_TOKEN
Available Endpoints
1. POST /quickjob
Synchronous PDF generation - Returns PDF immediately (completes in <30 seconds)
Request:
json
{
"input_type": "html|markdown|image",
"html": "string (required if input_type=html)",
"markdown": "string (required if input_type=markdown)",
"options": {
"format": "A4|Letter|Legal|Tabloid|A3|A5",
"margin": {
"top": "20mm",
"right": "20mm",
"bottom": "20mm",
"left": "20mm"
},
"printBackground": true,
"scale": 1.0,
"landscape": false
}
}
Response:
- Binary PDF file
- Headers include: X-PDF-Pages, X-Job-Id, X-PDF-Truncated
Limits: - Content size: †5 MB - Image size: †5 MB per image, 10 MB total - Image dimensions: †10,000 x 10,000 pixels - Page limit: 100 pages (production environment)
2. POST /longjob
Asynchronous PDF generation - For larger documents (>30 seconds)
Request:
json
{
"input_type": "html|markdown|image",
"html": "string",
"options": { ... },
"webhook_url": "https://your-domain.com/webhook (optional)"
}
Response:
json
{
"job": {
"job_id": "uuid",
"status": "queued",
"created_at": "2024-01-15T10:30:00Z"
}
}
Webhook Notification:
When job completes, receives POST with:
json
{
"job_id": "uuid",
"status": "completed|failed",
"s3_url": "https://...",
"pages": 42,
"completed_at": "2024-01-15T10:30:45Z"
}
3. GET /jobs
List all jobs - Paginated job history
Query Parameters:
- limit: Number of results (default: 20, max: 100)
- offset: Pagination offset
- status: Filter by status (queued, processing, completed, failed)
Response:
json
{
"jobs": [...],
"count": 150,
"limit": 20,
"offset": 0
}
4. GET /jobs/{job_id}
Get job details - Retrieve specific job information
Response:
json
{
"job": {
"job_id": "uuid",
"user_id": "uuid",
"status": "completed",
"job_type": "quick|long",
"input_type": "html|markdown|image",
"pages": 42,
"s3_url": "https://...",
"s3_url_expires_at": "2024-01-15T11:30:00Z",
"created_at": "2024-01-15T10:30:00Z",
"completed_at": "2024-01-15T10:30:45Z"
}
}
5. GET /accounts/me
Get account information - View your account details and usage
Response:
json
{
"account": {
"user_id": "uuid",
"email": "user@example.com",
"account_status": "free|paid",
"plan_id": "free-basic",
"total_pdf_count": 45,
"quota_exceeded": false,
"created_at": "2024-01-01T00:00:00Z"
},
"plan": {
"name": "Free Basic",
"type": "free",
"monthly_quota": 50,
"rate_limit_per_minute": 20
}
}
6. GET /plans
List available plans - View pricing options (No authentication required)
Response:
json
{
"plans": [
{
"plan_id": "free-basic",
"name": "Free Basic",
"type": "free",
"monthly_quota": 100,
"price_per_pdf": 0,
"rate_limit_per_minute": 20,
"enabled_conversion_types": ["html", "markdown", "image"],
"max_webhooks": 1
},
{
"plan_id": "paid-standard",
"name": "Paid Standard",
"type": "paid",
"monthly_quota": null,
"price_per_pdf": 0.01,
"rate_limit_per_minute": null,
"enabled_conversion_types": ["html", "markdown", "image"],
"max_webhooks": 5
}
]
}
7. POST /accounts/me/credits/purchase
Purchase credits - Add credits to your account balance (automatically upgrades free users to paid plan)
Request:
json
{
"amount": 10.50
}
Response:
json
{
"message": "Credits purchased successfully. Account upgraded to paid plan.",
"credits_balance": 10.50,
"amount_purchased": 10.50,
"transaction_id": "01ARZ3NDEKTSV4RRFFQ69G5FAV",
"purchased_at": "2025-12-24T15:30:00.000Z",
"upgraded": true,
"plan": {
"plan_id": "paid-standard",
"name": "Paid Standard",
"type": "paid",
"price_per_pdf": 0.01
}
}
8. POST /accounts/me/webhooks
Create webhook - Create a new webhook configuration
Request:
json
{
"name": "Production Webhook",
"url": "https://api.example.com/webhooks/podpdf",
"events": ["job.completed", "job.failed"],
"is_active": true
}
9. GET /accounts/me/webhooks
List webhooks - Get all webhook configurations for your account
10. GET /accounts/me/webhooks/{webhook_id}/history
Webhook delivery history - View delivery history for a specific webhook
11. GET /accounts/me/api-keys
List API keys - View all API keys (shows prefixes only, not full keys)
12. POST /accounts/me/api-keys
Create API key - Generate a new API key (full key shown only once)
Note: For complete API documentation, see ENDPOINTS.md
đ» Code Examples
JavaScript / Node.js
```javascript const fetch = require(ânode-fetchâ); const fs = require(âfsâ);
async function generatePDF() {
const response = await fetch(âhttps://api.podpdf.com/quickjobâ, {
method: âPOSTâ,
headers: {
âAuthorizationâ: Bearer ${process.env.PODPDF_API_KEY},
âContent-Typeâ: âapplication/jsonâ
},
body: JSON.stringify({
input_type: âhtmlâ,
html: `
<!DOCTYPE html>
<html>
<head>
if (response.ok) { const buffer = await response.buffer(); fs.writeFileSync(âinvoice.pdfâ, buffer); console.log(âPDF generated successfully!â); console.log(âPages:â, response.headers.get(âX-PDF-Pagesâ)); console.log(âJob ID:â, response.headers.get(âX-Job-Idâ)); } else { const error = await response.json(); console.error(âError:â, error); } }
generatePDF(); ```
Python
```python import requests import os
def generate_pdf(): api_key = os.environ.get(âPODPDF_API_KEYâ)
response = requests.post(
'https://api.podpdf.com/quickjob',
headers={
'Authorization': f'Bearer {api_key}',
'Content-Type': 'application/json'
},
json={
'input_type': 'html',
'html': '''
<!DOCTYPE html>
<html>
<head><title>Report</title></head>
<body>
<h1>Monthly Report</h1>
<p>Generated on: {}</p>
</body>
</html>
'''.format(datetime.now().strftime('%Y-%m-%d')),
'options': {
'format': 'A4',
'margin': {
'top': '20mm',
'right': '20mm',
'bottom': '20mm',
'left': '20mm'
}
}
}
)
if response.status_code == 200:
with open('report.pdf', 'wb') as f:
f.write(response.content)
print('PDF generated successfully!')
print(f"Pages: {response.headers.get('X-PDF-Pages')}")
print(f"Job ID: {response.headers.get('X-Job-Id')}")
else:
print(f"Error: {response.json()}")
generate_pdf() ```
PHP
```php <?php
function generatePDF() { $apiKey = getenv(âPODPDF_API_KEYâ);
$data = [
'input_type' => 'html',
'html' => '<!DOCTYPE html><html><head><title>Invoice</title></head><body><h1>Invoice #1234</h1></body></html>',
'options' => [
'format' => 'A4',
'margin' => [
'top' => '20mm',
'right' => '20mm',
'bottom' => '20mm',
'left' => '20mm'
]
]
];
$ch = curl_init('https://api.podpdf.com/quickjob');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json'
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($httpCode == 200) {
file_put_contents('invoice.pdf', $response);
echo "PDF generated successfully!\n";
} else {
echo "Error: " . $response . "\n";
}
curl_close($ch); }
generatePDF(); ?> ```
Ruby
```ruby require ânet/httpâ require âjsonâ require âuriâ
def generate_pdf api_key = ENV[âPODPDF_API_KEYâ] uri = URI(âhttps://api.podpdf.com/quickjobâ)
request = Net::HTTP::Post.new(uri) request[âAuthorizationâ] = âBearer #{api_key}â request[âContent-Typeâ] = âapplication/jsonâ request.body = { input_type: âhtmlâ, html: â<!DOCTYPE html><html><head>
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http| http.request(request) end
if response.code == â200â File.write(âinvoice.pdfâ, response.body) puts âPDF generated successfully!â puts âPages: #{response[âX-PDF-Pagesâ]}â puts âJob ID: #{response[âX-Job-Idâ]}â else puts âError: #{response.body}â end end
generate_pdf ```
đš Advanced Examples
Styled Invoice with CSS
```javascript const invoiceHTML = ` <!DOCTYPE html>
INVOICE
Invoice #INV-2024-001
Bill To:
Acme Corporation
123 Business St
New York, NY 10001
Invoice Date:
January 15, 2024
Due Date:
February 15, 2024
| Description | Quantity | Price | Total |
|---|---|---|---|
| Web Development Services | 40 hours | $150.00 | $6,000.00 |
| Design Consultation | 10 hours | $100.00 | $1,000.00 |
| Hosting & Maintenance | 1 month | $500.00 | $500.00 |
`;
// Generate the PDF
const response = await fetch(âhttps://api.podpdf.com/quickjobâ, {
method: âPOSTâ,
headers: {
âAuthorizationâ: Bearer ${process.env.PODPDF_API_KEY},
âContent-Typeâ: âapplication/jsonâ
},
body: JSON.stringify({
input_type: âhtmlâ,
html: invoiceHTML,
options: {
format: âA4â,
margin: { top: â15mmâ, right: â15mmâ, bottom: â15mmâ, left: â15mmâ },
printBackground: true,
scale: 1.0
}
})
});
```
Markdown Technical Documentation
```javascript const markdownDoc = ` # API Integration Guide
Overview
This guide will help you integrate our API into your application in less than 10 minutes.
Prerequisites
Before you begin, ensure you have:
- An active account
- An API key (available in dashboard)
- Basic knowledge of REST APIs
Quick Start
Step 1: Install Dependencies
```bash npm install axios ```
Step 2: Set Up Authentication
```javascript const axios = require(âaxiosâ);
const client = axios.create({ baseURL: âhttps://api.example.comâ, headers: { âAuthorizationâ: âBearer YOUR_API_KEYâ } }); ```
Step 3: Make Your First Request
```javascript async function getData() { const response = await client.get(â/dataâ); console.log(response.data); } ```
API Endpoints
| Endpoint | Method | Description |
|---|---|---|
| /users | GET | List all users |
| /users/:id | GET | Get user details |
| /users | POST | Create new user |
| /users/:id | PUT | Update user |
| /users/:id | DELETE | Delete user |
Error Handling
The API returns standard HTTP status codes:
- 200 OK - Request succeeded
- 400 Bad Request - Invalid input
- 401 Unauthorized - Missing or invalid auth
- 404 Not Found - Resource not found
- 500 Server Error - Internal error
Best Practices
- Cache responses when possible to reduce API calls
- Handle errors gracefully with proper retry logic
- Use webhooks for real-time notifications
- Monitor usage through the dashboard
Support
Need help? Contact us at support@example.com
Last updated: January 2024 `;
// Generate the PDF
const response = await fetch(âhttps://api.podpdf.com/quickjobâ, {
method: âPOSTâ,
headers: {
âAuthorizationâ: Bearer ${process.env.PODPDF_API_KEY},
âContent-Typeâ: âapplication/jsonâ
},
body: JSON.stringify({
input_type: âmarkdownâ,
markdown: markdownDoc,
options: {
format: âA4â,
margin: { top: â20mmâ, right: â20mmâ, bottom: â20mmâ, left: â20mmâ }
}
})
});
```
đ Webhook Integration
Multiple Webhooks System
PodPDF supports multiple webhook configurations per account with event-based subscriptions. This allows you to: - Configure different webhooks for different purposes (production, staging, monitoring) - Subscribe to specific events you care about - Track delivery history and statistics - Activate/deactivate webhooks without deletion
Plan-Based Limits: - Free Tier: Maximum 1 webhook configuration - Paid Standard: Maximum 5 webhook configurations (default) - Enterprise Plans: Up to 50 webhook configurations
Setting Up Webhooks
Create Webhook via API
```javascript
// Create a new webhook
const response = await fetch(âhttps://api.podpdf.com/accounts/me/webhooksâ, {
method: âPOSTâ,
headers: {
âAuthorizationâ: Bearer ${process.env.PODPDF_API_KEY},
âContent-Typeâ: âapplication/jsonâ
},
body: JSON.stringify({
name: âProduction Webhookâ,
url: âhttps://api.example.com/webhooks/podpdfâ,
events: [âjob.completedâ, âjob.failedâ],
is_active: true
})
});
const webhook = await response.json(); console.log(âWebhook created:â, webhook.webhook_id); ```
Configure Webhook via Dashboard
- Navigate to Settings â Webhooks
- Click Create New Webhook
- Enter webhook name and URL (must be HTTPS)
- Select event types to subscribe to
- Click Save
Webhook Event Types
You can subscribe to the following event types:
job.completed- When a job successfully completes (default)job.failed- When a job fails during processingjob.timeout- When a quick job exceeds 30-second timeoutjob.queued- When a long job is queuedjob.processing- When a long job starts processing
Example: Subscribe only to failures for monitoring:
json
{
"name": "Error Monitoring",
"url": "https://api.example.com/alerts",
"events": ["job.failed", "job.timeout"],
"is_active": true
}
Webhook Payload Examples
job.completed Event
json
{
"event": "job.completed",
"job_id": "9f0a4b78-2c0c-4d14-9b8b-123456789abc",
"status": "completed",
"job_type": "long",
"mode": "html",
"pages": 150,
"truncated": false,
"s3_url": "https://s3.amazonaws.com/podpdf-dev-pdfs/...",
"s3_url_expires_at": "2025-12-21T11:32:15Z",
"created_at": "2025-12-21T10:30:00Z",
"completed_at": "2025-12-21T10:32:15Z",
"timestamp": "2025-12-21T10:32:15Z"
}
job.failed Event
json
{
"event": "job.failed",
"job_id": "9f0a4b78-2c0c-4d14-9b8b-123456789abc",
"status": "failed",
"job_type": "long",
"mode": "html",
"error_message": "PDF generation failed: Chromium process crashed",
"created_at": "2025-12-21T10:30:00Z",
"failed_at": "2025-12-21T10:32:15Z",
"timestamp": "2025-12-21T10:32:15Z"
}
Webhook Headers
All webhook requests include standard headers:
http
Content-Type: application/json
User-Agent: PodPDF-Webhook/1.0
X-Webhook-Event: job.completed
X-Webhook-Id: 01ARZ3NDEKTSV4RRFFQ69G5FAV
X-Webhook-Delivery-Id: 01ARZ3NDEKTSV4RRFFQ69G5FAY
X-Webhook-Timestamp: 2025-12-21T10:32:15Z
Important: Use X-Webhook-Delivery-Id for idempotency - deduplicate duplicate deliveries.
Webhook Delivery & Retry Logic
Retry Behavior: - 3 retries with exponential backoff (1s, 2s, 4s) - Retries on: network errors, timeouts (10 seconds), HTTP 5xx errors, HTTP 429 - Does NOT retry on: HTTP 2xx (success), HTTP 4xx client errors (except 429)
Delivery Guarantees: - At-least-once delivery: Webhooks may be delivered multiple times - Best-effort delivery: Failed webhooks are retried, but delivery is not guaranteed if all retries fail - Ordering: Webhooks are delivered in order, but order is not guaranteed across different webhooks
Webhook Delivery History:
- All delivery attempts are permanently logged
- View delivery history via GET /accounts/me/webhooks/{webhook_id}/history
- History includes: delivery status, HTTP status codes, retry counts, timestamps, duration, payload sizes
Webhook Handler Example
```javascript const express = require(âexpressâ); const app = express();
app.use(express.json());
// Store processed delivery IDs for idempotency const processedDeliveries = new Set();
app.post(â/webhookâ, async (req, res) => { // Get delivery ID from headers for idempotency const deliveryId = req.headers[âx-webhook-delivery-idâ]; const eventType = req.headers[âx-webhook-eventâ]; const webhookId = req.headers[âx-webhook-idâ];
// Idempotency check - skip if already processed
if (processedDeliveries.has(deliveryId)) {
console.log(Duplicate delivery ${deliveryId}, skipping);
return res.status(200).send(âOKâ);
}
const { event, job_id, status, s3_url, pages, error_message } = req.body;
try {
// Handle different event types
switch (event) {
case âjob.completedâ:
console.log(Job ${job_id} completed with ${pages} pages);
// Download the PDF
const pdfResponse = await fetch(s3_url);
const pdfBuffer = await pdfResponse.buffer();
// Process or store the PDF
// ... your logic here ...
break;
case 'job.failed':
console.error(`Job ${job_id} failed: ${error_message}`);
// Send alert, log error, etc.
break;
case 'job.timeout':
console.warn(`Job ${job_id} timed out`);
// Handle timeout
break;
case 'job.queued':
console.log(`Job ${job_id} queued`);
break;
case 'job.processing':
console.log(`Job ${job_id} started processing`);
break;
}
// Mark as processed
processedDeliveries.add(deliveryId);
// Return 200 quickly - process asynchronously if needed
res.status(200).send('OK'); } catch (error) {
console.error('Webhook processing error:', error);
// Still return 200 to prevent retries for processing errors
res.status(200).send('OK'); } });
app.listen(3000, () => { console.log(âWebhook server listening on port 3000â); }); ```
đ Dashboard & Web Application
Web Dashboard
Access your dashboard at https://app.podpdf.com
Perfect for non-technical users! You can convert documents to PDF entirely through the web interface without writing any code.
Available Pages
- Dashboard - Overview of account and usage statistics
- Convert - Interactive PDF generation tool (No coding required!)
- Jobs - Complete job history with filtering and search
- Settings - Account management and API keys
Convert Page (Interactive Web Application)
Generate PDFs directly in your browser without any coding!
How to Use:
- Choose Input Type:
- HTML Tab - Write or paste HTML code directly in the editor
- Markdown Tab - Write or paste Markdown content
- File Upload Tab - Upload .html, .htm, .md, or .markdown files
- Images Tab - Drag & drop or upload multiple PNG/JPEG images
- Configure Options:
- Select page format (A4, Letter, Legal, etc.)
- Choose orientation (Portrait or Landscape)
- Set custom margins
- Adjust scaling and other advanced options
- Generate & Download:
- Click the Generate PDF button
- Preview your PDF in the browser
- Download the PDF file to your computer
- View job details and history
Features:
- No Coding Required - User-friendly visual interface
- Real-time Preview - See your PDF before downloading
- Example Templates - Load sample content to get started
- Drag & Drop - Easy file and image uploads
- Live Job Tracking - Monitor generation progress
- Instant Download - Get your PDF in seconds
- Options Panel - Full control over PDF settings
- Image Reordering - Arrange images by dragging
- Persistent Settings - Your preferences are saved
Perfect for: - Creating invoices manually - Converting documents one at a time - Testing layouts before API integration - Non-technical team members - Quick ad-hoc PDF generation
Jobs Page
Monitor all your PDF generation jobs:
- Real-time Status - Track queued, processing, completed, and failed jobs
- Job Details - View pages, creation time, completion time
- Download PDFs - Direct download links for completed jobs
- Filter & Search - Find jobs by status, type, or date
- Pagination - Browse through job history
Settings Page
Manage your account:
- Account Info - View user details and plan information
- API Keys - Create, view, and revoke API keys (with names and usage tracking)
- Webhooks Management - Create and manage multiple webhook configurations
- Configure webhook URLs, names, and event subscriptions
- View webhook delivery history and statistics
- Activate/deactivate webhooks
- Plan-based limits (1 for free, 5 for paid)
- Credit Management - Purchase credits, view balance, and transaction history
- Usage Statistics - Track quota, PDF generation count, and credit balance
- Plan Information - View current plan and enabled conversion types
â ïž Error Handling
Common Error Codes
| Code | Status | Description | Solution |
|---|---|---|---|
UNAUTHORIZED |
401 | Invalid or missing authentication | Check your API key or JWT token |
ACCOUNT_NOT_FOUND |
403 | User account doesnât exist | Sign up for an account |
QUOTA_EXCEEDED |
403 | Free tier limit reached (100 PDFs) | Purchase credits to upgrade |
INSUFFICIENT_CREDITS |
403 | Insufficient credit balance | Purchase credits to continue |
CONVERSION_TYPE_NOT_ENABLED |
403 | Requested conversion type not enabled for plan | Check plan details or upgrade |
RATE_LIMIT_EXCEEDED |
403 | Too many requests | Wait before retrying or upgrade |
WEBHOOK_LIMIT_EXCEEDED |
403 | Maximum webhooks reached for plan | Upgrade plan or delete unused webhooks |
INVALID_INPUT_TYPE |
400 | Invalid input_type value | Use âhtmlâ, âmarkdownâ, or âimageâ |
MISSING_CONTENT_FIELD |
400 | Missing required content | Include html, markdown, or images |
CONTENT_TOO_LARGE |
400 | Content exceeds size limit | Reduce content size (max 5 MB) |
PAGE_LIMIT_EXCEEDED |
400 | PDF exceeds page limit | Reduce content (max 100 pages) |
PDF_GENERATION_FAILED |
500 | PDF generation error | Check content format and try again |
IMAGE_TOO_LARGE |
400 | Image file too large | Reduce image size (max 5 MB each) |
INVALID_IMAGE_FORMAT |
400 | Unsupported image format | Use PNG or JPEG only |
INVALID_WEBHOOK_URL |
400 | Invalid webhook URL | Use valid HTTPS URL |
INVALID_EVENTS |
400 | Invalid webhook event types | Use valid event types |
Error Response Format
json
{
"error": {
"code": "QUOTA_EXCEEDED",
"message": "You have reached your quota limit of 100 PDFs. Please purchase credits to continue.",
"details": {
"current_usage": 100,
"quota_limit": 100,
"action_required": "purchase_credits"
}
}
}
Example: Insufficient Credits Error
json
{
"error": {
"code": "INSUFFICIENT_CREDITS",
"message": "Insufficient credits. Current balance: $0.05, required: $0.01 per PDF.",
"details": {
"credits_balance": 0.05,
"price_per_pdf": 0.01,
"action_required": "purchase_credits"
}
}
}
Example: Conversion Type Not Enabled Error
json
{
"error": {
"code": "CONVERSION_TYPE_NOT_ENABLED",
"message": "Conversion type 'markdown' is not enabled for your plan.",
"details": {
"requested_type": "markdown",
"enabled_types": ["html"],
"plan_id": "free-basic",
"action_required": "upgrade_plan"
}
}
}
Retry Logic Example
```javascript
async function generatePDFWithRetry(data, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const response = await fetch(âhttps://api.podpdf.com/quickjobâ, {
method: âPOSTâ,
headers: {
âAuthorizationâ: Bearer ${process.env.PODPDF_API_KEY},
âContent-Typeâ: âapplication/jsonâ
},
body: JSON.stringify(data)
});
if (response.ok) {
return await response.buffer();
}
const error = await response.json();
// Don't retry on client errors (4xx)
if (response.status >= 400 && response.status < 500) {
throw new Error(`Client error: ${error.error.message}`);
}
// Retry on server errors (5xx)
if (attempt < maxRetries) {
const delay = Math.pow(2, attempt) * 1000; // Exponential backoff
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
throw new Error(`Server error after ${maxRetries} attempts`);
} catch (err) {
if (attempt === maxRetries) throw err;
} } } ```
đ Security Best Practices
API Key Security
- Never commit API keys to version control
- Use environment variables to store keys
- Rotate keys regularly for production systems
- Use separate keys for development and production
- Revoke unused keys immediately
Example: Using Environment Variables
bash
# .env file (never commit this!)
PODPDF_API_KEY=pk_live_your_secret_key_here
javascript
// Load from environment
require('dotenv').config();
const apiKey = process.env.PODPDF_API_KEY;
Content Validation
Always validate and sanitize user input before generating PDFs:
```javascript function sanitizeHTML(html) { // Remove potentially dangerous scripts const sanitized = html .replace(/<script\b[^<](?:(?!<\/script>)<[^<])<\/script>/gi, ââ) .replace(/on\w+=â[^â]â/gi, ââ);
return sanitized; }
const safeHTML = sanitizeHTML(userProvidedHTML); ```
đ Performance Optimization
Best Practices
- Use Quick Jobs for documents that generate in <30 seconds
- Use Long Jobs for larger documents with webhooks
- Optimize HTML/CSS - Reduce unnecessary styling and scripts
- Compress images before converting to PDF
- Cache generated PDFs when possible to avoid regeneration
- Use appropriate page limits - Donât generate unnecessarily large PDFs
- Batch operations when generating multiple PDFs
Image Optimization
```javascript // Before uploading images, compress them const sharp = require(âsharpâ);
async function compressImage(inputPath, outputPath) { await sharp(inputPath) .resize(1920, 1920, { fit: âinsideâ, withoutEnlargement: true }) .jpeg({ quality: 85 }) .toFile(outputPath); } ```
Caching Strategy
```javascript const crypto = require(âcryptoâ);
// Generate hash of content to use as cache key function getCacheKey(html, options) { const content = JSON.stringify({ html, options }); return crypto.createHash(âmd5â).update(content).digest(âhexâ); }
// Check cache before generating async function getCachedOrGenerate(html, options) { const cacheKey = getCacheKey(html, options);
// Check if PDF exists in your cache/storage const cached = await getFromCache(cacheKey); if (cached) return cached;
// Generate new PDF const pdf = await generatePDF(html, options);
// Store in cache await saveToCache(cacheKey, pdf);
return pdf; } ```
đ Support & Resources
Getting Help
We serve customers worldwide and provide support in English.
- Documentation: https://podpdf.com/docs
- Dashboard: https://app.podpdf.com
- Email Support: podpdf@gmail.com
- Status Page: https://status.podpdf.com
- Global Service: Available to customers in all countries
Response Times
- Free Tier: Best-effort support, no guaranteed response time
- Paid Standard: Priority support with target response times:
- Critical issues (service down): 4 business hours
- High priority: 1 business day
- Normal priority: 2 business days
- Low priority: 5 business days
Useful Links
- API Reference: https://podpdf.com/docs
- Changelog: https://podpdf.com/changelog
- Community Forum: https://community.podpdf.com
- GitHub Examples: https://github.com/podpdf/examples
đ Limits & Quotas Summary
| Resource | Free Tier | Paid Standard |
|---|---|---|
| PDF Quota | 100 (lifetime) | Unlimited (credit-based) |
| Billing Model | Free | Credit-based ($0.01/PDF) |
| Rate Limit | 20 requests/min | Unlimited |
| Content Size | 5 MB | 5 MB |
| Image Size | 5 MB per image | 5 MB per image |
| Total Upload | 10 MB | 10 MB |
| Image Dimensions | 10,000 x 10,000 px | 10,000 x 10,000 px |
| Page Limit | 100 pages | 100 pages |
| Job History | 90 days | 365 days |
| API Keys | Unlimited | Unlimited |
| Webhooks | 1 webhook | 5 webhooks (default) |
| Webhook Events | Event subscriptions | Event subscriptions |
| Conversion Types | Plan-dependent | Plan-dependent |
| Uptime SLA | Best-effort | 99.9% guaranteed |
| Support | Email (best-effort) | Priority Email |
đŠ Getting Started Checklist
For All Users:
- [ ] Sign up for a PodPDF account
- [ ] Confirm your email address
- [ ] Explore the dashboard
- [ ] Monitor usage and quota
Web Application Users:
- [ ] Navigate to the Convert page
- [ ] Try converting an HTML, Markdown, or image file
- [ ] Experiment with different PDF options
- [ ] Download your first PDF
- [ ] Check job history in the Jobs page
API Integration Users:
- [ ] Generate your first PDF in the web app (optional, for testing)
- [ ] Create an API key in Settings
- [ ] Test the API with one of our code examples
- [ ] Set up webhook notifications (optional)
- [ ] Integrate into your application
- [ ] Implement error handling and retry logic
When Ready:
- [ ] Purchase credits to automatically upgrade to paid plan
- [ ] Set up production API keys
- [ ] Configure multiple webhooks with event subscriptions
- [ ] Set up monitoring and alerts
đ Terms & Compliance
Fair Use Policy
- API is for legitimate PDF generation purposes
- No abuse, spam, or illegal content
- Rate limits are enforced to ensure service quality
- We reserve the right to suspend accounts violating terms
Data & Privacy
- Your content is processed securely on AWS infrastructure
- Generated PDFs are stored temporarily (1 hour only)
- Input content is processed in memory and not stored persistently
- We do not read or analyze your content
- GDPR and CCPA compliant
- Webhook delivery history is permanently retained for audit purposes
- Credit transaction records are retained for accounting compliance
SLA (Service Level Agreement)
Paid Standard Plan: - 99.9% uptime guarantee (calculated monthly) - SLA credits as free PDFs if uptime commitment is not met: - 10% of monthly PDFs if uptime < 99.9% but â„ 99.0% - 25% of monthly PDFs if uptime < 99.0% but â„ 95.0% - 50% of monthly PDFs if uptime < 95.0% - Credits provided as free PDF generation quota (valid for 12 months) - Automatic failover and redundancy via AWS infrastructure - Real-time status monitoring - Excludes scheduled maintenance (48-hour notice) and force majeure events
Free Tier: - Best-effort service without uptime guarantees - Not eligible for SLA credits
đ Ready to Get Started?
Start generating professional PDFs today!
For Everyone:
- Sign Up - Create your free account (no credit card required)
- Try the Web App - Convert your first PDF in the browser
- View Pricing - Choose the right plan for you
For Developers:
- Create API Keys - Get your API credentials
- Read API Docs - Explore the full API reference
- View Examples - Check out code samples
Which Option Is Right for You?
Use the Web Application if you: - Want to convert documents manually - Donât need automation - Prefer a visual interface - Need to generate PDFs occasionally - Are a non-technical user
Use the API if you: - Need automated PDF generation - Want to integrate into your app - Process documents in bulk - Need webhook notifications - Are building a product or service
Need Help?
Contact us at podpdf@gmail.com or visit our Help Center
Customers worldwide may use the Service - we serve users in all countries with our global cloud infrastructure.
© 2024 PodPDF. All rights reserved.