How to Use the Internet Printing Protocol

Version 2018.0430

by Michael R Sweet, Peter Zehler

Copyright © 2017-2018 by The Printer Working Group

Table of Contents

Chapter 1: Introduction

What is IPP?

The Internet Printing Protocol ("IPP") is a secure application level protocol used for network printing. The protocol allows a Client to inquire about capabilities of and defaults for a Printer (supported media sizes, two-sided printing, etc.), inquire about the state of the Printer (paper out/jam, low ink/toner, etc.), submit files for printing, and inquire about and/or cancel submitted print Jobs. IPP is supported by all modern network printers and replaces all legacy network protocols including port 9100 printing and LPD/lpr.

IPP is widely implemented in software as well, including the following open source projects:

IPP Overview

The IPP architecture defines an abstract, hierarchical data model that provides information about the printing process and the print jobs and capabilities of the printer. It also defines operations with common semantics (business logic) for working with the objects in this data model. Because the semantics of IPP are followed by all printers, the client (software) does not need to know the internal details of the printer (hardware).

IPP uses HTTP as its transport protocol. Each IPP request is a HTTP POST with an IPP message (and print file, if any) in the request message body. The corresponding IPP response is returned in the POST response message body. The IPP message itself uses a simple binary encoding that is described in the next section. HTTP connections can be unencrypted, upgraded to TLS encryption using an HTTP OPTIONS request, or encrypted immediately (HTTPS). HTTP POST requests can also be authenticated using any of the usual HTTP mechanisms like Basic (username and password).

Note: Legacy network protocols do not support authentication, authorization, or privacy (encryption).

Printers are identified using Universal Resource Identifiers ("URIs") with the "ipp" or "ipps" scheme, for example:

ipp://printer.example.com/ipp/print
ipps://printer2.example.com:443/ipp/print
ipps://server.example.com/ipp/print/printer3

These are mapped to "http" and "https" URLs, with a default port number of 631 for IPP. For example, the previous IPP URIs would be mapped to:

http://printer.example.com:631/ipp/print
https://printer2.example.com/ipp/print
https://server.example.com:631/ipp/print/printer3

The resource path "/ipp/print" is commonly used by IPP printers, however there is no hard requirement to follow that convention and older IPP printers used a variety of different locations. Consult your printer documentation or the printer's Bonjour registration information to determine the proper hostname, port number, and path to use for your printer.

Print jobs are identified using the printer's URI and a job number that is unique to that printer.

IPP Message Encoding

IPP messages use a common format for both requests (from the client to the printer) and responses (from the printer to the client). Each IPP message starts with a version number (2.0 is the most common), an operation (request) or status (response) code, a request number, and a list of attributes. Attributes are named and have strongly typed values such as:

Attributes are also placed in groups according to their usage - the operation group for attributes used for the operation request or response, the job group for print job attributes, and so forth.

The first two attributes in an IPP message are always "attributes-charset", which defines the character set to use for all name and text strings, and "attributes-natural-language", which defines the default language ("en" for English, "fr" for French, "ja" for Japanese, etc.) for those strings.

The next attributes in a request are the printer's URI ("printer-uri") and, if the request is targeting a print job, the job's ID number ("job-id").

Most requests include the name of the user that is submitting the request ("requesting-user-name").

A request containing an attached print file includes the MIME media type for the file ("document-format"). The media type is 'text/plain' for text files, 'image/jpeg' for JPEG files, 'application/pdf' for PDF files, etc.

The following example encodes a Print-Job request using the ipptool test file format:

{
    VERSION 2.0
    OPERATION Print-Job
    REQUEST-ID 42

    GROUP operation-attributes-tag
    ATTR charset "attributes-charset" "utf-8"
    ATTR naturalLanguage "attributes-natural-language" "en"
    ATTR uri "printer-uri" "ipp://printer.example.com/ipp/print"
    ATTR name "requesting-user-name" "John Doe"
    ATTR mimeMediaType "document-format" "text/plain"

    FILE "testfile.txt"
}

The same request using the CUPS API would look like the following:

#include <cups/cups.h>

...

http_t *http;
ipp_t *request, *response;

http = httpConnect2("printer.example.com", 631, NULL, AF_UNSPEC, HTTP_ENCRYPTION_IF_REQUESTED, 1, 30000, NULL);

request = ippNewRequest(IPP_OP_PRINT_JOB);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, "ipp://printer.example.com/ipp/print");
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, "John Doe");
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format", NULL, "text/plain");

response = cupsDoFileRequest(http, request, "/ipp/print", "testfile.txt");

ipp_attribute_t *attr;
const char *name;
char value[2048];

for (attr = ippFirstAttribute(response); attr; attr = ippNextAttribute(response))
{
  name = ippGetName(attr);

  if (name)
  {
    ippAttributeString(attr, name, sizeof(name));
    printf("%s=%s\n", name, value);
  }
}

And this is how you'd send a Print-Job request using the nodejs API:

var ipp = require("ipp");
var printer = ipp.Printer("http://printer.example.com:631/ipp/print");
var fs = require("fs");
var document;

fs.readFile("testfile.txt", function(err, data) {
  if (err) throw err;

  document = data;
});

var msg = {
  "operation-attributes-tag": {
    "requesting-user-name": "John Doe",
    "document-format": "text/plain"
  },
  data: document;
};

printer.execute("Print-Job", msg, function(err, res) {
        console.log(err);
        console.log(res);
});

The response message uses the same version number, request number, character set, and natural language values as the request. A status code replaces the operation code in the initial message header - for the Print-Job operation the printer will return the 'successful-ok' status code if the print request is successful or 'server-error-printer-busy' if the printer is busy and wants you to try again at a later time.

The character set and natural language values in the response are followed by operation-specific attributes. For example, the Print-Job operation returns the print job identifier ("job-id") and state ("job-state" and "job-state-reasons") attributes.

You can learn more about the IPP message encoding by reading the Internet Printing Protocol/1.1: Encoding and Transport document.

Operations

There are literally dozens of operations defined for IPP. The following are the most commonly used and are described in the following chapters:

Clients typically use the Create-Job and Send-Document operations to submit files for printing so that these print jobs can be canceled while the document data is being transferred to the printer.

Summary

IPP is a widely implemented and secure application level protocol used for network printing. IPP defines an abstract model for printing that allows a generic client application to communicate with any type of printer. IPP uses HTTP or HTTPS POST requests with binary encoded messages to perform a variety of printing functions. IPP supports multiple languages and file formats.

Chapter 2: Printers

What are Printers?

Printers in IPP are an abstract object that represents a real printer, a collection of printers, or a virtual output device (for saving/emailing/publishing PDFs, etc.)

Printers provide attributes that describe the status of the printer (it is printing something, has it run out of paper, etc.), the capabilities of the printer (what paper sizes are supported, can the printer reproduce color, can the printer staple the output, etc.), and general information about the printer (where the printer is located, the URL for the printer's administrative web page, etc.)

Printers also manage one or more queued print jobs and provide a history of jobs that have been printed.

Printer Status Attributes

Printers provide two main status attributes: "printer-state" and "printer-state-reasons". The "printer-state" attribute is a number that describes the general state of the printer:

The "printer-state-reasons" attribute is a list of strings that provide details about the printer's state:

The strings may also have a severity suffix ("-error", "-warning", or "-report") to tell the client whether the reason prevents the printer from printing a job.

Note: The IANA IPP registry lists all of the registered strings for the "printer-state-reasons" attribute.

Many printers also provide status attributes for alerts ("printer-alert"), consumables ("printer-supply", "printer-supply-description", and "printer-supply-info-uri"), input trays ("printer-input-tray"), output trays ("printer-output-tray"), and so forth.

Printer Description Attributes

Printers provide seven main description attributes: "printer-uri-supported", "uri-authentication-supported", "uri-security-supported", "printer-info", "printer-more-info", "printer-location", and "printer-geo-location".

The "printer-uri-supported" attribute lists the supported printer URI values. The "uri-authentication-supported" attribute lists the authorization and access control requirements for each of the supported printer URI values. Similarly, the "uri-security-supported" attribute lists the encryption requirements for each of the supported printer URI values.

The "printer-info" attribute provides a textual description of the printer and often defaults to the make and model of the printer. The "printer-more-info" attribute provides a URL to the printer's administrative web page.

The "printer-location" attribute provides a textual location of the printer, for example 'Second floor near the break room.'. The "printer-geo-location" attribute provides the GPS location of the printer, if known.

Printer Capability Attributes

Printers provide many capability attributes, including:

Querying the Printer Attributes

The Get-Printer-Attributes operation is used to query any of the printer attributes mentioned previously. The following ipptool test will report the current printer attribute values:

{
    VERSION 2.0
    OPERATION Get-Printer-Attributes

    GROUP operation-attributes-tag
    ATTR charset "attributes-charset" "utf-8"
    ATTR naturalLanguage "attributes-natural-language" "en"
    ATTR uri "printer-uri" "ipp://printer.example.com/ipp/print"
    ATTR name "requesting-user-name" "John Doe"
}

The same request using the CUPS API would look like the following:

#include <cups/cups.h>

...

http_t *http;
ipp_t *request, *response;

http = httpConnect2("printer.example.com", 631, NULL, AF_UNSPEC, HTTP_ENCRYPTION_IF_REQUESTED, 1, 30000, NULL);

request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, "ipp://printer.example.com/ipp/print");
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, "John Doe");

response = cupsDoRequest(http, request, "/ipp/print");

ipp_attribute_t *attr;
const char *name;
char value[2048];

for (attr = ippFirstAttribute(response); attr; attr = ippNextAttribute(response))
{
  name = ippGetName(attr);

  if (name)
  {
    ippAttributeString(attr, name, sizeof(name));
    printf("%s=%s\n", name, value);
  }
}

And this is how you'd query a printer using the nodejs API:

var ipp = require("ipp");
var printer = ipp.Printer("http://printer.example.com:631/ipp/print");

var msg = {
  "operation-attributes-tag": {
    "requesting-user-name": "John Doe",
  }
};

printer.execute("Get-Printer-Attributes", msg, function(err, res) {
        console.log(err);
        console.log(res);
});

Summary

IPP printers track the state, capabilities, administrative information, and print jobs of one or more real or virtual printers. IPP printers provide many attributes which are queried using the Get-Printer-Attributes request.

Chapter 3: Print Jobs

What are Print Jobs?

Print jobs in IPP are an abstract object that represents work to be done by a printer - typically printing or faxing a document.

Print jobs provide attributes that describe the status of the job (pending, held for some reason, printing, completed, etc.), general information about the job (the job's owner, name, submission time, etc.) the job ticket (print options), and the job receipt (what print options were used, how many pages were printed, when the job was printed, etc.)

Print jobs contain zero or more documents that are processed (printed, faxed, etc.) as a single work item, although most printers only support a single document per job so the multiple-document capability of IPP is rarely used.

Note: A print job with no documents cannot be processed and will (eventually) be aborted so that other jobs can be processed.

Job Status Attributes

Jobs provide five main status attributes: "job-id", "job-originating-user-name", "job-printer-uri", "job-state", and "job-state-reasons". The "job-id" and "job-printer-uri" attributes provide an identifying (integer) number and the printer that will be processing the job. The "job-originating-user-name" attribute provides the name of the submitter, e.g., "Bob Smith". The "job-originating-user-name" and "job-printer-uri" attributes are provided in the job creation request (Create-Job or Print-Job), while the printer generates a unique "job-id" for each job, starting at 1.

The "job-state" attribute is a number that describes the general state of the job:

The "job-state-reasons" attribute is a list of strings that provide details about the job's state:

Note: The IANA IPP registry lists all of the registered strings for the "job-state-reasons" attribute.

Page counts are recorded in the following attributes:

Some printers also record a read-only job receipt in attributes named "xxx-actual" for each job template attribute, for example "copies-actual", "media-actual", and so forth.

Job Description Attributes

Jobs provide many descriptive attributes, including the job's name ("job-name") and page counts ("job-impressions", "job-media-sheets", and "job-pages") which are provided in the job creation request (Create-Job or Print-Job).

Job Template Attributes

Job template attributes tell the printer how you want the document(s) printed. Clients can query the printer capability attributes to get the supported values. The following is a list of commonly-supported job template attributes:

Documents

Printers report the list of document formats they support in the "document-format" printer capability attribute. Most IPP printers support standard formats like PDF ('application/pdf'), PWG Raster ('image/pwg-raster'), and JPEG (image/jpeg). AirPrint printers also support a simple raster format called Apple Raster ('image/urf').

Many IPP printers also support legacy formats such as Adobe PostScript ('application/postscript'), and HP Page Control Language (PCL, 'application/vnd.hp-pcl'), along with a variety of vendor-specific languages.

The 'application/octet-stream' document format is used to tell the printer it should automatically detect the format. Detection accuracy varies widely between printers, so you should specify the actual format whenever possible.

Submitting Print Jobs

There are two ways to submit a print job:

The Print-Job Operation

The Print-Job operation allows you to create a print job and send the document data in one request. While all IPP printers support this operation, using it means that you cannot reliably cancel the job while it is being submitted, and for many document formats this means that the entire job will be printed before you get the response to the request.

The following ipptool test will submit a US Letter print job using the Print-Job operation:

{
    VERSION 2.0
    OPERATION Print-Job

    GROUP operation-attributes-tag
    ATTR charset "attributes-charset" "utf-8"
    ATTR naturalLanguage "attributes-natural-language" "en"
    ATTR uri "printer-uri" "ipp://printer.example.com/ipp/print"
    ATTR name "requesting-user-name" "John Doe"
    ATTR mimeMediaType "document-format" "$filetype"

    GROUP job-attributes-tag
    ATTR keyword media "na_letter_8.5x11in"

    FILE $filename
}

The same request using the CUPS API would look like the following:

#include <cups/cups.h>

...

const char *filename;
const char *filetype;
http_t *http;
ipp_t *request;

http = httpConnect2("printer.example.com", 631, NULL, AF_UNSPEC, HTTP_ENCRYPTION_IF_REQUESTED, 1, 30000, NULL);

request = ippNewRequest(IPP_OP_PRINT_JOB);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, "ipp://printer.example.com/ipp/print");
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, "John Doe");
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format", NULL, filetype);

ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, "media", NULL, "na_letter_8.5x11in");

ippDelete(cupsDoFileRequest(http, request, "/ipp/print", filename));

And this is how you'd print a job using the nodejs API:

var ipp = require("ipp");
var fs = require("fs");
var printer = ipp.Printer("http://printer.example.com:631/ipp/print");
var filename;
var filetype;

var filedata = "";
fs.readFile(filename, function(err,data) {
  filedata = data;
}

var msg = {
  "operation-attributes-tag": {
    "requesting-user-name": "John Doe",
    "document-format": filetype
  },
  "job-attributes-tag": {
    "media": "na_letter_8.5x11in"
  },
  data: filedata
};

printer.execute("Print-Job", msg, function(err, res) {
        console.log(err);
        console.log(res);
});

The Create-Job and Send-Document Operations

The Create-Job and Send-Document operations split the job submission into two steps. You first send a Create-Job request with your job template attributes, and the printer will return a "job-id" value to identify the new job you've just created. You then send a Send-Document request with your document data to complete the job submission. If you want to stop the job while sending the document data, you can open a separate connection to the printer and send a Cancel-Job request using the "job-id" value you got from the Create-Job request.

The following ipptool test will submit a US Letter print job using the Create-Job and Send-Document operations:

{
    VERSION 2.0
    OPERATION Create-Job

    GROUP operation-attributes-tag
    ATTR charset "attributes-charset" "utf-8"
    ATTR naturalLanguage "attributes-natural-language" "en"
    ATTR uri "printer-uri" "ipp://printer.example.com/ipp/print"
    ATTR name "requesting-user-name" "John Doe"

    GROUP job-attributes-tag
    ATTR keyword media "na_letter_8.5x11in"

    EXPECT job-id OF-TYPE integer
}

{
    VERSION 2.0
    OPERATION Send-Document

    GROUP operation-attributes-tag
    ATTR charset "attributes-charset" "utf-8"
    ATTR naturalLanguage "attributes-natural-language" "en"
    ATTR uri "printer-uri" "ipp://printer.example.com/ipp/print"
    ATTR integer "job-id" $job-id
    ATTR name "requesting-user-name" "John Doe"
    ATTR mimeMediaType "document-format" "$filetype"
    ATTR boolean "last-document" true

    FILE $filename
}

The same request using the CUPS API would look like the following:

#include <cups/cups.h>

...

const char *filename;
const char *filetype;
http_t *http;
ipp_t *request, *response;

http = httpConnect2("printer.example.com", 631, NULL, AF_UNSPEC, HTTP_ENCRYPTION_IF_REQUESTED, 1, 30000, NULL);

request = ippNewRequest(IPP_OP_CREATE_JOB);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, "ipp://printer.example.com/ipp/print");
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, "John Doe");

ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, "media", NULL, "na_letter_8.5x11in");

response = cupsDoFileRequest(http, request, "/ipp/print", filename);

int job_id = ippGetInteger(ippFindAttribute(response, "job-id", IPP_TAG_INTEGER), 0);

ippDelete(response);

request = ippNewRequest(IPP_OP_SEND_DOCUMENT);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, "ipp://printer.example.com/ipp/print");
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", job_id);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, "John Doe");
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format", NULL, filetype);

ippDelete(cupsDoFileRequest(http, request, "/ipp/print", filename));

And this is how you'd print a job using the nodejs API:

var ipp = require("ipp");
var fs = require("fs");
var printer = ipp.Printer("http://printer.example.com:631/ipp/print");
var filename;
var filetype;

var filedata = "";
fs.readFile(filename, function(err,data) {
  filedata = data;
}

var create_msg = {
  "operation-attributes-tag": {
    "requesting-user-name": "John Doe"
  },
  "job-attributes-tag": {
    "media": "na_letter_8.5x11in"
  }
};

var job_id = 0;

printer.execute("Create-Job", msg, function(err, res) {
        console.log(err);
        console.log(res);

	job_id = res["job-id"];
});

var send_msg = {
  "operation-attributes-tag": {
    "job-id": job_id,
    "requesting-user-name": "John Doe",
    "document-format": filetype
  },
  data: filedata
};

printer.execute("Send-Document", msg, function(err, res) {
        console.log(err);
        console.log(res);
});

Summary

IPP print jobs track the state and options of an individual document that has been submitted for printing. IPP supports a wide range of printing options using job template attributes. IPP provides two ways to submit print jobs.

Appendix A: Quick Reference

Common Operations

The following table lists the common IPP operations (all defined in RFC 8011) and the commonly-used attributes. Each request always starts with the following three attributes:

Note: The syntax uses the standard IPP data types. Except for Job attributes, all attributes are in the operation group. The "document-format" attribute is optional for the Get-Printer-Attributes operation but highly recommended.

Operation Required Attributes (syntax) Optional Attributes (syntax)
Cancel-Job job-id (integer), requesting-user-name (name)
Create-Job requesting-user-name (name), job-name (name) Job Attributes
Get-Job-Attributes job-id (integer), requesting-user-name (name) requested-attributes (1setOf keyword)
Get-Jobs requesting-user-name (name) my-jobs (boolean), requested-attributes (1setOf keyword), which-jobs (keyword)
Get-Printer-Attributes document-format (mimeMediaType), requested-attributes (1setOf keyword)
Print-Job requesting-user-name (name), job-name (name) Job Attributes
Send-Document job-id (integer), requesting-user-name (name) document-format (mimeMediaType), document-name (name)

Common Document Formats

The "document-format" attribute specifies the format of a print file. The following is a list of common formats used for printing:

Common Job Attributes

The following table lists the common Job attributes that are supported by most IPP printers in the Create-Job and Print-Job operations. You can query the corresponding Printer attributes using the Get-Printer-Attributes operation, just remember to send a "document-format (mimeMediaType)" attribute to get the values for the file format you are using.

Note: The syntax uses the standard IPP data types. A "1setOf something" is an array of one or more values. The "finishings-ready" and "media-ready" Printer attributes should be used when available, otherwise use the "finishings-supported" and "media-supported" attributes. Similarly, the "finishings-col-ready" and "media-col-ready" Printer attributes should be used when available, otherwise use the "finishings-col-database" and "media-col-database" attributes.

Job Attribute (syntax) Printer Attribute (Syntax) Standard
copies (integer) copies-supported (integer) RFC 8011
finishings (1setOf enum) finishings-ready (1setOf enum) PWG 5100.1
finishings-col (1setOf collection) finishings-col-ready (1setOf collection) PWG 5100.1
media (keyword) media-ready (1setOf keyword) RFC 8011
media-col (collection) media-col-ready (1setOf collection) PWG 5100.3
output-bin (keyword) output-bin-supported (1setOf keyword) PWG 5100.2
page-ranges (rangeOfInteger) page-ranges-supported (boolean) RFC 8011
print-color-mode (keyword) print-color-mode-supported (1setOf keyword) PWG 5100.13
print-quality (enum) print-quality-supported (1setOf enum) RFC 8011
print-scaling (keyword) print-scaling-supported (1setOf keyword) PWG 5100.13
printer-resolution (resolution) printer-resolution-supported (1setOf resolution) RFC 8011
sides (keyword) sides-supported (1setOf keyword) RFC 8011

Common Printer Attributes

The following table lists the common Printer attributes that are supported by most IPP printers. You can query them using the Get-Printer-Attributes operation.

Note: The syntax uses the standard IPP data types. A "1setOf something" is an array of one or more values.

Printer Attribute (Syntax) Standard
document-format-supported (1setOf mimeMediaType) RFC 8011
ipp-features-supported (1setOf keyword) PWG 5100.13
ipp-versions-supported (1setOf keyword) RFC 8011
job-creation-attributes-supported (1setOf keyword) PWG 5100.11
operations-supported (1setOf enum) RFC 8011
printer-alert (1setOf octetString) PWG 5100.9
printer-alert-description (1setOf text) PWG 5100.9
printer-geo-location (uri) PWG 5100.13
printer-info (text) RFC 8011
printer-input-tray (1setOf octetString) PWG 5100.13
printer-is-accepting-jobs (boolean) RFC 8011
printer-location (text) RFC 8011
printer-make-and-model (text) RFC 8011
printer-more-info (uri) RFC 8011
printer-name (name) RFC 8011
printer-output-tray (1setOf octetString) PWG 5100.13
printer-state (enum) RFC 8011
printer-state-reasons (1setOf keyword) RFC 8011
printer-strings-languages-supported (1setOf naturalLanguage) PWG 5100.13
printer-strings-uri (uri) PWG 5100.13
printer-supply (1setOf octetString) PWG 5100.13
printer-supply-description (1setOf text) PWG 5100.13
printer-supply-info-uri (uri) PWG 5100.13
printer-uri-supported (1setOf uri) RFC 8011
pwg-raster-document-resolution-supported (1setOf resolution) PWG 5102.4
pwg-raster-document-sheet-back (keyword) PWG 5102.4
pwg-raster-document-type-supported (1setOf keyword) PWG 5102.4
uri-authentication-supported (1setOf keyword) RFC 8011
uri-security-supported (1setOf keyword) RFC 8011

Standards

The IANA IPP Registry provides a list of all IPP attributes, values, operations, and status codes with links to the corresponding standards.

These are the core Internet Printing Protocol standards:

These are the standards for media naming and the common file formats:

These are the Internet Printing Protocol standards that define how to support specific printer features: