Welcome to the PDFShift API. This documentation contains all the details needed to use the API and how to
convert documents from HTML to PDF.
You will find code samples in Shell, Javascript, Python and PHP.
Getting an API Key
In order to generate PDF without the PDFShift's watermark, you will need an API Key.
You can request one by creating an account on PDFShift's
website.
Once you have submitted the form, we will send you an email containing your API Key.
You can also create other API Key if you want, to split your keys accross your project.
This can be done via your Dashboard.
You can test and play with our API without an API Key. Simply don't provide a "Basic Auth" header and the
request will be done, with the difference that a watermark will be applied to the document.
Note that applying a watermark makes the generation slower, so you will have better result when using
your API Key.
Authentication
Authenticate your account by including your secret key in API requests. You can manage your API keys in
the Dashboard.
Authentication to the API is performed via HTTP Basic Auth.
Provide your API key as the basic auth username value. The password is ignored and can be set to
whatever you want (an empty string works fine).
Authorization: Basic your_api_key:
Rate limiting
Rate limiting is only forced for unauthenticated accounts with a limit of 2 requests per
minutes.
As soon as you are authenticated, the restriction is lifted and you can convert as many documents as you
want.
When reaching the rate limit, you will get an HTTP status code of 429.
Each request will contain three headers to let you know your usage:
# HTTP response from PDFShift's API will contain these three headers:
X-RateLimit-Remaining: 30
X-RateLimit-Limit: 45
X-RateLimit-Reset: 1466368960
Key
Explanation
X-RateLimit-Remaining
Indicates the number of requests before hitting the rate limit.
X-RateLimit-Reset
Indicates the number of requests you can make per minutes (always 45).
X-RateLimit-Reset
Indicates when the rate limit will reset.
Errors
The PDFShift API uses the following error codes:
Error Code
Meaning
400
Bad Request -- Your request is invalid. Often, it means a parameter was wrongly set.
401
Unauthorized -- No API key were found.
403
Forbidden -- The provided API key is invalid.
404
Not Found -- The page you tried to reach was not found.
405
Method Not Allowed -- The endpoint you tried to reach is not available with this HTTP
method.
408
A timeout error occured when trying to convert a document.
429
Too Many Requests -- You sent too many request. Please see the Rate limiting section for more
details.
500
Internal Server Error -- We had a problem with our server. Try again later.
Convert
General
This is the main endpoint of the PDFShift's API.
The main idea is to pass a source document in HTML (either raw HTML or an URL) and get a PDF in return.
Many parameters are available to let you customize the resulting PDF to your needs.
HTTP Request
POST https://api.pdfshift.io/v2/convert
Parameters
Provide the parameters as a JSON object.
Parameter
Type
Default
Description
source
String or URL
required
Original document to convert to PDF. PDFShift will automatically detect if it's an URL and
load it, or an HTML document and charge it. You can also send an array of documents to
convert if parallel conversions is enabled on your account. In that case, you will also need
to provide the webhook parameters as this operation is asynchronous.
sandbox
Boolean
false
Will generates documents that doesn't count in the credits. The generated document will come
with a watermark.
encode
Boolean
false
Will return the generated PDF in Base64 encoded format, instead of raw.
timeout
Integer
null
If provided, will kill the page loading at a specified time without stopping with a
TimeoutError. Value in seconds
wait_for
String
null
Name of a function available globally. When present, PDFShift will wait for this function to
return a truthy value (true, 1, a string, etc) or up to 30 seconds, then proceed to the
conversion.
landscape
Boolean
false
Will set the view in landscape mode instead of portrait
css
String or URL
null
Will append this CSS styles to the document before saving it. Can be an URL or a String of
CSS rules.
javascript
String or URL
null
Will execute the given Javascript before saving the document. Can be an URL or a String of
JS code.
disable_images
Boolean
false
Images will not be included in the final document.
disable_javascript
Boolean
false
Will not execute the javascript at all in the document
disable_links
Boolean
false
The link in the document will not point anywhere.
disable_backgrounds
Boolean
false
The final document will not have the background images.
remove_blank
Boolean
false
Remove the last page if it is considered empty..
delay
Integer
0
In milliseconds. Will wait for this duration before capturing the document. Up to 10 seconds
max.
use_print
Boolean
false
Use the print stylesheet instead of the general one.
format
String
A4
Format of the document. You can either use the standard values (Letter, Legal, Tabloid,
Ledger, A0, A1, A2, A3, A4, A5) or a custom {width}x{height} value. For {width}
and {height}, you can indicate the following units: in, cm, mm.
pages
String
null
Pages to print. Can be one number (3), a range (1-5), a list (4,5,6) or a combination of both (1-3,6,7). If the number is higher than the real number of pages, that number will be ignored.
zoom
Float
1
A value between 0 and 2. Allows you to increase the zoom in the document for specific
purposes. 1 is the default zoom, lower is smaller, higher is bigger.
webhook
String (URL)
null
An URL where we will send a POST request containing a JSON body similar to when you use the
filename parameter. The JSON response will contain a URL key that
points to your file, stored on Amazon S3.
margin
String or Object
null
Empty spaces between the outer and the beginning of the content
auth
Object
null
Object containing username and password for accessing
password-protected content.
cookies
Array
null
List of cookies you want to send along with the requests when loading the source. See the
related part at the bottom of the document
http_headers
Object
null
List of http headers that you can customize for a better end result.
header
Object
null
Defines a custom header. See the "Header/Footer" section for more details.
footer
Object
null
Same as header.
protection
Object
null
Will add restrictions on the PDF document. See the #Protection part for more details
watermark
Object
null
Add a watermark to the generated document. See the #Watermark part for more details.
Cookies
List of accepted parameters for the Cookie object.
Parameter
Type
Default
Description
name
String
required
Name of the cookie
value
String
** required **
Value for the specified cookie
secure
Boolean
false
If set to true, This cookie will only be available for secure (https) connections.
http_only
Boolean
false
If set to true, this cookie will only be available to HTTP request only (no javascript).
Margin
You can define margin for the document (space between the limits of the document and the beginning of the
content).
You can either pass an object as defined below, or use a CSS like string, like the following:
10px: Will set a margin of 10px for all four borders.
10px 0: Will set a margin of 10px for top and bottom, and a margin of
0 for left and right.
10px 0 20px: Will set a margin of 10px for top, 0 for left and right
and 20px for the bottom.
10px 20px 30px 40px: Will set a margin of 10px for top, 20px for
right, 30px for bottom and 40px for left.
Otherwise, you can use an object to directly target a specific margin, using the following:
Parameter
Type
Default
Description
top
Integer or String
null
Space between the top and the content.
right
Integer or String
null
Space between the right and the content.
bottom
Integer or String
null
Space between the bottom and the content.
left
Integer or String
null
Space between the left and the content.
Header/Footer
You can configure the aspect of your header and footer document using the following values.
Parameter
Type
Default
Description
source
String or URL
null
Element to add in the header/footer part of the document. You can use variables, indicated
at the end of the document. PDFShift will automatically detect if it's an URL and load it,
or an HTML data and charge it.
spacing
Integer or String
null
A spacing between the header or footer and the content. For header, it's the space between
the header and the beginning of the document. For the footer, it's the space between the end
of the document and the bottom of the page.
start_at
Integer
1
Display the header/footer starting at the given page. The number is 1-based. IMPORTANT: You can not set different start_at value for the header and footer if they are higher than 1. For instance header.start_at = 1 and footer.start_at = 2 is possible,
but header.start_at = 2 and footer.start_at = 3 is not supported.
Header/Footer variables
Variable
Description
{{date}}
Formatted print date
{{title}}
Title of the HTML document
{{url}}
Page URL
{{page}}
Current page
{{total}}
Total number of pages
Protection
You can restrict access to your generated document using the following rules. The encryption is made in
128bits.
Parameter
Type
Default
Description
author
String
null
Document's author name
user_password
String
null
A user who has the password will be able to view the document and perform operations allowed
by the permission options
owner_password
String
null
A user who has the password will have unlimited access to the PDF, including changing the
passwords and permission options.
no_print
Boolean
false
When set to true, printing will be disabled.
no_copy
Boolean
false
When set to true, the possibility to copy any text will be disabled.
no_modify
Boolean
false
When set to true, the possibility to modify the document will be disabled.
Watermark
You can add a watermark to your documents via three alternatives:
Via a PDF
Via Text
Via Image
Each alternatives has a set of options, which is detailed here:
Via PDF
Parameter
Type
Default
Description
source
URL or Base64 encoded PDF content
required
You can provide the source either as an URL, or a base 64 encoded PDF
content. Raw PDF content will be refused. We recommend you to send a one page PDF content
because only the first page is used on each of your generated content.
Via Text
Parameter
Type
Default
Description
text
String
required
The text to display as watermark.
font_size
Integer
16
The font size used.
font_family
String
Helvetica
The font family used.
font_color
String
000000
The color of the text.
font_opacity
Integer
100
The opacity for the text.
font_bold
Boolean
false
Set to true if you want the text bold.
font_italic
Boolean
false
Set to true if you want the text in italic.
offset_x
String
center
The X position. Can be either a String (left, center, right) or a number with unit (defaults
to pixels. Allowed units are 'px', 'in', 'cm', 'mm', 'pt').
offset_y
String
middle
The Y position. Can be either a string (top, middle, bottom) or a number with unit (defaults
to pixels. Allowed units are 'px', 'in', 'cm', 'mm', 'pt').
rotate
Integer
-45
The degree for the rotated element.
Via Image
Parameter
Type
Default
Description
image
URL or Base64 encoded image content
required
The image to display as watermark.
offset_x
String
center
The X position. Can be either a String (left, center, right) or a number with unit (defaults
to pixels. Allowed units are 'px', 'in', 'cm', 'mm', 'pt').
offset_y
String
middle
The Y position. Can be either a string (top, middle, bottom) or a number with unit (defaults
to pixels. Allowed units are 'px', 'in', 'cm', 'mm', 'pt').
rotate
Integer
-45
The degree for the rotated element.
Misc
When converting a document, if successful, the HTTP response from PDFShift's API will contain the
following header:
Header
Description
X-Response-StatusCode
The status code from your URL source, when an URL is provided. This can be useful to ensure
the URL worked correctly.
Webhooks
If the webhook parameter is defined, the call to PDFShift's API will return a Queued
response along with a 202 status code, like the following:
{"queued": true}
Once the processing has been done, we will send a POST request to your webhook endpoint,
containing a JSON payload with the URL to your converted document, stored at Amazon S3 (for two days).
<?php// Using the function at
// https://gist.github.com/cnicodeme/f2c73d89ac49313d023d738b5cdb7046
$response=pdfshift('your_api_key_here',array('source'=>'https://www.example.com'));file_put_contents('result.pdf',$response);
require'uri'require'net/https'require'json'# for hash to_json conversionuri=URI("https://api.pdfshift.io/v2/convert/")data={"source"=>"https://www.example.com"}Net::HTTP.start(uri.host,uri.port,:use_ssl=>true)do|http|request=Net::HTTP::Post.new(uri.request_uri)request.body=data.to_jsonrequest["Content-Type"]="application/json"request.basic_auth'your_api_key',''response=http.request(request)ifresponse.code=='200'# Since Ruby 1.9.1 only:File.binwrite("result.pdf",response.body)else# Handle other codes hereputs"#{response.code}#{response.body}"endend
publicstaticvoidmain(String...args)throwsException{varjsonObject=newJSONObject();jsonObject.put("source","https://example.com");varhttpRequest=HttpRequest.newBuilder().uri(URI.create("https://api.pdfshift.io/v2/convert")).timeout(Duration.ofSeconds(20)).header("Content-Type","application/json").header("Authentication","Basic "+"your_api_key").POST(HttpRequest.BodyPublishers.ofString(jsonObject.toString())).build();varhttpClient=HttpClient.newBuilder().version(HttpClient.Version.HTTP_1_1).build();varresponse=httpClient.send(httpRequest,HttpResponse.BodyHandlers.ofInputStream());varstatusCode=response.statusCode();if(statusCode==200||statusCode==201){// Save the file locallyvartargetFile=newFile("src/main/resources/targetFile.pdf");Files.copy(response.body(),targetFile.toPath(),StandardCopyOption.REPLACE_EXISTING);}else{// error occurred}}
staticvoidMain(string[]args){IRestClientclient=newRestClient("https://api.pdfshift.io/v2/convert");client.Authenticator=newHttpBasicAuthenticator("your_api_key","");IRestRequestrequest=newRestRequest(Method.POST);varjson=new{source="https://www.example.com"};request.AddJsonBody(json);IRestResponseresponse=client.Execute(request);if(!response.IsSuccessful){// Check why status is not int 2xx.}else{File.WriteAllBytes("result.pdf",response.RawBytes);}}
packagemainimport("bytes""encoding/json""io/ioutil""log""net/http")funcmain(){API_KEY:="your_api_key"message:=map[string]interface{}{"source":"https://example.com",}bytesRepresentation,err:=json.Marshal(message)iferr!=nil{log.Fatalln(err)}client:=http.Client{}request,err:=http.NewRequest("POST","https://api.pdfshift.io/v2/convert",bytes.NewBuffer(bytesRepresentation))iferr!=nil{log.Fatalln(err)}request.Header.Set("Content-Type","application/json")request.Header.Set("Authorization","Basic "+API_KEY)resp,err:=client.Do(request)iferr!=nil{log.Fatalln(err)}ifresp.StatusCode>=200&&resp.StatusCode<300{body,err:=ioutil.ReadAll(resp.Body)iferr!=nil{log.Fatalln(err)}// write the response to fileioutil.WriteFile("example.pdf",body,0644)}else{// An error occurredvarresultmap[string]interface{}json.NewDecoder(resp.Body).Decode(&result)log.Println(result)log.Println(result["data"])}}
The above command returns a PDF in binary format.
This endpoint the given URL to PDF.
Saving the document to Amazon S3
constpdfshift=require('pdfshift')('your_api_key');constfs=require('fs');pdfshift.convert('https://www.example.com',{filename:'result.pdf'}).then(function(body){letjson=JSON.parse(body);// The URL is on console.log(json.url);}).catch(function({message,code,response,errors=null}){})
<?php$response=pdfshift('your_api_key_here',array('source'=>'https://www.example.com','filename'=>'result.pdf'));$json=json_decode($response,true);// The URL is at $json['url'];
importrequestsresponse=requests.post('https://api.pdfshift.io/v2/convert',auth=('your_api_key_here',''),json={'source':'https://www.example.com','filename':'result.pdf'})response.raise_for_status()json_response=response.json()# The URL to the document is at json_response['url]
require'uri'require'net/https'require'json'# for hash to_json conversionuri=URI("https://api.pdfshift.io/v2/convert/")data={"source"=>'http://www.example.com',"filename"=>"result.pdf"}Net::HTTP.start(uri.host,uri.port,:use_ssl=>true)do|http|request=Net::HTTP::Post.new(uri.request_uri)request.body=data.to_jsonrequest["Content-Type"]="application/json"request.basic_auth'your_api_key',''response=http.request(request)ifresponse.code=='200'putsresponse.body# { "duration":1309,# "filesize":37511,# "success":true,# "url":"<amazon_s3_url>/result.pdf"}data=JSON.parse(response.body)redirect_todata['url']else# Handle other codes hereputs"#{response.code}#{response.body}"endend
publicstaticvoidmain(String...args)throwsException{JSONObjectjsonObject=newJSONObject();jsonObject.put("source","https://example.com");jsonObject.put("filename","result.pdf");varhttpRequest=HttpRequest.newBuilder().uri(URI.create("https://api.pdfshift.io/v2/convert")).timeout(Duration.ofSeconds(20)).header("Content-Type","application/json").header("Authentication","Basic "+"your_api_key").POST(HttpRequest.BodyPublishers.ofFile(Paths.get("src/main/resources/body.json"))).build();varhttpClient=HttpClient.newBuilder().version(HttpClient.Version.HTTP_1_1).build();varresponse=httpClient.send(httpRequest,HttpResponse.BodyHandlers.ofString());varstatusCode=response.statusCode();if(statusCode==200||statusCode==201){// Response body is a json string. varresult=newJSONObject(response.body());System.out.println(result.get("url"));}else{// error occurred}}
staticvoidMain(string[]args){IRestClientclient=newRestClient("https://api.pdfshift.io/v2/convert");client.Authenticator=newHttpBasicAuthenticator("your_api_key","");IRestRequestrequest=newRestRequest(Method.POST);varjson=new{source="https://www.example.com",filename="result.pdf"};request.AddJsonBody(json);IRestResponseresponse=client.Execute(request);if(!response.IsSuccessful){// Check why status is not int 2xx.}else{varjObject=JObject.Parse(response.Content);Console.WriteLine(jObject["url"].Value<string>());}}
packagemainimport("net/http""log""encoding/json""bytes")funcmain(){API_KEY:="your_api_key"message:=map[string]interface{}{"source":"https://example.com","filename":"anotherExample.pdf",}bytesRepresentation,err:=json.Marshal(message)iferr!=nil{log.Fatalln(err)}client:=http.Client{}request,err:=http.NewRequest("POST","https://api.pdfshift.io/v2/convert",bytes.NewBuffer(bytesRepresentation))iferr!=nil{log.Fatalln(err)}request.Header.Set("Content-Type","application/json")request.Header.Set("Authorization","Basic "+API_KEY)resp,err:=client.Do(request)iferr!=nil{log.Fatalln(err)}ifresp.StatusCode>=200&&resp.StatusCode<300{varresultmap[string]interface{}json.NewDecoder(resp.Body).Decode(&result)log.Println(result["url"])}else{// An error occurredvarresultmap[string]interface{}json.NewDecoder(resp.Body).Decode(&result)log.Println(result)}}
The above command returns JSON structured like this:
By passing the "filename" parameter, the endpoint won't return the binary PDF, but an URL from Amazon S3
where the document will be stored for 2 days before being automatically deleted.
This can be useful if you don't want to download a large PDF to your server to then serve it to your
users, but instead redirect them directly to that document.
Accessing secured pages
constpdfshift=require('pdfshift')('your_api_key');constfs=require('fs');// We use .prepare() instead of .convert to easily handle advanced configurationpdfshift.prepare('https://httpbin.org/basic-auth/user/passwd').auth('user','passwd').convert().then(function(binary_file){fs.writeFile('result.pdf',binary_file,"binary",function(){})}).catch(function({message,code,response,errors=null}){})
require'uri'require'net/https'require'json'# for hash to_json conversionuri=URI("https://api.pdfshift.io/v2/convert/")data={"source"=>"https://httpbin.org/basic-auth/user/passwd","auth"=>{"username"=>"user","password"=>"passwd"}}Net::HTTP.start(uri.host,uri.port,:use_ssl=>true)do|http|request=Net::HTTP::Post.new(uri.request_uri)request.body=data.to_jsonrequest["Content-Type"]="application/json"request.basic_auth'your_api_key',''response=http.request(request)ifresponse.code=='200'# Since Ruby 1.9.1 only:File.binwrite("result.pdf",response.body)else# Handle other codes hereputs"#{response.code}#{response.body}"endend
publicstaticvoidmain(String...args)throwsException{varjsonObject=newJSONObject();jsonObject.put("source","https://httpbin.org/basic-auth/user/passwd");varauth=newJSONObject();auth.put("username","user");auth.put("password","passwd");jsonObject.put("auth",auth);varhttpRequest=HttpRequest.newBuilder().uri(URI.create("https://api.pdfshift.io/v2/convert")).timeout(Duration.ofSeconds(20)).header("Content-Type","application/json").header("Authentication","Basic "+"your_api_key").POST(HttpRequest.BodyPublishers.ofString(jsonObject.toString())).build();varhttpClient=HttpClient.newBuilder().version(HttpClient.Version.HTTP_1_1).build();varresponse=httpClient.send(httpRequest,HttpResponse.BodyHandlers.ofInputStream());varstatusCode=response.statusCode();if(statusCode==200||statusCode==201){// Save the file locallyvartargetFile=newFile("src/main/resources/targetFile.pdf");Files.copy(response.body(),targetFile.toPath(),StandardCopyOption.REPLACE_EXISTING);}else{// error occurred}}
staticvoidMain(string[]args){IRestClientclient=newRestClient("https://api.pdfshift.io/v2/convert");client.Authenticator=newHttpBasicAuthenticator("your_api_key","");IRestRequestrequest=newRestRequest(Method.POST);varjson=new{source="https://httpbin.org/basic-auth/user/passwd",auth=new{username="user",password="passwd"}};request.AddJsonBody(json);IRestResponseresponse=client.Execute(request);if(!response.IsSuccessful){// Check why status is not int 2xx.}else{File.WriteAllBytes("result.pdf",response.RawBytes);}}
packagemainimport("bytes""encoding/json""io/ioutil""log""net/http")funcmain(){API_KEY:="your_api_key"message:=map[string]interface{}{"source":"https://httpbin.org/basic-auth/user/passwd","auth":map[string]string{"username":"user","password":"passwd",},}bytesRepresentation,err:=json.Marshal(message)iferr!=nil{log.Fatalln(err)}client:=http.Client{}request,err:=http.NewRequest("POST","https://api.pdfshift.io/v2/convert",bytes.NewBuffer(bytesRepresentation))iferr!=nil{log.Fatalln(err)}request.Header.Set("Content-Type","application/json")request.Header.Set("Authorization","Basic "+API_KEY)resp,err:=client.Do(request)iferr!=nil{log.Fatalln(err)}ifresp.StatusCode>=200&&resp.StatusCode<300{body,err:=ioutil.ReadAll(resp.Body)iferr!=nil{log.Fatalln(err)}// write the response to fileioutil.WriteFile("example.pdf",body,0644)}else{varresultmap[string]interface{}json.NewDecoder(resp.Body).Decode(&result)log.Println(result)}}
The above command returns a PDF in binary format.
If your documents are located inside a protected area requiring a Basic Auth access, you can use the
auth parameter from PDFShift's API to connect to your website.
Here's an example on how to do so.
Using Cookies
constpdfshift=require('pdfshift')('your_api_key');constfs=require('fs');// We use .prepare() instead of .convert to easily handle advanced configurationpdfshift.prepare('https://httpbin.org/cookies').addCookie({name:'session',value:'4cb496a8-a3eb-4a7e-a704-f993cb6a4dac'}).convert().then(function(binary_file){fs.writeFile('result.pdf',binary_file,"binary",function(){})}).catch(function({message,code,response,errors=null}){})
require'uri'require'net/https'require'json'# for hash to_json conversionuri=URI("https://api.pdfshift.io/v2/convert/")data={"source"=>"https://httpbin.org/cookies","cookies"=>[{"name"=>"session","value"=>"4cb496a8-a3eb-4a7e-a704-f993cb6a4dac"}]}Net::HTTP.start(uri.host,uri.port,:use_ssl=>true)do|http|request=Net::HTTP::Post.new(uri.request_uri)request.body=data.to_jsonrequest["Content-Type"]="application/json"request.basic_auth'your_api_key',''response=http.request(request)ifresponse.code=='200'# Since Ruby 1.9.1 only:File.binwrite("result.pdf",response.body)else# Handle other codes hereputs"#{response.code}#{response.body}"endend
publicstaticvoidmain(String...args)throwsException{varjsonObject=newJSONObject();jsonObject.put("source","https://httpbin.org/cookies");varcookie=newJSONObject();cookie.put("name","session");cookie.put("value","4cb496a8-a3eb-4a7e-a704-f993cb6a4dac");varcookies=newJSONArray();cookies.put(cookie);jsonObject.put("cookies",cookies);varhttpRequest=HttpRequest.newBuilder().uri(URI.create("https://api.pdfshift.io/v2/convert")).timeout(Duration.ofSeconds(20)).header("Content-Type","application/json").header("Authentication","Basic "+"your_api_key").POST(HttpRequest.BodyPublishers.ofString(jsonObject.toString())).build();varhttpClient=HttpClient.newBuilder().version(HttpClient.Version.HTTP_1_1).build();varresponse=httpClient.send(httpRequest,HttpResponse.BodyHandlers.ofInputStream());varstatusCode=response.statusCode();if(statusCode==200||statusCode==201){// Save the file locallyvartargetFile=newFile("src/main/resources/targetFile.pdf");Files.copy(response.body(),targetFile.toPath(),StandardCopyOption.REPLACE_EXISTING);}else{// error occurred}}
staticvoidMain(string[]args){IRestClientclient=newRestClient("https://api.pdfshift.io/v2/convert");client.Authenticator=newHttpBasicAuthenticator("your_api_key","");IRestRequestrequest=newRestRequest(Method.POST);varjson=new{source="https://httpbin.org/cookies",cookies=newobject[]{new{name="Session",value="4cb496a8-a3eb-4a7e-a704-f993cb6a4dac"}}};request.AddJsonBody(json);IRestResponseresponse=client.Execute(request);if(!response.IsSuccessful){// Check why status is not int 2xx.}else{File.WriteAllBytes("result.pdf",response.RawBytes);}}
packagemainimport("net/http""log""encoding/json""bytes""io/ioutil")funcmain(){API_KEY:="your_api_key"cookies:=make([]map[string]string,1)cookies[0]=make(map[string]string)cookies[0]["name"]="session"cookies[0]["value"]="4cb496a8-a3eb-4a7e-a704-f993cb6a4dac"message:=map[string]interface{}{"source":"<html><head><title>Hello world</title><body><h1>Hello World</h1></body></head></html>","cookies":cookies,}bytesRepresentation,err:=json.Marshal(message)iferr!=nil{log.Fatalln(err)}client:=http.Client{}request,err:=http.NewRequest("POST","https://api.pdfshift.io/v2/convert",bytes.NewBuffer(bytesRepresentation))iferr!=nil{log.Fatalln(err)}request.Header.Set("Content-Type","application/json")request.Header.Set("Authorization","Basic "+API_KEY)resp,err:=client.Do(request)iferr!=nil{log.Fatalln(err)}ifresp.StatusCode>=200&&resp.StatusCode<300{body,err:=ioutil.ReadAll(resp.Body)iferr!=nil{log.Fatalln(err)}// write the response to fileioutil.WriteFile("example.pdf",body,0644)}else{varresultmap[string]interface{}json.NewDecoder(resp.Body).Decode(&result)log.Println(result)}}
The above command returns a PDF in binary format.
On the contrary, if your endpoint requires a more advanced authentication format, like a PHP session.
You can add cookies to the parameter to simulate an active session.
This can be easily done with the cookies parameter from our API.
Adding a custom footer
constpdfshift=require('pdfshift')('your_api_key');constfs=require('fs');// We use .prepare() instead of .convert to easily handle advanced configurationpdfshift.prepare('https://www.example.com').footer({source:'<div>Page {{page}} of {{total}}</div>',spacing:'50px'}).convert().then(function(binary_file){fs.writeFile('result.pdf',binary_file,"binary",function(){})}).catch(function({message,code,response,errors=null}){})
<?php$response=pdfshift('your_api_key_here',array('source'=>'https://www.example.com','footer'=>array('source'=>'<div style="font-size: 12px">Page {{ "{{page}}" }} of {{ "{{total}}" }}</div>','spacing'=>'50px')));file_put_contents('result.pdf',$response);
importrequestsresponse=requests.post('https://api.pdfshift.io/v2/convert',auth=('your_api_key_here',''),json={'source':'https://www.example.com','footer':{'source':'<div style="font-size: 12px">Page {{ "{{page}}" }} of {{ "{{total}}" }}</div>','spacing':'50px'}},stream=True)response.raise_for_status()withopen('result.pdf','wb')asoutput:forchunckinresponse.iter_content(chunck_size=1024):output.write(chunck)
require'uri'require'net/https'require'json'# for hash to_json conversionuri=URI("https://api.pdfshift.io/v2/convert/")data={"source"=>"https://www.example.com",'footer'=>{'source'=>'<div style="font-size: 12px">Page {{ "{{page}}" }} of {{ "{{total}}" }}</div>','spacing'=>'50px'}}Net::HTTP.start(uri.host,uri.port,:use_ssl=>true)do|http|request=Net::HTTP::Post.new(uri.request_uri)request.body=data.to_jsonrequest["Content-Type"]="application/json"request.basic_auth'your_api_key',''response=http.request(request)ifresponse.code=='200'# Since Ruby 1.9.1 only:File.binwrite("result.pdf",response.body)else# Handle other codes hereputs"#{response.code}#{response.body}"endend
publicstaticvoidmain(String...args)throwsException{varjsonObject=newJSONObject();jsonObject.put("source","https://www.example.com");varfooter=newJSONObject();footer.put("source","<div style='font-size: 12px'>Page {{ "{{page}}" }} of {{ "{{total}}" }}</div>");footer.put("spacing","50px");jsonObject.put("footer",footer);varhttpRequest=HttpRequest.newBuilder().uri(URI.create("https://api.pdfshift.io/v2/convert")).timeout(Duration.ofSeconds(20)).header("Content-Type","application/json").header("Authentication","Basic "+"your_api_key").POST(HttpRequest.BodyPublishers.ofString(jsonObject.toString())).build();varhttpClient=HttpClient.newBuilder().version(HttpClient.Version.HTTP_1_1).build();varresponse=httpClient.send(httpRequest,HttpResponse.BodyHandlers.ofInputStream());varstatusCode=response.statusCode();if(statusCode==200||statusCode==201){// Save the file locallyvartargetFile=newFile("src/main/resources/targetFile.pdf");Files.copy(response.body(),targetFile.toPath(),StandardCopyOption.REPLACE_EXISTING);}else{// error occurred}}
staticvoidMain(string[]args){IRestClientclient=newRestClient("https://api.pdfshift.io/v2/convert");client.Authenticator=newHttpBasicAuthenticator("your_api_key","");IRestRequestrequest=newRestRequest(Method.POST);varjson=new{source="https://www.example.com",footer=new{source="<div style=\"font-size: 12px\">Page {{ "{{page}}" }} of {{ "{{total}}" }}</div>",spacing="50px"}};request.AddJsonBody(json);IRestResponseresponse=client.Execute(request);if(!response.IsSuccessful){// Check why status is not int 2xx.}else{File.WriteAllBytes("result.pdf",response.RawBytes);}}
packagemainimport("bytes""encoding/json""io/ioutil""log""net/http")funcmain(){API_KEY:="your_api_key"message:=map[string]interface{}{"source":"https://www.example.com","footer":map[string]string{"source":"<div style='font-size: 12px'>Page {{ "{{page}}" }} of {{ "{{total}}" }}</div>","spacing":"50px",},}bytesRepresentation,err:=json.Marshal(message)iferr!=nil{log.Fatalln(err)}client:=http.Client{}request,err:=http.NewRequest("POST","https://api.pdfshift.io/v2/convert",bytes.NewBuffer(bytesRepresentation))iferr!=nil{log.Fatalln(err)}request.Header.Set("Content-Type","application/json")request.Header.Set("Authorization","Basic "+API_KEY)resp,err:=client.Do(request)iferr!=nil{log.Fatalln(err)}ifresp.StatusCode>=200&&resp.StatusCode<300{body,err:=ioutil.ReadAll(resp.Body)iferr!=nil{log.Fatalln(err)}// write the response to fileioutil.WriteFile("example.pdf",body,0644)}else{varresultmap[string]interface{}json.NewDecoder(resp.Body).Decode(&result)log.Println(result)}}
The above command returns a PDF in binary format.
One frequent action when converting a web document to PDF is to add header and footer.
This is useful to add page number for instance, or the name of your company at the top of each pages.
This is easily done in PDFShift with the header/footer parameter.
Sending an invoice by email
constexpress=require('express');constfs=require('fs');constnodemail=require('nodemailer');constpdfshift=require('pdfshift')('your_api_key');constapp=express();app.get('/send/',(req,res,next)=>{letinvoice=fs.readFileSync('invoice.html','utf8');pdfshift.convert(invoice).then(function(binary_pdf){lettransporter=nodemailer.createTransport({host:"smtp.gmail.com",port:587,secure:true,auth:{user:account.user,pass:account.pass}});letmailOptions={from:'"Billing at Your-Site" <billing@your-site.tld>',to:"customer@gmail.com"subject:"Thank you for your purchase",text:fs.readFileSync('templates/emails/invoice.txt','utf8'),html:fs.readFileSync('templates/emails/invoice.html','utf8'),attachments:[{filename:'invoice.pdf',contentType:'application/pdf',content:binary_pdf}]};// send mail with defined transport objectawaittransporter.sendMail(mailOptions)// Then, we redirectres.redirect(301,'/thank-you');}).catch(function({message,code,response,errors=null}){})})
<?phpusePHPMailer\PHPMailer\PHPMailer;usePHPMailer\PHPMailer\Exception;require'path/to/PHPMailer/src/Exception.php';require'path/to/PHPMailer/src/PHPMailer.php';require'path/to/PHPMailer/src/SMTP.php';$source=file_get_contents('invoice.html');$binary_pdf=pdfshift('your_api_key_here',array('source'=>$source));$mail=newPHPMailer(true);try{$mail->isSMTP();$mail->Host='smtp1.example.com;smtp2.example.com';$mail->SMTPAuth=true;$mail->Username='billing@your-site.tld';$mail->Password='secret';$mail->SMTPSecure='tls';$mail->Port=587;$mail->setFrom('billing@your-site.tld','Billing at Your-Site');$mail->addAddress('customer@gmail.com','John Doe');// Body of the email
$mail->isHTML(true);$mail->Subject='Thank you for your purchase';$mail->Body=file_get_contents('templates/emails/invoice.html');$mail->AltBody=file_get_contents('templates/emails/invoice.txt');// Add the invoice from PDFShift:
$mail->addStringAttachment($binary_pdf,'invoice.pdf','base64','application/pdf');$mail->send();returnredirect('/thank-you');}catch(Exception$e){// Manage exception
}
fromdjango.core.mailimportEmailMultiAlternativesfromdjango.shortcutsimportredirectimportrequestsdocument=open('invoice.html','r')document_content=document.read()document.close()response=requests.post('https://api.pdfshift.io/v2/convert',auth=('your_api_key_here',''),json={'source':document_content})response.raise_for_status()text_content=Nonewithopen('templates/emails/invoice.txt','r')asf:text_content=f.read()html_content=Nonewithopen('templates/emails/invoice.html','r')asf:html_content=f.read()msg=EmailMultiAlternatives("Thank you for your purchase",text_content,'billing@your-site.tld',['customer@gmail.com'])msg.attach_alternative(html_content,"text/html")msg.attach('invoice.pdf',response.content,'application/pdf')msg.send()returnredirect('/thank-you')
require'uri'require'net/https'require'json'require'net/smtp'require'mail'require'sinatra'get'/send'dogenerate_invoicesend_invoice_via_emailredirectto('/thank-you')endget'/thank-you'do'Check your email! thanks for using PDFShift!'enddefgenerate_invoicefile=File.read("invoice.html")uri=URI("https://api.pdfshift.io/v2/convert/")data={"source"=>file}Net::HTTP.start(uri.host,uri.port,:use_ssl=>true)do|http|request=Net::HTTP::Post.new(uri.request_uri)request.body=data.to_jsonrequest["Content-Type"]="application/json"request.basic_auth'your_api_key',''response=http.request(request)ifresponse.code=='200'File.binwrite("result.pdf",response.body)elseputs"#{response.code}#{response.body}"endendenddefsend_invoice_via_email# Update user_name and password with a valid gmail accountoptions={:address=>"smtp.gmail.com",:port=>587,:domain=>'pdfshift.io',:user_name=>'example@gmail.com',:password=>'examplepassword',:authentication=>'plain',:enable_starttls_auto=>true}Mail.defaultsdodelivery_method:smtp,optionsend# Update the email fields to your needsMail.deliverdofrom'pdfshift-user@pdfshift.io'to'recipient@domain.com'subject'Your invoice'body"Here's the invoice you requested"add_file'result.pdf'endend
publicstaticvoidmain(String...args)throwsException{byte[]encoded=Files.readAllBytes(Paths.get("src/main/resources/example.html"));StringdocumentContent=newString(encoded,Charset.defaultCharset());varjsonObject=newJSONObject();jsonObject.put("source",documentContent);varhttpRequest=HttpRequest.newBuilder().uri(URI.create("https://api.pdfshift.io/v2/convert")).timeout(Duration.ofSeconds(10)).header("Content-Type","application/json").header("Authentication","Basic "+"your_api_key").POST(HttpRequest.BodyPublishers.ofString(jsonObject.toString())).build();varhttpClient=HttpClient.newBuilder().version(HttpClient.Version.HTTP_1_1).build();varresponse=httpClient.send(httpRequest,HttpResponse.BodyHandlers.ofInputStream());varstatusCode=response.statusCode();if(statusCode==200||statusCode==201){// save pdf to file targetFile.pdfvartargetFile=newFile("src/main/resources/targetFile.pdf");Files.copy(response.body(),targetFile.toPath(),StandardCopyOption.REPLACE_EXISTING);// Send pdf as email attachmentvarprop=newProperties();prop.put("mail.smtp.auth",true);prop.put("mail.smtp.starttls.enable","true");prop.put("mail.smtp.host","smtp.mailtrap.io");prop.put("mail.smtp.port","25");prop.put("mail.smtp.ssl.trus","smtp.mailtrap.io");varusername="get username from mailtrap.io";varpassword="get password from mailtrap.io";varsession=Session.getInstance(prop,newAuthenticator(){@OverrideprotectedPasswordAuthenticationgetPasswordAuthentication(){returnnewPasswordAuthentication(username,password);}});varmessage=newMimeMessage(session);message.setFrom(newInternetAddress("from@gmail.com"));message.setRecipients(Message.RecipientType.TO,InternetAddress.parse("to@gmail.com"));message.setSubject("Mail Subject");varattachment=newFile("src/main/resources/targetFile.pdf");varmimeBodyPart=newMimeBodyPart();mimeBodyPart.setContent("Just ignore this message","text/plain");mimeBodyPart.attachFile(attachment);varmultipart=newMimeMultipart();multipart.addBodyPart(mimeBodyPart);message.setContent(multipart);Transport.send(message);}else{System.out.println("Error occured");}}
staticvoidMain(string[]args){IRestClientclient=newRestClient("https://api.pdfshift.io/v2/convert");client.Authenticator=newHttpBasicAuthenticator("your_api_key","");IRestRequestrequest=newRestRequest(Method.POST);stringdocument_content=File.ReadAllText("invoice.html");varjson=new{source=document_content,sandbox=true,};request.AddJsonBody(json);IRestResponseresponse=client.Execute(request);if(!response.IsSuccessful){// Check why status is not int 2xx.}SmtpClientsmtpClient=newSmtpClient();smtpClient.EnableSsl=true;NetworkCredentialbasicCredential=newNetworkCredential("YourMail","YourPassword");MailMessagemessage=newMailMessage();MailAddressfromAddress=newMailAddress("billing@your-site.tld");// setup up the host, increase the timeout to 5 minutessmtpClient.Host="smtp.gmail.com";smtpClient.UseDefaultCredentials=false;smtpClient.Credentials=basicCredential;smtpClient.Timeout=(60*5*1000);message.From=fromAddress;message.Subject="Thank you for your purchase";message.IsBodyHtml=false;message.Body=File.ReadAllText("templates/emails/invoice.html");message.To.Add("customer@gmail.com");Attachmentattachment;using(MemoryStreamstream=newMemoryStream(response.RawBytes)){attachment=newAttachment(stream,"invoice.pdf");message.Attachments.Add(attachment);}smtpClient.Send(message);}
packagemainimport("bytes""encoding/json""io/ioutil""log""net/http""net/mail""net/smtp""github.com/scorredoira/email")funcmain(){API_KEY:="your_api_key"encoded,err:=ioutil.ReadFile("example.html")iferr!=nil{log.Fatalln(err)}documentContent:=string(encoded)message:=map[string]interface{}{"source":documentContent,"sandbox":true,}bytesRepresentation,err:=json.Marshal(message)iferr!=nil{log.Fatalln(err)}client:=http.Client{}request,err:=http.NewRequest("POST","https://api.pdfshift.io/v2/convert",bytes.NewBuffer(bytesRepresentation))iferr!=nil{log.Fatalln(err)}request.Header.Set("Content-Type","application/json")request.Header.Set("Authorization","Basic "+API_KEY)resp,err:=client.Do(request)iferr!=nil{log.Fatalln(err)}ifresp.StatusCode>=200&&resp.StatusCode<300{body,err:=ioutil.ReadAll(resp.Body)iferr!=nil{log.Fatalln(err)}// write the response to fileioutil.WriteFile("example.pdf",body,0644)// Send emailm:=email.NewMessage("Hi","This is an example converted file")m.From=mail.Address{Name:"From",Address:"from@example.com"}m.To=[]string{"to@example.com"}iferr:=m.Attach("example.pdf");err!=nil{log.Fatalln(err)}auth:=smtp.PlainAuth("","c33e0593149230","84d1dec05f668b","smtp.mailtrap.io")iferr:=email.Send("smtp.mailtrap.io:2525",auth,m);err!=nil{log.Fatalln(err)}}else{// An error occurredvarresultmap[string]interface{}json.NewDecoder(resp.Body).Decode(&result)log.Println(result)log.Println(result["data"])}}
The above command returns a PDF in binary format.
Here's a complete example of how PDFShift can be integrated in one of your project.
A frequent use case is to use PDFShift to convert a locally generated invoice made in HTML (displayed in
the back-office of your customer), converted in PDF and then sent by email.
Credits
Credits status
Sending a GET request to the credits endpoint returns JSON structured like this:
{"total":1000,"used":150,"remaining":850}
Simply send a GET request toward https://api.pdfshift.io/v2/credits/ to know in details your
credits usage for your account.
Don't forget to set your API key as "Basic auth".
HTTP Request
GET https://api.pdfshift.io/v2/credits/
Support
If you need any help converting your HTML documents, feel free to reach out to our support team.
We are available via support@pdfshift.io and we will do our best
to help you convert your documents the way you want to.