ZPL Web Service
POST http://api.labelary.com/v1/printers/8dpmm/labels/4x6/0/
--data "^xa^cfa,50^fo100,100^fdHello World^fs^xz"
> POST /v1/printers/8dpmm/labels/4x6/0/ HTTP/1.1
> Host: api.labelary.com
> Accept: */*
> Content-Length: 40
> Content-Type: application/x-www-form-urlencoded
>
> ^xa^cfa,50^fo100,100^fdHello World^fs^xz
< HTTP/1.1 200 OK
< Content-Type: image/png
< Transfer-Encoding: chunked
< Connection: keep-alive
< X-Total-Count: 1
<
< +-----------------------------------------------+
< | NOTE: binary image data not shown in terminal |
< +-----------------------------------------------+
1. Introduction
The Labelary ZPL rendering engine is available as an online service, and can be invoked via a simple, easy-to-use RESTful API:
GET http://api.labelary.com/v1/printers/{dpmm}/labels/{width}x{height}/{index}/{zpl}
By default the service returns PNG images:
Accept: image/png
However, PDF documents can also be requested:
Accept: application/pdf
You can also use POST instead of GET by moving the ZPL out of the URL and into the POST message body (see below for examples).
The POST HTTP method is useful when:
- your ZPL is very large (since URLs are limited to roughly 3,000 characters), or
- you are running into character encoding issues, or
- your ZPL contains embedded binary data.
2. Parameters
- dpmm
- The desired print density, in dots per millimeter.
Valid values are 6dpmm, 8dpmm, 12dpmm, and 24dpmm. See your printer's documentation for more information. - width
- The label width, in inches. Any numeric value may be used.
- height
- The label height, in inches. Any numeric value may be used.
- index
- The label index (base 0).
Some ZPL code will generate multiple labels, and this parameter can be used to access these different labels. In general though, the value of this parameter will be 0 (zero).
Note that this parameter is optional when requesting PDF documents. If not specified, the resultant PDF document will contain all labels (one label per page). - zpl
- The ZPL code to render.
Note that if you are using the GET HTTP method and the ZPL contains any hashes (#), they should be encoded (%23) in order to avoid parts of the ZPL being incorrectly interpreted as URL fragments.
3. Limits
As a shared service, the Labelary API incorporates a number of usage limits which ensure that no single user can negatively impact the workloads of other users:
- Maximum 5 requests per second per client. Additional requests result in a HTTP 429 (Too Many Requests)error.
- Maximum 50 labels per request. Additional labels result in a HTTP 413 (Payload Too Large) error.
- Maximum label size of 15 x 15 inches. Larger labels result in a HTTP 400 (Bad Request) error.
- Maximum embedded object size of 5MB, for e.g. ~DU and ~DY. Larger embedded objects result in a HTTP 400 (Bad Request) error.
- Maximum embedded image dimensions of 2,000 x 2,000 pixels, for e.g. ~DG and ~DY. Larger embedded images result in a HTTP 400 (Bad Request) error.
The image conversion service (image → ZPL) also has the following limits:
- Maximum input image file size of 200 KB. Larger files result in a HTTP 400 (Bad Request) error.
- Maximum input image dimensions of 2,000 x 2,000 pixels. Larger image sizes result in a HTTP 400 (Bad Request) error.
Note that these limits may be changed as needed in order to ensure smooth operation of the service for all users.
If these limits are too restrictive for your intended use, you may want to consider licensing Labelary for private on-premise use.
4. Examples
The code snippets and examples below are intended to help you start consuming the Labelary API quickly, regardless of your client-side technology stack. If you have a code sample that uses a different technology stack, and you'd like to share it with other Labelary users, feel free to email us.
4.1. Live Examples
Some live examples that use GET requests to convert the ZPL encoded in the URLs into PNG images:
- http://api.labelary.com/v1/printers/8dpmm/labels/4x6/0/^xa^cfa,50^fo100,100^fdHello World^fs^xz
- http://api.labelary.com/v1/printers/12dpmm/labels/3.5x1.5/0/^xa^cfa,50^fo100,100^fdSmaller Label^fs^xz
- http://api.labelary.com/v1/printers/6dpmm/labels/4x6/1/^xa^cfa,50^fo100,100^fdFirst Label^fs^xz^xa^cfa,50^fo100,100^fdSecond Label^fs^xz
4.2. curl Examples
Using the GET method:
curl --get http://api.labelary.com/v1/printers/8dpmm/labels/4x6/0/ --data-urlencode "^xa^cfa,50^fo100,100^fdHello World^fs^xz" > label.png
Using the POST method (with application/x-www-form-urlencoded content):
curl --request POST http://api.labelary.com/v1/printers/8dpmm/labels/4x6/0/ --data "^xa^cfa,50^fo100,100^fdHello World^fs^xz" > label.png
Using the POST method (with multipart/form-data content):
curl --request POST http://api.labelary.com/v1/printers/8dpmm/labels/4x6/0/ --form file=@label.zpl > label.png
Using the POST method (with multipart/form-data content), requesting a PDF file instead of a PNG image:
curl --request POST http://api.labelary.com/v1/printers/8dpmm/labels/4x6/0/ --form file=@label.zpl --header "Accept: application/pdf" > label.pdf
4.3. Postman Examples
You can also test the Labelary API by importing this request collection into Postman and running any of the requests therein.
4.4. PowerShell Examples
Using the POST method (with application/x-www-form-urlencoded content) to request a PNG image:
Invoke-RestMethod `
-Method Post `
-Uri http://api.labelary.com/v1/printers/8dpmm/labels/4x6/0/ `
-ContentType "application/x-www-form-urlencoded" `
-InFile label.zpl `
-OutFile label.png
Using the POST method (with application/x-www-form-urlencoded content) to request a PDF file:
Invoke-RestMethod `
-Method Post `
-Uri http://api.labelary.com/v1/printers/8dpmm/labels/4x6/0/ `
-ContentType "application/x-www-form-urlencoded" `
-Headers @{"Accept" = "application/pdf"} `
-InFile label.zpl `
-OutFile label.pdf
4.5. Java Example
A Java example that uses the Java 11 HttpClient API to send a POST request to convert a ZPL string to a PDF file:
var zpl = "^xa^cfa,50^fo100,100^fdHello World^fs^xz";
// adjust print density (8dpmm), label width (4 inches), label height (6 inches), and label index (0) as necessary
var uri = URI.create("http://api.labelary.com/v1/printers/8dpmm/labels/4x6/0/");
var request = HttpRequest.newBuilder(uri)
.header("Accept", "application/pdf") // omit this line to get PNG images back
.POST(BodyPublishers.ofString(zpl))
.build();
var client = HttpClient.newHttpClient();
var response = client.send(request, BodyHandlers.ofByteArray());
var body = response.body();
if (response.statusCode() == 200) {
var file = new File("label.pdf"); // change file name for PNG images
Files.write(file.toPath(), body);
} else {
var errorMessage = new String(body, StandardCharsets.UTF_8);
System.out.println(errorMessage);
}
4.6. Python Example
A Python example that uses the Requests library to send a POST request to convert a ZPL string to a PDF file:
import requests
import shutil
zpl = '^xa^cfa,50^fo100,100^fdHello World^fs^xz'
# adjust print density (8dpmm), label width (4 inches), label height (6 inches), and label index (0) as necessary
url = 'http://api.labelary.com/v1/printers/8dpmm/labels/4x6/0/'
files = {'file' : zpl}
headers = {'Accept' : 'application/pdf'} # omit this line to get PNG images back
response = requests.post(url, headers = headers, files = files, stream = True)
if response.status_code == 200:
response.raw.decode_content = True
with open('label.pdf', 'wb') as out_file: # change file name for PNG images
shutil.copyfileobj(response.raw, out_file)
else:
print('Error: ' + response.text)
4.7. Ruby Example
A Ruby example that uses a POST request to convert a ZPL string to a PDF file (courtesy Robert Coleman):
require 'net/http'
zpl = '^xa^cfa,50^fo100,100^fdHello World^fs^xz'
# adjust print density (8dpmm), label width (4 inches), label height (6 inches), and label index (0) as necessary
uri = URI 'http://api.labelary.com/v1/printers/8dpmm/labels/4x6/0/'
http = Net::HTTP.new uri.host, uri.port
request = Net::HTTP::Post.new uri.request_uri
request.body = zpl
request['Accept'] = 'application/pdf' # omit this line to get PNG images back
response = http.request request
case response
when Net::HTTPSuccess then
File.open 'label.pdf', 'wb' do |f| # change file name for PNG images
f.write response.body
end
else
puts "Error: #{response.body}"
end
4.8. Node.js Example
A Node.js example that uses a POST request to convert a ZPL string to a PDF file (courtesy Katy LaVallee):
var fs = require('fs');
var request = require('request');
var zpl = "^xa^cfa,50^fo100,100^fdHello World^fs^xz";
var options = {
encoding: null,
formData: { file: zpl },
// omit this line to get PNG images back
headers: { 'Accept': 'application/pdf' },
// adjust print density (8dpmm), label width (4 inches), label height (6 inches), and label index (0) as necessary
url: 'http://api.labelary.com/v1/printers/8dpmm/labels/4x6/0/'
};
request.post(options, function(err, resp, body) {
if (err) {
return console.log(err);
}
var filename = 'label.pdf'; // change file name for PNG images
fs.writeFile(filename, body, function(err) {
if (err) {
console.log(err);
}
});
});
4.9. D Language Example
A D language example that uses a POST request to convert a ZPL string to a PDF file (courtesy Andrea Freschi):
import std.stdio;
import std.net.curl;
// adjust print density (8dpmm), label width (4 inches), label height (6 inches), and label index (0) as necessary
auto url = "http://api.labelary.com/v1/printers/8dpmm/labels/4x6/0/";
auto zpl = "^xa^cfa,50^fo100,100^fdHello World^fs^xz";
void main() {
auto conn = HTTP();
conn.addRequestHeader("Accept", "application/pdf"); // omit this line to get PNG images back
auto label = url.post!ubyte(zpl, conn);
if (conn.statusLine.code == 200) {
label.toFile("label.pdf"); // change file name for PNG images
} else {
writeln(conn.statusLine.toString());
}
}
4.10. C# Example
A C# example that uses a POST request to convert a ZPL string to a PDF file:
byte[] zpl = Encoding.UTF8.GetBytes("^xa^cfa,50^fo100,100^fdHello World^fs^xz");
// adjust print density (8dpmm), label width (4 inches), label height (6 inches), and label index (0) as necessary
var request = (HttpWebRequest) WebRequest.Create("http://api.labelary.com/v1/printers/8dpmm/labels/4x6/0/");
request.Method = "POST";
request.Accept = "application/pdf"; // omit this line to get PNG images back
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = zpl.Length;
var requestStream = request.GetRequestStream();
requestStream.Write(zpl, 0, zpl.Length);
requestStream.Close();
try {
var response = (HttpWebResponse) request.GetResponse();
var responseStream = response.GetResponseStream();
var fileStream = File.Create("label.pdf"); // change file name for PNG images
responseStream.CopyTo(fileStream);
responseStream.Close();
fileStream.Close();
} catch (WebException e) {
Console.WriteLine("Error: {0}", e.Status);
}
4.11. VB.NET Example
A VB.NET example that uses a POST request to convert a ZPL string to a PDF file:
Dim zpl() As Byte = Encoding.UTF8.GetBytes("^xa^cfa,50^fo100,100^fdHello World^fs^xz")
' adjust print density (8dpmm), label width (4 inches), label height (6 inches), and label index (0) as necessary
Dim request As HttpWebRequest = WebRequest.Create("http://api.labelary.com/v1/printers/8dpmm/labels/4x6/0/")
request.Method = "POST"
request.Accept = "application/pdf" ' omit this line to get PNG images back
request.ContentType = "application/x-www-form-urlencoded"
request.ContentLength = zpl.Length
Dim requestStream As Stream = request.GetRequestStream()
requestStream.Write(zpl, 0, zpl.Length)
requestStream.Close()
Try
Dim response As HttpWebResponse = request.GetResponse()
Dim responseStream As Stream = response.GetResponseStream()
Dim fileStream As Stream = File.Create("label.pdf") ' change file name for PNG images
responseStream.CopyTo(fileStream)
responseStream.Close()
fileStream.Close()
Catch e As WebException
Console.WriteLine("Error: {0}", e.Status)
End Try
4.12. ColdFusion Example
A ColdFusion example that uses a POST request to convert a ZPL string to a PDF file:
<cfoutput>
<cfset zpl="^xa^cfa,50^fo100,100^fdHello World^fs^xz">
<!-- change type to "image/png" to get PNG images -->
<cfset type="application/pdf">
<!-- adjust print density (8dpmm), label width (4 inches), label height (6 inches), and label index (0) as necessary -->
<cfhttp url="http://api.labelary.com/v1/printers/8dpmm/labels/4x6/0/" method="post" result="result">
<cfhttpparam type="header" name="Content-Type" value="application/x-www-form-urlencoded">
<cfhttpparam type="header" name="Accept" value="#type#">
<cfhttpparam type="body" value="#zpl#">
</cfhttp>
<cfcontent variable="#result.Filecontent#" type="#type#" reset="true" />
</cfoutput>
4.13. PHP Example
A PHP example that uses a POST request to convert a ZPL string to a PDF file:
<?php
$zpl = "^xa^cfa,50^fo100,100^fdHello World^fs^xz";
$curl = curl_init();
// adjust print density (8dpmm), label width (4 inches), label height (6 inches), and label index (0) as necessary
curl_setopt($curl, CURLOPT_URL, "http://api.labelary.com/v1/printers/8dpmm/labels/4x6/0/");
curl_setopt($curl, CURLOPT_POST, TRUE);
curl_setopt($curl, CURLOPT_POSTFIELDS, $zpl);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Accept: application/pdf")); // omit this line to get PNG images back
$result = curl_exec($curl);
if (curl_getinfo($curl, CURLINFO_HTTP_CODE) == 200) {
$file = fopen("label.pdf", "w"); // change file name for PNG images
fwrite($file, $result);
fclose($file);
} else {
print_r("Error: $result");
}
curl_close($curl);
?>
4.14. Go Language Example
A Go language example that uses a POST request to convert a ZPL string to a PDF file:
package main
import (
"os"
"io"
"io/ioutil"
"log"
"bytes"
"net/http"
)
func main() {
zpl := []byte("^xa^cfa,50^fo100,100^fdHello World^fs^xz")
// adjust print density (8dpmm), label width (4 inches), label height (6 inches), and label index (0) as necessary
req, err := http.NewRequest("POST", "http://api.labelary.com/v1/printers/8dpmm/labels/4x6/0/", bytes.NewBuffer(zpl))
if err != nil {
log.Fatalln(err)
}
req.Header.Set("Accept", "application/pdf") // omit this line to get PNG images back
client := &http.Client{}
response, err := client.Do(req)
if err != nil {
log.Fatalln(err)
}
defer response.Body.Close()
if response.StatusCode == http.StatusOK {
file, err := os.Create("label.pdf") // change file name for PNG images
if err != nil {
log.Fatalln(err)
}
defer file.Close()
io.Copy(file, response.Body)
} else {
body, err := ioutil.ReadAll(response.Body)
if err != nil {
log.Fatalln(err)
}
log.Fatalln(string(body))
}
}
5. Advanced
Some advanced features provided by the Labelary API:
5.1. Rotate labels
Your ZPL template already defines a label rotation / orientation. Sometimes, however, the label orientation that is most suitable for your printer is not the orientation that you'd like to use during format conversion.
If this is the case, you can ask Labelary to rotate the label image by adding a X-Rotation HTTP header to the request. The value of this header should be the number of degrees to rotate the label clockwise, and may be one of 0, 90, 180 or 270.
This header is available for both PNG and PDF requests.
5.2. PDF with multiple labels
When requesting a PNG image, you can only get one label back at a time, even if your ZPL defines multiple labels. However, PDF files can contain more than one label. If you are requesting a PDF file and you would like it to contain all of the labels defined in your ZPL template, simply omit the index parameter from the request URL.
For example, instead of sending your request to this URL, which returns the label at index 0 (the first label):
http://api.labelary.com/v1/printers/8dpmm/labels/4x6/0/
You can omit the index and instead send your request to this URL:
http://api.labelary.com/v1/printers/8dpmm/labels/4x6/
Note that this option is only available for PDF requests.
5.3. PDF page size and orientation
By default, Labelary generates PDFs whose page size matches the label size. However, you may want to generate PDFs with a different page size. If this is the case, you can add the X-Page-Size and X-Page-Orientation HTTP headers to your request.
The X-Page-Size HTTP header tells Labelary to use a specific PDF page size. Valid values are Letter, A4, A5 and A6.
The X-Page-Orientation HTTP header tells Labelary to use a specific orientation of the specified page size. Valid values are Portrait and Landscape.
Note that these headers can only be used with PDF requests.
5.4. PDF page layout
If you customize the PDF page size, you may also want to include multiple labels on each page. If this is the case, you can add the X-Page-Layout, X-Page-Align and X-Page-Vertical-Align HTTP headers to your request.
The X-Page-Layout HTTP header tells Labelary to lay out the labels on the PDF pages in a tabular format. The header value must be in the form <columns>x<rows>. For example, a value of 2x3 would generate a PDF file with 6 labels per page, arranged in 2 columns and 3 rows.
The X-Page-Align HTTP header tells Labelary how to align the labels horizontally. Valid values are Left, Right, Centerand Justify. The default value is Justify, which distributes extra horizontal whitespace evenly across the page.
The X-Page-Vertical-Align HTTP header tells Labelary how to align the labels vertically. Valid values are Top, Bottom, Center and Justify. The default value is Justify, which distributes extra vertical whitespace evenly across the page.
Note that these headers can only be used with PDF requests.
5.5. How many labels?
Sometimes your ZPL code may define multiple labels. If you want to know how many labels were generated by your ZPL, you can read the value of the X-Total-Count HTTP response header returned by Labelary. The value of this header will be accurate regardless of whether you requested that a single label be rendered (as in a PNG conversion) or you requested that all labels be rendered (as in some PDF conversions).
This header is available in both PNG and PDF responses.
5.6. Print quality
By default, Labelary generates 8-bit grayscale PNG images optimized for electronic viewing. However, you can add the X-Quality HTTP header to your request in order to customize the quality of the output images. Valid values are Grayscale and Bitonal.
Grayscale generates 8-bit grayscale images suitable for electronic viewing and printing on high-density printers. This is the default setting.
Bitonal generates 1-bit monochrome images suitable for printing on low-density printers. It also generates smaller files (useful when file size is more important than output quality).
This header is only available for PNG requests.
5.7. Linting
EXPERIMENTAL: This option is experimental and may be removed or significantly changed.
It is possible to ask Labelary to check your ZPL for potential errors while rendering the ZPL. This process is known aslinting. You can enable the Labelary linter by adding the X-Linter HTTP header to your request. Valid values are On (to enable the linter), and Off (to disable the linter). The linter is disabled by default.
Once the linter is enabled, warnings will be returned in the X-Warnings HTTP response header. The maximum number of warnings that will be returned is 20. Additional warnings (if any) will not be returned. Warnings will be returned in pipe-delimited format, and each warning will include 5 attributes:
- The byte index of the ZPL section which triggered the warning (integer, never empty)
- The byte size of the ZPL section which triggered the warning (integer, never empty)
- The name of the ZPL command which triggered the warning (string, may be empty if the warning is not associated with a specific command)
- The parameter number of the command parameter which triggered the warning (integer, may be empty if the warning is not associated with a specific parameter)
- The warning message (string, never empty)
As an example, the following HTTP response header indicates that the submitted ZPL generated 2 warnings:
X-Warnings: 303|1|^GB|2|Value 1 is less than minimum value 3; used 3 instead|591|3|||Ignored unrecognized content
The first warning, starting at byte index 303 and extending for 1 byte, indicates that the second parameter of the ^GBcommand used a value that was too small. The second