API Documentation

Introduction

The PrintNode API aims to make it quick and simple to integrate remote printing into your application. This API is used to control the PrintNode Server and Client.

It is only available via HTTPS and all requests must be authenticated using HTTP basic authentication. You will need to sign up for a free PrintNode account and generate an API Key.

You can sign up at https://app.printnode.com/account/register.
You can generate API Keys at https://app.printnode.com/account/apiKey.

If you have any questions or concerns, want some help or see anything unexpected, please contact us at support@printnode.com.

API Endpoint

https://api.printnode.com

Resource Urls

/whoami

/credits

/computers
/computers/computer set

/printers
/printers/printer set
/computers/computer set/printers
/computers/computer set/printers/printer set

/printjobs
/printjobs/printjob set
/printers/printer set/printjobs
/printers/printer set/printjobs/printjob set

/account
/account/tag/name
/account/apikey/description

Authentication

All requests must be authenticated using HTTP basic authentication. API Keys are links to a single account and are used for both authentication and identification. Any API Key attached to your account will work. You can have as many API Keys as you wish.

Submitting the API Key as the username and leaving the password empty will authenticate you.

You can view and create API Keys here: https://app.printnode.com/account/apiKey. This is how your API Key will appear:


Username: 44784dd8d88be9631046ff83e9044419ff824b10
Password: None. Leave this blank.

A example curl request might look like this:

curl -u 44784dd8d88be9631046ff83e9044419ff824b10: \ https://api.printnode.com/whoami

Curl uses the -u flag to transmit basic auth credentials. Note the colon at the end of the username string. This is not part of your API key – it just indicates the end of the username part of curl's credentials argument.

Successful Authentication

Any requests which successfully authenticate have the header X-Account set and do not return a HTTP 401 Unauthorised.

Unsuccessful Authentication

Requests which are unsuccessful will return HTTP 401 Unauthorised.

Versioning

The PrintNode API has support for semantic versioning. If you wish to request a specific version of the API other than the latest, submit your request with the HTTP header Accept-Version, e.g., Accept-Version: ~3. We have no plans to make incompatible changes but for maximum future stability it is probably best to include this header for each request.

Example Request curl

curl https://api.printnode.com/whoami \ -H "Accept-Version: ~3" \ -u 44784dd8d88be9631046ff83e9044419ff824b10:

Get the latest version of the API in the v3 series.

Content Types

You can POST data using either: Content-Type: application/json or Content-Type: application/x-www-form-urlencoded.

The key-value structure for both types should be the same. If you don't specify a Content-Type then Content-Type: application/json will be assumed. In either case the PrintNode API will always respond with Content-Type: application/json.

Parameters

Assets in the API are uniquely identified by a positive integer. A set, as described by the PrintNode API, is a string representation of an unordered collection of positive integers. You can use these to identify and request multiple assets quickly and easily.

Where ever you see COMPUTER SET, PRINTER SET or PRINTJOB SET you can substitute a set.

The easiest way to understand them is to look at some examples.

Examples

11
1-51, 2, 3, 4 and 5
5-All positive integers greater than or equal to 5
-5All positive integers less than or equal to 5
-All positive integers
1,3,51, 3 and 5
5,1,31, 3 and 5
1,3-1 and all positive integers greater than or equal to 3
-2,4-All positive integers other than 3
-4,3-All positive integers
1, 3, 5Not a valid set (no whitespace allowed)

Sets can be composed of multiple sections; just separate each one with a comma. It doesn't matter if a set overlaps or contains another. The ordering of the sections doesn't matter. No whitespace is allowed in sets.

Pagination

If you have a large number of PrintJobs you may include the URL query parameters limit and offset. This will cause limit rows to be returned, starting at the (offset+1)th row. If these are omitted the default limit is 500 and the offset is 0.

Example Request curl

curl https://api.printnode.com/printjobs?limit=100&offset=5000 \ -u 44784dd8d88be9631046ff83e9044419ff824b10:

Limits the returned printjobs to 100 starting at the 5001st printjob.

Headers

Request

You can send the following extra headers with any request:

X-Pretty Returns indented JSON for human readability to aid in development.
X-Dont-Log We keep our API logs for about 24 hours. If you do not wish your data to be stored in this manner just send this header and we'll only log the request and response headers.

Headers submitted to the server are case-insensitive.

Response

The server responds with the following extra headers.

Api-Version The version of the server API used to service your request.
Request-Id A UUID for your request. We store most API requests for a short amount of time to aid in debugging. If you keep hold of this we can help you debug problems. We do not store submitted PrintJob data.
Response-Time The number of milliseconds the server took generating its response to you.
Access-Control-Allow-Origin
Access-Control-Allow-Headers
Access-Control-Allow-Methods
Access-Control-Expose-Headers
HTTP access control headers.
Records-Returned The number of records returned by the PrintNode API.
Records-Returned-Offset The offset of the records returned.
Records-Returned-Limit The number of records to which the results have been limited.
Records-Total The total number of records that would have been returned if there had been no limiting. This isn’t always returned.

Rate Limiting

The API is throttled to 10 requests per second per request IP address and is burstable for a short while. If this is a problem please contact support@printnode.com; we can consider changes for specific accounts and/or IP addresses.

Exceeding these limits will return a HTTP 429 Too Many Requests.

Example Response

< HTTP/1.1 429 Too Many Requests < Date: Thu, 20 Mar 2014 16:20:07 GMT < Content-Type: application/json < Content-Length: 95 < Connection: keep-alive < { "code": "TooManyRequests", "message": "You have exceeded your request rate of 10 r/s." }

Errors

If something goes wrong the HTTP response code will be either a 4xx Client Error or a 5xx Server Error. The response body will be a JSON object with two keys: "code" and "message".

We've tried hard to make any errors self documenting. Just look to the "message" for a human readable description of what has gone wrong.

Error Codes

BadMethod, BadRequest, Conflict, Forbidden, HttpVersionNotSupported, Internal, InternalServer, InvalidArgument, InvalidContent, InvalidCredentials, InvalidHeader, InvalidVersion, LengthRequired, MethodNotAllowed, MissingParameter, NotAcceptable, NotAuthorized, NotFound, NotImplemented, PaymentRequired, PreconditionFailed, PreconditionRequired, RequestEntityTooLarge, RequestExpired, RequestHeaderFieldsTooLarge, RequestThrottled, RequestTimeout, RequesturiTooLarge, ResourceNotFound, ServiceUnavailable, TooManyRequests, Unauthorized.

Example Errors

< HTTP/1.1 401 Unauthorized < Date: Thu, 20 Mar 2014 16:54:06 GMT < Content-Type: application/json < Content-Length: 87 < Connection: keep-alive < WWW-Authenticate: Basic realm="Api" < { "code": "InvalidCredentials", "message": "Expects HTTP Basic authentication." }
< HTTP/1.1 400 Bad Request < Date: Thu, 20 Mar 2014 16:55:43 GMT < Content-Type: application/json < Content-Length: 86 < Connection: keep-alive < { "code": "InvalidContent", "message": "Invalid JSON: Unexpected end of input" }

Account Information

Who Am I?

Returns information about your account including your account details any connected computers.

Example Request curl

curl -H "X-Pretty: true" https://api.printnode.com/whoami \ -u 44784dd8d88be9631046ff83e9044419ff824b10:

Response

{ "id": 433, "firstname": "Peter", "lastname": "Tuthill", "email": "peter@omlet.co.uk", "canCreateSubAccounts": false, "creatorEmail": null, "creatorRef": null, "childAccounts": [], "credits": 10058, "numComputers": 1, "totalPrints": 80, "versions": [], "connected": [], "Tags": [], "state": "active", "permissions": [ "Unrestricted" ] }
HTTP/1.1 200 OK Date: Sun, 28 Jun 2015 23:01:34 GMT Content-Type: application/json Content-Length: 377 Connection: keep-alive Server: PrintNodeApi Api-Version: 3.0.0 Request-Id: fb24db7f-713c-4678-8f05-2864f557a4c3 Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Access-Control-Allow-Methods: * Access-Control-Allow-Headers: Accept, Accept-Version, Api-Version, Authorization, Content-Length, Content-MD5, Content-Type, Date, X-Account, X-Requested-With, X-Pretty, X-Dont-Log, X-Child-Account-By-Id, X-Child-Account-By-Email, X-Child-Account-By-CreatorRef Access-Control-Expose-Headers: Api-Version, Records-Returned, Records-Returned-Limit, Records-Returned-Offset, Records-Total, Request-Id, Response-Time, X-Authorized-As, X-Auth-With, X-Child-Account-By-CreatorRef, X-Child-Account-By-Email, X-Child-Account-By-Id X-Auth-With: ApiKey X-Account: 433 Content-MD5: gBVJmORRiyd0MtpfedG2rQ== Response-Time: 14

Credits

Returns number of printing credits remaining to this account. A return value of null denotes unlimited printing.

Example Request curl

curl -H "X-Pretty: true" https://api.printnode.com/credits \ -u 44784dd8d88be9631046ff83e9044419ff824b10:

Response

10058
HTTP/1.1 200 OK Date: Sun, 28 Jun 2015 23:01:34 GMT Content-Type: application/json Content-Length: 7 Connection: keep-alive Server: PrintNodeApi Api-Version: 3.0.0 Request-Id: 6c409029-52f8-4956-8abb-64a4904659aa Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Access-Control-Allow-Methods: * Access-Control-Allow-Headers: Accept, Accept-Version, Api-Version, Authorization, Content-Length, Content-MD5, Content-Type, Date, X-Account, X-Requested-With, X-Pretty, X-Dont-Log, X-Child-Account-By-Id, X-Child-Account-By-Email, X-Child-Account-By-CreatorRef Access-Control-Expose-Headers: Api-Version, Records-Returned, Records-Returned-Limit, Records-Returned-Offset, Records-Total, Request-Id, Response-Time, X-Authorized-As, X-Auth-With, X-Child-Account-By-CreatorRef, X-Child-Account-By-Email, X-Child-Account-By-Id X-Auth-With: ApiKey X-Account: 433 Content-MD5: gdFhrsSVo7yg96dalytHJA== Response-Time: 5

Computers

Computers are devices which have the PrintNode Client software installed on them and which have successfully connected to PrintNode. They are uniquely identified by their id property. Computers cannot be created or deleted using the API.

Example Request curl

curl -H "X-Pretty: true" https://api.printnode.com/computers \ -u 44784dd8d88be9631046ff83e9044419ff824b10:

Response

[ { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" } ]
HTTP/1.1 200 OK Date: Sun, 28 Jun 2015 23:01:34 GMT Content-Type: application/json Content-Length: 235 Connection: keep-alive Server: PrintNodeApi Api-Version: 3.0.0 Request-Id: 82ad3e46-9534-4ce5-b11e-6e71b1dce158 Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Access-Control-Allow-Methods: * Access-Control-Allow-Headers: Accept, Accept-Version, Api-Version, Authorization, Content-Length, Content-MD5, Content-Type, Date, X-Account, X-Requested-With, X-Pretty, X-Dont-Log, X-Child-Account-By-Id, X-Child-Account-By-Email, X-Child-Account-By-CreatorRef Access-Control-Expose-Headers: Api-Version, Records-Returned, Records-Returned-Limit, Records-Returned-Offset, Records-Total, Request-Id, Response-Time, X-Authorized-As, X-Auth-With, X-Child-Account-By-CreatorRef, X-Child-Account-By-Email, X-Child-Account-By-Id X-Auth-With: ApiKey X-Account: 433 Records-Returned: 1 Records-Returned-Offset: 0 Records-Returned-Limit: 500 Records-Total: 1 Content-MD5: qyHiXTqWQA4sEidk5YAOfA== Response-Time: 7

Viewing Printers

Printers are attached to Computers. Just like Computers, they are uniquely identified by their id property. Printers cannot be created or deleted using the API. You can also filter returned Printers by Computer. Just substitute the appropriate parameter into one of the URLs below.

/printers
/printers/printer set
/computers/computer set/printers
/computers/computer set/printers/printer set

Example Request curl

curl -H "X-Pretty: true" https://api.printnode.com/printers \ -u 44784dd8d88be9631046ff83e9044419ff824b10:

Response

[ { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" } ]
HTTP/1.1 200 OK Date: Sun, 28 Jun 2015 23:01:35 GMT Content-Type: application/json Content-Length: 476 Connection: keep-alive Server: PrintNodeApi Api-Version: 3.0.0 Request-Id: b575c2e5-bbd4-453e-bfe7-2478cc4d2d69 Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Access-Control-Allow-Methods: * Access-Control-Allow-Headers: Accept, Accept-Version, Api-Version, Authorization, Content-Length, Content-MD5, Content-Type, Date, X-Account, X-Requested-With, X-Pretty, X-Dont-Log, X-Child-Account-By-Id, X-Child-Account-By-Email, X-Child-Account-By-CreatorRef Access-Control-Expose-Headers: Api-Version, Records-Returned, Records-Returned-Limit, Records-Returned-Offset, Records-Total, Request-Id, Response-Time, X-Authorized-As, X-Auth-With, X-Child-Account-By-CreatorRef, X-Child-Account-By-Email, X-Child-Account-By-Id X-Auth-With: ApiKey X-Account: 433 Records-Returned: 1 Records-Returned-Offset: 0 Records-Returned-Limit: 500 Records-Total: 1 Content-MD5: q++hA0MuGeuYTsBC1/1wow== Response-Time: 7

Printer Capabilities

Most printers support various options to customise printing. Things like printing to a different paper tray, choosing a media size, setting number of copies, duplex printing, etc.

If you are using a version of the PrintNode client v4.7.0 or greater it will report a JSON object in the capabilities property of the printer object. If you are using a version of the PrintNode client older than v4.7.0 the capabilities property will be null. If the capabilities property is not null it will tell you what printing options you can use when creating a PrintJob for this printer.

Attribute Type Description
binsArray of stringsA array of paper tray names the printer driver supports. May be zero length.
collateBooleanDoes this printer support collation?
copiesIntegerThe maximum number of copies this printer supports. If the printer does not support multiple copies this value will be 1.
colorBooleanIs this a colour printer?
dpisStringIn format "horizontal" x "vertical" dpis. May be zero length.
extentArray of arraysIf the printer driver reports its maximum and minumum supported paper sizes this will be represented as a 2x2 dimensional array of integers. Where [0][0], and [0][1] elements are the minimum supported width and height respectively and the [1][0] and [1][1] elements are the maximum supported with and height respectively. The integer units used are 1/10ths of a mm. If the printer driver does not report this information a zero length array is returned.
mediasArray of stringsA array of media names the printer driver supports. May be zero length.
nupArray of integersThe number of pages to print per page for a compact layout printing. This will be a zero length array if nup printing is not supported.
papersObjectObject of supported paper sizes where each key represents a paper name and the value is the dimension of the paper expressed in a two value array. As with the extent the dimension array is encoded [width, height] with width and height expressed in 1/10ths of a mm. In some circumstances the width and height are not reported by the printer driver in which case the width and height values will be null.
printrateObject or nullObject describing the printer's reported print rate. If not null the printrate object will have two keys – "unit" and "rate". "unit" can be one of "ppm", "ipm", "lmp" or "cpm". "rate" is a float.
supports_custom_paper_sizeBooleanDoes the printer support PrintJobs created with a custom paper size?

A sample Printer capabilities object is shown below.

{ "bins": [ "Auto", "Multipurpose Tray", "Tray 1", "Tray 2" ], "collate": true, "color": true, "copies": 999, "dpis": [ "300x300", "600x600" ], "duplex": true, "extent": [ [640, 900], [2970, 13208] ], "medias": [], "nup": [], "papers": { "Letter": [2159, 2794], "Tabloid": [2794, 4318], "Legal": [2159, 3556], "Statement": [1397, 2159], "Executive": [1842, 2667], "A3": [2970, 4200], "A4": [2100, 2970], "A5": [1480, 2100], "B4": [2570, 3640], "B5": [1820, 2570], "Legal13": [2159, 3302], "Com-10": [1047, 2413], "DL": [1100, 2200], "C5": [1620, 2290], "C4": [2290, 3240], "Hagaki": [1000, 1480], "A6": [1050, 1480], "Kakugata #2": [2400, 3320], "Kakugata #3": [2160, 2770], "Nagagata #3": [1200, 2350], "Nagagata #4": [900, 2050], "Oufuku Hagaki": [2000, 1480], "Yougata #4": [1050, 2350], "User Defined Size": [2100, 2970], "B6": [1280, 1820], "B6 Half": [640, 1820], "Yougata #0": [1200, 2350], "Legal 13.5": [2159, 3429], "Index Card": [762, 1270], "16K": [1840, 2600], "16K 195 x 270mm": 1950, 2700], "16K 197 x 273mm": [1970, 2730], "8K": [2600, 3680], "8K 270 x 390mm": [2700, 3900], "8K 273 x 394mm": [2730, 3940], "Nagagata #40": [900, 2250], "Banner": [2100, 9000], "Banner 215.0 x 900.0mm": [2150, 9000], "Banner 215.0 x 1200.0mm": [2150, 12000], "Banner 297.0 x 900.0mm": [2970, 9000], "Banner 297.0 x 1200.0mm": [2970, 12000] }, "printrate": { "unit": "ppm", "rate": 23 }, "supports_custom_paper_size": false }

Creating PrintJobs

A PrintJob is a document that has been printed or has been submitted for printing. PrintNode currently supports PDF documents and RAW printing Each PrintJob represents one request to print. Use HTTP POST to create a new PrintJob. Use HTTP GET to retrieve information about existing PrintJobs.

Attribute Type Is Required? Specification
idIntegerIgnoredAssigned by API. Any value submitted here will be ignored.
printer or printerIdIntegerYesThe printer id associated with your account.
titleStringYesA title to give the PrintJob. This is the name which will appear in the operating system's print queue.
contentType String Yes Either 'pdf_uri', 'pdf_base64', 'raw_uri', 'raw_base64'. See content.
content String Yes

A uri accessible by the client when contentType is 'pdf_uri'.

or

A base64 encoded representation of the pdf when contentType is 'pdf_base64'.

sourceStringYesA text description of how the printjob was created or where the printjob originated.
options Object No An object describing various options which can be set for this PrintJob. See options. Printing options have no effect when raw printing.
expireAfterIntegerNoThe maximum number of seconds PrintNode should retain this PrintJob for attempted printing in the event the PrintJob cannot be printed immediately. The current default is 14 days or 1,209,600 seconds.
qty Integer No The default value is 1. A positive integer representing the number of times this PrintJob should be delivered to the print queue. This differs from the "copies" option in that this will send a document to a printer multiple times and does not rely on print driver support. This is the only way to support multiple copies when raw printing. This also enables printing multiple copies even when a printer driver does not natively support this.
authenticationObjectNo

If a contentType of 'pdf_uri' or 'raw_uri' is used and the uri requires either HTTP Basic or Digest Authentication you can specify the username and password information here. Supported in clients v4.7.0 or newer.

For Basic authentication

{ "type": "BasicAuth", "credentials": { "user": "username", "pass": "password" } }

For Digest authentication

{ "type": "DigestAuth", "credentials": { "user": "username", "pass": "password" } }

Just replace the "username" and "password" with your credentials as appropriate.

stateStringIgnored
createTimestampDateTimeIgnored

Example Request curl

curl -H "X-Pretty: true" -X POST https://api.printnode.com/printjobs \ -u 44784dd8d88be9631046ff83e9044419ff824b10: \ -H "Content-Type: application/json" \ -d '{ "printerId": 39, "title": "My Test PrintJob", "contentType": "pdf_uri", "content": "http:\/\/sometest.com\/pdfhere", "source": "api documentation!" }'
curl -H "X-Pretty: true" -X POST https://api.printnode.com/printjobs \ -u 44784dd8d88be9631046ff83e9044419ff824b10: \ -d 'printerId=39' \ -d 'title=My%20Test%20PrintJob' \ -d 'contentType=pdf_uri' \ -d 'content=http%3A%2F%2Fsometest.com%2Fpdfhere' \ -d 'source=api%20documentation%21'

Response

637
HTTP/1.1 201 Created Date: Sun, 28 Jun 2015 23:01:35 GMT Content-Type: application/json Content-Length: 5 Connection: keep-alive Server: PrintNodeApi Api-Version: 3.0.0 Request-Id: e22773ae-ad14-4129-8afe-2b76f4ca133f Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Access-Control-Allow-Methods: * Access-Control-Allow-Headers: Accept, Accept-Version, Api-Version, Authorization, Content-Length, Content-MD5, Content-Type, Date, X-Account, X-Requested-With, X-Pretty, X-Dont-Log, X-Child-Account-By-Id, X-Child-Account-By-Email, X-Child-Account-By-CreatorRef Access-Control-Expose-Headers: Api-Version, Records-Returned, Records-Returned-Limit, Records-Returned-Offset, Records-Total, Request-Id, Response-Time, X-Authorized-As, X-Auth-With, X-Child-Account-By-CreatorRef, X-Child-Account-By-Email, X-Child-Account-By-Id X-Auth-With: ApiKey X-Account: 433 Content-MD5: jaWCkRpiB3rJnXHrfBWnjQ== Response-Time: 18

Example Request curl

curl -H "X-Pretty: true" -X POST https://api.printnode.com/printjobs \ -u 44784dd8d88be9631046ff83e9044419ff824b10: \ -H "Content-Type: application/json" \ -d '{ "printerId": 39, "title": "My Test PrintJob", "contentType": "pdf_uri", "content": "http:\/\/sometest.com\/pdfhere", "source": "api documentation!", "expireAfter": 600, "options": {"copies":2,"pages":"1,3,5","duplex":"long-edge","paper":"A4","bin":"Tray 1"}, "authentication": {"type":"BasicAuth","credentials":{"user":"username","pass":"password"}} }'

Response

638
HTTP/1.1 201 Created Date: Sun, 28 Jun 2015 23:01:35 GMT Content-Type: application/json Content-Length: 5 Connection: keep-alive Server: PrintNodeApi Api-Version: 3.0.0 Request-Id: dafd8a42-dc7d-4130-b531-278974fdc26b Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Access-Control-Allow-Methods: * Access-Control-Allow-Headers: Accept, Accept-Version, Api-Version, Authorization, Content-Length, Content-MD5, Content-Type, Date, X-Account, X-Requested-With, X-Pretty, X-Dont-Log, X-Child-Account-By-Id, X-Child-Account-By-Email, X-Child-Account-By-CreatorRef Access-Control-Expose-Headers: Api-Version, Records-Returned, Records-Returned-Limit, Records-Returned-Offset, Records-Total, Request-Id, Response-Time, X-Authorized-As, X-Auth-With, X-Child-Account-By-CreatorRef, X-Child-Account-By-Email, X-Child-Account-By-Id X-Auth-With: ApiKey X-Account: 433 Content-MD5: cwB7p+FAZEotmuo1w62ZmQ== Response-Time: 13

RAW Printing or PDF Printing?

The most common RAW printing languages are ZPL, EPL or ESC/P but this isn't a exhaustive list. RAW printing is very powerful and provides a low level way of communicating with any Printer. Use a contentType raw_uri or raw_base64 for RAW printing.

If your document is a PDF then you need to use contentType pdf_uri or pdf_base64.

PrintJob Option Specification

Clients v4.7.0 and newer support additional printing options. It's not a problem to send options to an older client – nothing bad will happen – but they won't have any effect.

All properties are optional. You can use null or {} to represent no printing options.

Property Type Required Description
binStringNo The name of one of the paper trays or output bins reported by the printer capability property "bins".
collateBooleanNo Enables print copy collation when printing multiple copies. If this option is not specified the printer default is used.
copiesIntegerNo Positive integer. Default 1. The number of copies to be printed. Maximum value as reported by the printer capability property "copies".
dpiStringNo The dpi setting to use for this PrintJob. Allowed values are those reported by the printer capability property "dpis".
duplexStringNo One of long-edge or short-edge for 2 sides printing along the long-edge (portrait) or the short edge (landscape) respectively. If this option is not specified the the printer default is used.
fit_to_pageBooleanNo OSX only. Defaults true. If you wish to disable this option pass false here.
mediaStringNo The named media to use for this PrintJob. Allowed values are one of the values reported by the printer capability property "medias". We've found some printers on OSX ignore this setting unless a "bin" (paper tray) option is also set.
nupIntegerNo OSX only. Allows support for printing muliple pages per physical sheet of paper. Default 1. Allowed values are those reported by the printer capability property "nup".
pagesStringNo A set of pages to print from a PDF. The format is described here. A few quick exampleE.g. 1,3 prints pages 1 and 3. -5 prints pages 1 through 5 inclusive. - prints all pages. Different components can be combined with a comma. 1,3- prints all pages except page 2.
paperStringNo A named paper size to use. Allowed values are the keys in the object returned by the printer capability property "papers".
rotateIntegerNo One of 90, 180 or 270. Supports rotating all pages while printing. We've found support on OSX to be patchy. Support depends on both printer and driver.

Which Content Type is Right For You?

The content parameter of the PrintJob may be either a HTTP URI to the resource or the content base64_encoded. We take security seriously at PrintNode but understand that some organisations will not be comfortable submitting PrintJobs to a third party. If this sounds like you, we recommend working with pdf_uri or raw_uri as your contentType and hosting the PDF yourself so that your PrintJob content is never stored at PrintNode.

Using pdf_base64 or raw_base64 to send a PrintJob means that your data will need to be base64 encoded. This is very easy to do and you don't have to worry about hosting and managing your own PrintJobs. If you are sending small PDFs or doing raw printing, e.g., courier labels, barcodes or reciepts, then this is a good option to choose. Note that base64 encoding increases the size of the content by 25%.

If your client can download the content from a local network or web server, it may be faster to use the pdf_uri and raw_uri contentType. This means that your PrintJob content is never sent via the PrintNode server. This is usually faster if content is accessible locally and it can reduce bandwidth requirements for everyone.

In either case, the request body may not be larger than 10MB. If you attempt to POST a request that is larger than 10MB you will receive a HTTP 413 Request Body Too Large. If you would like to print PDFs larger than 10MB you should submit them using content type pdf_uri.

URI Base64
Security PrintJobs are hosted on your own servers. PrintJobs are sent through PrintNode servers which may be located outside you country. Note - we don't store your printjobs once they are printed and don't read them.
Speed Slightly faster without the slightly increased overhead of base64. If you can serve the printjob contents to your customers locally this will be faster still. Slower because of the 25% base64 overhead.This will make the biggest difference over a slow internet connection.
Developer Work You have to store, manage and deliver your own PrintJobs. You don't need to worry about hosting and managing your own PrintJobs. PrintNode does this for you.
Maximum supported document size Unlimited document size. Documents must be smaller than 10MB.

Responses

When the PrintJob is received, the PrintNode API will add it to the print queue and respond immediately, i.e., the PrintNode API does not wait for the PrintJob to be sent to the specified Printer before responding.

If the Computer that controls that Printer is not connected the job will be queued and sent to the Computer when it reconnects.

The response body to a successfully created PrintJob is the id of the newly created PrintJob.

Sample PDFs

Below are links to some sample PDF files that you can use for testing your printing.

Filename Size Pages Dimensions (inches)
4x6_2_up_ol145.pdf 293.8KB 1 8.5 x 11
4x6_2_up_on_8x11_avery_5126_or_ol400.pdf 297.91KB 1 8.5 x 11
4x6_2_up_on_8x11_with_packing_slip_avery_5127.pdf 217.21KB 1 8.5 x 11
4x6_combo_vertical_ol829.pdf 128.54KB 1 8.5 x 11
4x6_label_on_8x11_centered_on_letter_paper.pdf 148.92KB 1 8.5 x 11
a4_10_pages.pdf 17.74KB 10 3.9 x 6
a4_500_pages.pdf 406.73KB 500 8.3 x 11.7
a4_portrait.pdf 30.78KB 1 8.3 x 11.7
a5_portrait.pdf 30.54KB 1 5.8 x 8.3
fedex_label.pdf 30.72KB 1 4 x 6
label_3in_x_1in_barcode.pdf 6.86KB 1 3 x 1
label_4in_x_6in_ups_with_packing.pdf 216.08KB 2 6 x 4
label_4in_x_6in_ups.pdf 149.51KB 1 4 x 6
label_4in_x_6in.pdf 30.53KB 1 4 x 6
label_6in_x_4in.pdf 30.19KB 1 6 x 4
letter_portrait.pdf 30.74KB 1 8.5 x 11
test.pdf 23.86KB 2 3 x 1
ups_label.pdf 32.33KB 1 4 x 6
multipage.pdf 17.74KB 10 3.9 x 6

Viewing PrintJobs

You can view your PrintJob history via GET /printjobs. You can also filter returned PrintJobs by Printer or PrintJob id. Just substitute the appropriate parameter into one of the URLs below.

/printjobs
/printjobs/printjob set
/printers/printer set/printjobs
/printers/printer set/printjobs/printjob set

Example Request curl

curl -H "X-Pretty: true" https://api.printnode.com/printjobs \ -u 44784dd8d88be9631046ff83e9044419ff824b10:

Response

[ { "id": 557, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "Print Job 1", "contentType": "pdf_uri", "source": "Google", "expireAt": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "preparing_to_print" }, { "id": 558, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "Print Job 2", "contentType": "pdf_uri", "source": "Google", "expireAt": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "downloading" }, { "id": 559, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "Print Job 3", "contentType": "pdf_uri", "source": "Google", "expireAt": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "queued" }, { "id": 560, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "Print Job 4", "contentType": "pdf_uri", "source": "Google", "expireAt": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "new" }, { "id": 561, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "Print Job 5", "contentType": "pdf_uri", "source": "Google", "expireAt": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "preparing_to_print" }, { "id": 562, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "Print Job 6", "contentType": "pdf_uri", "source": "Google", "expireAt": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "pending_confirmation" }, { "id": 563, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "Print Job 7", "contentType": "pdf_uri", "source": "Google", "expireAt": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "in_progress" }, { "id": 564, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "Print Job 8", "contentType": "pdf_uri", "source": "Google", "expireAt": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "downloading" }, { "id": 565, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "Print Job 9", "contentType": "pdf_uri", "source": "Google", "expireAt": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "downloading" }, { "id": 566, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "Print Job 10", "contentType": "pdf_uri", "source": "Google", "expireAt": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "deleted" }, { "id": 567, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "Print Job 11", "contentType": "pdf_uri", "source": "Google", "expireAt": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "sent_to_client" }, { "id": 568, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "Print Job 12", "contentType": "pdf_uri", "source": "Google", "expireAt": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "downloading" }, { "id": 569, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "Print Job 13", "contentType": "pdf_uri", "source": "Google", "expireAt": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "done" }, { "id": 570, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "Print Job 14", "contentType": "pdf_uri", "source": "Google", "expireAt": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "queued_to_print" }, { "id": 571, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "Print Job 15", "contentType": "pdf_uri", "source": "Google", "expireAt": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "received" }, { "id": 572, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "Print Job 16", "contentType": "pdf_uri", "source": "Google", "expireAt": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "downloaded" }, { "id": 573, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "Print Job 17", "contentType": "pdf_uri", "source": "Google", "expireAt": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "done" }, { "id": 574, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "Print Job 18", "contentType": "pdf_uri", "source": "Google", "expireAt": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "in_progress" }, { "id": 575, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "Print Job 19", "contentType": "pdf_uri", "source": "Google", "expireAt": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "preparing_to_print" }, { "id": 576, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "Print Job 19", "contentType": "pdf_uri", "source": "Google", "expireAt": null, "createTimestamp": "2015-06-28T18:29:26.528Z", "state": "done" }, { "id": 577, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": null, "createTimestamp": "2015-06-28T18:33:07.141Z", "state": "new" }, { "id": 578, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": "2015-06-28T18:43:07.000Z", "createTimestamp": "2015-06-28T18:33:07.210Z", "state": "new" }, { "id": 579, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": null, "createTimestamp": "2015-06-28T18:33:36.335Z", "state": "new" }, { "id": 580, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": "2015-06-28T18:43:36.000Z", "createTimestamp": "2015-06-28T18:33:36.380Z", "state": "new" }, { "id": 581, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": null, "createTimestamp": "2015-06-28T18:33:42.661Z", "state": "new" }, { "id": 582, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": "2015-06-28T18:43:42.000Z", "createTimestamp": "2015-06-28T18:33:42.700Z", "state": "new" }, { "id": 583, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": null, "createTimestamp": "2015-06-28T18:34:19.194Z", "state": "new" }, { "id": 584, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": "2015-06-28T18:44:19.000Z", "createTimestamp": "2015-06-28T18:34:19.250Z", "state": "new" }, { "id": 585, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": null, "createTimestamp": "2015-06-28T18:35:00.532Z", "state": "new" }, { "id": 586, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": "2015-06-28T18:45:00.000Z", "createTimestamp": "2015-06-28T18:35:00.570Z", "state": "new" }, { "id": 587, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": null, "createTimestamp": "2015-06-28T20:47:11.788Z", "state": "new" }, { "id": 588, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": "2015-06-28T20:57:11.000Z", "createTimestamp": "2015-06-28T20:47:11.834Z", "state": "new" }, { "id": 589, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": null, "createTimestamp": "2015-06-28T20:48:12.891Z", "state": "new" }, { "id": 590, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": "2015-06-28T20:58:12.000Z", "createTimestamp": "2015-06-28T20:48:12.931Z", "state": "new" }, { "id": 591, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": null, "createTimestamp": "2015-06-28T20:48:51.128Z", "state": "new" }, { "id": 592, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": "2015-06-28T20:58:51.000Z", "createTimestamp": "2015-06-28T20:48:51.169Z", "state": "new" }, { "id": 593, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": null, "createTimestamp": "2015-06-28T20:53:06.389Z", "state": "new" }, { "id": 594, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": "2015-06-28T21:03:06.000Z", "createTimestamp": "2015-06-28T20:53:06.428Z", "state": "new" }, { "id": 595, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": null, "createTimestamp": "2015-06-28T20:54:30.267Z", "state": "new" }, { "id": 596, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": "2015-06-28T21:04:30.000Z", "createTimestamp": "2015-06-28T20:54:30.326Z", "state": "new" }, { "id": 597, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": null, "createTimestamp": "2015-06-28T21:21:19.945Z", "state": "new" }, { "id": 598, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": "2015-06-28T21:31:19.000Z", "createTimestamp": "2015-06-28T21:21:19.983Z", "state": "new" }, { "id": 599, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": null, "createTimestamp": "2015-06-28T21:33:56.756Z", "state": "new" }, { "id": 600, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": "2015-06-28T21:43:56.000Z", "createTimestamp": "2015-06-28T21:33:56.800Z", "state": "new" }, { "id": 601, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": null, "createTimestamp": "2015-06-28T21:35:40.742Z", "state": "new" }, { "id": 602, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": "2015-06-28T21:45:40.000Z", "createTimestamp": "2015-06-28T21:35:40.785Z", "state": "new" }, { "id": 603, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": null, "createTimestamp": "2015-06-28T21:55:15.634Z", "state": "new" }, { "id": 604, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": "2015-06-28T22:05:15.000Z", "createTimestamp": "2015-06-28T21:55:15.674Z", "state": "new" }, { "id": 605, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": null, "createTimestamp": "2015-06-28T22:00:11.917Z", "state": "new" }, { "id": 606, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": "2015-06-28T22:10:11.000Z", "createTimestamp": "2015-06-28T22:00:11.956Z", "state": "new" }, { "id": 607, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": null, "createTimestamp": "2015-06-28T22:05:38.078Z", "state": "new" }, { "id": 608, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": "2015-06-28T22:15:38.000Z", "createTimestamp": "2015-06-28T22:05:38.116Z", "state": "new" }, { "id": 609, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": null, "createTimestamp": "2015-06-28T22:08:36.050Z", "state": "new" }, { "id": 610, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": "2015-06-28T22:18:36.000Z", "createTimestamp": "2015-06-28T22:08:36.087Z", "state": "new" }, { "id": 611, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": null, "createTimestamp": "2015-06-28T22:11:33.291Z", "state": "new" }, { "id": 612, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": "2015-06-28T22:21:33.000Z", "createTimestamp": "2015-06-28T22:11:33.330Z", "state": "new" }, { "id": 613, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": null, "createTimestamp": "2015-06-28T22:24:04.223Z", "state": "new" }, { "id": 614, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": "2015-06-28T22:34:04.000Z", "createTimestamp": "2015-06-28T22:24:04.261Z", "state": "new" }, { "id": 615, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": null, "createTimestamp": "2015-06-28T22:24:20.114Z", "state": "new" }, { "id": 616, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": "2015-06-28T22:34:20.000Z", "createTimestamp": "2015-06-28T22:24:20.150Z", "state": "new" }, { "id": 617, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": null, "createTimestamp": "2015-06-28T22:26:41.179Z", "state": "new" }, { "id": 618, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": "2015-06-28T22:36:41.000Z", "createTimestamp": "2015-06-28T22:26:41.218Z", "state": "new" }, { "id": 619, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": null, "createTimestamp": "2015-06-28T22:27:15.745Z", "state": "new" }, { "id": 620, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": "2015-06-28T22:37:15.000Z", "createTimestamp": "2015-06-28T22:27:15.782Z", "state": "new" }, { "id": 621, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": null, "createTimestamp": "2015-06-28T22:27:41.177Z", "state": "new" }, { "id": 622, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": "2015-06-28T22:37:41.000Z", "createTimestamp": "2015-06-28T22:27:41.213Z", "state": "new" }, { "id": 623, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": null, "createTimestamp": "2015-06-28T22:29:09.523Z", "state": "new" }, { "id": 624, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": "2015-06-28T22:39:09.000Z", "createTimestamp": "2015-06-28T22:29:09.559Z", "state": "new" }, { "id": 625, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": null, "createTimestamp": "2015-06-28T22:31:07.198Z", "state": "new" }, { "id": 626, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": "2015-06-28T22:41:07.000Z", "createTimestamp": "2015-06-28T22:31:07.240Z", "state": "new" }, { "id": 627, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": null, "createTimestamp": "2015-06-28T22:34:00.243Z", "state": "new" }, { "id": 628, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": "2015-06-28T22:44:00.000Z", "createTimestamp": "2015-06-28T22:34:00.281Z", "state": "new" }, { "id": 629, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": null, "createTimestamp": "2015-06-28T22:34:13.334Z", "state": "new" }, { "id": 630, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": "2015-06-28T22:44:13.000Z", "createTimestamp": "2015-06-28T22:34:13.371Z", "state": "new" }, { "id": 631, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": null, "createTimestamp": "2015-06-28T22:34:28.326Z", "state": "new" }, { "id": 632, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": "2015-06-28T22:44:28.000Z", "createTimestamp": "2015-06-28T22:34:28.362Z", "state": "new" }, { "id": 633, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": null, "createTimestamp": "2015-06-28T22:56:33.503Z", "state": "new" }, { "id": 634, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": "2015-06-28T23:06:33.000Z", "createTimestamp": "2015-06-28T22:56:33.542Z", "state": "new" }, { "id": 635, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": null, "createTimestamp": "2015-06-28T22:57:40.870Z", "state": "new" }, { "id": 636, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": "2015-06-28T23:07:40.000Z", "createTimestamp": "2015-06-28T22:57:40.913Z", "state": "new" }, { "id": 637, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": null, "createTimestamp": "2015-06-28T23:01:35.029Z", "state": "new" }, { "id": 638, "printer": { "id": 39, "computer": { "id": 11, "name": "AnalyticalEngine", "inet": null, "inet6": null, "hostname": null, "version": null, "jre": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "disconnected" }, "name": "Printer 1", "description": "Test Printer 1", "capabilities": null, "default": null, "createTimestamp": "2015-06-28T18:29:19.871Z", "state": "printing" }, "title": "My Test PrintJob", "contentType": "pdf_uri", "source": "api documentation!", "expireAt": "2015-06-28T23:11:35.000Z", "createTimestamp": "2015-06-28T23:01:35.066Z", "state": "new" } ]
HTTP/1.1 200 OK Date: Sun, 28 Jun 2015 23:01:35 GMT Content-Type: application/json Content-Length: 61028 Connection: keep-alive Vary: Accept-Encoding Server: PrintNodeApi Api-Version: 3.0.0 Request-Id: b2f9576d-bba5-47f2-b1aa-eb8c4f4d72ba Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Access-Control-Allow-Methods: * Access-Control-Allow-Headers: Accept, Accept-Version, Api-Version, Authorization, Content-Length, Content-MD5, Content-Type, Date, X-Account, X-Requested-With, X-Pretty, X-Dont-Log, X-Child-Account-By-Id, X-Child-Account-By-Email, X-Child-Account-By-CreatorRef Access-Control-Expose-Headers: Api-Version, Records-Returned, Records-Returned-Limit, Records-Returned-Offset, Records-Total, Request-Id, Response-Time, X-Authorized-As, X-Auth-With, X-Child-Account-By-CreatorRef, X-Child-Account-By-Email, X-Child-Account-By-Id X-Auth-With: ApiKey X-Account: 433 Records-Returned: 82 Records-Returned-Offset: 0 Records-Returned-Limit: 500 Records-Total: 82 Content-MD5: O6oSkiX5LQ7+wQAoNTCVFQ== Response-Time: 39

PrintJob States

You can see how a individual PrintJob is progressing by it's state. Problems or delays printing a individual job can often be diagnosed here.

You can filter printjob states by PrintJob id. Just substitute the appropriate parameter into the URLs below.

/printjobs/states
/printjobs/printjob set/states

Each PrintJob goes through a number of states as part of the printing process. The PrintJob state transitions are shown below.

Each PrintJob can have multiple states and the API endpoints can return states for multiple PrintJobs. A request for PrintJob States will return a JSON array (PrintJobs) of arrays (States) which contain a object describing the State. PrintJobs are sorted by createTimestamp descending. States for a PrintJob are sorted createTimestamp ascending.

The object which describes a PrintJob State has the following keys.

Attribute Type Description
printJobIdIntegerThe id of the PrintJob this state relates to.
state String The PrintJob string. The allowed states are pending_confirmation, new, sent_to_client, deleted, done, error, in_progress, queued, disappeared, received, downloading, downloaded, preparing_to_print, queued_to_print and expired.
messageStringAdditional human readable information about the state. If a error has occoured this where to look to diagnose the problem.
dataObjectA machine readable representation of the information contained in the property 'message'. Implmented shortly. Currently this is null.
clientVersionStringThe version of the client which reported this state. This will be null null if the state did not originate from the client.
createTimestampDateThe UTC date this state was reported to the server.
ageIntegerThe age of this state relative to the first state in milliseconds.

Example Request curl

curl -H "X-Pretty: true" https://api.printnode.com/printjobs/states?limit=1 \ -u 44784dd8d88be9631046ff83e9044419ff824b10:

Response

[ [ { "printJobId": 638, "state": "new", "message": null, "data": null, "clientVersion": null, "createTimestamp": "2015-06-28T22:01:35.066Z", "age": 0 } ] ]
HTTP/1.1 200 OK Date: Sun, 28 Jun 2015 23:01:35 GMT Content-Type: application/json Content-Length: 212 Connection: keep-alive Server: PrintNodeApi Api-Version: 3.0.0 Request-Id: a7594054-b756-48ac-a38e-186a7d5daf79 Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Access-Control-Allow-Methods: * Access-Control-Allow-Headers: Accept, Accept-Version, Api-Version, Authorization, Content-Length, Content-MD5, Content-Type, Date, X-Account, X-Requested-With, X-Pretty, X-Dont-Log, X-Child-Account-By-Id, X-Child-Account-By-Email, X-Child-Account-By-CreatorRef Access-Control-Expose-Headers: Api-Version, Records-Returned, Records-Returned-Limit, Records-Returned-Offset, Records-Total, Request-Id, Response-Time, X-Authorized-As, X-Auth-With, X-Child-Account-By-CreatorRef, X-Child-Account-By-Email, X-Child-Account-By-Id X-Auth-With: ApiKey X-Account: 433 Records-Returned: 1 Records-Returned-Offset: 0 Records-Returned-Limit: 1 Content-MD5: BzJmYMT6byiyQXanpvKOkw== Response-Time: 41

Weighing Scale Integration

HTTP REST

You can get a list of USB weighing scales attached to a computer by making a GET request to any of the following URLs.

/computer/computer id/scales

computer id refers to a computer id. You can determine the computer ids of all the computers registered to your account with GET /computers. device name is a string which identifies a make and model of scales. By default this is a of the form "manufacturer - model" but can be altered in the PrintNode client to a more descriptive and convenient identifier. Operating systems don't always allow unique identification of usb devices and in the event multiple scales of the same make and model are connected to a computer a individual device can be distingushed by the integer device num.

Example Request curl

curl -H "X-Pretty: true" https://api.printnode.com/computer/12/scales \ -u 44784dd8d88be9631046ff83e9044419ff824b10:

Response

[ { "mass": [ 23, 1 ], "deviceName": "packing_scales", "deviceNum": 0, "port": "USB1", "count": 23, "measurement": { "g": 23 }, "clientReportedCreateTimestamp": "2015-06-28T23:01:35.188Z", "ntpOffset": null, "ageOfData": 23, "computerId": 12, "vendor": "PrintNode", "product": "Virtual Scale", "vendorId": 0, "productId": 0 } ]
HTTP/1.1 200 OK Date: Sun, 28 Jun 2015 23:01:35 GMT Content-Type: application/json Content-Length: 415 Connection: keep-alive Server: PrintNodeApi Api-Version: 3.0.0 Request-Id: 6b0a1132-9309-4e0a-9105-d66c8b88deef Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Access-Control-Allow-Methods: * Access-Control-Allow-Headers: Accept, Accept-Version, Api-Version, Authorization, Content-Length, Content-MD5, Content-Type, Date, X-Account, X-Requested-With, X-Pretty, X-Dont-Log, X-Child-Account-By-Id, X-Child-Account-By-Email, X-Child-Account-By-CreatorRef Access-Control-Expose-Headers: Api-Version, Records-Returned, Records-Returned-Limit, Records-Returned-Offset, Records-Total, Request-Id, Response-Time, X-Authorized-As, X-Auth-With, X-Child-Account-By-CreatorRef, X-Child-Account-By-Email, X-Child-Account-By-Id X-Auth-With: ApiKey X-Account: 433 Content-MD5: gYVUXjDiDrns+37GPlL1Yw== Response-Time: 3

The response will be an array of the most recent scales data objects produced by this computer. If there are no scales atached to your account the response will be a empty JSON array. Provided computer Id is a positive integer this method will always return a 200 OK. That is to say if you pass a computerId which does not correspond to a computer attached to your account the response will be a zero length JSON array.

Scales Data Object Detail

  • massArray - length 2

    The first element represents the mass returned by the scale in micrograms as a unsigned integer. If the scale is been unable to calucate a weight null will be returned here. This most commonly happens when scales display a negative weight. It seems to be a limitation of most scales USB implementations that, whilst they can usually display and return negative weights on their physical interfaces, they do not send this information over usb.
    The second element represents the resolution of the scale in micrograms where known or null if not known. Suppose a scale is displaying a weight of 125g accurate to 5g the returned mass value array would be [125000000, 5000000].

  • computerIdInteger

    The computer id.

  • vendorText

    String description of the vendor or manufacturer of the scales device. This is supplied by the usb subsystem

  • vendorId, deviceIdInteger

    The USB device vendor id and device id. See here for detailed description and here for up to date list of vendor and device ids.

  • portText

    A string description of the scales connection method. Eg, "USB1" or "COM0".

  • deviceNameText

    A string identifier for the scales. By default this will be the scales manufacturer and description. The PrintNode client may rename a scale. Max length 251 characters.

  • deviceNumInteger

    Zero indexed integer. A deviceName and deviceNum pair may be used to distingish between two identical devices. That is to say, at any point in time a deviceName, deviceNum pair uniquely identifies a specific scale. The first scale connected to a client will recieve a deviceNum of 0. If a second, identical scale is connected before the first is removed it will recieve a deviceNum of 1 and so on. A scales deviceNum won't change whilst a scale is connected but a deviceNum be reused. For example, should a scale be disconnected and reconnected it will recieve the lowest currently unused deviceNum.

  • countInteger

    Support for counting scales. Should a scale support counting and make this information available over usb this value will be returned here. null otherwise.

  • measurementObject

    Scales usually allow display of mass in imperial or metric units. The keys in this object represent the units on dispay at the scales physical interface at the time of measurement. At time of writing supported keys are 'g', 'kg', 'lb', 'oz' by more may be added as we encounter them. The value for each key is a integer representation of the value in 1 millionths (1/1000000ths) of that unit. This information is provided to allow for a accurate recreation of a scales physcial display to be produced. You don't need to parse this into a SI unit as PrintNode has already done this for you, see the property mass.

    E.g. a scales display values of "1.25 kg", "1200g" or "2lb 10.32oz" would have a the same mass value but measurement value of {"kg":1250000}, {"g": 1200000000} and {"lb": 2000000, "oz": 10320000} respectively.

  • clientReportedCreateTimestampDateTime

    The system time as reported by the client computer at the time of generation of the scales data. The accuracy of this timestamp is entirely dependant on the system clock of the computer which generated the scales data which is entirely variable. Innaccuracies of greater than ± 5 minutes are not uncommon. This has been been provided so that the total latency in the system can be accurately measured if the consumer of the api is the same as the machine producing the scales data.

  • ntpOffsetInteger

    Inaccuracy of the system time of the client computer generating the scales data in milliseconds as determined via by NTP. Positive values represent a system clock running fast and a negative value represents a system clock running slow. Under normal conditions this offset is usually accurate to ± 10 milliseconds. It takes a short while to determine the ntpOffset after the client starts up. When this information is not avaliable the value will be null.

  • ageOfDataInteger

    The time the scales data has be stored at PrintNode before being delivered to an API client in milliseconds. For the streaming and websocket api endpoints where data can be immediately delivered to subscribers this will be low - expect values around ~3-10ms. For the polling HTTP GET endpoints this will normally be much larger.

    It is important to note that large values here do not mean that the data in old. Clients update PrintNode when they connect, disconnect or the weight returned from the scales changes. If the weight returned by the scale is stable the ageOfData field can grow but still be accurate.


Filtering by Device Name

GET /computer/computer id/scales/device name

Example Request curl

curl -H "X-Pretty: true" "https://api.printnode.com/computer/12/scales/packing_scales" \ -u 44784dd8d88be9631046ff83e9044419ff824b10:

Response

[ { "mass": [ 23, 1 ], "deviceName": "packing_scales", "deviceNum": 0, "port": "USB1", "count": 23, "measurement": { "g": 23 }, "clientReportedCreateTimestamp": "2015-06-28T23:01:35.188Z", "ntpOffset": null, "ageOfData": 42, "computerId": 12, "vendor": "PrintNode", "product": "Virtual Scale", "vendorId": 0, "productId": 0 } ]
HTTP/1.1 200 OK Date: Sun, 28 Jun 2015 23:01:35 GMT Content-Type: application/json Content-Length: 415 Connection: keep-alive Server: PrintNodeApi Api-Version: 3.0.0 Request-Id: c0d08244-d426-41e1-b69c-84d78d51fe22 Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Access-Control-Allow-Methods: * Access-Control-Allow-Headers: Accept, Accept-Version, Api-Version, Authorization, Content-Length, Content-MD5, Content-Type, Date, X-Account, X-Requested-With, X-Pretty, X-Dont-Log, X-Child-Account-By-Id, X-Child-Account-By-Email, X-Child-Account-By-CreatorRef Access-Control-Expose-Headers: Api-Version, Records-Returned, Records-Returned-Limit, Records-Returned-Offset, Records-Total, Request-Id, Response-Time, X-Authorized-As, X-Auth-With, X-Child-Account-By-CreatorRef, X-Child-Account-By-Email, X-Child-Account-By-Id X-Auth-With: ApiKey X-Account: 433 Content-MD5: zUiUTvKu+MQNIoYR3Rgdxw== Response-Time: 2

Filtering by Device Name and Number

GET /computer/computer id/scale/device name/device number

N.B. the /scale/ part of this endpoint is not pluralised which is different from the other scales api endpoints.

Example Request curl

curl -H "X-Pretty: true" "https://api.printnode.com/computer/12/scale/packing_scales/0" \ -u 44784dd8d88be9631046ff83e9044419ff824b10:

Response

{ "mass": [ 23, 1 ], "deviceName": "packing_scales", "deviceNum": 0, "port": "USB1", "count": 23, "measurement": { "g": 23 }, "clientReportedCreateTimestamp": "2015-06-28T23:01:35.188Z", "ntpOffset": null, "ageOfData": 61, "computerId": 12, "vendor": "PrintNode", "product": "Virtual Scale", "vendorId": 0, "productId": 0 }
HTTP/1.1 200 OK Date: Sun, 28 Jun 2015 23:01:35 GMT Content-Type: application/json Content-Length: 369 Connection: keep-alive Server: PrintNodeApi Api-Version: 3.0.0 Request-Id: c2f8b121-8540-468b-81cb-0f5baa3af54b Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Access-Control-Allow-Methods: * Access-Control-Allow-Headers: Accept, Accept-Version, Api-Version, Authorization, Content-Length, Content-MD5, Content-Type, Date, X-Account, X-Requested-With, X-Pretty, X-Dont-Log, X-Child-Account-By-Id, X-Child-Account-By-Email, X-Child-Account-By-CreatorRef Access-Control-Expose-Headers: Api-Version, Records-Returned, Records-Returned-Limit, Records-Returned-Offset, Records-Total, Request-Id, Response-Time, X-Authorized-As, X-Auth-With, X-Child-Account-By-CreatorRef, X-Child-Account-By-Email, X-Child-Account-By-Id X-Auth-With: ApiKey X-Account: 433 Content-MD5: pBoVKu1UhTdsFM8FfHxvrg== Response-Time: 3

Returns a scales data object with HTTP response 200 OK if a scales with matching device name and number can be found. Returns 404 Not Found if no scales device is found with the passed device name and number.

Example Request curl

curl -H "X-Pretty: true" "https://api.printnode.com/computer/12/scale/not_a_real_scales_device_name/0" \ -u 44784dd8d88be9631046ff83e9044419ff824b10:

Response

{ "code": "ResourceNotFound", "message": "Unable to find any scales with device name 'not_a_real_scales_device_name', device number 0 attached to computer id 12." }
HTTP/1.1 404 Not Found Date: Sun, 28 Jun 2015 23:01:35 GMT Content-Type: application/json Content-Length: 170 Connection: keep-alive Server: PrintNodeApi Api-Version: 3.0.0 Request-Id: 29742671-61a8-4106-bba1-3bed67e07705 Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Access-Control-Allow-Methods: * Access-Control-Allow-Headers: Accept, Accept-Version, Api-Version, Authorization, Content-Length, Content-MD5, Content-Type, Date, X-Account, X-Requested-With, X-Pretty, X-Dont-Log, X-Child-Account-By-Id, X-Child-Account-By-Email, X-Child-Account-By-CreatorRef Access-Control-Expose-Headers: Api-Version, Records-Returned, Records-Returned-Limit, Records-Returned-Offset, Records-Total, Request-Id, Response-Time, X-Authorized-As, X-Auth-With, X-Child-Account-By-CreatorRef, X-Child-Account-By-Email, X-Child-Account-By-Id X-Auth-With: ApiKey X-Account: 433 Content-MD5: DSKhM5cRa1lRF+L7BZwqPQ== Response-Time: 3

HTTP Streaming

The streaming API endpoints provide low latency access to scales streaming data. They allow PrintNode to push scales data messages to connected client without any of the overhead associated with polling a REST endpoint.

Connecting to the streaming API requires keeping a persistent HTTP connection open. Each HTTP connections is initally established and authenticated in exactly the same manner as the every other PrintNode API request. The difference is that instead of the returning a single resource and closing the connection the connection is maintained so that when new resources become available they can be delivered immediately.

Processing streaming data

The body of a streaming API response consists of a series of newline-delimited messages, where "newline" is considered to \r\n (in hex, 0x0D 0x0A) and "message" is a JSON encoded data structure or a blank line. JSON messages will never contain \r\n.

Streaming connections are encoded using chunked transfer encoding, and indicated by HTTP response header Transfer-Encoding: chunked. Most HTTP libraries transparently manage chunked transfer encoding and this document will assume that your code has access to the reassembled HTTP stream and does not have to deal with this encoding. Should your code actually parse a raw TCP stream, you will need to reassemble HTTP chunks manually. Consider that streamed messages will not necessarily fall on HTTP chunk boundaries.

Streaming messages

Messages come in three types. Application and control messages are JSON data structures. "keep-alive" messages are simply \n and may be sent periodically if a connection is in danger of timing out. Control messages are used to inform clients of server events related to the HTTP connection. Specifically these are disconnect and stall warnings. Application messages are the interesting bit and follow a similar structure to a response returned by the PrintNode HTTP rest API; it'll all look pretty familiar.

Anything else?

Yes. You can't send a Connection: close header in your request. There's no support for pretty printing the JSON messages with X-Pretty due to \n considerations. You've got to make a HTTP 1.1 request and include a non empty User-Agent.

Falling behind. Each stream has a buffer and should this fill the connection will be closed. This will happen if a client can't read the stream of data as fast as it is produced for a sustained time.

The streaming API is throttled independantly to HTTP REST requests; there's a limit to number of simultaneous streams each account can have open and streaming connections should be kept open for as long as possible.

We think the streaming API is great and offers a fantastic user experience but it isn't a replacement for the REST API. You'll need to use both to access all the data available from PrintNode.

Does any of this work in browsers?

No. But we've got websocket support in beta which does!

Ok, what are the endpoints?

GET /streaming/computer/computer id/scales
GET /streaming/computer/computer id/scales/device name
GET /streaming/computer/computer id/scale/device name/device num

Websockets

Creating Child Accounts

If you are integrating PrintNode into your application then you might want to programmatically create PrintNode accounts for your customers. To do this, you need a special kind of PrintNode account called a Parent Account which will allow you to create Child Accounts. These Child Accounts are controllable with your Parent Account credentials.

To enable this feature please contact support@printnode.com.

Attribute Type Is Required? Specification
Account[id]IntegerIgnoredAssigned by API. Any value submitted here will be ignored.
Account[firstname]stringYes
Account[lastname]stringYes
Account[email]stringYesA valid email address. This must be unique and would normally be the email address of your customer. This email is for actions like account password resets, informing customers of new versions of the client, etc. Your email will never be shared with any third party or used for marketing purposes.
Account[password]stringYesThe password should be plain text. It will be encoded in the PrintNode database and cannot be retrieved, only reset.
Account[creatorRef]stringNoA unique reference which you can use as a method to identify an account.
ApiKeys[]Array[String]NoA array of named API Keys you wish to create for this account.
Tags[]Array[tagname]NoA array of tag names and values to be associated with an account.

Example Request curl

curl -H "X-Pretty: true" -X POST https://api.printnode.com/account \ -u 44784dd8d88be9631046ff83e9044419ff824b10: \ -H "Content-Type: application/json" \ -d '{ "Account": { "firstname": "Ada", "lastname": "Lovelace", "email": "ada.lovelace@myfirstprogram.com", "password": "password", "creatorRef": "ada.lovelace" }, "ApiKeys": [ "development", "production" ], "Tags": { "likes": "pianos" } }'
curl -H "X-Pretty: true" -X POST https://api.printnode.com/account \ -u 44784dd8d88be9631046ff83e9044419ff824b10: \ -d 'Account[firstname]=Ada' \ -d 'Account[lastname]=Lovelace' \ -d 'Account[email]=ada.lovelace@myfirstprogram.com' \ -d 'Account[password]=password' \ -d 'Account[creatorRef]=ada.lovelace' \ -d 'ApiKeys[]=development' \ -d 'ApiKeys[]=production' \ -d 'Tags[likes]=pianos'

Response

{ "Account": { "id": 480, "creatorRef": "ada.lovelace", "firstname": "Ada", "lastname": "Lovelace", "email": "ada.lovelace@myfirstprogram.com" }, "ApiKeys": { "development": "a33d3c3327faf536c8d751e9de3e5595f3c9afd1", "production": "fc378c7ebb67f4886334fe38a2c6e7e504256451" }, "Tags": { "likes": "pianos" }, "credits": null }
HTTP/1.1 200 OK Date: Sun, 28 Jun 2015 23:01:35 GMT Content-Type: application/json Content-Length: 374 Connection: keep-alive Server: PrintNodeApi Api-Version: 3.0.0 Request-Id: fc97a85e-8019-4369-90e4-f91ae05f1426 Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Access-Control-Allow-Methods: * Access-Control-Allow-Headers: Accept, Accept-Version, Api-Version, Authorization, Content-Length, Content-MD5, Content-Type, Date, X-Account, X-Requested-With, X-Pretty, X-Dont-Log, X-Child-Account-By-Id, X-Child-Account-By-Email, X-Child-Account-By-CreatorRef Access-Control-Expose-Headers: Api-Version, Records-Returned, Records-Returned-Limit, Records-Returned-Offset, Records-Total, Request-Id, Response-Time, X-Authorized-As, X-Auth-With, X-Child-Account-By-CreatorRef, X-Child-Account-By-Email, X-Child-Account-By-Id X-Auth-With: ApiKey X-Account: 437 Content-MD5: cnyAvjrUCnmxZBap9kAsCg== Response-Time: 33

Modifying Child Accounts

You may update a Child Account's properties via PATCH /accounts. You cannot modify your own account details. Any of the properties in the table below can be set. Just identify the account with one of the X-Child-Account-By-* headers.

The HTTP verb PATCH is not new but support varies. If you are having problems using this please contact support@printnode.com and we’ll do what we can to help.

Attribute Type Is Required?
firstnamestringNo
lastnamestringNo
passwordstringNo
emailstringNo
creatorRefstringNo

The response details the new updated account information and has the same structure as what would be returned by GET /whoami.

Example Request curl

curl -H "X-Pretty: true" -X PATCH https://api.printnode.com/account \ -H 'X-Child-Account-By-Id: 480' \ -u 44784dd8d88be9631046ff83e9044419ff824b10: \ -d 'firstname=Charles' \ -d 'lastname=Babbage' \ -d 'password=steampunk' \ -d 'email=charles.babbage@mechanicalmarvels.com' \ -d 'creatorRef=charles.babbage'
curl -H "X-Pretty: true" -X PATCH https://api.printnode.com/account \ -H 'X-Child-Account-By-Id: 480' \ -H "Content-Type: application/json" \ -u 44784dd8d88be9631046ff83e9044419ff824b10: \ -d '{ "firstname": "Charles", "lastname": "Babbage", "password": "steampunk", "email": "charles.babbage@mechanicalmarvels.com", "creatorRef": "charles.babbage" }'

Response

{ "id": 480, "firstname": "Charles", "lastname": "Babbage", "email": "charles.babbage@mechanicalmarvels.com", "canCreateSubAccounts": false, "creatorEmail": "god@printnode.com", "creatorRef": "charles.babbage", "childAccounts": [], "credits": null, "numComputers": 0, "totalPrints": 0, "versions": [], "connected": [], "Tags": { "likes": "pianos" }, "ApiKeys": { "production": "fc378c7ebb67f4886334fe38a2c6e7e504256451", "development": "a33d3c3327faf536c8d751e9de3e5595f3c9afd1" }, "state": "active" }
HTTP/1.1 200 OK Date: Sun, 28 Jun 2015 23:01:35 GMT Content-Type: application/json Content-Length: 551 Connection: keep-alive Server: PrintNodeApi Api-Version: 3.0.0 Request-Id: f888c753-33b0-417c-81e7-6aa51980b813 Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Access-Control-Allow-Methods: * Access-Control-Allow-Headers: Accept, Accept-Version, Api-Version, Authorization, Content-Length, Content-MD5, Content-Type, Date, X-Account, X-Requested-With, X-Pretty, X-Dont-Log, X-Child-Account-By-Id, X-Child-Account-By-Email, X-Child-Account-By-CreatorRef Access-Control-Expose-Headers: Api-Version, Records-Returned, Records-Returned-Limit, Records-Returned-Offset, Records-Total, Request-Id, Response-Time, X-Authorized-As, X-Auth-With, X-Child-Account-By-CreatorRef, X-Child-Account-By-Email, X-Child-Account-By-Id X-Auth-With: ApiKey X-Child-Account-By-Id: 480 X-Authorized-As: 437 X-Account: 480 Content-MD5: XehzN89ewTbPA2obUuNzWQ== Response-Time: 17

Delete Child Accounts

A Parent may delete any of its Child Accounts by sending a DELETE /account and identifying the child account with any of the X-Child-Account-By-* headers.

Soft vs Hard Deletion

Accounts which have no associated PrintJobs (or have never printed anything) can be completely removed from the system. This frees the Account username (i.e. email) to be used in the future. This is a hard delete. It can be useful if there was a mistake made when creating the Account. It will not be possible to logon with this Account’s credentials.

If the Account has printed anything or has had any PrintJobs submitted to it, it will be marked as deleted but all Account information will be retained in the PrintNode database. No further access or modification to this Account is possible either through the website or the via the API. The only access possible is a GET /whoami request with a X-Child-Account-By-* header. This returns the Account information as normal and the 'state' property will be set to 'deleted'. This is a soft delete and is reversible; please contact support@printnode.com.

You cannot delete non-Child Accounts. If you wish to delete your own account please contact support@printnode.com.

Example Request curl

curl -H "X-Pretty: true" -X DELETE https://api.printnode.com/account \ -H 'X-Child-Account-By-Email: ada.lovelace@myfirstprogram.com' \ -u 44784dd8d88be9631046ff83e9044419ff824b10:
curl -H "X-Pretty: true" -X DELETE https://api.printnode.com/account \ -H 'X-Child-Account-By-CreatorRef: ada.lovelace' \ -u 44784dd8d88be9631046ff83e9044419ff824b10:
curl -H "X-Pretty: true" -X DELETE https://api.printnode.com/account \ -H 'X-Child-Account-By-Id: 480' \ -u 44784dd8d88be9631046ff83e9044419ff824b10:

Response

true
HTTP/1.1 200 OK Date: Sun, 28 Jun 2015 23:01:35 GMT Content-Type: application/json Content-Length: 6 Connection: keep-alive Server: PrintNodeApi Api-Version: 3.0.0 Request-Id: fdf7904a-71c7-4d6e-b767-ebcc6bbbabdf Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Access-Control-Allow-Methods: * Access-Control-Allow-Headers: Accept, Accept-Version, Api-Version, Authorization, Content-Length, Content-MD5, Content-Type, Date, X-Account, X-Requested-With, X-Pretty, X-Dont-Log, X-Child-Account-By-Id, X-Child-Account-By-Email, X-Child-Account-By-CreatorRef Access-Control-Expose-Headers: Api-Version, Records-Returned, Records-Returned-Limit, Records-Returned-Offset, Records-Total, Request-Id, Response-Time, X-Authorized-As, X-Auth-With, X-Child-Account-By-CreatorRef, X-Child-Account-By-Email, X-Child-Account-By-Id X-Auth-With: ApiKey X-Child-Account-By-Id: 480 X-Authorized-As: 437 X-Account: 480 Content-MD5: uZVMo5kdxzrrKZ33JGgovQ== Response-Time: 8

The response is true for a hard delete and false for a soft delete.

Making API Requests To Child Accounts

A Parent Account can make an API request as if it were being performed by any of your Child Accounts by including an identifying header in your request. An Account can be uniquely identified by its id, email or creatorRef.

The headers which correspond to these identifiers are as follows.

Only one header is required. Choose and submit your header with the header value set to the property value of the Child Accounts you wish to run the API request against.

How this Works

If the API key for the Parent Account is valid and it has a Child Account matching the identifier sent in a X-Child-Account-By-* header it will respond with two informational headers, as follows:

The X-Account response header is returned as usual and gives the Account id of the Child Account. Submitting a X-Child-Account-By-* header which does not specify a valid Child Account will return a HTTP 401 Unauthorised even if the Parent Account API key is valid.

Example Request curl

curl -H "X-Pretty: true" https://api.printnode.com/whoami \ -H 'X-Child-Account-By-Email: ada.lovelace@myfirstprogram.com' \ -u 44784dd8d88be9631046ff83e9044419ff824b10:
curl -H "X-Pretty: true" https://api.printnode.com/whoami \ -H 'X-Child-Account-By-CreatorRef: ada.lovelace' \ -u 44784dd8d88be9631046ff83e9044419ff824b10:
curl -H "X-Pretty: true" https://api.printnode.com/whoami \ -H 'X-Child-Account-By-Id: 480' \ -u 44784dd8d88be9631046ff83e9044419ff824b10:

Response

{ "id": 480, "firstname": "Ada", "lastname": "Lovelace", "email": "ada.lovelace@myfirstprogram.com", "canCreateSubAccounts": false, "creatorEmail": "god@printnode.com", "creatorRef": "ada.lovelace", "childAccounts": [], "credits": null, "numComputers": 0, "totalPrints": 0, "versions": [], "connected": [], "Tags": { "likes": "pianos" }, "ApiKeys": { "production": "fc378c7ebb67f4886334fe38a2c6e7e504256451", "development": "a33d3c3327faf536c8d751e9de3e5595f3c9afd1" }, "state": "active", "permissions": [ "Unrestricted" ] }
HTTP/1.1 200 OK Date: Sun, 28 Jun 2015 23:01:35 GMT Content-Type: application/json Content-Length: 582 Connection: keep-alive Server: PrintNodeApi Api-Version: 3.0.0 Request-Id: 960a2688-5837-4fa4-897f-b1eba2fe152e Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Access-Control-Allow-Methods: * Access-Control-Allow-Headers: Accept, Accept-Version, Api-Version, Authorization, Content-Length, Content-MD5, Content-Type, Date, X-Account, X-Requested-With, X-Pretty, X-Dont-Log, X-Child-Account-By-Id, X-Child-Account-By-Email, X-Child-Account-By-CreatorRef Access-Control-Expose-Headers: Api-Version, Records-Returned, Records-Returned-Limit, Records-Returned-Offset, Records-Total, Request-Id, Response-Time, X-Authorized-As, X-Auth-With, X-Child-Account-By-CreatorRef, X-Child-Account-By-Email, X-Child-Account-By-Id X-Auth-With: ApiKey X-Child-Account-By-Id: 480 X-Authorized-As: 437 X-Account: 480 Content-MD5: vMY0+c9RZ14ZWJvbCmte/Q== Response-Time: 9

Account Management

Tagging

You can attach metadata to any type of PrintNode account using tags. Tags have two parts: a name and a value.

Name String. Max length 64. Alphanumeric, dot, dash and underscore characters only.
Value String. Max length 1024.

To create or update a tag make a POST request to /account/tag/name.

Example Request curl

curl -X POST -H "X-Pretty: true" https://api.printnode.com/account/tag/enjoys \ -H "Content-Type: application/json" \ -u 44784dd8d88be9631046ff83e9044419ff824b10: \ -d '"long walks in the park"'
curl -X POST -H "X-Pretty: true" https://api.printnode.com/account/tag/enjoys \ -H "Content-Type: text/plain" \ -u 44784dd8d88be9631046ff83e9044419ff824b10: \ -d 'long walks in the park'

Response

"created"
HTTP/1.1 201 Created Date: Sun, 28 Jun 2015 23:01:35 GMT Content-Type: application/json Content-Length: 11 Connection: keep-alive Server: PrintNodeApi Api-Version: 3.0.0 Request-Id: 7004ee24-6ca8-49df-ba65-cf2197e3a3c8 Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Access-Control-Allow-Methods: * Access-Control-Allow-Headers: Accept, Accept-Version, Api-Version, Authorization, Content-Length, Content-MD5, Content-Type, Date, X-Account, X-Requested-With, X-Pretty, X-Dont-Log, X-Child-Account-By-Id, X-Child-Account-By-Email, X-Child-Account-By-CreatorRef Access-Control-Expose-Headers: Api-Version, Records-Returned, Records-Returned-Limit, Records-Returned-Offset, Records-Total, Request-Id, Response-Time, X-Authorized-As, X-Auth-With, X-Child-Account-By-CreatorRef, X-Child-Account-By-Email, X-Child-Account-By-Id X-Auth-With: ApiKey X-Account: 433 Content-MD5: JGVRHkmsRdtcb6omc1o/EQ== Response-Time: 6

To get a tag's value make a GET request to /account/tag/name.

Example Request curl

curl -H "X-Pretty: true" https://api.printnode.com/account/tag/enjoys \ -u 44784dd8d88be9631046ff83e9044419ff824b10:

Response

"long walks in the park"
HTTP/1.1 200 OK Date: Sun, 28 Jun 2015 23:01:35 GMT Content-Type: application/json Content-Length: 26 Connection: keep-alive Server: PrintNodeApi Api-Version: 3.0.0 Request-Id: f474e7f3-79a8-4fd6-b7cb-cd982da93b67 Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Access-Control-Allow-Methods: * Access-Control-Allow-Headers: Accept, Accept-Version, Api-Version, Authorization, Content-Length, Content-MD5, Content-Type, Date, X-Account, X-Requested-With, X-Pretty, X-Dont-Log, X-Child-Account-By-Id, X-Child-Account-By-Email, X-Child-Account-By-CreatorRef Access-Control-Expose-Headers: Api-Version, Records-Returned, Records-Returned-Limit, Records-Returned-Offset, Records-Total, Request-Id, Response-Time, X-Authorized-As, X-Auth-With, X-Child-Account-By-CreatorRef, X-Child-Account-By-Email, X-Child-Account-By-Id X-Auth-With: ApiKey X-Account: 433 Content-MD5: ZQBY97Ek9yE+koEjoNd7tQ== Response-Time: 5

To delete a tag make a DELETE request to /account/tag/name.

Example Request curl

curl -X DELETE -H "X-Pretty: true" https://api.printnode.com/account/tag/enjoys \ -u 44784dd8d88be9631046ff83e9044419ff824b10:

Response

true
HTTP/1.1 200 OK Date: Sun, 28 Jun 2015 23:01:35 GMT Content-Type: application/json Content-Length: 6 Connection: keep-alive Server: PrintNodeApi Api-Version: 3.0.0 Request-Id: 96224e93-1d6f-469e-9650-7e715531c450 Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Access-Control-Allow-Methods: * Access-Control-Allow-Headers: Accept, Accept-Version, Api-Version, Authorization, Content-Length, Content-MD5, Content-Type, Date, X-Account, X-Requested-With, X-Pretty, X-Dont-Log, X-Child-Account-By-Id, X-Child-Account-By-Email, X-Child-Account-By-CreatorRef Access-Control-Expose-Headers: Api-Version, Records-Returned, Records-Returned-Limit, Records-Returned-Offset, Records-Total, Request-Id, Response-Time, X-Authorized-As, X-Auth-With, X-Child-Account-By-CreatorRef, X-Child-Account-By-Email, X-Child-Account-By-Id X-Auth-With: ApiKey X-Account: 433 Content-MD5: uZVMo5kdxzrrKZ33JGgovQ== Response-Time: 6

API Keys

You can get, create or delete any Child Account API Keys as follows. You can only perform these actions for your own Account via the web interface.

API Keys have a unique name to identify them. Replace description in the URLs below with an identifier of your own.

To create an API Key make a POST request to /account/apikey/description.

Example Request curl

curl -X POST -H "X-Pretty: true" https://api.printnode.com/account/apikey/description \ -H 'X-Child-Account-By-Id: 480' \ -u 44784dd8d88be9631046ff83e9044419ff824b10:

Response

"bfef945385bb73d4c39c99b3f9c3dab350fced39"
HTTP/1.1 200 OK Date: Sun, 28 Jun 2015 23:01:35 GMT Content-Type: application/json Content-Length: 44 Connection: keep-alive Server: PrintNodeApi Api-Version: 3.0.0 Request-Id: cd9a0f0b-5bb3-4827-b074-70cfeac029a8 Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Access-Control-Allow-Methods: * Access-Control-Allow-Headers: Accept, Accept-Version, Api-Version, Authorization, Content-Length, Content-MD5, Content-Type, Date, X-Account, X-Requested-With, X-Pretty, X-Dont-Log, X-Child-Account-By-Id, X-Child-Account-By-Email, X-Child-Account-By-CreatorRef Access-Control-Expose-Headers: Api-Version, Records-Returned, Records-Returned-Limit, Records-Returned-Offset, Records-Total, Request-Id, Response-Time, X-Authorized-As, X-Auth-With, X-Child-Account-By-CreatorRef, X-Child-Account-By-Email, X-Child-Account-By-Id X-Auth-With: ApiKey X-Child-Account-By-Id: 480 X-Authorized-As: 437 X-Account: 480 Content-MD5: tsgZlJOrjOHYW5IzZkX4ow== Response-Time: 16

To get an API Key from its description make a GET request to /account/apikey/description.

Example Request curl

curl -H "X-Pretty: true" https://api.printnode.com/account/apikey/description \ -H 'X-Child-Account-By-Id: 480' \ -u 44784dd8d88be9631046ff83e9044419ff824b10:

Response

"bfef945385bb73d4c39c99b3f9c3dab350fced39"
HTTP/1.1 200 OK Date: Sun, 28 Jun 2015 23:01:35 GMT Content-Type: application/json Content-Length: 44 Connection: keep-alive Server: PrintNodeApi Api-Version: 3.0.0 Request-Id: 38c1fb53-2f97-4824-aa09-3e0642c39d69 Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Access-Control-Allow-Methods: * Access-Control-Allow-Headers: Accept, Accept-Version, Api-Version, Authorization, Content-Length, Content-MD5, Content-Type, Date, X-Account, X-Requested-With, X-Pretty, X-Dont-Log, X-Child-Account-By-Id, X-Child-Account-By-Email, X-Child-Account-By-CreatorRef Access-Control-Expose-Headers: Api-Version, Records-Returned, Records-Returned-Limit, Records-Returned-Offset, Records-Total, Request-Id, Response-Time, X-Authorized-As, X-Auth-With, X-Child-Account-By-CreatorRef, X-Child-Account-By-Email, X-Child-Account-By-Id X-Auth-With: ApiKey X-Child-Account-By-Id: 480 X-Authorized-As: 437 X-Account: 480 Content-MD5: tsgZlJOrjOHYW5IzZkX4ow== Response-Time: 6

To delete an API Key make a DELETE request to /account/apikey/description.

Example Request curl

curl -X DELETE -H "X-Pretty: true" https://api.printnode.com/account/apikey/description \ -H 'X-Child-Account-By-Id: 480' \ -u 44784dd8d88be9631046ff83e9044419ff824b10:

Response

true
HTTP/1.1 200 OK Date: Sun, 28 Jun 2015 23:01:35 GMT Content-Type: application/json Content-Length: 6 Connection: keep-alive Server: PrintNodeApi Api-Version: 3.0.0 Request-Id: 0cd07144-f2f0-4351-8f9d-068fa29181aa Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Access-Control-Allow-Methods: * Access-Control-Allow-Headers: Accept, Accept-Version, Api-Version, Authorization, Content-Length, Content-MD5, Content-Type, Date, X-Account, X-Requested-With, X-Pretty, X-Dont-Log, X-Child-Account-By-Id, X-Child-Account-By-Email, X-Child-Account-By-CreatorRef Access-Control-Expose-Headers: Api-Version, Records-Returned, Records-Returned-Limit, Records-Returned-Offset, Records-Total, Request-Id, Response-Time, X-Authorized-As, X-Auth-With, X-Child-Account-By-CreatorRef, X-Child-Account-By-Email, X-Child-Account-By-Id X-Auth-With: ApiKey X-Child-Account-By-Id: 480 X-Authorized-As: 437 X-Account: 480 Content-MD5: uZVMo5kdxzrrKZ33JGgovQ== Response-Time: 6

Delegated Client Authentication

If you have a custom branded version of the PrintNode client it can support 3rd party authentication systems. If you implement support for this, and we hope you do, your users can securely authenticate and identify themselves using credentials which aren't provided, managed or ever known by PrintNode.

This can be useful in situations where PrintNode is being used as a component in another system which already has a authentication and identification system. We think this is great user for user experience (one less password to remember and manage) and it provides a really seamless way to integrate with us.

Ok, but how does it all work?

The first time you install and run a PrintNode client it asks for a username and password. The username and password are used to request a Client Key. A Client Key is a 47 character string and is conceptually very similar to an API key. It is used by a client to authenticate and identify all of its communications with PrintNode.

When using Delegated Client Authentication a client requests a Client Key from an API endpoint under your control. You can authenticate and identify the account using the passed username and password however you wish. If the username and password are valid you request a Client Key (for the appropriate PrintNode account) from the PrintNode API and return this to the [originally requesting] client. If the credentials are invalid return a HTTP 401 Unauthorised. Account credentials are never sent to PrintNode and account credentials are not retained or recorded by the client.

The following are required.

Authentication URL specification

Request

Your authentication URL must respond to a HTTPS GET request. The username and password will be encoded in the Authorisation header using standard BasicAuth encoding. We are flexible as to the exact format of the URL so long as we can encode (and you can decode) the following parameters.

  • A client identifier UUID. 36 chars.
  • A version number.
  • A edition name.
By way of an example this could be a request made by the unbranded PrintNode client.

GET https://api.printnode.com/client/key/a6860624-3838-4efd-b918-f4de765cf192?version=4.7.1&edition=printnode

Response

The semantics for the response are essentially the same as the PrintNode API but you don't need to implement everything. Only the following are required.

  • Set a Content-Type: application/json header.
  • Valid JSON responses only.
  • Non HTTP 2xx responses should be in the following format.
  • HTTP 401 responses for unauthorised should contain useful information in the "message" part of the response body. This text is displayed to the user.

One other thing …

In order to get a client key for a PrintNode account it needs to exist, but, there isn't any reason why the trigger for any account creation work required not simply be the client request to your authentication URL. After you've validated credentials check to see if you have created a PrintNode account. If not simply create it and then request a Client Key for the newly created account. Account creation and requesting a Client Key are both fast operations and the delay incurred by making two sequential API requests will be small and will only happen once.

Getting a Client Key From PrintNode

GET /client/key/uuid?edition=edition&version=version

Where uuid, edition and version are the parameters passed by the client to your delegated endpoint.

Example Request curl

curl -H "X-Pretty: true" "https://api.printnode.com/client/key/0a756864-602e-428f-a90b-842dee47f57e?version=4.7.1&edition=printnode" \ -H 'X-Child-Account-By-Id: 480' \ -u 44784dd8d88be9631046ff83e9044419ff824b10:

Response

"ck-Ytkmk4xTKkjgtdXu6iryzjUm9yOgS8zbK/FN4ElvtqtJ"
HTTP/1.1 200 OK Date: Sun, 28 Jun 2015 23:01:35 GMT Content-Type: application/json Content-Length: 51 Connection: keep-alive Server: PrintNodeApi Api-Version: 3.0.0 Request-Id: f94e10ff-cc83-4ab9-8f02-01bd667672c7 Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Access-Control-Allow-Methods: * Access-Control-Allow-Headers: Accept, Accept-Version, Api-Version, Authorization, Content-Length, Content-MD5, Content-Type, Date, X-Account, X-Requested-With, X-Pretty, X-Dont-Log, X-Child-Account-By-Id, X-Child-Account-By-Email, X-Child-Account-By-CreatorRef Access-Control-Expose-Headers: Api-Version, Records-Returned, Records-Returned-Limit, Records-Returned-Offset, Records-Total, Request-Id, Response-Time, X-Authorized-As, X-Auth-With, X-Child-Account-By-CreatorRef, X-Child-Account-By-Email, X-Child-Account-By-Id X-Auth-With: ApiKey X-Child-Account-By-Id: 480 X-Authorized-As: 437 X-Account: 480 Content-MD5: KKdXs2Nf7X3gxwOTEHHRHQ== Response-Time: 10

Managing Client Downloads

The PrintNode client is actively developed and we release new versions with new features and bug fixes regularly. If we are providing you with a custom branded client the latest version will be made available at.

https://app.printnode.com/download/client/edition name/operating system

The currently supported operating systems are osx and windows. We are adding support for Linux. You can may choose your edition name when first provide you a custom branded client.

We strongly recommend that your users download the client directly from PrintNode using this URL. At this time we don't prevent our customers from hosting a custom branded version on their site but doing this has two significant disadvatages.

  • The update checker in your custom branded client will be disabled because the client can't tell what version of the client you are distributing.
  • If a client is released with a bug that doesn't get caught in testing, but, is serious enough we would want to stop distribution, 3rd party hosting would delay this.

Most customers are happy to automatically track the releases of the standard PrintNode client but you may have additional QA requirements or you might wish to pin your customers to a certain version. If this is the case, no problem, the following API endpoints allow you full control over the client download presented at your edition URL.

Getting The Latest Client

Use GET /download/clients/operating system to fetch information about the latest version of the client available for an operating system. PrintNode currently supports the windows and osx operating systems.

Example Request curl

curl -H "X-Pretty: true" https://api.printnode.com/download/client/windows \ -u 44784dd8d88be9631046ff83e9044419ff824b10:

Response

{ "edition": "tyrell", "version": "3.3.0", "os": "windows", "filename": "TyrellCorporation-3.3.0+6c8.exe", "filesize": 14186992, "sha1": "a3b51db935a425b4149f57f58bbd8d9aa42af401", "releaseTimestamp": "2015-06-28T24:29:26.503Z", "url": "https://app.printnode.com/download/client/tyrell/windows" }
HTTP/1.1 200 OK Date: Sun, 28 Jun 2015 23:01:35 GMT Content-Type: application/json Content-Length: 314 Connection: keep-alive Server: PrintNodeApi Api-Version: 3.0.0 Request-Id: 49c0c105-45b4-4a64-a850-d4cb41b845af Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Access-Control-Allow-Methods: * Access-Control-Allow-Headers: Accept, Accept-Version, Api-Version, Authorization, Content-Length, Content-MD5, Content-Type, Date, X-Account, X-Requested-With, X-Pretty, X-Dont-Log, X-Child-Account-By-Id, X-Child-Account-By-Email, X-Child-Account-By-CreatorRef Access-Control-Expose-Headers: Api-Version, Records-Returned, Records-Returned-Limit, Records-Returned-Offset, Records-Total, Request-Id, Response-Time, X-Authorized-As, X-Auth-With, X-Child-Account-By-CreatorRef, X-Child-Account-By-Email, X-Child-Account-By-Id X-Auth-With: ApiKey X-Account: 437 Content-MD5: uqrvMQa06a8huxdIeLW0rw== Response-Time: 6

Getting All Clients

You can get a list of all client versions supported for your account from the following endpoints.

GET /download/clients
GET /download/clients/download id set

Example Request curl

curl -H "X-Pretty: true" https://api.printnode.com/download/clients \ -u 44784dd8d88be9631046ff83e9044419ff824b10:

Response

[ { "id": 18, "enabled": false, "edition": "tyrell", "version": "3.3.0", "os": "osx", "filename": "TyrellCorporation-3.3.0+75d.dmg", "filesize": 14146066, "sha1": "6b024e74492663c0980cb9ab8843ed189605c2da", "releaseTimestamp": "2015-06-28T24:29:26.503Z", "url": "https://app.printnode.com/bundles/printnodemain/downloads/3.3.0/tyrell/TyrellCorporation-3.3.0+75d.dmg" }, { "id": 17, "enabled": true, "edition": "tyrell", "version": "3.3.0", "os": "linux", "filename": "TyrellCorporation-3.3.0+704.deb", "filesize": 14320392, "sha1": "af9aa964bf51d77f27d2089c823eeee86c3cf3b7", "releaseTimestamp": "2015-06-28T24:29:26.503Z", "url": "https://app.printnode.com/bundles/printnodemain/downloads/3.3.0/tyrell/TyrellCorporation-3.3.0+704.deb" }, { "id": 16, "enabled": true, "edition": "tyrell", "version": "3.3.0", "os": "windows", "filename": "TyrellCorporation-3.3.0+6c8.exe", "filesize": 14186992, "sha1": "a3b51db935a425b4149f57f58bbd8d9aa42af401", "releaseTimestamp": "2015-06-28T24:29:26.503Z", "url": "https://app.printnode.com/bundles/printnodemain/downloads/3.3.0/tyrell/TyrellCorporation-3.3.0+6c8.exe" }, { "id": 15, "enabled": true, "edition": "tyrell", "version": "3.2.1", "os": "osx", "filename": "TyrellCorporation-3.2.1+30d.dmg", "filesize": 14963060, "sha1": "13ec5dae73d09d5a5a0685e7dc7e1e17b60b94a6", "releaseTimestamp": "2015-06-28T24:29:26.503Z", "url": "https://app.printnode.com/bundles/printnodemain/downloads/3.2.1/tyrell/TyrellCorporation-3.2.1+30d.dmg" }, { "id": 14, "enabled": true, "edition": "tyrell", "version": "3.2.1", "os": "linux", "filename": "TyrellCorporation-3.2.1+24e.deb", "filesize": 14566899, "sha1": "dbeaad9c460fd1cc42d4f9c079b268b78607f1c1", "releaseTimestamp": "2015-06-28T24:29:26.503Z", "url": "https://app.printnode.com/bundles/printnodemain/downloads/3.2.1/tyrell/TyrellCorporation-3.2.1+24e.deb" }, { "id": 13, "enabled": true, "edition": "tyrell", "version": "3.2.1", "os": "windows", "filename": "TyrellCorporation-3.2.1+7ab.exe", "filesize": 14247315, "sha1": "8b7a000020215d323de897e32c0e81e4e4d25426", "releaseTimestamp": "2015-06-28T24:29:26.503Z", "url": "https://app.printnode.com/bundles/printnodemain/downloads/3.2.1/tyrell/TyrellCorporation-3.2.1+7ab.exe" }, { "id": 12, "enabled": true, "edition": "tyrell", "version": "3.2.0", "os": "osx", "filename": "TyrellCorporation-3.2.0+017.dmg", "filesize": 14115128, "sha1": "6e720fda6f1c1075fa3517f79ec2170c9278423b", "releaseTimestamp": "2015-06-28T24:29:26.503Z", "url": "https://app.printnode.com/bundles/printnodemain/downloads/3.2.0/tyrell/TyrellCorporation-3.2.0+017.dmg" }, { "id": 11, "enabled": true, "edition": "tyrell", "version": "3.2.0", "os": "linux", "filename": "TyrellCorporation-3.2.0+5f6.deb", "filesize": 14841511, "sha1": "59367e2cda38077d9d8b7979ada5548d7f720ae5", "releaseTimestamp": "2015-06-28T24:29:26.503Z", "url": "https://app.printnode.com/bundles/printnodemain/downloads/3.2.0/tyrell/TyrellCorporation-3.2.0+5f6.deb" }, { "id": 10, "enabled": true, "edition": "tyrell", "version": "3.2.0", "os": "windows", "filename": "TyrellCorporation-3.2.0+c22.exe", "filesize": 14701902, "sha1": "add85676165d846cb3840e4aa3ac97fa281284e4", "releaseTimestamp": "2015-06-28T24:29:26.503Z", "url": "https://app.printnode.com/bundles/printnodemain/downloads/3.2.0/tyrell/TyrellCorporation-3.2.0+c22.exe" } ]
HTTP/1.1 200 OK Date: Sun, 28 Jun 2015 23:01:35 GMT Content-Type: application/json Content-Length: 3722 Connection: keep-alive Vary: Accept-Encoding Server: PrintNodeApi Api-Version: 3.0.0 Request-Id: 23f58c2b-b83d-432e-beda-358bdc58e6c5 Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Access-Control-Allow-Methods: * Access-Control-Allow-Headers: Accept, Accept-Version, Api-Version, Authorization, Content-Length, Content-MD5, Content-Type, Date, X-Account, X-Requested-With, X-Pretty, X-Dont-Log, X-Child-Account-By-Id, X-Child-Account-By-Email, X-Child-Account-By-CreatorRef Access-Control-Expose-Headers: Api-Version, Records-Returned, Records-Returned-Limit, Records-Returned-Offset, Records-Total, Request-Id, Response-Time, X-Authorized-As, X-Auth-With, X-Child-Account-By-CreatorRef, X-Child-Account-By-Email, X-Child-Account-By-Id X-Auth-With: ApiKey X-Account: 437 Content-MD5: XWgfgSdlop/Ise/1LN1D7g== Response-Time: 7


Enabling and Disabling Specific Clients

The generic download endpoint at https://app.printnode.com/download/client/edition name/operating system and GET /download/clients/operating system, fetch and fetch information about respectively, the highest versioned client which is enabled for a given operating system. By specifying the enabled state of each individual client downloads PrintNode provides you may control which version is presented at the generic download endpoint.

To enable or disable one or more downloads perform a HTTP PATCH request to /download/clients/download id set with a JSON body as one of {"enabled": true} or {"enabled": false} to enable or disable a download. The return value is a JSON array of the download ids which have been affected.

Example Request curl

curl -H "X-Pretty: true" -X PATCH https://api.printnode.com/download/clients/18 \ -u 44784dd8d88be9631046ff83e9044419ff824b10: \ -H "Content-Type: application/json" \ -d '{"enabled": false}'

Response

[ 18 ]
HTTP/1.1 200 OK Date: Sun, 28 Jun 2015 23:01:35 GMT Content-Type: application/json Content-Length: 10 Connection: keep-alive Server: PrintNodeApi Api-Version: 3.0.0 Request-Id: 1b70cebe-c0df-44a3-9dd7-e764c6050915 Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Access-Control-Allow-Methods: * Access-Control-Allow-Headers: Accept, Accept-Version, Api-Version, Authorization, Content-Length, Content-MD5, Content-Type, Date, X-Account, X-Requested-With, X-Pretty, X-Dont-Log, X-Child-Account-By-Id, X-Child-Account-By-Email, X-Child-Account-By-CreatorRef Access-Control-Expose-Headers: Api-Version, Records-Returned, Records-Returned-Limit, Records-Returned-Offset, Records-Total, Request-Id, Response-Time, X-Authorized-As, X-Auth-With, X-Child-Account-By-CreatorRef, X-Child-Account-By-Email, X-Child-Account-By-Id X-Auth-With: ApiKey X-Account: 437 Content-MD5: ijeMl/Zcy9T8Q5M2mJ4kzw== Response-Time: 7