PDF generator API
This guide explains how to go from a standard HTML file to a fully featured invoice, making use of all the functionality our PDF generator API provides. For more advanced configuration details such as layout, forms, and headers/footers, refer to the PDF generation developer guide.
Basics of PDF generation
PDF generation enables you to create a completely new PDF from a standard HTML document. You can make use of all the tools, including:
- CSS for styling
- Images and fonts
- HTML forms
The PDF generation API converts these to a PDF. The most basic example generates a PDF with the text “Hello World, I am red!” in large black letters. The text color is addressed in the next section.
To run this, create an index.html file containing the HTML in the same folder as your code. Run the code, and you should get result.pdf with your newly generated PDF.
HTML template section:
<h1>Hello World, I am red!</h1><p>And I am green.</p>Command to generate a PDF file (basic API):
curl -X POST https://api.nutrient.io/processor/generate_pdf \ -H "Authorization: Bearer your_api_key_here" \ -o result.pdf \ --fail \ -F html=@index.htmlcurl -X POST https://api.nutrient.io/processor/generate_pdf ^ -H "Authorization: Bearer your_api_key_here" ^ -o result.pdf ^ --fail ^ -F html=@index.htmlpackage com.example.pspdfkit;
import java.io.File;import java.io.IOException;import java.nio.file.FileSystems;import java.nio.file.Files;import java.nio.file.StandardCopyOption;
import org.json.JSONArray;import org.json.JSONObject;
import okhttp3.MediaType;import okhttp3.MultipartBody;import okhttp3.OkHttpClient;import okhttp3.Request;import okhttp3.RequestBody;import okhttp3.Response;
public final class PspdfkitApiExample { public static void main(final String[] args) throws IOException { final RequestBody body = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart( "html", "index.html", RequestBody.create( MediaType.parse("text/html"), new File("index.html") ) ) .build();
final Request request = new Request.Builder() .url("https://api.nutrient.io/processor/generate_pdf") .method("POST", body) .addHeader("Authorization", "Bearer your_api_key_here") .build();
final OkHttpClient client = new OkHttpClient() .newBuilder() .build();
final Response response = client.newCall(request).execute();
if (response.isSuccessful()) { Files.copy( response.body().byteStream(), FileSystems.getDefault().getPath("result.pdf"), StandardCopyOption.REPLACE_EXISTING ); } else { // Handle the error. throw new IOException(response.body().string()); } }}using System;using System.IO;using System.Net;using RestSharp;
namespace PspdfkitApiDemo{ class Program { static void Main(string[] args) { var client = new RestClient("https://api.nutrient.io/processor/generate_pdf");
var request = new RestRequest(Method.POST) .AddHeader("Authorization", "Bearer your_api_key_here") .AddFile("html", "index.html");
request.AdvancedResponseWriter = (responseStream, response) => { if (response.StatusCode == HttpStatusCode.OK) { using (responseStream) { using var outputFileWriter = File.OpenWrite("result.pdf"); responseStream.CopyTo(outputFileWriter); } } else { var responseStreamReader = new StreamReader(responseStream); Console.Write(responseStreamReader.ReadToEnd()); } };
client.Execute(request); } }}// This code requires Node.js. Do not run this code directly in a web browser.
const axios = require('axios')const FormData = require('form-data')const fs = require('fs')
const formData = new FormData()formData.append('html', fs.createReadStream('index.html'))
;(async () => { try { const response = await axios.post('https://api.nutrient.io/processor/generate_pdf', formData, { headers: formData.getHeaders({ 'Authorization': 'Bearer your_api_key_here' }), responseType: "stream" })
response.data.pipe(fs.createWriteStream("result.pdf")) } catch (e) { const errorString = await streamToString(e.response.data) console.log(errorString) }})()
function streamToString(stream) { const chunks = [] return new Promise((resolve, reject) => { stream.on("data", (chunk) => chunks.push(Buffer.from(chunk))) stream.on("error", (err) => reject(err)) stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8"))) })}import requestsimport json
response = requests.request( 'POST', 'https://api.nutrient.io/processor/generate_pdf', headers = { 'Authorization': 'Bearer your_api_key_here' }, files = { 'html': open('index.html', 'rb') }, stream = True)
if response.ok: with open('result.pdf', 'wb') as fd: for chunk in response.iter_content(chunk_size=8096): fd.write(chunk)else: print(response.text) exit()<?php
$FileHandle = fopen('result.pdf', 'w+');
$curl = curl_init();
curl_setopt_array($curl, array( CURLOPT_URL => 'https://api.nutrient.io/processor/generate_pdf', CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_POSTFIELDS => array( 'html' => new CURLFILE('index.html') ), CURLOPT_HTTPHEADER => array( 'Authorization: Bearer your_api_key_here' ), CURLOPT_FILE => $FileHandle,));
$response = curl_exec($curl);
curl_close($curl);
fclose($FileHandle);POST https://api.nutrient.io/processor/generate_pdf HTTP/1.1Content-Type: multipart/form-data; boundary=--customboundaryAuthorization: Bearer your_api_key_here
--customboundaryContent-Disposition: form-data; name="html"; filename="index.html"Content-Type: text/html
(html data)--customboundary--Advanced API:
curl -X POST https://api.nutrient.io/build \ -H "Authorization: Bearer your_api_key_here" \ -o result.pdf \ --fail \ -F index.html=@index.html \ -F instructions='{ "parts": [ { "html": "index.html" } ] }'curl -X POST https://api.nutrient.io/build ^ -H "Authorization: Bearer your_api_key_here" ^ -o result.pdf ^ --fail ^ -F index.html=@index.html ^ -F instructions="{\"parts\": [{\"html\": \"index.html\"}]}"package com.example.pspdfkit;
import java.io.File;import java.io.IOException;import java.nio.file.FileSystems;import java.nio.file.Files;import java.nio.file.StandardCopyOption;
import org.json.JSONArray;import org.json.JSONObject;
import okhttp3.MediaType;import okhttp3.MultipartBody;import okhttp3.OkHttpClient;import okhttp3.Request;import okhttp3.RequestBody;import okhttp3.Response;
public final class PspdfkitApiExample { public static void main(final String[] args) throws IOException { final RequestBody body = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart( "index.html", "index.html", RequestBody.create( MediaType.parse("text/html"), new File("index.html") ) ) .addFormDataPart( "instructions", new JSONObject() .put("parts", new JSONArray() .put(new JSONObject() .put("html", "index.html") ) ).toString() ) .build();
final Request request = new Request.Builder() .url("https://api.nutrient.io/build") .method("POST", body) .addHeader("Authorization", "Bearer your_api_key_here") .build();
final OkHttpClient client = new OkHttpClient() .newBuilder() .build();
final Response response = client.newCall(request).execute();
if (response.isSuccessful()) { Files.copy( response.body().byteStream(), FileSystems.getDefault().getPath("result.pdf"), StandardCopyOption.REPLACE_EXISTING ); } else { // Handle the error. throw new IOException(response.body().string()); } }}using System;using System.IO;using System.Net;using RestSharp;
namespace PspdfkitApiDemo{ class Program { static void Main(string[] args) { var client = new RestClient("https://api.nutrient.io/build");
var request = new RestRequest(Method.POST) .AddHeader("Authorization", "Bearer your_api_key_here") .AddFile("index.html", "index.html") .AddParameter("instructions", new JsonObject { ["parts"] = new JsonArray { new JsonObject { ["html"] = "index.html" } } }.ToString());
request.AdvancedResponseWriter = (responseStream, response) => { if (response.StatusCode == HttpStatusCode.OK) { using (responseStream) { using var outputFileWriter = File.OpenWrite("result.pdf"); responseStream.CopyTo(outputFileWriter); } } else { var responseStreamReader = new StreamReader(responseStream); Console.Write(responseStreamReader.ReadToEnd()); } };
client.Execute(request); } }}// This code requires Node.js. Do not run this code directly in a web browser.
const axios = require('axios')const FormData = require('form-data')const fs = require('fs')
const formData = new FormData()formData.append('instructions', JSON.stringify({ parts: [ { html: "index.html" } ]}))formData.append('index.html', fs.createReadStream('index.html'))
;(async () => { try { const response = await axios.post('https://api.nutrient.io/build', formData, { headers: formData.getHeaders({ 'Authorization': 'Bearer your_api_key_here' }), responseType: "stream" })
response.data.pipe(fs.createWriteStream("result.pdf")) } catch (e) { const errorString = await streamToString(e.response.data) console.log(errorString) }})()
function streamToString(stream) { const chunks = [] return new Promise((resolve, reject) => { stream.on("data", (chunk) => chunks.push(Buffer.from(chunk))) stream.on("error", (err) => reject(err)) stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8"))) })}import requestsimport json
response = requests.request( 'POST', 'https://api.nutrient.io/build', headers = { 'Authorization': 'Bearer your_api_key_here' }, files = { 'index.html': open('index.html', 'rb') }, data = { 'instructions': json.dumps({ 'parts': [ { 'html': 'index.html' } ] }) }, stream = True)
if response.ok: with open('result.pdf', 'wb') as fd: for chunk in response.iter_content(chunk_size=8096): fd.write(chunk)else: print(response.text) exit()<?php
$FileHandle = fopen('result.pdf', 'w+');
$curl = curl_init();
curl_setopt_array($curl, array( CURLOPT_URL => 'https://api.nutrient.io/build', CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_POSTFIELDS => array( 'instructions' => '{ "parts": [ { "html": "index.html" } ] }', 'index.html' => new CURLFILE('index.html') ), CURLOPT_HTTPHEADER => array( 'Authorization: Bearer your_api_key_here' ), CURLOPT_FILE => $FileHandle,));
$response = curl_exec($curl);
curl_close($curl);
fclose($FileHandle);POST https://api.nutrient.io/build HTTP/1.1Content-Type: multipart/form-data; boundary=--customboundaryAuthorization: Bearer your_api_key_here
--customboundaryContent-Disposition: form-data; name="instructions"Content-Type: application/json
{ "parts": [ { "html": "index.html" } ]}--customboundaryContent-Disposition: form-data; name="index.html"; filename="index.html"Content-Type: text/html
(index.html data)--customboundary--Applying basic styling
Now you have your basic PDF, but in spite of what the text says, it’s all black. Use inline CSS to style your text.
In our example, you can make the heading red and the text below it green. Update your index.html file, adding the inline styles, and run your code again.
HTML template section:
<h1 style="color: red;">Hello World, I am red!</h1><p style="color: green;">And I am green.</p>Command to generate a PDF file (basic API):
curl -X POST https://api.nutrient.io/processor/generate_pdf \ -H "Authorization: Bearer your_api_key_here" \ -o result.pdf \ --fail \ -F html=@index.htmlcurl -X POST https://api.nutrient.io/processor/generate_pdf ^ -H "Authorization: Bearer your_api_key_here" ^ -o result.pdf ^ --fail ^ -F html=@index.htmlpackage com.example.pspdfkit;
import java.io.File;import java.io.IOException;import java.nio.file.FileSystems;import java.nio.file.Files;import java.nio.file.StandardCopyOption;
import org.json.JSONArray;import org.json.JSONObject;
import okhttp3.MediaType;import okhttp3.MultipartBody;import okhttp3.OkHttpClient;import okhttp3.Request;import okhttp3.RequestBody;import okhttp3.Response;
public final class PspdfkitApiExample { public static void main(final String[] args) throws IOException { final RequestBody body = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart( "html", "index.html", RequestBody.create( MediaType.parse("text/html"), new File("index.html") ) ) .build();
final Request request = new Request.Builder() .url("https://api.nutrient.io/processor/generate_pdf") .method("POST", body) .addHeader("Authorization", "Bearer your_api_key_here") .build();
final OkHttpClient client = new OkHttpClient() .newBuilder() .build();
final Response response = client.newCall(request).execute();
if (response.isSuccessful()) { Files.copy( response.body().byteStream(), FileSystems.getDefault().getPath("result.pdf"), StandardCopyOption.REPLACE_EXISTING ); } else { // Handle the error. throw new IOException(response.body().string()); } }}using System;using System.IO;using System.Net;using RestSharp;
namespace PspdfkitApiDemo{ class Program { static void Main(string[] args) { var client = new RestClient("https://api.nutrient.io/processor/generate_pdf");
var request = new RestRequest(Method.POST) .AddHeader("Authorization", "Bearer your_api_key_here") .AddFile("html", "index.html");
request.AdvancedResponseWriter = (responseStream, response) => { if (response.StatusCode == HttpStatusCode.OK) { using (responseStream) { using var outputFileWriter = File.OpenWrite("result.pdf"); responseStream.CopyTo(outputFileWriter); } } else { var responseStreamReader = new StreamReader(responseStream); Console.Write(responseStreamReader.ReadToEnd()); } };
client.Execute(request); } }}// This code requires Node.js. Do not run this code directly in a web browser.
const axios = require('axios')const FormData = require('form-data')const fs = require('fs')
const formData = new FormData()formData.append('html', fs.createReadStream('index.html'))
;(async () => { try { const response = await axios.post('https://api.nutrient.io/processor/generate_pdf', formData, { headers: formData.getHeaders({ 'Authorization': 'Bearer your_api_key_here' }), responseType: "stream" })
response.data.pipe(fs.createWriteStream("result.pdf")) } catch (e) { const errorString = await streamToString(e.response.data) console.log(errorString) }})()
function streamToString(stream) { const chunks = [] return new Promise((resolve, reject) => { stream.on("data", (chunk) => chunks.push(Buffer.from(chunk))) stream.on("error", (err) => reject(err)) stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8"))) })}import requestsimport json
response = requests.request( 'POST', 'https://api.nutrient.io/processor/generate_pdf', headers = { 'Authorization': 'Bearer your_api_key_here' }, files = { 'html': open('index.html', 'rb') }, stream = True)
if response.ok: with open('result.pdf', 'wb') as fd: for chunk in response.iter_content(chunk_size=8096): fd.write(chunk)else: print(response.text) exit()<?php
$FileHandle = fopen('result.pdf', 'w+');
$curl = curl_init();
curl_setopt_array($curl, array( CURLOPT_URL => 'https://api.nutrient.io/processor/generate_pdf', CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_POSTFIELDS => array( 'html' => new CURLFILE('index.html') ), CURLOPT_HTTPHEADER => array( 'Authorization: Bearer your_api_key_here' ), CURLOPT_FILE => $FileHandle,));
$response = curl_exec($curl);
curl_close($curl);
fclose($FileHandle);POST https://api.nutrient.io/processor/generate_pdf HTTP/1.1Content-Type: multipart/form-data; boundary=--customboundaryAuthorization: Bearer your_api_key_here
--customboundaryContent-Disposition: form-data; name="html"; filename="index.html"Content-Type: text/html
(html data)--customboundary--Advanced API:
curl -X POST https://api.nutrient.io/build \ -H "Authorization: Bearer your_api_key_here" \ -o result.pdf \ --fail \ -F index.html=@index.html \ -F instructions='{ "parts": [ { "html": "index.html" } ] }'curl -X POST https://api.nutrient.io/build ^ -H "Authorization: Bearer your_api_key_here" ^ -o result.pdf ^ --fail ^ -F index.html=@index.html ^ -F instructions="{\"parts\": [{\"html\": \"index.html\"}]}"package com.example.pspdfkit;
import java.io.File;import java.io.IOException;import java.nio.file.FileSystems;import java.nio.file.Files;import java.nio.file.StandardCopyOption;
import org.json.JSONArray;import org.json.JSONObject;
import okhttp3.MediaType;import okhttp3.MultipartBody;import okhttp3.OkHttpClient;import okhttp3.Request;import okhttp3.RequestBody;import okhttp3.Response;
public final class PspdfkitApiExample { public static void main(final String[] args) throws IOException { final RequestBody body = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart( "index.html", "index.html", RequestBody.create( MediaType.parse("text/html"), new File("index.html") ) ) .addFormDataPart( "instructions", new JSONObject() .put("parts", new JSONArray() .put(new JSONObject() .put("html", "index.html") ) ).toString() ) .build();
final Request request = new Request.Builder() .url("https://api.nutrient.io/build") .method("POST", body) .addHeader("Authorization", "Bearer your_api_key_here") .build();
final OkHttpClient client = new OkHttpClient() .newBuilder() .build();
final Response response = client.newCall(request).execute();
if (response.isSuccessful()) { Files.copy( response.body().byteStream(), FileSystems.getDefault().getPath("result.pdf"), StandardCopyOption.REPLACE_EXISTING ); } else { // Handle the error. throw new IOException(response.body().string()); } }}using System;using System.IO;using System.Net;using RestSharp;
namespace PspdfkitApiDemo{ class Program { static void Main(string[] args) { var client = new RestClient("https://api.nutrient.io/build");
var request = new RestRequest(Method.POST) .AddHeader("Authorization", "Bearer your_api_key_here") .AddFile("index.html", "index.html") .AddParameter("instructions", new JsonObject { ["parts"] = new JsonArray { new JsonObject { ["html"] = "index.html" } } }.ToString());
request.AdvancedResponseWriter = (responseStream, response) => { if (response.StatusCode == HttpStatusCode.OK) { using (responseStream) { using var outputFileWriter = File.OpenWrite("result.pdf"); responseStream.CopyTo(outputFileWriter); } } else { var responseStreamReader = new StreamReader(responseStream); Console.Write(responseStreamReader.ReadToEnd()); } };
client.Execute(request); } }}// This code requires Node.js. Do not run this code directly in a web browser.
const axios = require('axios')const FormData = require('form-data')const fs = require('fs')
const formData = new FormData()formData.append('instructions', JSON.stringify({ parts: [ { html: "index.html" } ]}))formData.append('index.html', fs.createReadStream('index.html'))
;(async () => { try { const response = await axios.post('https://api.nutrient.io/build', formData, { headers: formData.getHeaders({ 'Authorization': 'Bearer your_api_key_here' }), responseType: "stream" })
response.data.pipe(fs.createWriteStream("result.pdf")) } catch (e) { const errorString = await streamToString(e.response.data) console.log(errorString) }})()
function streamToString(stream) { const chunks = [] return new Promise((resolve, reject) => { stream.on("data", (chunk) => chunks.push(Buffer.from(chunk))) stream.on("error", (err) => reject(err)) stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8"))) })}import requestsimport json
response = requests.request( 'POST', 'https://api.nutrient.io/build', headers = { 'Authorization': 'Bearer your_api_key_here' }, files = { 'index.html': open('index.html', 'rb') }, data = { 'instructions': json.dumps({ 'parts': [ { 'html': 'index.html' } ] }) }, stream = True)
if response.ok: with open('result.pdf', 'wb') as fd: for chunk in response.iter_content(chunk_size=8096): fd.write(chunk)else: print(response.text) exit()<?php
$FileHandle = fopen('result.pdf', 'w+');
$curl = curl_init();
curl_setopt_array($curl, array( CURLOPT_URL => 'https://api.nutrient.io/build', CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_POSTFIELDS => array( 'instructions' => '{ "parts": [ { "html": "index.html" } ] }', 'index.html' => new CURLFILE('index.html') ), CURLOPT_HTTPHEADER => array( 'Authorization: Bearer your_api_key_here' ), CURLOPT_FILE => $FileHandle,));
$response = curl_exec($curl);
curl_close($curl);
fclose($FileHandle);POST https://api.nutrient.io/build HTTP/1.1Content-Type: multipart/form-data; boundary=--customboundaryAuthorization: Bearer your_api_key_here
--customboundaryContent-Disposition: form-data; name="instructions"Content-Type: application/json
{ "parts": [ { "html": "index.html" } ]}--customboundaryContent-Disposition: form-data; name="index.html"; filename="index.html"Content-Type: text/html
(index.html data)--customboundary--Introducing assets
While inline styling is functional, it’s often more efficient to manage styles in an external CSS file. The PDF generation API supports this by enabling you to include multiple assets with your request. To start, create a file named style.css in the same directory as your HTML and paste your styles there.
CSS file:
h1 { color: red;}
p { color: green;}To make use of your new style.css file, you’ll have to update your index.html file. When updating your HTML file, refer to the CSS file with just its name. Nested paths aren’t currently supported — use filenames without paths.
HTML template section:
<!DOCTYPE html><html lang="en"> <head> <link rel="stylesheet" href="style.css" /> </head> <body> <h1>Hello World, I am red!</h1> <p>And I am green.</p> </body></html>You’ll also have to include your new CSS file in your request. Add the CSS file both as a request file and in the assets key of your HTML part.
Command to generate a PDF file (basic API):
curl -X POST https://api.nutrient.io/processor/generate_pdf \ -H "Authorization: Bearer your_api_key_here" \ -o result.pdf \ --fail \ -F html=@index.html \ -F style.css=@style.css \ -F data='{ "assets": [ "style.css" ] }'curl -X POST https://api.nutrient.io/processor/generate_pdf ^ -H "Authorization: Bearer your_api_key_here" ^ -o result.pdf ^ --fail ^ -F html=@index.html ^ -F style.css=@style.css ^ -F data="{\"assets\": [\"style.css\"]}"package com.example.pspdfkit;
import java.io.File;import java.io.IOException;import java.nio.file.FileSystems;import java.nio.file.Files;import java.nio.file.StandardCopyOption;
import org.json.JSONArray;import org.json.JSONObject;
import okhttp3.MediaType;import okhttp3.MultipartBody;import okhttp3.OkHttpClient;import okhttp3.Request;import okhttp3.RequestBody;import okhttp3.Response;
public final class PspdfkitApiExample { public static void main(final String[] args) throws IOException { final RequestBody body = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart( "html", "index.html", RequestBody.create( MediaType.parse("text/html"), new File("index.html") ) ) .addFormDataPart( "style.css", "style.css", RequestBody.create( MediaType.parse("text/css"), new File("style.css") ) ) .addFormDataPart( "data", new JSONObject() .put("assets", new JSONArray() .put("style.css") ).toString() ) .build();
final Request request = new Request.Builder() .url("https://api.nutrient.io/processor/generate_pdf") .method("POST", body) .addHeader("Authorization", "Bearer your_api_key_here") .build();
final OkHttpClient client = new OkHttpClient() .newBuilder() .build();
final Response response = client.newCall(request).execute();
if (response.isSuccessful()) { Files.copy( response.body().byteStream(), FileSystems.getDefault().getPath("result.pdf"), StandardCopyOption.REPLACE_EXISTING ); } else { // Handle the error. throw new IOException(response.body().string()); } }}using System;using System.IO;using System.Net;using RestSharp;
namespace PspdfkitApiDemo{ class Program { static void Main(string[] args) { var client = new RestClient("https://api.nutrient.io/processor/generate_pdf");
var request = new RestRequest(Method.POST) .AddHeader("Authorization", "Bearer your_api_key_here") .AddFile("html", "index.html") .AddFile("style.css", "style.css") .AddParameter("data", new JsonObject { ["assets"] = new JsonArray { "style.css" } }.ToString());
request.AdvancedResponseWriter = (responseStream, response) => { if (response.StatusCode == HttpStatusCode.OK) { using (responseStream) { using var outputFileWriter = File.OpenWrite("result.pdf"); responseStream.CopyTo(outputFileWriter); } } else { var responseStreamReader = new StreamReader(responseStream); Console.Write(responseStreamReader.ReadToEnd()); } };
client.Execute(request); } }}// This code requires Node.js. Do not run this code directly in a web browser.
const axios = require('axios')const FormData = require('form-data')const fs = require('fs')
const formData = new FormData()formData.append('data', JSON.stringify({ assets: [ "style.css" ]}))formData.append('html', fs.createReadStream('index.html'))formData.append('style.css', fs.createReadStream('style.css'))
;(async () => { try { const response = await axios.post('https://api.nutrient.io/processor/generate_pdf', formData, { headers: formData.getHeaders({ 'Authorization': 'Bearer your_api_key_here' }), responseType: "stream" })
response.data.pipe(fs.createWriteStream("result.pdf")) } catch (e) { const errorString = await streamToString(e.response.data) console.log(errorString) }})()
function streamToString(stream) { const chunks = [] return new Promise((resolve, reject) => { stream.on("data", (chunk) => chunks.push(Buffer.from(chunk))) stream.on("error", (err) => reject(err)) stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8"))) })}import requestsimport json
response = requests.request( 'POST', 'https://api.nutrient.io/processor/generate_pdf', headers = { 'Authorization': 'Bearer your_api_key_here' }, files = { 'html': open('index.html', 'rb'), 'style.css': open('style.css', 'rb') }, data = { 'data': json.dumps({ 'assets': [ 'style.css' ] }) }, stream = True)
if response.ok: with open('result.pdf', 'wb') as fd: for chunk in response.iter_content(chunk_size=8096): fd.write(chunk)else: print(response.text) exit()<?php
$FileHandle = fopen('result.pdf', 'w+');
$curl = curl_init();
curl_setopt_array($curl, array( CURLOPT_URL => 'https://api.nutrient.io/processor/generate_pdf', CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_POSTFIELDS => array( 'data' => '{ "assets": [ "style.css" ] }', 'html' => new CURLFILE('index.html'), 'style.css' => new CURLFILE('style.css') ), CURLOPT_HTTPHEADER => array( 'Authorization: Bearer your_api_key_here' ), CURLOPT_FILE => $FileHandle,));
$response = curl_exec($curl);
curl_close($curl);
fclose($FileHandle);POST https://api.nutrient.io/processor/generate_pdf HTTP/1.1Content-Type: multipart/form-data; boundary=--customboundaryAuthorization: Bearer your_api_key_here
--customboundaryContent-Disposition: form-data; name="data"Content-Type: application/json
{ "assets": [ "style.css" ]}--customboundaryContent-Disposition: form-data; name="html"; filename="index.html"Content-Type: text/html
(html data)--customboundaryContent-Disposition: form-data; name="style.css"; filename="style.css"Content-Type: text/css
(style.css data)--customboundary--Advanced API:
curl -X POST https://api.nutrient.io/build \ -H "Authorization: Bearer your_api_key_here" \ -o result.pdf \ --fail \ -F index.html=@index.html \ -F style.css=@style.css \ -F instructions='{ "parts": [ { "html": "index.html", "assets": [ "style.css" ] } ] }'curl -X POST https://api.nutrient.io/build ^ -H "Authorization: Bearer your_api_key_here" ^ -o result.pdf ^ --fail ^ -F index.html=@index.html ^ -F style.css=@style.css ^ -F instructions="{\"parts\": [{\"html\": \"index.html\", \"assets\": [\"style.css\"]}]}"package com.example.pspdfkit;
import java.io.File;import java.io.IOException;import java.nio.file.FileSystems;import java.nio.file.Files;import java.nio.file.StandardCopyOption;
import org.json.JSONArray;import org.json.JSONObject;
import okhttp3.MediaType;import okhttp3.MultipartBody;import okhttp3.OkHttpClient;import okhttp3.Request;import okhttp3.RequestBody;import okhttp3.Response;
public final class PspdfkitApiExample { public static void main(final String[] args) throws IOException { final RequestBody body = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart( "index.html", "index.html", RequestBody.create( MediaType.parse("text/html"), new File("index.html") ) ) .addFormDataPart( "style.css", "style.css", RequestBody.create( MediaType.parse("text/css"), new File("style.css") ) ) .addFormDataPart( "instructions", new JSONObject() .put("parts", new JSONArray() .put(new JSONObject() .put("html", "index.html") .put("assets", new JSONArray() .put("style.css") ) ) ).toString() ) .build();
final Request request = new Request.Builder() .url("https://api.nutrient.io/build") .method("POST", body) .addHeader("Authorization", "Bearer your_api_key_here") .build();
final OkHttpClient client = new OkHttpClient() .newBuilder() .build();
final Response response = client.newCall(request).execute();
if (response.isSuccessful()) { Files.copy( response.body().byteStream(), FileSystems.getDefault().getPath("result.pdf"), StandardCopyOption.REPLACE_EXISTING ); } else { // Handle the error. throw new IOException(response.body().string()); } }}using System;using System.IO;using System.Net;using RestSharp;
namespace PspdfkitApiDemo{ class Program { static void Main(string[] args) { var client = new RestClient("https://api.nutrient.io/build");
var request = new RestRequest(Method.POST) .AddHeader("Authorization", "Bearer your_api_key_here") .AddFile("index.html", "index.html") .AddFile("style.css", "style.css") .AddParameter("instructions", new JsonObject { ["parts"] = new JsonArray { new JsonObject { ["html"] = "index.html", ["assets"] = new JsonArray { "style.css" } } } }.ToString());
request.AdvancedResponseWriter = (responseStream, response) => { if (response.StatusCode == HttpStatusCode.OK) { using (responseStream) { using var outputFileWriter = File.OpenWrite("result.pdf"); responseStream.CopyTo(outputFileWriter); } } else { var responseStreamReader = new StreamReader(responseStream); Console.Write(responseStreamReader.ReadToEnd()); } };
client.Execute(request); } }}// This code requires Node.js. Do not run this code directly in a web browser.
const axios = require('axios')const FormData = require('form-data')const fs = require('fs')
const formData = new FormData()formData.append('instructions', JSON.stringify({ parts: [ { html: "index.html", assets: [ "style.css" ] } ]}))formData.append('index.html', fs.createReadStream('index.html'))formData.append('style.css', fs.createReadStream('style.css'))
;(async () => { try { const response = await axios.post('https://api.nutrient.io/build', formData, { headers: formData.getHeaders({ 'Authorization': 'Bearer your_api_key_here' }), responseType: "stream" })
response.data.pipe(fs.createWriteStream("result.pdf")) } catch (e) { const errorString = await streamToString(e.response.data) console.log(errorString) }})()
function streamToString(stream) { const chunks = [] return new Promise((resolve, reject) => { stream.on("data", (chunk) => chunks.push(Buffer.from(chunk))) stream.on("error", (err) => reject(err)) stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8"))) })}import requestsimport json
response = requests.request( 'POST', 'https://api.nutrient.io/build', headers = { 'Authorization': 'Bearer your_api_key_here' }, files = { 'index.html': open('index.html', 'rb'), 'style.css': open('style.css', 'rb') }, data = { 'instructions': json.dumps({ 'parts': [ { 'html': 'index.html', 'assets': [ 'style.css' ] } ] }) }, stream = True)
if response.ok: with open('result.pdf', 'wb') as fd: for chunk in response.iter_content(chunk_size=8096): fd.write(chunk)else: print(response.text) exit()<?php
$FileHandle = fopen('result.pdf', 'w+');
$curl = curl_init();
curl_setopt_array($curl, array( CURLOPT_URL => 'https://api.nutrient.io/build', CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_POSTFIELDS => array( 'instructions' => '{ "parts": [ { "html": "index.html", "assets": [ "style.css" ] } ] }', 'index.html' => new CURLFILE('index.html'), 'style.css' => new CURLFILE('style.css') ), CURLOPT_HTTPHEADER => array( 'Authorization: Bearer your_api_key_here' ), CURLOPT_FILE => $FileHandle,));
$response = curl_exec($curl);
curl_close($curl);
fclose($FileHandle);POST https://api.nutrient.io/build HTTP/1.1Content-Type: multipart/form-data; boundary=--customboundaryAuthorization: Bearer your_api_key_here
--customboundaryContent-Disposition: form-data; name="instructions"Content-Type: application/json
{ "parts": [ { "html": "index.html", "assets": [ "style.css" ] } ]}--customboundaryContent-Disposition: form-data; name="index.html"; filename="index.html"Content-Type: text/html
(index.html data)--customboundaryContent-Disposition: form-data; name="style.css"; filename="style.css"Content-Type: text/css
(style.css data)--customboundary--Creating an invoice
With the core building blocks (the HTML and external assets) out of the way, this section shows a real-world example: creating a PDF invoice. You’ll start with the basic invoice and then add some advanced features on top.
First, update your CSS. All the code is taken from the invoice example, but the relevant parts are also duplicated here. Replace the contents of style.css . Define some common styles used throughout the invoice, as well as the styles only applying to the header.
CSS file:
body { font-size: 0.75rem; font-weight: 400; color: #000000; margin: 0 auto; position: relative;}
h2 { font-size: 1.25rem; font-weight: 400;}
h4 { font-size: 1rem; font-weight: 400;}
.page { margin-left: 5rem; margin-right: 5rem;}
.intro-table { display: flex; justify-content: space-between; margin: 3rem 0 3rem 0; border-top: 1px solid #000000; border-bottom: 1px solid #000000;}
.intro-form { display: flex; flex-direction: column; border-right: 1px solid #000000; width: 50%;}
.intro-form:last-child { border-right: none;}
.intro-table-title { font-size: 0.625rem; margin: 0;}
.intro-form-item { padding: 1.25rem 1.5rem 1.25rem 1.5rem;}
.intro-form-item:first-child { padding-left: 0;}
.intro-form-item:last-child { padding-right: 0;}
.intro-form-item-border { padding: 1.25rem 0 0.75rem 1.5rem; border-bottom: 1px solid #000000;}
.intro-form-item-border:last-child { border-bottom: none;}Next, update your index.html file, adding the invoice numbers, as well as an address block, and some additional data, such as date and type of payment. This example uses only plain HTML.
HTML template section:
<!DOCTYPE html><html lang="en"> <head> <link rel="stylesheet" href="style.css" /> </head> <body> <div class="page" style="page-break-after: always"> <div> <h2>Invoice #</h2> </div>
<div class="intro-table"> <div class="intro-form intro-form-item"> <p class="intro-table-title">Billed To:</p> <p> Company Ltd.<br /> Address<br /> Country<br /> VAT ID: ATU12345678 </p> </div>
<div class="intro-form"> <div class="intro-form-item-border"> <p class="intro-table-title">Payment Date:</p> <p>November 22nd 2021</p> </div>
<div class="intro-form-item-border"> <p class="intro-table-title">Payment Method:</p> <p>Bank Transfer</p> </div> </div> </div> </div> </body></html>If you rerun the generation with the new HTML and CSS, you’ll see a nicely formatted invoice header in your PDF.
Command to generate a PDF file (basic API):
curl -X POST https://api.nutrient.io/processor/generate_pdf \ -H "Authorization: Bearer your_api_key_here" \ -o result.pdf \ --fail \ -F html=@index.html \ -F style.css=@style.css \ -F data='{ "assets": [ "style.css" ] }'curl -X POST https://api.nutrient.io/processor/generate_pdf ^ -H "Authorization: Bearer your_api_key_here" ^ -o result.pdf ^ --fail ^ -F html=@index.html ^ -F style.css=@style.css ^ -F data="{\"assets\": [\"style.css\"]}"package com.example.pspdfkit;
import java.io.File;import java.io.IOException;import java.nio.file.FileSystems;import java.nio.file.Files;import java.nio.file.StandardCopyOption;
import org.json.JSONArray;import org.json.JSONObject;
import okhttp3.MediaType;import okhttp3.MultipartBody;import okhttp3.OkHttpClient;import okhttp3.Request;import okhttp3.RequestBody;import okhttp3.Response;
public final class PspdfkitApiExample { public static void main(final String[] args) throws IOException { final RequestBody body = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart( "html", "index.html", RequestBody.create( MediaType.parse("text/html"), new File("index.html") ) ) .addFormDataPart( "style.css", "style.css", RequestBody.create( MediaType.parse("text/css"), new File("style.css") ) ) .addFormDataPart( "data", new JSONObject() .put("assets", new JSONArray() .put("style.css") ).toString() ) .build();
final Request request = new Request.Builder() .url("https://api.nutrient.io/processor/generate_pdf") .method("POST", body) .addHeader("Authorization", "Bearer your_api_key_here") .build();
final OkHttpClient client = new OkHttpClient() .newBuilder() .build();
final Response response = client.newCall(request).execute();
if (response.isSuccessful()) { Files.copy( response.body().byteStream(), FileSystems.getDefault().getPath("result.pdf"), StandardCopyOption.REPLACE_EXISTING ); } else { // Handle the error. throw new IOException(response.body().string()); } }}using System;using System.IO;using System.Net;using RestSharp;
namespace PspdfkitApiDemo{ class Program { static void Main(string[] args) { var client = new RestClient("https://api.nutrient.io/processor/generate_pdf");
var request = new RestRequest(Method.POST) .AddHeader("Authorization", "Bearer your_api_key_here") .AddFile("html", "index.html") .AddFile("style.css", "style.css") .AddParameter("data", new JsonObject { ["assets"] = new JsonArray { "style.css" } }.ToString());
request.AdvancedResponseWriter = (responseStream, response) => { if (response.StatusCode == HttpStatusCode.OK) { using (responseStream) { using var outputFileWriter = File.OpenWrite("result.pdf"); responseStream.CopyTo(outputFileWriter); } } else { var responseStreamReader = new StreamReader(responseStream); Console.Write(responseStreamReader.ReadToEnd()); } };
client.Execute(request); } }}// This code requires Node.js. Do not run this code directly in a web browser.
const axios = require('axios')const FormData = require('form-data')const fs = require('fs')
const formData = new FormData()formData.append('data', JSON.stringify({ assets: [ "style.css" ]}))formData.append('html', fs.createReadStream('index.html'))formData.append('style.css', fs.createReadStream('style.css'))
;(async () => { try { const response = await axios.post('https://api.nutrient.io/processor/generate_pdf', formData, { headers: formData.getHeaders({ 'Authorization': 'Bearer your_api_key_here' }), responseType: "stream" })
response.data.pipe(fs.createWriteStream("result.pdf")) } catch (e) { const errorString = await streamToString(e.response.data) console.log(errorString) }})()
function streamToString(stream) { const chunks = [] return new Promise((resolve, reject) => { stream.on("data", (chunk) => chunks.push(Buffer.from(chunk))) stream.on("error", (err) => reject(err)) stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8"))) })}import requestsimport json
response = requests.request( 'POST', 'https://api.nutrient.io/processor/generate_pdf', headers = { 'Authorization': 'Bearer your_api_key_here' }, files = { 'html': open('index.html', 'rb'), 'style.css': open('style.css', 'rb') }, data = { 'data': json.dumps({ 'assets': [ 'style.css' ] }) }, stream = True)
if response.ok: with open('result.pdf', 'wb') as fd: for chunk in response.iter_content(chunk_size=8096): fd.write(chunk)else: print(response.text) exit()<?php
$FileHandle = fopen('result.pdf', 'w+');
$curl = curl_init();
curl_setopt_array($curl, array( CURLOPT_URL => 'https://api.nutrient.io/processor/generate_pdf', CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_POSTFIELDS => array( 'data' => '{ "assets": [ "style.css" ] }', 'html' => new CURLFILE('index.html'), 'style.css' => new CURLFILE('style.css') ), CURLOPT_HTTPHEADER => array( 'Authorization: Bearer your_api_key_here' ), CURLOPT_FILE => $FileHandle,));
$response = curl_exec($curl);
curl_close($curl);
fclose($FileHandle);POST https://api.nutrient.io/processor/generate_pdf HTTP/1.1Content-Type: multipart/form-data; boundary=--customboundaryAuthorization: Bearer your_api_key_here
--customboundaryContent-Disposition: form-data; name="data"Content-Type: application/json
{ "assets": [ "style.css" ]}--customboundaryContent-Disposition: form-data; name="html"; filename="index.html"Content-Type: text/html
(html data)--customboundaryContent-Disposition: form-data; name="style.css"; filename="style.css"Content-Type: text/css
(style.css data)--customboundary--Advanced API:
curl -X POST https://api.nutrient.io/build \ -H "Authorization: Bearer your_api_key_here" \ -o result.pdf \ --fail \ -F index.html=@index.html \ -F style.css=@style.css \ -F instructions='{ "parts": [ { "html": "index.html", "assets": [ "style.css" ] } ] }'curl -X POST https://api.nutrient.io/build ^ -H "Authorization: Bearer your_api_key_here" ^ -o result.pdf ^ --fail ^ -F index.html=@index.html ^ -F style.css=@style.css ^ -F instructions="{\"parts\": [{\"html\": \"index.html\", \"assets\": [\"style.css\"]}]}"package com.example.pspdfkit;
import java.io.File;import java.io.IOException;import java.nio.file.FileSystems;import java.nio.file.Files;import java.nio.file.StandardCopyOption;
import org.json.JSONArray;import org.json.JSONObject;
import okhttp3.MediaType;import okhttp3.MultipartBody;import okhttp3.OkHttpClient;import okhttp3.Request;import okhttp3.RequestBody;import okhttp3.Response;
public final class PspdfkitApiExample { public static void main(final String[] args) throws IOException { final RequestBody body = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart( "index.html", "index.html", RequestBody.create( MediaType.parse("text/html"), new File("index.html") ) ) .addFormDataPart( "style.css", "style.css", RequestBody.create( MediaType.parse("text/css"), new File("style.css") ) ) .addFormDataPart( "instructions", new JSONObject() .put("parts", new JSONArray() .put(new JSONObject() .put("html", "index.html") .put("assets", new JSONArray() .put("style.css") ) ) ).toString() ) .build();
final Request request = new Request.Builder() .url("https://api.nutrient.io/build") .method("POST", body) .addHeader("Authorization", "Bearer your_api_key_here") .build();
final OkHttpClient client = new OkHttpClient() .newBuilder() .build();
final Response response = client.newCall(request).execute();
if (response.isSuccessful()) { Files.copy( response.body().byteStream(), FileSystems.getDefault().getPath("result.pdf"), StandardCopyOption.REPLACE_EXISTING ); } else { // Handle the error. throw new IOException(response.body().string()); } }}using System;using System.IO;using System.Net;using RestSharp;
namespace PspdfkitApiDemo{ class Program { static void Main(string[] args) { var client = new RestClient("https://api.nutrient.io/build");
var request = new RestRequest(Method.POST) .AddHeader("Authorization", "Bearer your_api_key_here") .AddFile("index.html", "index.html") .AddFile("style.css", "style.css") .AddParameter("instructions", new JsonObject { ["parts"] = new JsonArray { new JsonObject { ["html"] = "index.html", ["assets"] = new JsonArray { "style.css" } } } }.ToString());
request.AdvancedResponseWriter = (responseStream, response) => { if (response.StatusCode == HttpStatusCode.OK) { using (responseStream) { using var outputFileWriter = File.OpenWrite("result.pdf"); responseStream.CopyTo(outputFileWriter); } } else { var responseStreamReader = new StreamReader(responseStream); Console.Write(responseStreamReader.ReadToEnd()); } };
client.Execute(request); } }}// This code requires Node.js. Do not run this code directly in a web browser.
const axios = require('axios')const FormData = require('form-data')const fs = require('fs')
const formData = new FormData()formData.append('instructions', JSON.stringify({ parts: [ { html: "index.html", assets: [ "style.css" ] } ]}))formData.append('index.html', fs.createReadStream('index.html'))formData.append('style.css', fs.createReadStream('style.css'))
;(async () => { try { const response = await axios.post('https://api.nutrient.io/build', formData, { headers: formData.getHeaders({ 'Authorization': 'Bearer your_api_key_here' }), responseType: "stream" })
response.data.pipe(fs.createWriteStream("result.pdf")) } catch (e) { const errorString = await streamToString(e.response.data) console.log(errorString) }})()
function streamToString(stream) { const chunks = [] return new Promise((resolve, reject) => { stream.on("data", (chunk) => chunks.push(Buffer.from(chunk))) stream.on("error", (err) => reject(err)) stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8"))) })}import requestsimport json
response = requests.request( 'POST', 'https://api.nutrient.io/build', headers = { 'Authorization': 'Bearer your_api_key_here' }, files = { 'index.html': open('index.html', 'rb'), 'style.css': open('style.css', 'rb') }, data = { 'instructions': json.dumps({ 'parts': [ { 'html': 'index.html', 'assets': [ 'style.css' ] } ] }) }, stream = True)
if response.ok: with open('result.pdf', 'wb') as fd: for chunk in response.iter_content(chunk_size=8096): fd.write(chunk)else: print(response.text) exit()<?php
$FileHandle = fopen('result.pdf', 'w+');
$curl = curl_init();
curl_setopt_array($curl, array( CURLOPT_URL => 'https://api.nutrient.io/build', CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_POSTFIELDS => array( 'instructions' => '{ "parts": [ { "html": "index.html", "assets": [ "style.css" ] } ] }', 'index.html' => new CURLFILE('index.html'), 'style.css' => new CURLFILE('style.css') ), CURLOPT_HTTPHEADER => array( 'Authorization: Bearer your_api_key_here' ), CURLOPT_FILE => $FileHandle,));
$response = curl_exec($curl);
curl_close($curl);
fclose($FileHandle);POST https://api.nutrient.io/build HTTP/1.1Content-Type: multipart/form-data; boundary=--customboundaryAuthorization: Bearer your_api_key_here
--customboundaryContent-Disposition: form-data; name="instructions"Content-Type: application/json
{ "parts": [ { "html": "index.html", "assets": [ "style.css" ] } ]}--customboundaryContent-Disposition: form-data; name="index.html"; filename="index.html"Content-Type: text/html
(index.html data)--customboundaryContent-Disposition: form-data; name="style.css"; filename="style.css"Content-Type: text/css
(style.css data)--customboundary--Now that you’ve got your basic header, make things a bit nicer and add some custom fonts. Much like with the CSS file, place all the fonts you use in the same folder as your HTML file and then add them to your Nutrient DWS API request. The example below is already updated to show you how.
Always refer to assets by their name, as subfolders aren’t supported.
First, add the @font-family definitions to your CSS file. The updated style.css file includes the following information.
CSS file:
@font-face { font-family: "Inter"; src: url("Inter-Regular.ttf") format("truetype"); font-weight: 400; font-style: normal;}
@font-face { font-family: "Inter"; src: url("Inter-Medium.ttf") format("truetype"); font-weight: 500; font-style: normal;}
@font-face { font-family: "Inter"; src: url("Inter-Bold.ttf") format("truetype"); font-weight: 700; font-style: normal;}
@font-face { font-family: "Space Mono"; src: url("SpaceMono-Regular.ttf") format("truetype"); font-weight: 400; font-style: normal;}
body { font-size: 0.75rem; font-family: "Inter", sans-serif; font-weight: 400; color: #000000; margin: 0 auto; position: relative;}
h2 { font-family: "Space Mono", monospace; font-size: 1.25rem; font-weight: 400;}
h4 { font-family: "Space Mono", monospace; font-size: 1rem; font-weight: 400;}
.page { margin-left: 5rem; margin-right: 5rem;}
.intro-table { display: flex; justify-content: space-between; margin: 3rem 0 3rem 0; border-top: 1px solid #000000; border-bottom: 1px solid #000000;}
.intro-form { display: flex; flex-direction: column; border-right: 1px solid #000000; width: 50%;}
.intro-form:last-child { border-right: none;}
.intro-table-title { font-size: 0.625rem; margin: 0;}
.intro-form-item { padding: 1.25rem 1.5rem 1.25rem 1.5rem;}
.intro-form-item:first-child { padding-left: 0;}
.intro-form-item:last-child { padding-right: 0;}
.intro-form-item-border { padding: 1.25rem 0 0.75rem 1.5rem; border-bottom: 1px solid #000000;}
.intro-form-item-border:last-child { border-bottom: none;}Then add the fonts to your code for making requests. Add the font files in the same folder as your HTML file and CSS file. This way, they can be sent with the request. Refer to the invoice example for fonts.
Add all the font files to the same folder as your index.html and style.css files.
Running the new code displays your custom fonts, giving the invoice a cleaner appearance.
Command to generate a PDF file (basic API):
curl -X POST https://api.nutrient.io/processor/generate_pdf \ -H "Authorization: Bearer your_api_key_here" \ -o result.pdf \ --fail \ -F html=@index.html \ -F style.css=@style.css \ -F Inter-Regular.ttf=@Inter-Regular.ttf \ -F Inter-Medium.ttf=@Inter-Medium.ttf \ -F Inter-Bold.ttf=@Inter-Bold.ttf \ -F SpaceMono-Regular.ttf=@SpaceMono-Regular.ttf \ -F data='{ "assets": [ "style.css", "Inter-Regular.ttf", "Inter-Medium.ttf", "Inter-Bold.ttf", "SpaceMono-Regular.ttf" ] }'curl -X POST https://api.nutrient.io/processor/generate_pdf ^ -H "Authorization: Bearer your_api_key_here" ^ -o result.pdf ^ --fail ^ -F html=@index.html ^ -F style.css=@style.css ^ -F Inter-Regular.ttf=@Inter-Regular.ttf ^ -F Inter-Medium.ttf=@Inter-Medium.ttf ^ -F Inter-Bold.ttf=@Inter-Bold.ttf ^ -F SpaceMono-Regular.ttf=@SpaceMono-Regular.ttf ^ -F data="{\"assets\": [\"style.css\", \"Inter-Regular.ttf\", \"Inter-Medium.ttf\", \"Inter-Bold.ttf\", \"SpaceMono-Regular.ttf\"]}"package com.example.pspdfkit;
import java.io.File;import java.io.IOException;import java.nio.file.FileSystems;import java.nio.file.Files;import java.nio.file.StandardCopyOption;
import org.json.JSONArray;import org.json.JSONObject;
import okhttp3.MediaType;import okhttp3.MultipartBody;import okhttp3.OkHttpClient;import okhttp3.Request;import okhttp3.RequestBody;import okhttp3.Response;
public final class PspdfkitApiExample { public static void main(final String[] args) throws IOException { final RequestBody body = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart( "html", "index.html", RequestBody.create( MediaType.parse("text/html"), new File("index.html") ) ) .addFormDataPart( "style.css", "style.css", RequestBody.create( MediaType.parse("text/css"), new File("style.css") ) ) .addFormDataPart( "Inter-Regular.ttf", "Inter-Regular.ttf", RequestBody.create( MediaType.parse("font/ttf"), new File("Inter-Regular.ttf") ) ) .addFormDataPart( "Inter-Medium.ttf", "Inter-Medium.ttf", RequestBody.create( MediaType.parse("font/ttf"), new File("Inter-Medium.ttf") ) ) .addFormDataPart( "Inter-Bold.ttf", "Inter-Bold.ttf", RequestBody.create( MediaType.parse("font/ttf"), new File("Inter-Bold.ttf") ) ) .addFormDataPart( "SpaceMono-Regular.ttf", "SpaceMono-Regular.ttf", RequestBody.create( MediaType.parse("font/ttf"), new File("SpaceMono-Regular.ttf") ) ) .addFormDataPart( "data", new JSONObject() .put("assets", new JSONArray() .put("style.css") .put("Inter-Regular.ttf") .put("Inter-Medium.ttf") .put("Inter-Bold.ttf") .put("SpaceMono-Regular.ttf") ).toString() ) .build();
final Request request = new Request.Builder() .url("https://api.nutrient.io/processor/generate_pdf") .method("POST", body) .addHeader("Authorization", "Bearer your_api_key_here") .build();
final OkHttpClient client = new OkHttpClient() .newBuilder() .build();
final Response response = client.newCall(request).execute();
if (response.isSuccessful()) { Files.copy( response.body().byteStream(), FileSystems.getDefault().getPath("result.pdf"), StandardCopyOption.REPLACE_EXISTING ); } else { // Handle the error. throw new IOException(response.body().string()); } }}using System;using System.IO;using System.Net;using RestSharp;
namespace PspdfkitApiDemo{ class Program { static void Main(string[] args) { var client = new RestClient("https://api.nutrient.io/processor/generate_pdf");
var request = new RestRequest(Method.POST) .AddHeader("Authorization", "Bearer your_api_key_here") .AddFile("html", "index.html") .AddFile("style.css", "style.css") .AddFile("Inter-Regular.ttf", "Inter-Regular.ttf") .AddFile("Inter-Medium.ttf", "Inter-Medium.ttf") .AddFile("Inter-Bold.ttf", "Inter-Bold.ttf") .AddFile("SpaceMono-Regular.ttf", "SpaceMono-Regular.ttf") .AddParameter("data", new JsonObject { ["assets"] = new JsonArray { "style.css", "Inter-Regular.ttf", "Inter-Medium.ttf", "Inter-Bold.ttf", "SpaceMono-Regular.ttf" } }.ToString());
request.AdvancedResponseWriter = (responseStream, response) => { if (response.StatusCode == HttpStatusCode.OK) { using (responseStream) { using var outputFileWriter = File.OpenWrite("result.pdf"); responseStream.CopyTo(outputFileWriter); } } else { var responseStreamReader = new StreamReader(responseStream); Console.Write(responseStreamReader.ReadToEnd()); } };
client.Execute(request); } }}// This code requires Node.js. Do not run this code directly in a web browser.
const axios = require('axios')const FormData = require('form-data')const fs = require('fs')
const formData = new FormData()formData.append('data', JSON.stringify({ assets: [ "style.css", "Inter-Regular.ttf", "Inter-Medium.ttf", "Inter-Bold.ttf", "SpaceMono-Regular.ttf" ]}))formData.append('html', fs.createReadStream('index.html'))formData.append('style.css', fs.createReadStream('style.css'))formData.append('Inter-Regular.ttf', fs.createReadStream('Inter-Regular.ttf'))formData.append('Inter-Medium.ttf', fs.createReadStream('Inter-Medium.ttf'))formData.append('Inter-Bold.ttf', fs.createReadStream('Inter-Bold.ttf'))formData.append('SpaceMono-Regular.ttf', fs.createReadStream('SpaceMono-Regular.ttf'))
;(async () => { try { const response = await axios.post('https://api.nutrient.io/processor/generate_pdf', formData, { headers: formData.getHeaders({ 'Authorization': 'Bearer your_api_key_here' }), responseType: "stream" })
response.data.pipe(fs.createWriteStream("result.pdf")) } catch (e) { const errorString = await streamToString(e.response.data) console.log(errorString) }})()
function streamToString(stream) { const chunks = [] return new Promise((resolve, reject) => { stream.on("data", (chunk) => chunks.push(Buffer.from(chunk))) stream.on("error", (err) => reject(err)) stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8"))) })}import requestsimport json
response = requests.request( 'POST', 'https://api.nutrient.io/processor/generate_pdf', headers = { 'Authorization': 'Bearer your_api_key_here' }, files = { 'html': open('index.html', 'rb'), 'style.css': open('style.css', 'rb'), 'Inter-Regular.ttf': open('Inter-Regular.ttf', 'rb'), 'Inter-Medium.ttf': open('Inter-Medium.ttf', 'rb'), 'Inter-Bold.ttf': open('Inter-Bold.ttf', 'rb'), 'SpaceMono-Regular.ttf': open('SpaceMono-Regular.ttf', 'rb') }, data = { 'data': json.dumps({ 'assets': [ 'style.css', 'Inter-Regular.ttf', 'Inter-Medium.ttf', 'Inter-Bold.ttf', 'SpaceMono-Regular.ttf' ] }) }, stream = True)
if response.ok: with open('result.pdf', 'wb') as fd: for chunk in response.iter_content(chunk_size=8096): fd.write(chunk)else: print(response.text) exit()<?php
$FileHandle = fopen('result.pdf', 'w+');
$curl = curl_init();
curl_setopt_array($curl, array( CURLOPT_URL => 'https://api.nutrient.io/processor/generate_pdf', CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_POSTFIELDS => array( 'data' => '{ "assets": [ "style.css", "Inter-Regular.ttf", "Inter-Medium.ttf", "Inter-Bold.ttf", "SpaceMono-Regular.ttf" ] }', 'html' => new CURLFILE('index.html'), 'style.css' => new CURLFILE('style.css'), 'Inter-Regular.ttf' => new CURLFILE('Inter-Regular.ttf'), 'Inter-Medium.ttf' => new CURLFILE('Inter-Medium.ttf'), 'Inter-Bold.ttf' => new CURLFILE('Inter-Bold.ttf'), 'SpaceMono-Regular.ttf' => new CURLFILE('SpaceMono-Regular.ttf') ), CURLOPT_HTTPHEADER => array( 'Authorization: Bearer your_api_key_here' ), CURLOPT_FILE => $FileHandle,));
$response = curl_exec($curl);
curl_close($curl);
fclose($FileHandle);POST https://api.nutrient.io/processor/generate_pdf HTTP/1.1Content-Type: multipart/form-data; boundary=--customboundaryAuthorization: Bearer your_api_key_here
--customboundaryContent-Disposition: form-data; name="data"Content-Type: application/json
{ "assets": [ "style.css", "Inter-Regular.ttf", "Inter-Medium.ttf", "Inter-Bold.ttf", "SpaceMono-Regular.ttf" ]}--customboundaryContent-Disposition: form-data; name="html"; filename="index.html"Content-Type: text/html
(html data)--customboundaryContent-Disposition: form-data; name="style.css"; filename="style.css"Content-Type: text/css
(style.css data)--customboundaryContent-Disposition: form-data; name="Inter-Regular.ttf"; filename="Inter-Regular.ttf"Content-Type: font/ttf
(Inter-Regular.ttf data)--customboundaryContent-Disposition: form-data; name="Inter-Medium.ttf"; filename="Inter-Medium.ttf"Content-Type: font/ttf
(Inter-Medium.ttf data)--customboundaryContent-Disposition: form-data; name="Inter-Bold.ttf"; filename="Inter-Bold.ttf"Content-Type: font/ttf
(Inter-Bold.ttf data)--customboundaryContent-Disposition: form-data; name="SpaceMono-Regular.ttf"; filename="SpaceMono-Regular.ttf"Content-Type: font/ttf
(SpaceMono-Regular.ttf data)--customboundary--Advanced API:
curl -X POST https://api.nutrient.io/build \ -H "Authorization: Bearer your_api_key_here" \ -o result.pdf \ --fail \ -F index.html=@index.html \ -F style.css=@style.css \ -F Inter-Regular.ttf=@Inter-Regular.ttf \ -F Inter-Medium.ttf=@Inter-Medium.ttf \ -F Inter-Bold.ttf=@Inter-Bold.ttf \ -F SpaceMono-Regular.ttf=@SpaceMono-Regular.ttf \ -F instructions='{ "parts": [ { "html": "index.html", "assets": [ "style.css", "Inter-Regular.ttf", "Inter-Medium.ttf", "Inter-Bold.ttf", "SpaceMono-Regular.ttf" ] } ] }'curl -X POST https://api.nutrient.io/build ^ -H "Authorization: Bearer your_api_key_here" ^ -o result.pdf ^ --fail ^ -F index.html=@index.html ^ -F style.css=@style.css ^ -F Inter-Regular.ttf=@Inter-Regular.ttf ^ -F Inter-Medium.ttf=@Inter-Medium.ttf ^ -F Inter-Bold.ttf=@Inter-Bold.ttf ^ -F SpaceMono-Regular.ttf=@SpaceMono-Regular.ttf ^ -F instructions="{\"parts\": [{\"html\": \"index.html\", \"assets\": [\"style.css\", \"Inter-Regular.ttf\", \"Inter-Medium.ttf\", \"Inter-Bold.ttf\", \"SpaceMono-Regular.ttf\"]}]}"package com.example.pspdfkit;
import java.io.File;import java.io.IOException;import java.nio.file.FileSystems;import java.nio.file.Files;import java.nio.file.StandardCopyOption;
import org.json.JSONArray;import org.json.JSONObject;
import okhttp3.MediaType;import okhttp3.MultipartBody;import okhttp3.OkHttpClient;import okhttp3.Request;import okhttp3.RequestBody;import okhttp3.Response;
public final class PspdfkitApiExample { public static void main(final String[] args) throws IOException { final RequestBody body = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart( "index.html", "index.html", RequestBody.create( MediaType.parse("text/html"), new File("index.html") ) ) .addFormDataPart( "style.css", "style.css", RequestBody.create( MediaType.parse("text/css"), new File("style.css") ) ) .addFormDataPart( "Inter-Regular.ttf", "Inter-Regular.ttf", RequestBody.create( MediaType.parse("font/ttf"), new File("Inter-Regular.ttf") ) ) .addFormDataPart( "Inter-Medium.ttf", "Inter-Medium.ttf", RequestBody.create( MediaType.parse("font/ttf"), new File("Inter-Medium.ttf") ) ) .addFormDataPart( "Inter-Bold.ttf", "Inter-Bold.ttf", RequestBody.create( MediaType.parse("font/ttf"), new File("Inter-Bold.ttf") ) ) .addFormDataPart( "SpaceMono-Regular.ttf", "SpaceMono-Regular.ttf", RequestBody.create( MediaType.parse("font/ttf"), new File("SpaceMono-Regular.ttf") ) ) .addFormDataPart( "instructions", new JSONObject() .put("parts", new JSONArray() .put(new JSONObject() .put("html", "index.html") .put("assets", new JSONArray() .put("style.css") .put("Inter-Regular.ttf") .put("Inter-Medium.ttf") .put("Inter-Bold.ttf") .put("SpaceMono-Regular.ttf") ) ) ).toString() ) .build();
final Request request = new Request.Builder() .url("https://api.nutrient.io/build") .method("POST", body) .addHeader("Authorization", "Bearer your_api_key_here") .build();
final OkHttpClient client = new OkHttpClient() .newBuilder() .build();
final Response response = client.newCall(request).execute();
if (response.isSuccessful()) { Files.copy( response.body().byteStream(), FileSystems.getDefault().getPath("result.pdf"), StandardCopyOption.REPLACE_EXISTING ); } else { // Handle the error. throw new IOException(response.body().string()); } }}using System;using System.IO;using System.Net;using RestSharp;
namespace PspdfkitApiDemo{ class Program { static void Main(string[] args) { var client = new RestClient("https://api.nutrient.io/build");
var request = new RestRequest(Method.POST) .AddHeader("Authorization", "Bearer your_api_key_here") .AddFile("index.html", "index.html") .AddFile("style.css", "style.css") .AddFile("Inter-Regular.ttf", "Inter-Regular.ttf") .AddFile("Inter-Medium.ttf", "Inter-Medium.ttf") .AddFile("Inter-Bold.ttf", "Inter-Bold.ttf") .AddFile("SpaceMono-Regular.ttf", "SpaceMono-Regular.ttf") .AddParameter("instructions", new JsonObject { ["parts"] = new JsonArray { new JsonObject { ["html"] = "index.html", ["assets"] = new JsonArray { "style.css", "Inter-Regular.ttf", "Inter-Medium.ttf", "Inter-Bold.ttf", "SpaceMono-Regular.ttf" } } } }.ToString());
request.AdvancedResponseWriter = (responseStream, response) => { if (response.StatusCode == HttpStatusCode.OK) { using (responseStream) { using var outputFileWriter = File.OpenWrite("result.pdf"); responseStream.CopyTo(outputFileWriter); } } else { var responseStreamReader = new StreamReader(responseStream); Console.Write(responseStreamReader.ReadToEnd()); } };
client.Execute(request); } }}// This code requires Node.js. Do not run this code directly in a web browser.
const axios = require('axios')const FormData = require('form-data')const fs = require('fs')
const formData = new FormData()formData.append('instructions', JSON.stringify({ parts: [ { html: "index.html", assets: [ "style.css", "Inter-Regular.ttf", "Inter-Medium.ttf", "Inter-Bold.ttf", "SpaceMono-Regular.ttf" ] } ]}))formData.append('index.html', fs.createReadStream('index.html'))formData.append('style.css', fs.createReadStream('style.css'))formData.append('Inter-Regular.ttf', fs.createReadStream('Inter-Regular.ttf'))formData.append('Inter-Medium.ttf', fs.createReadStream('Inter-Medium.ttf'))formData.append('Inter-Bold.ttf', fs.createReadStream('Inter-Bold.ttf'))formData.append('SpaceMono-Regular.ttf', fs.createReadStream('SpaceMono-Regular.ttf'))
;(async () => { try { const response = await axios.post('https://api.nutrient.io/build', formData, { headers: formData.getHeaders({ 'Authorization': 'Bearer your_api_key_here' }), responseType: "stream" })
response.data.pipe(fs.createWriteStream("result.pdf")) } catch (e) { const errorString = await streamToString(e.response.data) console.log(errorString) }})()
function streamToString(stream) { const chunks = [] return new Promise((resolve, reject) => { stream.on("data", (chunk) => chunks.push(Buffer.from(chunk))) stream.on("error", (err) => reject(err)) stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8"))) })}import requestsimport json
response = requests.request( 'POST', 'https://api.nutrient.io/build', headers = { 'Authorization': 'Bearer your_api_key_here' }, files = { 'index.html': open('index.html', 'rb'), 'style.css': open('style.css', 'rb'), 'Inter-Regular.ttf': open('Inter-Regular.ttf', 'rb'), 'Inter-Medium.ttf': open('Inter-Medium.ttf', 'rb'), 'Inter-Bold.ttf': open('Inter-Bold.ttf', 'rb'), 'SpaceMono-Regular.ttf': open('SpaceMono-Regular.ttf', 'rb') }, data = { 'instructions': json.dumps({ 'parts': [ { 'html': 'index.html', 'assets': [ 'style.css', 'Inter-Regular.ttf', 'Inter-Medium.ttf', 'Inter-Bold.ttf', 'SpaceMono-Regular.ttf' ] } ] }) }, stream = True)
if response.ok: with open('result.pdf', 'wb') as fd: for chunk in response.iter_content(chunk_size=8096): fd.write(chunk)else: print(response.text) exit()<?php
$FileHandle = fopen('result.pdf', 'w+');
$curl = curl_init();
curl_setopt_array($curl, array( CURLOPT_URL => 'https://api.nutrient.io/build', CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_POSTFIELDS => array( 'instructions' => '{ "parts": [ { "html": "index.html", "assets": [ "style.css", "Inter-Regular.ttf", "Inter-Medium.ttf", "Inter-Bold.ttf", "SpaceMono-Regular.ttf" ] } ] }', 'index.html' => new CURLFILE('index.html'), 'style.css' => new CURLFILE('style.css'), 'Inter-Regular.ttf' => new CURLFILE('Inter-Regular.ttf'), 'Inter-Medium.ttf' => new CURLFILE('Inter-Medium.ttf'), 'Inter-Bold.ttf' => new CURLFILE('Inter-Bold.ttf'), 'SpaceMono-Regular.ttf' => new CURLFILE('SpaceMono-Regular.ttf') ), CURLOPT_HTTPHEADER => array( 'Authorization: Bearer your_api_key_here' ), CURLOPT_FILE => $FileHandle,));
$response = curl_exec($curl);
curl_close($curl);
fclose($FileHandle);POST https://api.nutrient.io/build HTTP/1.1Content-Type: multipart/form-data; boundary=--customboundaryAuthorization: Bearer your_api_key_here
--customboundaryContent-Disposition: form-data; name="instructions"Content-Type: application/json
{ "parts": [ { "html": "index.html", "assets": [ "style.css", "Inter-Regular.ttf", "Inter-Medium.ttf", "Inter-Bold.ttf", "SpaceMono-Regular.ttf" ] } ]}--customboundaryContent-Disposition: form-data; name="index.html"; filename="index.html"Content-Type: text/html
(index.html data)--customboundaryContent-Disposition: form-data; name="style.css"; filename="style.css"Content-Type: text/css
(style.css data)--customboundaryContent-Disposition: form-data; name="Inter-Regular.ttf"; filename="Inter-Regular.ttf"Content-Type: font/ttf
(Inter-Regular.ttf data)--customboundaryContent-Disposition: form-data; name="Inter-Medium.ttf"; filename="Inter-Medium.ttf"Content-Type: font/ttf
(Inter-Medium.ttf data)--customboundaryContent-Disposition: form-data; name="Inter-Bold.ttf"; filename="Inter-Bold.ttf"Content-Type: font/ttf
(Inter-Bold.ttf data)--customboundaryContent-Disposition: form-data; name="SpaceMono-Regular.ttf"; filename="SpaceMono-Regular.ttf"Content-Type: font/ttf
(SpaceMono-Regular.ttf data)--customboundary--With your invoice looking good, the next feature is fillable forms.
Add forms to your PDF by including regular HTML input tags in your HTML file. Add the following HTML snippet to your index.html file below the div with the intro-table class.
HTML template section:
<!-- Add below the intro-table div --><div class="page" style="page-break-after: always"> <div> <h4>Thank you for your purchase!</h4> </div>
<div class="form"> <label for="notes" class="label"> Notes: </label> <input type="text" id="notes" class="border-bottom" value="" /> </div>
<div class="signer"> <div class="form signer-item"> <label for="date" class="label">Date:</label> <input type="text" id="date" class="border-bottom" value="01/01/2021" /> </div>
<div class="form signer-item"> <label for="signature" class="label">Issued by:</label> <input type="text" id="signature" class="border" value="Sign Here" /> </div> </div></div>You can make them look nice by adding some styling for the forms to your CSS file.
Add the following CSS snippet to your style.css file.
Running the generation now creates fillable PDF forms on the second page.
HTML template section:
/* Add below .intro-form-item-border:last-child */
.form { display: flex; flex-direction: column; margin-top: 6rem;}
.signer { display: flex; justify-content: space-between; gap: 2.5rem; margin: 2rem 0 2rem 0;}
.signer-item { flex-grow: 1;}
input { color: #4537de; font-family: "Space Mono", monospace; text-align: center; margin-top: 1.5rem; height: 4rem; width: 100%; box-sizing: border-box;}
input#date,input#notes { text-align: left;}
input#signature { height: 8rem;}Add headers and footers to your invoice by creating HTML elements with pspdfkit-header or pspdfkit-footer IDs as the first and last elements of the body.
The PDF generator automatically displays these elements on all pages and replaces {{ pageNumber }} and {{ pageCount }} placeholders with correct values.
For this example, add the HTML for the headers shown in the sample code as the first and last elements of the body element in the index.html file.
Include your logo in the header. Download logo.svg from the invoice example and place it in the same folder as your index.html. You can include the logo in the code later.
HTML template section:
<!-- Add as the first element in the body. --><div id="pspdfkit-header"> <div class="header-columns"> <div class="logotype"> <img class="logo" src="logo.svg" /> <p>Company</p> </div>
<div> <p>[Company Info]</p> </div> </div></div>
<!-- Add as the last element in the body. --><div id="pspdfkit-footer"> <div class="footer-columns"> <span>Invoice</span> <span>Page {{ pageNumber }} of {{ pageCount }}</span> </div></div>You should also make sure your headers and footers look good by updating your CSS file one last time. Add the following to your style.css file.
HTML template section:
/* Add below input#signature. */#pspdfkit-header { font-size: 0.625rem; text-transform: uppercase; letter-spacing: 2px; font-weight: 400; color: #8A8680; margin-top: 2.5rem; margin-bottom: 2.5rem; width: 100%;}
.header-columns { display: flex; justify-content: space-between; padding-left: 2.5rem; padding-right: 2.5rem;}
.logo { height: 1.5rem; width: auto; margin-right: 1rem;}
.logotype { display: flex; align-items: center; font-weight: 700;}
#pspdfkit-footer { font-size: 0.5rem; text-transform: uppercase; letter-spacing: 1px; font-weight: 500; color: #8A8680; margin-top: 2.5rem; bottom: 2.5rem; position: absolute; width: 100%;}
.footer-columns { display: flex; justify-content: space-between; padding-left: 2.5rem; padding-right: 2.5rem;}You can now include logo.svg in your request.
This shows how to use all PDF generation features — more specifically, using HTML to define the structure of your PDF, using CSS to style and lay out your content, adding fonts and images to the PDF, and even including fillable forms.
The invoice example includes everything you added till now, and it adds the actual invoice and summary in the middle. It’s a great starting point for your own PDF generation templates. You can also check out all our other fully featured examples here.
Command to generate a PDF file (basic API):
curl -X POST https://api.nutrient.io/processor/generate_pdf \ -H "Authorization: Bearer your_api_key_here" \ -o result.pdf \ --fail \ -F html=@index.html \ -F style.css=@style.css \ -F Inter-Regular.ttf=@Inter-Regular.ttf \ -F Inter-Medium.ttf=@Inter-Medium.ttf \ -F Inter-Bold.ttf=@Inter-Bold.ttf \ -F SpaceMono-Regular.ttf=@SpaceMono-Regular.ttf \ -F logo.svg=@logo.svg \ -F data='{ "assets": [ "style.css", "Inter-Regular.ttf", "Inter-Medium.ttf", "Inter-Bold.ttf", "SpaceMono-Regular.ttf", "logo.svg" ] }'curl -X POST https://api.nutrient.io/processor/generate_pdf ^ -H "Authorization: Bearer your_api_key_here" ^ -o result.pdf ^ --fail ^ -F html=@index.html ^ -F style.css=@style.css ^ -F Inter-Regular.ttf=@Inter-Regular.ttf ^ -F Inter-Medium.ttf=@Inter-Medium.ttf ^ -F Inter-Bold.ttf=@Inter-Bold.ttf ^ -F SpaceMono-Regular.ttf=@SpaceMono-Regular.ttf ^ -F logo.svg=@logo.svg ^ -F data="{\"assets\": [\"style.css\", \"Inter-Regular.ttf\", \"Inter-Medium.ttf\", \"Inter-Bold.ttf\", \"SpaceMono-Regular.ttf\", \"logo.svg\"]}"package com.example.pspdfkit;
import java.io.File;import java.io.IOException;import java.nio.file.FileSystems;import java.nio.file.Files;import java.nio.file.StandardCopyOption;
import org.json.JSONArray;import org.json.JSONObject;
import okhttp3.MediaType;import okhttp3.MultipartBody;import okhttp3.OkHttpClient;import okhttp3.Request;import okhttp3.RequestBody;import okhttp3.Response;
public final class PspdfkitApiExample { public static void main(final String[] args) throws IOException { final RequestBody body = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart( "html", "index.html", RequestBody.create( MediaType.parse("text/html"), new File("index.html") ) ) .addFormDataPart( "style.css", "style.css", RequestBody.create( MediaType.parse("text/css"), new File("style.css") ) ) .addFormDataPart( "Inter-Regular.ttf", "Inter-Regular.ttf", RequestBody.create( MediaType.parse("font/ttf"), new File("Inter-Regular.ttf") ) ) .addFormDataPart( "Inter-Medium.ttf", "Inter-Medium.ttf", RequestBody.create( MediaType.parse("font/ttf"), new File("Inter-Medium.ttf") ) ) .addFormDataPart( "Inter-Bold.ttf", "Inter-Bold.ttf", RequestBody.create( MediaType.parse("font/ttf"), new File("Inter-Bold.ttf") ) ) .addFormDataPart( "SpaceMono-Regular.ttf", "SpaceMono-Regular.ttf", RequestBody.create( MediaType.parse("font/ttf"), new File("SpaceMono-Regular.ttf") ) ) .addFormDataPart( "logo.svg", "logo.svg", RequestBody.create( MediaType.parse("image/svg+xml"), new File("logo.svg") ) ) .addFormDataPart( "data", new JSONObject() .put("assets", new JSONArray() .put("style.css") .put("Inter-Regular.ttf") .put("Inter-Medium.ttf") .put("Inter-Bold.ttf") .put("SpaceMono-Regular.ttf") .put("logo.svg") ).toString() ) .build();
final Request request = new Request.Builder() .url("https://api.nutrient.io/processor/generate_pdf") .method("POST", body) .addHeader("Authorization", "Bearer your_api_key_here") .build();
final OkHttpClient client = new OkHttpClient() .newBuilder() .build();
final Response response = client.newCall(request).execute();
if (response.isSuccessful()) { Files.copy( response.body().byteStream(), FileSystems.getDefault().getPath("result.pdf"), StandardCopyOption.REPLACE_EXISTING ); } else { // Handle the error. throw new IOException(response.body().string()); } }}using System;using System.IO;using System.Net;using RestSharp;
namespace PspdfkitApiDemo{ class Program { static void Main(string[] args) { var client = new RestClient("https://api.nutrient.io/processor/generate_pdf");
var request = new RestRequest(Method.POST) .AddHeader("Authorization", "Bearer your_api_key_here") .AddFile("html", "index.html") .AddFile("style.css", "style.css") .AddFile("Inter-Regular.ttf", "Inter-Regular.ttf") .AddFile("Inter-Medium.ttf", "Inter-Medium.ttf") .AddFile("Inter-Bold.ttf", "Inter-Bold.ttf") .AddFile("SpaceMono-Regular.ttf", "SpaceMono-Regular.ttf") .AddFile("logo.svg", "logo.svg") .AddParameter("data", new JsonObject { ["assets"] = new JsonArray { "style.css", "Inter-Regular.ttf", "Inter-Medium.ttf", "Inter-Bold.ttf", "SpaceMono-Regular.ttf", "logo.svg" } }.ToString());
request.AdvancedResponseWriter = (responseStream, response) => { if (response.StatusCode == HttpStatusCode.OK) { using (responseStream) { using var outputFileWriter = File.OpenWrite("result.pdf"); responseStream.CopyTo(outputFileWriter); } } else { var responseStreamReader = new StreamReader(responseStream); Console.Write(responseStreamReader.ReadToEnd()); } };
client.Execute(request); } }}// This code requires Node.js. Do not run this code directly in a web browser.
const axios = require('axios')const FormData = require('form-data')const fs = require('fs')
const formData = new FormData()formData.append('data', JSON.stringify({ assets: [ "style.css", "Inter-Regular.ttf", "Inter-Medium.ttf", "Inter-Bold.ttf", "SpaceMono-Regular.ttf", "logo.svg" ]}))formData.append('html', fs.createReadStream('index.html'))formData.append('style.css', fs.createReadStream('style.css'))formData.append('Inter-Regular.ttf', fs.createReadStream('Inter-Regular.ttf'))formData.append('Inter-Medium.ttf', fs.createReadStream('Inter-Medium.ttf'))formData.append('Inter-Bold.ttf', fs.createReadStream('Inter-Bold.ttf'))formData.append('SpaceMono-Regular.ttf', fs.createReadStream('SpaceMono-Regular.ttf'))formData.append('logo.svg', fs.createReadStream('logo.svg'))
;(async () => { try { const response = await axios.post('https://api.nutrient.io/processor/generate_pdf', formData, { headers: formData.getHeaders({ 'Authorization': 'Bearer your_api_key_here' }), responseType: "stream" })
response.data.pipe(fs.createWriteStream("result.pdf")) } catch (e) { const errorString = await streamToString(e.response.data) console.log(errorString) }})()
function streamToString(stream) { const chunks = [] return new Promise((resolve, reject) => { stream.on("data", (chunk) => chunks.push(Buffer.from(chunk))) stream.on("error", (err) => reject(err)) stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8"))) })}import requestsimport json
response = requests.request( 'POST', 'https://api.nutrient.io/processor/generate_pdf', headers = { 'Authorization': 'Bearer your_api_key_here' }, files = { 'html': open('index.html', 'rb'), 'style.css': open('style.css', 'rb'), 'Inter-Regular.ttf': open('Inter-Regular.ttf', 'rb'), 'Inter-Medium.ttf': open('Inter-Medium.ttf', 'rb'), 'Inter-Bold.ttf': open('Inter-Bold.ttf', 'rb'), 'SpaceMono-Regular.ttf': open('SpaceMono-Regular.ttf', 'rb'), 'logo.svg': open('logo.svg', 'rb') }, data = { 'data': json.dumps({ 'assets': [ 'style.css', 'Inter-Regular.ttf', 'Inter-Medium.ttf', 'Inter-Bold.ttf', 'SpaceMono-Regular.ttf', 'logo.svg' ] }) }, stream = True)
if response.ok: with open('result.pdf', 'wb') as fd: for chunk in response.iter_content(chunk_size=8096): fd.write(chunk)else: print(response.text) exit()<?php
$FileHandle = fopen('result.pdf', 'w+');
$curl = curl_init();
curl_setopt_array($curl, array( CURLOPT_URL => 'https://api.nutrient.io/processor/generate_pdf', CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_POSTFIELDS => array( 'data' => '{ "assets": [ "style.css", "Inter-Regular.ttf", "Inter-Medium.ttf", "Inter-Bold.ttf", "SpaceMono-Regular.ttf", "logo.svg" ] }', 'html' => new CURLFILE('index.html'), 'style.css' => new CURLFILE('style.css'), 'Inter-Regular.ttf' => new CURLFILE('Inter-Regular.ttf'), 'Inter-Medium.ttf' => new CURLFILE('Inter-Medium.ttf'), 'Inter-Bold.ttf' => new CURLFILE('Inter-Bold.ttf'), 'SpaceMono-Regular.ttf' => new CURLFILE('SpaceMono-Regular.ttf'), 'logo.svg' => new CURLFILE('logo.svg') ), CURLOPT_HTTPHEADER => array( 'Authorization: Bearer your_api_key_here' ), CURLOPT_FILE => $FileHandle,));
$response = curl_exec($curl);
curl_close($curl);
fclose($FileHandle);POST https://api.nutrient.io/processor/generate_pdf HTTP/1.1Content-Type: multipart/form-data; boundary=--customboundaryAuthorization: Bearer your_api_key_here
--customboundaryContent-Disposition: form-data; name="data"Content-Type: application/json
{ "assets": [ "style.css", "Inter-Regular.ttf", "Inter-Medium.ttf", "Inter-Bold.ttf", "SpaceMono-Regular.ttf", "logo.svg" ]}--customboundaryContent-Disposition: form-data; name="html"; filename="index.html"Content-Type: text/html
(html data)--customboundaryContent-Disposition: form-data; name="style.css"; filename="style.css"Content-Type: text/css
(style.css data)--customboundaryContent-Disposition: form-data; name="Inter-Regular.ttf"; filename="Inter-Regular.ttf"Content-Type: font/ttf
(Inter-Regular.ttf data)--customboundaryContent-Disposition: form-data; name="Inter-Medium.ttf"; filename="Inter-Medium.ttf"Content-Type: font/ttf
(Inter-Medium.ttf data)--customboundaryContent-Disposition: form-data; name="Inter-Bold.ttf"; filename="Inter-Bold.ttf"Content-Type: font/ttf
(Inter-Bold.ttf data)--customboundaryContent-Disposition: form-data; name="SpaceMono-Regular.ttf"; filename="SpaceMono-Regular.ttf"Content-Type: font/ttf
(SpaceMono-Regular.ttf data)--customboundaryContent-Disposition: form-data; name="logo.svg"; filename="logo.svg"Content-Type: image/svg+xml
(logo.svg data)--customboundary--Advanced API:
curl -X POST https://api.nutrient.io/build \ -H "Authorization: Bearer your_api_key_here" \ -o result.pdf \ --fail \ -F index.html=@index.html \ -F style.css=@style.css \ -F Inter-Regular.ttf=@Inter-Regular.ttf \ -F Inter-Medium.ttf=@Inter-Medium.ttf \ -F Inter-Bold.ttf=@Inter-Bold.ttf \ -F SpaceMono-Regular.ttf=@SpaceMono-Regular.ttf \ -F logo.svg=@logo.svg \ -F instructions='{ "parts": [ { "html": "index.html", "assets": [ "style.css", "Inter-Regular.ttf", "Inter-Medium.ttf", "Inter-Bold.ttf", "SpaceMono-Regular.ttf", "logo.svg" ] } ] }'curl -X POST https://api.nutrient.io/build ^ -H "Authorization: Bearer your_api_key_here" ^ -o result.pdf ^ --fail ^ -F index.html=@index.html ^ -F style.css=@style.css ^ -F Inter-Regular.ttf=@Inter-Regular.ttf ^ -F Inter-Medium.ttf=@Inter-Medium.ttf ^ -F Inter-Bold.ttf=@Inter-Bold.ttf ^ -F SpaceMono-Regular.ttf=@SpaceMono-Regular.ttf ^ -F logo.svg=@logo.svg ^ -F instructions="{\"parts\": [{\"html\": \"index.html\", \"assets\": [\"style.css\", \"Inter-Regular.ttf\", \"Inter-Medium.ttf\", \"Inter-Bold.ttf\", \"SpaceMono-Regular.ttf\", \"logo.svg\"]}]}"package com.example.pspdfkit;
import java.io.File;import java.io.IOException;import java.nio.file.FileSystems;import java.nio.file.Files;import java.nio.file.StandardCopyOption;
import org.json.JSONArray;import org.json.JSONObject;
import okhttp3.MediaType;import okhttp3.MultipartBody;import okhttp3.OkHttpClient;import okhttp3.Request;import okhttp3.RequestBody;import okhttp3.Response;
public final class PspdfkitApiExample { public static void main(final String[] args) throws IOException { final RequestBody body = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart( "index.html", "index.html", RequestBody.create( MediaType.parse("text/html"), new File("index.html") ) ) .addFormDataPart( "style.css", "style.css", RequestBody.create( MediaType.parse("text/css"), new File("style.css") ) ) .addFormDataPart( "Inter-Regular.ttf", "Inter-Regular.ttf", RequestBody.create( MediaType.parse("font/ttf"), new File("Inter-Regular.ttf") ) ) .addFormDataPart( "Inter-Medium.ttf", "Inter-Medium.ttf", RequestBody.create( MediaType.parse("font/ttf"), new File("Inter-Medium.ttf") ) ) .addFormDataPart( "Inter-Bold.ttf", "Inter-Bold.ttf", RequestBody.create( MediaType.parse("font/ttf"), new File("Inter-Bold.ttf") ) ) .addFormDataPart( "SpaceMono-Regular.ttf", "SpaceMono-Regular.ttf", RequestBody.create( MediaType.parse("font/ttf"), new File("SpaceMono-Regular.ttf") ) ) .addFormDataPart( "logo.svg", "logo.svg", RequestBody.create( MediaType.parse("image/svg+xml"), new File("logo.svg") ) ) .addFormDataPart( "instructions", new JSONObject() .put("parts", new JSONArray() .put(new JSONObject() .put("html", "index.html") .put("assets", new JSONArray() .put("style.css") .put("Inter-Regular.ttf") .put("Inter-Medium.ttf") .put("Inter-Bold.ttf") .put("SpaceMono-Regular.ttf") .put("logo.svg") ) ) ).toString() ) .build();
final Request request = new Request.Builder() .url("https://api.nutrient.io/build") .method("POST", body) .addHeader("Authorization", "Bearer your_api_key_here") .build();
final OkHttpClient client = new OkHttpClient() .newBuilder() .build();
final Response response = client.newCall(request).execute();
if (response.isSuccessful()) { Files.copy( response.body().byteStream(), FileSystems.getDefault().getPath("result.pdf"), StandardCopyOption.REPLACE_EXISTING ); } else { // Handle the error. throw new IOException(response.body().string()); } }}using System;using System.IO;using System.Net;using RestSharp;
namespace PspdfkitApiDemo{ class Program { static void Main(string[] args) { var client = new RestClient("https://api.nutrient.io/build");
var request = new RestRequest(Method.POST) .AddHeader("Authorization", "Bearer your_api_key_here") .AddFile("index.html", "index.html") .AddFile("style.css", "style.css") .AddFile("Inter-Regular.ttf", "Inter-Regular.ttf") .AddFile("Inter-Medium.ttf", "Inter-Medium.ttf") .AddFile("Inter-Bold.ttf", "Inter-Bold.ttf") .AddFile("SpaceMono-Regular.ttf", "SpaceMono-Regular.ttf") .AddFile("logo.svg", "logo.svg") .AddParameter("instructions", new JsonObject { ["parts"] = new JsonArray { new JsonObject { ["html"] = "index.html", ["assets"] = new JsonArray { "style.css", "Inter-Regular.ttf", "Inter-Medium.ttf", "Inter-Bold.ttf", "SpaceMono-Regular.ttf", "logo.svg" } } } }.ToString());
request.AdvancedResponseWriter = (responseStream, response) => { if (response.StatusCode == HttpStatusCode.OK) { using (responseStream) { using var outputFileWriter = File.OpenWrite("result.pdf"); responseStream.CopyTo(outputFileWriter); } } else { var responseStreamReader = new StreamReader(responseStream); Console.Write(responseStreamReader.ReadToEnd()); } };
client.Execute(request); } }}// This code requires Node.js. Do not run this code directly in a web browser.
const axios = require('axios')const FormData = require('form-data')const fs = require('fs')
const formData = new FormData()formData.append('instructions', JSON.stringify({ parts: [ { html: "index.html", assets: [ "style.css", "Inter-Regular.ttf", "Inter-Medium.ttf", "Inter-Bold.ttf", "SpaceMono-Regular.ttf", "logo.svg" ] } ]}))formData.append('index.html', fs.createReadStream('index.html'))formData.append('style.css', fs.createReadStream('style.css'))formData.append('Inter-Regular.ttf', fs.createReadStream('Inter-Regular.ttf'))formData.append('Inter-Medium.ttf', fs.createReadStream('Inter-Medium.ttf'))formData.append('Inter-Bold.ttf', fs.createReadStream('Inter-Bold.ttf'))formData.append('SpaceMono-Regular.ttf', fs.createReadStream('SpaceMono-Regular.ttf'))formData.append('logo.svg', fs.createReadStream('logo.svg'))
;(async () => { try { const response = await axios.post('https://api.nutrient.io/build', formData, { headers: formData.getHeaders({ 'Authorization': 'Bearer your_api_key_here' }), responseType: "stream" })
response.data.pipe(fs.createWriteStream("result.pdf")) } catch (e) { const errorString = await streamToString(e.response.data) console.log(errorString) }})()
function streamToString(stream) { const chunks = [] return new Promise((resolve, reject) => { stream.on("data", (chunk) => chunks.push(Buffer.from(chunk))) stream.on("error", (err) => reject(err)) stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8"))) })}import requestsimport json
response = requests.request( 'POST', 'https://api.nutrient.io/build', headers = { 'Authorization': 'Bearer your_api_key_here' }, files = { 'index.html': open('index.html', 'rb'), 'style.css': open('style.css', 'rb'), 'Inter-Regular.ttf': open('Inter-Regular.ttf', 'rb'), 'Inter-Medium.ttf': open('Inter-Medium.ttf', 'rb'), 'Inter-Bold.ttf': open('Inter-Bold.ttf', 'rb'), 'SpaceMono-Regular.ttf': open('SpaceMono-Regular.ttf', 'rb'), 'logo.svg': open('logo.svg', 'rb') }, data = { 'instructions': json.dumps({ 'parts': [ { 'html': 'index.html', 'assets': [ 'style.css', 'Inter-Regular.ttf', 'Inter-Medium.ttf', 'Inter-Bold.ttf', 'SpaceMono-Regular.ttf', 'logo.svg' ] } ] }) }, stream = True)
if response.ok: with open('result.pdf', 'wb') as fd: for chunk in response.iter_content(chunk_size=8096): fd.write(chunk)else: print(response.text) exit()<?php
$FileHandle = fopen('result.pdf', 'w+');
$curl = curl_init();
curl_setopt_array($curl, array( CURLOPT_URL => 'https://api.nutrient.io/build', CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_POSTFIELDS => array( 'instructions' => '{ "parts": [ { "html": "index.html", "assets": [ "style.css", "Inter-Regular.ttf", "Inter-Medium.ttf", "Inter-Bold.ttf", "SpaceMono-Regular.ttf", "logo.svg" ] } ] }', 'index.html' => new CURLFILE('index.html'), 'style.css' => new CURLFILE('style.css'), 'Inter-Regular.ttf' => new CURLFILE('Inter-Regular.ttf'), 'Inter-Medium.ttf' => new CURLFILE('Inter-Medium.ttf'), 'Inter-Bold.ttf' => new CURLFILE('Inter-Bold.ttf'), 'SpaceMono-Regular.ttf' => new CURLFILE('SpaceMono-Regular.ttf'), 'logo.svg' => new CURLFILE('logo.svg') ), CURLOPT_HTTPHEADER => array( 'Authorization: Bearer your_api_key_here' ), CURLOPT_FILE => $FileHandle,));
$response = curl_exec($curl);
curl_close($curl);
fclose($FileHandle);POST https://api.nutrient.io/build HTTP/1.1Content-Type: multipart/form-data; boundary=--customboundaryAuthorization: Bearer your_api_key_here
--customboundaryContent-Disposition: form-data; name="instructions"Content-Type: application/json
{ "parts": [ { "html": "index.html", "assets": [ "style.css", "Inter-Regular.ttf", "Inter-Medium.ttf", "Inter-Bold.ttf", "SpaceMono-Regular.ttf", "logo.svg" ] } ]}--customboundaryContent-Disposition: form-data; name="index.html"; filename="index.html"Content-Type: text/html
(index.html data)--customboundaryContent-Disposition: form-data; name="style.css"; filename="style.css"Content-Type: text/css
(style.css data)--customboundaryContent-Disposition: form-data; name="Inter-Regular.ttf"; filename="Inter-Regular.ttf"Content-Type: font/ttf
(Inter-Regular.ttf data)--customboundaryContent-Disposition: form-data; name="Inter-Medium.ttf"; filename="Inter-Medium.ttf"Content-Type: font/ttf
(Inter-Medium.ttf data)--customboundaryContent-Disposition: form-data; name="Inter-Bold.ttf"; filename="Inter-Bold.ttf"Content-Type: font/ttf
(Inter-Bold.ttf data)--customboundaryContent-Disposition: form-data; name="SpaceMono-Regular.ttf"; filename="SpaceMono-Regular.ttf"Content-Type: font/ttf
(SpaceMono-Regular.ttf data)--customboundaryContent-Disposition: form-data; name="logo.svg"; filename="logo.svg"Content-Type: image/svg+xml
(logo.svg data)--customboundary--