Top Tips for using the Public Web Services API


The PaperCut public API is super handy for a lot of different things, from the simple to the complex. This post provides some hints and tips to help you get the most from the API.

Before going any further you should read the API Overview. This post mainly expands on the overview material and calls out specific topics that we have been asked about before.

What can you do with the API?

The functionality in the API is broad and covers things such as:

  • Managing users, shared account, groups and printers. It includes things such as updating user’s account balance.
  • Adding jobs details from a third party system
  • Managing admin users
  • Getting and settings advanced config settings
  • Starting import jobs

Starting out with server-command

The easiest way to use the API is to use theserver-command program from a script. This examples use the Bash shell as the script engine. If you are using Windows you will either need to install the Windows 10 Linux subsystem, Cygwin or convert the script to a Windows batch file (more on how to support Windows in the resources links below).

Let’s start with an example. This script will swap the primary and secondary card numbers for every user in the PaperCut database.

server-command list-user-accounts | while read x;do
  primary=$(server-command get-user-property $x "secondary-card-number")
  secondary=$(server-command get-user-property $x "primary-card-number")
  server-command set-user-property $x "primary-card-number" "$primary"
  server-command set-user-property $x "secondary-card-number" "$secondary"

There are a number of things to note:

  1. The serve command utility can only be run on the PaperCut application server
  2. The path to the program is [app dir]/server/bin/<platform>/server-command. Obviously you will need to select the correct path for you server platform
  3. The server command will perform one command (API call) at a time. If you are performing very large bulk updates you may find this slow
  4. The program does not return error codes in an expected fashion because of the several types of errors that can occur. You will need to parse the text output

The example above, and others, can be found on the PaperCut Examples repository. Additional examples can also be found on the PaperCut MF/NG server [app dir]/server/examples/scripting

So let’s briefly look at the example script above in more detail. I suggest that you open up a command shell (cmd.exe on Windows) and try these out for yourself. Just make sure that server command is on your path.

So the first call is to get a list of the users (internal and external) in PaperCut. When I run this command on my test system I get this

$ server-command list-user-accounts

The next few commands just get repeated for each user (that’s the magic while read... bit).

When we have each user name we can a) read both card numbers from the database with get-user-property and then b) write them back to the database with set-user-property command.

So for instance

$ server-command get-user-property alec primary-card-number

More information about server-command here.

Using the API

If you want to use the API across the network or incorporate API calls into something larger then you will need to use the API directly. The following discussion assumes you have read the overview and I will also refer you to other documentation to read as we progress.

The following code examples are in Python 3. This is a common language and should provide easy to understand fragments that you can translate into your preferred programming language.

We also provide examples in C#, Ruby, PHP and Java (on your PaperCut server go to [app dir]/server/examples/webservices/). On our GitHub repo you can also find a Perl example contributed by @Joffcom (more contributions always welcome).


All the method calls use XML-RPC as the transport mechanism. You can find more details about XML-RPC here.

If you are new to XML-RPC programming you might this blog post useful.

However generally you don’t need to worry about the protocol details as that is handled by a library. Python 3 provides the xmlrpc library (Python 2 uses xmlrpclib). Please look in the example code for suggestions of libraries you can use. If you are using Go then consider using the gorilla-xmlrpc library. Otherwise Google is your friend.

So using Python 3 as our example, at the top of you script put import xmlrpc.client.


Pay special attention to the section on security in the overview.

The authentication token (required on each method call) should be defined in the advanced config key auth.webservices.auth-token. This is because:

  • Using the admin password could be a security risk if the password leaks
  • It’s possible to define a very large random secret in the auth.webservices.auth-token config key which would be secure, but not suitable as an admin password.
  • Using the admin password is also approximately 10 time slower because the auth token must be processed on each call.

In addition the IP white list can be set in the Admin GUI or via setting the auth.webservices.allowed-addresses advanced config key, which you can do via the server-command utility or API.

Another security consideration is the use of end-to-end encryption via the use of a Transport Layer Security(TLS). This allows for the data to be securely passed from client to server - meaning you can pass your auth.webservices.auth-token to the PaperCut servers without having it exposed to the internet.

An example of how to do this in Python:

from ssl import create_default_context, Purpose

# Prefer HTTPS connection
host="https://localhost:9192/rpc/api/xmlrpc" # If not localhost then this address will need to be whitelisted in PaperCut
auth="token"  # Value defined in advanced config property "auth.webservices.auth-token". Should be random

proxy = xmlrpc.client.ServerProxy(host, verbose=False,
      context = create_default_context(Purpose.CLIENT_AUTH))

You can now make API calls through the proxy instance.

Making API calls

Before making API calls it’s usual to set up values. In addition most XML-RPC libraries require you to set up some library object for later calls. In Python this looks like

#!/usr/bin/env python3

import xmlrpc.client

# If not localhost then this address will need to be whitelisted in PaperCut

# Value defined in advanced config property "auth.webservices.auth-token". Should be random

proxy = xmlrpc.client.ServerProxy(host)

You can now make method calls. For example


if not proxy.api.isUserExists(auth, user):
  print("Can't find user {}".format(user)

Notice the parameter auth, which must be provided in every API call.

The API overview does not provide enough detail on each API (specific parameters and types) and developers will need to refer to the detailed documentation installed on the PaperCut MF/NG server at [app dir]/server/examples/webservices/java/docs/api/index.html. Note that this Javadoc does not provide any information about the requirement to add the auth token as the first method parameter to every call.


  • You get the error “ERROR: java.lang.NoSuchMethodException:": Usually you have either:
  1. Forgotten to add the auth token parameter,
  2. Misspelled the method name,
  3. Provided the wrong number of parameters or
  4. At least one parameter is the wrong type. For instance supplying an integer when a double float type is required.
  • You are getting an error message about the client IP address not being whitelisted, even though you added in PaperCut.

Often your network or IT infrastructure is mangling the IP address in some fashion. Look in the PaperCut server log to see the IP address that PaperCut is seeing — look for the string BaseXMLRPCServlet

  • You have checked everything in your code and it’s still not working.
  1. Check the PaperCut server log — look for the string BaseXMLRPCServlet
  2. Double check your XML content, including the case of XML element names. For instance it’s <methodName>, not <methodname>
  3. Do some low level XML-RPC debugging
    • Install Curl (on a MacOS and Linux it’s already installed)
    • Optionally set up an access token (advanced config key auth.webservices.auth-token)
    • Create an XML data file with your API call paramters with the content of your method call. For instance
<?xml version="1.0"?>
  • Run a command similar to
curl -v  -H "content-type:text/xml"   http://<servername>:9191/rpc/api/xmlrpc --data @file.xml

and check the output.

Some partners have reported success in using Postman as a debugging tool as well.

Proxy Wrappers

The Python example above uses an XML-RPC library and the application programmer makes direct calls on the network API to connect to the PaperCut server. For certain languages (Java and C#) we have created example proxy wrappers around the network code.

In this case PaperCut have provided classes that implement each API call. The developer just makes a method call and the proxy class handles the marshalling and unmarshaling of the network calls.

Please note that the example proxy classes are often not up to date with the latest API changes. If you notice any omissions please let us know at <>

You can find the proxy wrapper examples on the PaperCut MF/NG server:

  • Java: [app dir]/server/examples/webservices/java/
  • C#: [app dir]/server/examples/webservices/csharp/ServerCommandProxy.cs

More Resources

  1. Email Group —!forum/papercut-webservices-api
  2. More information about PaperCut APIs in general —
  3. Online chat forum —
  4. Integrating the C# proxy wrapper into Windows PowerShell —
  5. Advanced Technical Notes on using getTaskStatus()

Categories: How-to Articles, Scripting and APIs

Keywords: API