SDKs & Integration
Official SDKs and code examples for integrating SyntaxDoc
Integrate SyntaxDoc into your application with these code examples and libraries.
Note: Official SDKs are coming soon! In the meantime, use the REST API directly with these examples.
REST API Integration
SyntaxDoc uses a simple REST API with multipart/form-data requests. Here are complete integration examples:
/**
* SyntaxDoc API Client
* Simple wrapper for the SyntaxDoc PDF generation API
*/
class SyntaxDocClient {
private apiKey: string;
private baseUrl: string;
constructor(apiKey: string, baseUrl = 'https://api.syntaxdoc.com') {
this.apiKey = apiKey;
this.baseUrl = baseUrl;
}
/**
* Generate a PDF from HTML content
*/
async generatePdf(
htmlContent: string,
options: {
fileName?: string;
format?: string;
orientation?: 'portrait' | 'landscape';
margin?: { top?: string; right?: string; bottom?: string; left?: string };
host?: boolean;
} = {}
): Promise<Blob | { url: string; pdfId: string; expiresAt: string }> {
const formData = new FormData();
const blob = new Blob([htmlContent], { type: 'text/html' });
formData.append('files', blob, 'index.html');
formData.append('options', JSON.stringify(options));
const response = await fetch(`${this.baseUrl}/pdf/generate`, {
method: 'POST',
headers: { 'X-API-Key': this.apiKey },
body: formData,
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.message || 'PDF generation failed');
}
if (response.headers.get('content-type')?.includes('application/json')) {
return response.json();
}
return response.blob();
}
/**
* Generate PDF with external resources (CSS, images, fonts)
*/
async generatePdfWithResources(
files: { name: string; content: Blob | string; type: string }[],
options: Record<string, any> = {}
): Promise<Blob | object> {
const formData = new FormData();
for (const file of files) {
const blob = typeof file.content === 'string'
? new Blob([file.content], { type: file.type })
: file.content;
formData.append('files', blob, file.name);
}
formData.append('options', JSON.stringify(options));
const response = await fetch(`${this.baseUrl}/pdf/generate`, {
method: 'POST',
headers: { 'X-API-Key': this.apiKey },
body: formData,
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.message);
}
const contentType = response.headers.get('content-type');
return contentType?.includes('application/json')
? response.json()
: response.blob();
}
/**
* Merge multiple PDF files
*/
async mergePdfs(
pdfFiles: File[],
options: { fileName?: string; host?: boolean } = {}
): Promise<Blob | object> {
const formData = new FormData();
for (const file of pdfFiles) {
formData.append('files', file);
}
formData.append('options', JSON.stringify(options));
const response = await fetch(`${this.baseUrl}/pdf/merge`, {
method: 'POST',
headers: { 'X-API-Key': this.apiKey },
body: formData,
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.message);
}
const contentType = response.headers.get('content-type');
return contentType?.includes('application/json')
? response.json()
: response.blob();
}
}
// Usage example
const client = new SyntaxDocClient('YOUR_API_KEY');
// Simple HTML to PDF
const pdf = await client.generatePdf('<h1>Hello World</h1>', {
fileName: 'hello',
format: 'A4',
});
// Host the PDF
const hosted = await client.generatePdf('<h1>Hosted PDF</h1>', {
host: true,
});
console.log('PDF URL:', hosted.url);"""
SyntaxDoc API Client
Simple wrapper for the SyntaxDoc PDF generation API
"""
import requests
import json
from typing import Optional, Dict, Any, Union, List
from pathlib import Path
class SyntaxDocClient:
def __init__(self, api_key: str, base_url: str = 'https://api.syntaxdoc.com'):
self.api_key = api_key
self.base_url = base_url
self.session = requests.Session()
self.session.headers.update({'X-API-Key': api_key})
def generate_pdf(
self,
html_content: str,
file_name: str = 'document',
format: str = 'A4',
orientation: str = 'portrait',
margin: Optional[Dict[str, str]] = None,
host: bool = False
) -> Union[bytes, Dict[str, Any]]:
"""Generate a PDF from HTML content."""
files = [('files', ('index.html', html_content, 'text/html'))]
options = {
'fileName': file_name,
'format': format,
'orientation': orientation,
'host': host
}
if margin:
options['margin'] = margin
data = {'options': json.dumps(options)}
response = self.session.post(
f'{self.base_url}/pdf/generate',
files=files,
data=data
)
response.raise_for_status()
if 'application/json' in response.headers.get('content-type', ''):
return response.json()
return response.content
def generate_pdf_from_file(
self,
html_path: str,
resource_paths: Optional[List[str]] = None,
**options
) -> Union[bytes, Dict[str, Any]]:
"""Generate PDF from HTML file with optional resources."""
files = []
# Add main HTML file
with open(html_path, 'rb') as f:
files.append(('files', ('index.html', f.read(), 'text/html')))
# Add resource files
if resource_paths:
for path in resource_paths:
p = Path(path)
mime_type = self._get_mime_type(p.suffix)
with open(path, 'rb') as f:
files.append(('files', (p.name, f.read(), mime_type)))
data = {'options': json.dumps(options)}
response = self.session.post(
f'{self.base_url}/pdf/generate',
files=files,
data=data
)
response.raise_for_status()
if 'application/json' in response.headers.get('content-type', ''):
return response.json()
return response.content
def merge_pdfs(
self,
pdf_paths: List[str],
file_name: str = 'merged',
host: bool = False
) -> Union[bytes, Dict[str, Any]]:
"""Merge multiple PDF files."""
files = []
for path in pdf_paths:
with open(path, 'rb') as f:
files.append(('files', (Path(path).name, f.read(), 'application/pdf')))
data = {'options': json.dumps({'fileName': file_name, 'host': host})}
response = self.session.post(
f'{self.base_url}/pdf/merge',
files=files,
data=data
)
response.raise_for_status()
if 'application/json' in response.headers.get('content-type', ''):
return response.json()
return response.content
def _get_mime_type(self, extension: str) -> str:
mime_types = {
'.html': 'text/html',
'.css': 'text/css',
'.js': 'application/javascript',
'.png': 'image/png',
'.jpg': 'image/jpeg',
'.jpeg': 'image/jpeg',
'.svg': 'image/svg+xml',
'.woff': 'font/woff',
'.woff2': 'font/woff2',
'.ttf': 'font/ttf',
}
return mime_types.get(extension.lower(), 'application/octet-stream')
# Usage example
if __name__ == '__main__':
client = SyntaxDocClient('YOUR_API_KEY')
# Simple HTML to PDF
pdf_bytes = client.generate_pdf(
'<h1>Hello World</h1>',
file_name='hello',
format='A4'
)
with open('hello.pdf', 'wb') as f:
f.write(pdf_bytes)
# Host the PDF
result = client.generate_pdf('<h1>Hosted</h1>', host=True)
print(f"PDF URL: {result['url']}")<?php
/**
* SyntaxDoc API Client
* Simple wrapper for the SyntaxDoc PDF generation API
*/
class SyntaxDocClient
{
private string $apiKey;
private string $baseUrl;
public function __construct(string $apiKey, string $baseUrl = 'https://api.syntaxdoc.com')
{
$this->apiKey = $apiKey;
$this->baseUrl = $baseUrl;
}
/**
* Generate a PDF from HTML content
*/
public function generatePdf(
string $htmlContent,
array $options = []
): array|string {
$options = array_merge([
'fileName' => 'document',
'format' => 'A4',
], $options);
$boundary = uniqid();
$body = $this->buildMultipartBody($boundary, [
['name' => 'files', 'filename' => 'index.html', 'content' => $htmlContent, 'type' => 'text/html'],
], $options);
$response = $this->request('/pdf/generate', $body, $boundary);
// Check if JSON response (hosted PDF)
$decoded = json_decode($response, true);
return $decoded !== null ? $decoded : $response;
}
/**
* Generate PDF with external resources
*/
public function generatePdfWithResources(array $files, array $options = []): array|string
{
$boundary = uniqid();
$fileData = [];
foreach ($files as $file) {
$fileData[] = [
'name' => 'files',
'filename' => $file['name'],
'content' => $file['content'],
'type' => $file['type'] ?? 'application/octet-stream',
];
}
$body = $this->buildMultipartBody($boundary, $fileData, $options);
$response = $this->request('/pdf/generate', $body, $boundary);
$decoded = json_decode($response, true);
return $decoded !== null ? $decoded : $response;
}
/**
* Merge multiple PDF files
*/
public function mergePdfs(array $pdfPaths, array $options = []): array|string
{
$boundary = uniqid();
$fileData = [];
foreach ($pdfPaths as $path) {
$fileData[] = [
'name' => 'files',
'filename' => basename($path),
'content' => file_get_contents($path),
'type' => 'application/pdf',
];
}
$body = $this->buildMultipartBody($boundary, $fileData, $options);
$response = $this->request('/pdf/merge', $body, $boundary);
$decoded = json_decode($response, true);
return $decoded !== null ? $decoded : $response;
}
private function request(string $endpoint, string $body, string $boundary): string
{
$ch = curl_init($this->baseUrl . $endpoint);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $body,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'X-API-Key: ' . $this->apiKey,
'Content-Type: multipart/form-data; boundary=' . $boundary,
],
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode >= 400) {
throw new Exception("API Error: " . $response);
}
return $response;
}
private function buildMultipartBody(string $boundary, array $files, array $options): string
{
$body = '';
foreach ($files as $file) {
$body .= "--{$boundary}\r\n";
$body .= "Content-Disposition: form-data; name=\"{$file['name']}\"; filename=\"{$file['filename']}\"\r\n";
$body .= "Content-Type: {$file['type']}\r\n\r\n";
$body .= $file['content'] . "\r\n";
}
$body .= "--{$boundary}\r\n";
$body .= "Content-Disposition: form-data; name=\"options\"\r\n\r\n";
$body .= json_encode($options) . "\r\n";
$body .= "--{$boundary}--\r\n";
return $body;
}
}
// Usage example
$client = new SyntaxDocClient('YOUR_API_KEY');
// Simple HTML to PDF
$pdf = $client->generatePdf('<h1>Hello World</h1>', [
'fileName' => 'hello',
'format' => 'A4',
]);
file_put_contents('hello.pdf', $pdf);
// Host the PDF
$result = $client->generatePdf('<h1>Hosted</h1>', ['host' => true]);
echo "PDF URL: " . $result['url'];package syntaxdoc
import (
"bytes"
"encoding/json"
"fmt"
"io"
"mime/multipart"
"net/http"
"os"
"path/filepath"
)
// Client is the SyntaxDoc API client
type Client struct {
APIKey string
BaseURL string
HTTP *http.Client
}
// Options for PDF generation
type Options struct {
FileName string `json:"fileName,omitempty"`
Format string `json:"format,omitempty"`
Orientation string `json:"orientation,omitempty"`
Margin map[string]string `json:"margin,omitempty"`
Host bool `json:"host,omitempty"`
}
// HostedPDF is the response when host=true
type HostedPDF struct {
URL string `json:"url"`
PdfID string `json:"pdfId"`
ExpiresAt string `json:"expiresAt"`
}
// NewClient creates a new SyntaxDoc client
func NewClient(apiKey string) *Client {
return &Client{
APIKey: apiKey,
BaseURL: "https://api.syntaxdoc.com",
HTTP: &http.Client{},
}
}
// GeneratePDF generates a PDF from HTML content
func (c *Client) GeneratePDF(html string, opts *Options) ([]byte, *HostedPDF, error) {
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
// Add HTML file
part, err := writer.CreateFormFile("files", "index.html")
if err != nil {
return nil, nil, err
}
part.Write([]byte(html))
// Add options
if opts != nil {
optionsJSON, _ := json.Marshal(opts)
writer.WriteField("options", string(optionsJSON))
}
writer.Close()
req, err := http.NewRequest("POST", c.BaseURL+"/pdf/generate", body)
if err != nil {
return nil, nil, err
}
req.Header.Set("X-API-Key", c.APIKey)
req.Header.Set("Content-Type", writer.FormDataContentType())
resp, err := c.HTTP.Do(req)
if err != nil {
return nil, nil, err
}
defer resp.Body.Close()
if resp.StatusCode >= 400 {
bodyBytes, _ := io.ReadAll(resp.Body)
return nil, nil, fmt.Errorf("API error: %s", string(bodyBytes))
}
// Check if JSON response (hosted PDF)
contentType := resp.Header.Get("Content-Type")
if contentType == "application/json" {
var hosted HostedPDF
if err := json.NewDecoder(resp.Body).Decode(&hosted); err != nil {
return nil, nil, err
}
return nil, &hosted, nil
}
// Binary PDF response
pdfBytes, err := io.ReadAll(resp.Body)
return pdfBytes, nil, err
}
// MergePDFs merges multiple PDF files
func (c *Client) MergePDFs(pdfPaths []string, opts *Options) ([]byte, *HostedPDF, error) {
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
for _, path := range pdfPaths {
file, err := os.Open(path)
if err != nil {
return nil, nil, err
}
defer file.Close()
part, err := writer.CreateFormFile("files", filepath.Base(path))
if err != nil {
return nil, nil, err
}
io.Copy(part, file)
}
if opts != nil {
optionsJSON, _ := json.Marshal(opts)
writer.WriteField("options", string(optionsJSON))
}
writer.Close()
req, err := http.NewRequest("POST", c.BaseURL+"/pdf/merge", body)
if err != nil {
return nil, nil, err
}
req.Header.Set("X-API-Key", c.APIKey)
req.Header.Set("Content-Type", writer.FormDataContentType())
resp, err := c.HTTP.Do(req)
if err != nil {
return nil, nil, err
}
defer resp.Body.Close()
if resp.StatusCode >= 400 {
bodyBytes, _ := io.ReadAll(resp.Body)
return nil, nil, fmt.Errorf("API error: %s", string(bodyBytes))
}
contentType := resp.Header.Get("Content-Type")
if contentType == "application/json" {
var hosted HostedPDF
json.NewDecoder(resp.Body).Decode(&hosted)
return nil, &hosted, nil
}
pdfBytes, _ := io.ReadAll(resp.Body)
return pdfBytes, nil, nil
}
// Usage example in main.go:
//
// client := syntaxdoc.NewClient("YOUR_API_KEY")
//
// // Simple HTML to PDF
// pdf, _, err := client.GeneratePDF("<h1>Hello</h1>", &syntaxdoc.Options{
// FileName: "hello",
// Format: "A4",
// })
// os.WriteFile("hello.pdf", pdf, 0644)
//
// // Hosted PDF
// _, hosted, _ := client.GeneratePDF("<h1>Hosted</h1>", &syntaxdoc.Options{Host: true})
// fmt.Println("URL:", hosted.URL)require 'net/http'
require 'json'
# SyntaxDoc API Client
class SyntaxDocClient
attr_accessor :api_key, :base_url
def initialize(api_key, base_url = 'https://api.syntaxdoc.com')
@api_key = api_key
@base_url = base_url
end
# Generate a PDF from HTML content
def generate_pdf(html_content, options = {})
options = {
fileName: 'document',
format: 'A4'
}.merge(options)
uri = URI("#{@base_url}/pdf/generate")
request = Net::HTTP::Post.new(uri)
request['X-API-Key'] = @api_key
form_data = [
['files', html_content, { filename: 'index.html', content_type: 'text/html' }],
['options', options.to_json]
]
request.set_form(form_data, 'multipart/form-data')
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
raise "API Error: #{response.body}" unless response.is_a?(Net::HTTPSuccess)
if response['content-type']&.include?('application/json')
JSON.parse(response.body)
else
response.body
end
end
# Merge multiple PDF files
def merge_pdfs(pdf_paths, options = {})
uri = URI("#{@base_url}/pdf/merge")
request = Net::HTTP::Post.new(uri)
request['X-API-Key'] = @api_key
form_data = pdf_paths.map do |path|
['files', File.open(path, 'rb'), { filename: File.basename(path), content_type: 'application/pdf' }]
end
form_data << ['options', options.to_json]
request.set_form(form_data, 'multipart/form-data')
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
raise "API Error: #{response.body}" unless response.is_a?(Net::HTTPSuccess)
if response['content-type']&.include?('application/json')
JSON.parse(response.body)
else
response.body
end
end
end
# Usage example
client = SyntaxDocClient.new('YOUR_API_KEY')
# Simple HTML to PDF
pdf = client.generate_pdf('<h1>Hello World</h1>', fileName: 'hello', format: 'A4')
File.binwrite('hello.pdf', pdf)
# Host the PDF
result = client.generate_pdf('<h1>Hosted</h1>', host: true)
puts "PDF URL: #{result['url']}"Framework Integration
Next.js API Route
// app/api/generate-pdf/route.ts
import { NextRequest, NextResponse } from 'next/server';
export async function POST(request: NextRequest) {
const { html, options } = await request.json();
const formData = new FormData();
formData.append('files', new Blob([html], { type: 'text/html' }), 'index.html');
formData.append('options', JSON.stringify(options));
const response = await fetch('https://api.syntaxdoc.com/pdf/generate', {
method: 'POST',
headers: { 'X-API-Key': process.env.SYNTAXDOC_API_KEY! },
body: formData,
});
if (!response.ok) {
return NextResponse.json({ error: 'PDF generation failed' }, { status: 500 });
}
const pdf = await response.arrayBuffer();
return new NextResponse(pdf, {
headers: {
'Content-Type': 'application/pdf',
'Content-Disposition': `attachment; filename="${options.fileName || 'document'}.pdf"`,
},
});
}Express.js Middleware
// middleware/pdfGenerator.js
const generatePdf = async (req, res, next) => {
const html = req.body.html || req.html;
if (!html) return next();
const formData = new FormData();
formData.append('files', new Blob([html], { type: 'text/html' }), 'index.html');
formData.append('options', JSON.stringify(req.body.options || {}));
try {
const response = await fetch('https://api.syntaxdoc.com/pdf/generate', {
method: 'POST',
headers: { 'X-API-Key': process.env.SYNTAXDOC_API_KEY },
body: formData,
});
if (!response.ok) {
throw new Error('PDF generation failed');
}
req.pdf = await response.arrayBuffer();
next();
} catch (error) {
next(error);
}
};
module.exports = { generatePdf };Django View
# views.py
from django.http import HttpResponse, JsonResponse
from django.views import View
import requests
import json
class GeneratePDFView(View):
def post(self, request):
html = request.POST.get('html', request.body.decode('utf-8'))
options = json.loads(request.POST.get('options', '{}'))
files = [('files', ('index.html', html, 'text/html'))]
data = {'options': json.dumps(options)}
response = requests.post(
'https://api.syntaxdoc.com/pdf/generate',
headers={'X-API-Key': settings.SYNTAXDOC_API_KEY},
files=files,
data=data
)
if not response.ok:
return JsonResponse({'error': 'PDF generation failed'}, status=500)
return HttpResponse(
response.content,
content_type='application/pdf',
headers={'Content-Disposition': f'attachment; filename="{options.get("fileName", "document")}.pdf"'}
)Coming Soon
Official Node.js SDK
npm install @syntaxdoc/node - Full TypeScript support
Official Python SDK
pip install syntaxdoc - Async support included
Official PHP SDK
composer require syntaxdoc/php
Want to contribute? We're looking for community SDK maintainers for Java, .NET, Rust, and other languages. Reach out on GitHub!