Quick Start for Rust
Integrate PDFBolt's REST API in Rust to generate PDFs from URLs, HTML, or templates. The examples below cover all three conversion modes (Direct, Sync, Async).
1. Get Your API Key
Find your API key on the API Keys page in your Dashboard. If you don't have an account, sign up – the free plan includes 100 document conversions per month.
2. Make Your First Request
Any HTTP client works – adjust the request structure to match your library.
Examples use the reqwest crate with tokio async runtime. Add to your Cargo.toml:
[dependencies]
reqwest = { version = "0.13", features = ["json"] }
serde_json = "1"
tokio = { version = "1", features = ["full"] }
base64 = "0.22"
Choose your endpoint:
- Direct
- Sync
- Async
The Direct endpoint provides immediate PDF generation and returns the raw PDF file in the response.
Choose your source:
- URL
- HTML
- Template
Convert a webpage to PDF:
use reqwest::Client;
use serde_json::json;
use std::fs;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = Client::new();
let url = "https://api.pdfbolt.com/v1/direct";
let response = client.post(url)
.header("API-KEY", "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")
.header("Content-Type", "application/json")
.json(&json!({
"url": "https://example.com",
"format": "A4",
"printBackground": true
}))
.send()
.await?;
if !response.status().is_success() {
println!("HTTP {}", response.status().as_u16());
let error_text = response.text().await?;
println!("Error Message: {}", error_text);
return Ok(());
}
let pdf_bytes = response.bytes().await?;
fs::write("webpage.pdf", pdf_bytes)?;
println!("PDF generated successfully");
Ok(())
}
Convert HTML to PDF (HTML must be base64 encoded):
use reqwest::Client;
use serde_json::json;
use base64::{Engine as _, engine::general_purpose};
use std::fs;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = Client::new();
let url = "https://api.pdfbolt.com/v1/direct";
let html_content = "<html><body><h1>Hello!</h1><p>This is a sample PDF.</p></body></html>";
let base64_html = general_purpose::STANDARD.encode(html_content.as_bytes());
let response = client.post(url)
.header("API-KEY", "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")
.header("Content-Type", "application/json")
.json(&json!({
"html": base64_html,
"format": "A4",
"printBackground": true,
"margin": {
"top": "30px",
"left": "30px"
}
}))
.send()
.await?;
if !response.status().is_success() {
println!("HTTP {}", response.status().as_u16());
let error_text = response.text().await?;
println!("Error Message: {}", error_text);
return Ok(());
}
let pdf_bytes = response.bytes().await?;
fs::write("document.pdf", pdf_bytes)?;
println!("PDF generated successfully");
Ok(())
}
Convert a template with data to PDF:
use reqwest::Client;
use serde_json::json;
use std::fs;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = Client::new();
let url = "https://api.pdfbolt.com/v1/direct";
let response = client.post(url)
.header("API-KEY", "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")
.header("Content-Type", "application/json")
.json(&json!({
"templateId": "your-template-id",
"templateData": {
"client_name": "John Doe",
"invoice_number": "INV-001",
"total_amount": "$299.99",
"line_items": [
{"description": "Web Development", "unit_price": "$200.00"},
{"description": "Design Services", "unit_price": "$99.99"}
]
}
}))
.send()
.await?;
if !response.status().is_success() {
println!("HTTP {}", response.status().as_u16());
let error_text = response.text().await?;
println!("Error Message: {}", error_text);
return Ok(());
}
let pdf_bytes = response.bytes().await?;
fs::write("invoice.pdf", pdf_bytes)?;
println!("PDF generated successfully");
Ok(())
}
Create your first template in the app, then use its ID with JSON data in your API calls. Learn more about Templates
The Sync endpoint returns a JSON response with a download URL for the PDF (valid for 24 hours).
Choose your source:
- URL
- HTML
- Template
Convert a webpage and get a download URL:
use reqwest::Client;
use serde_json::{json, Value};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = Client::new();
let url = "https://api.pdfbolt.com/v1/sync";
let response = client.post(url)
.header("API-KEY", "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")
.header("Content-Type", "application/json")
.json(&json!({
"url": "https://example.com",
"format": "A4",
"printBackground": true
}))
.send()
.await?;
if !response.status().is_success() {
println!("HTTP {}", response.status().as_u16());
let error_text = response.text().await?;
println!("Error Message: {}", error_text);
return Ok(());
}
let result: Value = response.json().await?;
println!("PDF URL: {}", result["documentUrl"].as_str().unwrap_or(""));
Ok(())
}
Convert HTML and get a download URL (HTML must be base64 encoded):
use reqwest::Client;
use serde_json::{json, Value};
use base64::{Engine as _, engine::general_purpose};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = Client::new();
let url = "https://api.pdfbolt.com/v1/sync";
let html_content = "<html><body><h1>Hello!</h1><p>This is a sample PDF.</p></body></html>";
let base64_html = general_purpose::STANDARD.encode(html_content.as_bytes());
let response = client.post(url)
.header("API-KEY", "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")
.header("Content-Type", "application/json")
.json(&json!({
"html": base64_html,
"format": "A4",
"printBackground": true,
"margin": {
"top": "30px",
"left": "30px"
}
}))
.send()
.await?;
if !response.status().is_success() {
println!("HTTP {}", response.status().as_u16());
let error_text = response.text().await?;
println!("Error Message: {}", error_text);
return Ok(());
}
let result: Value = response.json().await?;
println!("PDF URL: {}", result["documentUrl"].as_str().unwrap_or(""));
Ok(())
}
Convert a template with data and get a download URL:
use reqwest::Client;
use serde_json::{json, Value};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = Client::new();
let url = "https://api.pdfbolt.com/v1/sync";
let response = client.post(url)
.header("API-KEY", "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")
.header("Content-Type", "application/json")
.json(&json!({
"templateId": "your-template-id",
"templateData": {
"client_name": "John Doe",
"invoice_number": "INV-001",
"total_amount": "$299.99",
"line_items": [
{"description": "Web Development", "unit_price": "$200.00"},
{"description": "Design Services", "unit_price": "$99.99"}
]
}
}))
.send()
.await?;
if !response.status().is_success() {
println!("HTTP {}", response.status().as_u16());
let error_text = response.text().await?;
println!("Error Message: {}", error_text);
return Ok(());
}
let result: Value = response.json().await?;
println!("PDF URL: {}", result["documentUrl"].as_str().unwrap_or(""));
Ok(())
}
Create your first template in the app, then use its ID with JSON data in your API calls. Learn more about Templates
The Async endpoint returns a requestId immediately and delivers the final result via webhook callback.
Choose your source:
- URL
- HTML
- Template
Convert a webpage and receive a webhook callback:
use reqwest::Client;
use serde_json::{json, Value};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = Client::new();
let url = "https://api.pdfbolt.com/v1/async";
let response = client.post(url)
.header("API-KEY", "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")
.header("Content-Type", "application/json")
.json(&json!({
"url": "https://example.com",
"format": "A4",
"printBackground": true,
"webhook": "https://your-app.com/webhook"
}))
.send()
.await?;
if !response.status().is_success() {
println!("HTTP {}", response.status().as_u16());
let error_text = response.text().await?;
println!("Error Message: {}", error_text);
return Ok(());
}
let result: Value = response.json().await?;
println!("Request ID: {}", result["requestId"].as_str().unwrap_or(""));
println!("PDF will be sent to webhook when ready");
Ok(())
}
Convert HTML and receive a webhook callback (HTML must be base64 encoded):
use reqwest::Client;
use serde_json::{json, Value};
use base64::{Engine as _, engine::general_purpose};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = Client::new();
let url = "https://api.pdfbolt.com/v1/async";
let html_content = "<html><body><h1>Hello!</h1><p>This is a sample PDF.</p></body></html>";
let base64_html = general_purpose::STANDARD.encode(html_content.as_bytes());
let response = client.post(url)
.header("API-KEY", "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")
.header("Content-Type", "application/json")
.json(&json!({
"html": base64_html,
"format": "A4",
"printBackground": true,
"margin": {
"top": "30px",
"left": "30px"
},
"webhook": "https://your-app.com/webhook"
}))
.send()
.await?;
if !response.status().is_success() {
println!("HTTP {}", response.status().as_u16());
let error_text = response.text().await?;
println!("Error Message: {}", error_text);
return Ok(());
}
let result: Value = response.json().await?;
println!("Request ID: {}", result["requestId"].as_str().unwrap_or(""));
println!("PDF will be sent to webhook when ready");
Ok(())
}
Convert a template with data and receive a webhook callback:
use reqwest::Client;
use serde_json::{json, Value};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = Client::new();
let url = "https://api.pdfbolt.com/v1/async";
let response = client.post(url)
.header("API-KEY", "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")
.header("Content-Type", "application/json")
.json(&json!({
"templateId": "your-template-id",
"templateData": {
"client_name": "John Doe",
"invoice_number": "INV-001",
"total_amount": "$299.99",
"line_items": [
{"description": "Web Development", "unit_price": "$200.00"},
{"description": "Design Services", "unit_price": "$99.99"}
]
},
"webhook": "https://your-app.com/webhook"
}))
.send()
.await?;
if !response.status().is_success() {
println!("HTTP {}", response.status().as_u16());
let error_text = response.text().await?;
println!("Error Message: {}", error_text);
return Ok(());
}
let result: Value = response.json().await?;
println!("Request ID: {}", result["requestId"].as_str().unwrap_or(""));
println!("PDF will be sent to webhook when ready");
Ok(())
}
Create your first template in the app, then use its ID with JSON data in your API calls. Learn more about Templates
Next Steps
📄️ API Endpoints
📄️ Conversion Parameters
📄️ Error Handling
📄️ Templates
- Optimizing HTML for Professional PDF Output – HTML/CSS techniques: page breaks, fonts, and image optimization.
- Compress PDF via API: Reduce File Size Programmatically – reduce PDF file size via the PDFBolt API.