.. /* * This file is part of the SavaPage project . * Copyright (c) 2026 Datraverse B.V. * Author: Rijk Ravestein. * * SPDX-FileCopyrightText: (c) 2020 Datraverse B.V. * SPDX-License-Identifier: CC-BY-SA-4.0 * * For more information, please contact Datraverse B.V. at this * address: info@datraverse.com */ .. _app-tools-webservices: Web Services ------------ .. contents:: |RST_TABLE_OF_CONTENTS| :depth: 1 :local: .. _app-tools-webservices-intro: Introduction ~~~~~~~~~~~~ SavaPage uses `XML-RPC `__, `JSON-RPC `__ and `RESTful API `__ for its public Web Services. Both protocols are Open Standard, lightweight and have support for all major programming and scripting languages. .. note:: :ref:`Rate Limiting ` is applied to unauthorized access and invalid requests. .. note:: The range of Web Services will grow upon request. Please tell us if you need extra methods. .. _app-tools-xmlrpc: XML-RPC ~~~~~~~ .. contents:: :depth: 1 :local: The secure endpoint is: ``https://savapage:8632/xmlrpc/v1`` .. _xmlrpc_onetime-auth_createToken: onetime-auth.createToken ^^^^^^^^^^^^^^^^^^^^^^^^ With this method a Trusted Third Party (TTP) acquires a one-time token for Web App user authentication. The requesting User Name and returned Token must be offered to the Web App by hidden HTTP POST input names ``auth_user`` and ``auth_token``. The Web App decrypts the token and honours the authentication request if the offered and encrypted Users match and the token is not expired. .. list-table:: XML-RPC method: onetime-auth.createToken :width: 100% :header-rows: 1 * - - Name - Type - Description * - Parameters - apikey - string - The TTP API key as set in the ``web-login.ttp.apikey`` configuration property. * - - username - string - | The User Name to authenticate. See :ref:`Login `. | :ref:`User Alias ` mapping is applied. * - Returns - token - string - | The one-time authentication token holding the | encrypted User Name and token creation time. | | The expiration criterion in milliseconds is set in the | ``web-login.ttp.token.expiry-msecs`` configuration property. .. note:: This method is used by `moodle-block_savapage `__. .. important:: TTP Web App Login authentication must be enabled by setting the ``web-login.ttp.enable`` configuration property to ``Y``. See |RST_LINK_CONFIG_EDITOR| on how to set the configuration properties ``web-login.ttp.enable``, ``web-login.ttp.apikey`` and ``web-login.ttp.token.expiry-msecs``. .. code-block:: xml :caption: sample request.xml onetime-auth.createToken your-apikey a-userid .. code-block:: bash :caption: sample request curl -k -H "content-type:text/xml" https://savapage:8632/xmlrpc/v1 --data @request.xml .. code-block:: xml :caption: sample response the-onetime-token .. code-block:: html :caption: sample html
.. _app-tools-jsonrpc: JSON-RPC ~~~~~~~~ .. contents:: :depth: 1 :local: .. _app-tools-jsonrpc-intro: Introduction ^^^^^^^^^^^^ The secure endpoint is: ``https://savapage:8632/jsonrpc/v1`` The following configuration properties apply: .. list-table:: JSON-RPC Configuration Properties :width: 100% :header-rows: 1 * - Configuration property - Description * - api.jsonrpc.secret-key - The secret key to be passed as ``X-Auth-Key`` HTTP header. * - api.jsonrpc.ext.ip-addresses-allowed - A :ref:`CIDR Set ` of allowed client IPv4 and/or IPv6 addresses. When void access is denied for *all* clients. See |RST_LINK_CONFIG_EDITOR| on how to set these items. The sections below discuss the individual methods. All methods default to the same response layout in case of an error. .. figure:: ../images/manual/screenshots/admin/sp-02-00-jsonrpc-basic-error-rsp.png :width: 470 JSON-RPC : Basic Error .. _jsonrpc_system_status: systemStatus ^^^^^^^^^^^^ This method returns the system status as enum value. ``READY`` indicates the system is ready to use and users have access to the Web App. All other values indicate that user access is *denied*, because: system ``SETUP`` is needed, ``MAINTENANCE`` is in progress, or the system is temporarily ``UNAVAILABLE`` due to running batch jobs (database backup, user synchronization, database cleanup). .. note:: Although the system can have multiple "deny status" at the same time, the single most important status is returned, in the order ``SETUP``, ``MAINTENANCE``, ``UNAVAILABLE``. .. figure:: ../images/manual/screenshots/admin/sp-02-00-jsonrpc-system-status-req.png :width: 470 JSON-RPC : systemStatus (request) .. figure:: ../images/manual/screenshots/admin/sp-02-00-jsonrpc-system-status-rsp.png :width: 470 JSON-RPC : systemStatus (response) .. code-block:: bash :caption: sample request curl -k --request POST --header "X-Auth-Key: 7961b5ec-bee4-11e7-8731-406186940c49" \ --data '{"jsonrpc":"2.0","id":"reference","method":"systemStatus"}' \ https://savapage:8632/jsonrpc/v1 .. code-block:: json :caption: sample response { "jsonrpc" : "2.0", "id" : "reference", "result" : { "data" : { "@type" : "enum", "value" : "READY" } } } .. _jsonrpc_auth_user_source: authUserSource ^^^^^^^^^^^^^^ This method authenticates an external user against the configured :ref:`User Source `. .. figure:: ../images/manual/screenshots/admin/sp-02-00-jsonrpc-auth-user-source-req.png :width: 470 JSON-RPC : authUserSource (request) .. figure:: ../images/manual/screenshots/admin/sp-02-00-jsonrpc-auth-user-source-rsp.png :width: 470 JSON-RPC : authUserSource (response) .. code-block:: bash :caption: sample request curl -k --request POST --header "X-Auth-Key: 7961b5ec-bee4-11e7-8731-406186940c49" \ --data '{"jsonrpc":"2.0","id":"reference","method":"authUserSource", \ "params":{"username":"john","password":"AzFi7I"}}' https://savapage:8632/jsonrpc/v1 .. code-block:: json :caption: sample response { "jsonrpc" : "2.0", "id" : "reference", "result" : { "data" : { "@type" : "boolean", "value" : true } } } .. code-block:: json :caption: sample error { "jsonrpc" : "2.0", "id" : "reference", "result" : false, "error" : { "code" : -32603, "message" : "ldapserver:636 [No route to host (Host unreachable)]", "data" : { "@type" : "BASIC", "reason" : "ldapserver:636" } } } .. _app-tools-restful: RESTful API ~~~~~~~~~~~ .. contents:: :depth: 1 :local: |image78| .. note:: RESTful Web Services is a :ref:`Feature Preview ` that is partly operational and impermanent. The preview is offered to provoke feedback based on real world use. Please tell us your requirements. The secure endpoint is: ``https://savapage:8632/restful/v1`` Services are described with ``curl`` examples. .. _app-restful-public: RESTful Public Services ^^^^^^^^^^^^^^^^^^^^^^^ .. contents:: :depth: 1 :local: .. _app-restful-admin-system-version: GET /system/version ''''''''''''''''''' .. code-block:: bash :caption: sample request curl -k -X GET "https://savapage:8632/restful/v1/system/version" .. code-block:: text :caption: sample response SavaPage 1.2.0-rc (Build 20200121) .. _app-restful-tests-http-request: GET /tests/http/request ''''''''''''''''''''''' .. code-block:: bash :caption: sample request curl -k -X GET \ "https://savapage.example.com/restful/v1/tests/http/request" .. code-block:: json :caption: sample response { "remoteAddr" : "[2021:661:4cc6:1:5561:96ff:ca11:d4a]", "remoteHost" : "[2021:661:4cc6:1:5561:96ff:ca11:d4a]", "remotePort" : 53840, "localAddr" : "127.0.0.1", "serverName" : "savapage.example.com", "serverPort" : 443, "headers" : { "Accept" : "*/*", "User-Agent" : "curl/7.47.0", "X-Forwarded-Proto" : "https", "X-Forwarded-Host" : "savapage.example.com", "Connection" : "keep-alive", "X-Forwarded-For" : "2021:661:4cc6:1:5561:96ff:ca11:d4a", "Host" : "savapage.example.com", "X-Forwarded-Server" : "savapage.example.com" } } .. _app-restful-admin: RESTful Admin Services ^^^^^^^^^^^^^^^^^^^^^^ .. contents:: :depth: 1 :local: Access to Admin Services is controlled by Basic HTTP Authentication. .. list-table:: RESTful Admin Services Configuration Properties :width: 100% :header-rows: 1 * - Configuration property - Description * - api.restful.auth.username - Basic Authentication Username. * - api.restful.auth.password - Basic Authentication Password. * - api.restful.ip-addresses-allowed - | A :ref:`CIDR Set ` of allowed client IPv4 and/or IPv6 addresses. | When void access is allowed for *all* clients. .. _app-restful-admin-tests-echo: POST /tests/echo '''''''''''''''' .. code-block:: bash :caption: sample request curl -k -u admin:password -X POST \ "https://savapage:8632/restful/v1/tests/echo" \ -H "Content-Type:text/plain" -d "Hello World!" .. code-block:: text :caption: response Hello World! .. _app-restful-admin-get-docs: GET /documents '''''''''''''' .. code-block:: bash :caption: sample request #1 # GET JSON info of first 5 documents sorted by creation datetime descending curl -k -u admin:password -X GET \ "https://savapage:8632/restful/v1/documents?sort=-created" # ... sorted ascending curl -k -u admin:password -X GET \ "https://savapage:8632/restful/v1/documents?sort=+created" .. code-block:: bash :caption: sample request #2 # GET JSON info of first page chunk of 2 proxy printed documents # type = all (default) | in | out | pdf | print | ticket curl -k -u admin:password -X GET \ "https://savapage:8632/restful/v1/documents?sort=-created&type=print&limit=2&page=0" .. code-block:: json :caption: sample response #2 [ { "id" : 6263, "ext_id" : "", "type" : "print", "title" : "Document A", "created" : "2019-09-13T09:18:38+0200", "store" : false }, { "id" : 6258, "ext_id" : "c5a9dd70e931", "type" : "print", "title" : "Document B", "created" : "2019-09-12T09:49:48+0200", "store" : false } ] .. _app-restful-admin-get-docs-id: GET /documents/ ''''''''''''''''''' .. code-block:: bash :caption: sample request # GET JSON info of document id 6272 curl -k -u admin:password -X GET \ "https://savapage:8632/restful/v1/documents/6272" .. code-block:: json :caption: sample response { "id" : 6272, "ext_id" : "d2a3a71c11e9", "type" : "print", "title" : "Invoice 20190248", "created" : "2019-09-16T12:29:15+0200", "store" : true } .. _app-restful-admin-get-docs-ext-id: GET /documents/ext_id= '''''''''''''''''''''''''''''' .. code-block:: bash :caption: sample request # GET JSON info of document with ext_id d2a3a71c11e9 curl -k -u admin:password -X GET \ "https://savapage:8632/restful/v1/documents/ext_id=d2a3a71c11e9" .. _app-restful-admin-get-docs-id-pdf: GET /documents//pdf ''''''''''''''''''''''' .. code-block:: bash :caption: sample request # GET stored PDF document 6272 curl -k -u admin:password -X GET \ "https://savapage:8632/restful/v1/documents/6272/pdf" > 6272.pdf .. _app-restful-admin-get-docs-ext-id-pdf: GET /documents/ext_id=/pdf '''''''''''''''''''''''''''''''''' .. code-block:: bash :caption: sample request # GET stored PDF document with ext_id d2a3a71c11e9 curl -k -u admin:password -X GET \ "https://savapage:8632/restful/v1/documents/ext_id=d2a3a71c11e9/pdf" \ > d2a3a71c11e9.pdf .. _app-restful-admin-get-financial-account-balance: GET /financial/account/balance '''''''''''''''''''''''''''''' .. code-block:: bash :caption: sample request # GET JSON info of account balance # type = USER | GROUP | SHARED curl -k -u admin:password -X GET \ "https://savapage:8632/restful/v1/financial/account/balance?type=USER&name=rijk" .. code-block:: json :caption: sample response (succes) { "succes" : true, "result" : "9.260000" } .. code-block:: json :caption: sample response (failure) { "succes" : false, "error" : "error message" } See :ref:`SavaPage Financial `. .. _app-restful-admin-post-financial-account-balance: POST /financial/account/balance ''''''''''''''''''''''''''''''' .. code-block:: bash :caption: sample request # Sets or adjusts account balance of an account. # # URL parameters (by example): # # Mandatory : # # type=USER : USER | GROUP | SHARED # name=rijk : identifying name of account # amount=2.50 : can be negative, like -2.50 # # Optional: # # details=my%20text : transaction details "my text" # adjust=true : 'true' creates a transaction to adjust the balance with amount # (a negative amount reduces the balance), 'false' (default) # creates a transaction to set balance to amount curl -k -u admin:password -X POST \ "https://savapage:8632/restful/v1/financial/account/balance?type=USER&name=rijk&amount=2.50" .. code-block:: json :caption: sample response with resulting balance { "succes" : true "result" : "2.50" } .. code-block:: json :caption: sample response (failure) { "succes" : false, "error" : "error message" } See :ref:`SavaPage Financial `. .. note:: The value of URL parameter ``details`` is visible in the transaction logs. See :ref:`Transactions ` and :ref:`Account List `. .. _app-restful-admin-post-reports-accounttrx: POST /reports/accounttrx '''''''''''''''''''''''' .. code-block:: bash :caption: sample request # POST selection to download Account Transactions of user "rijk" curl -k -u admin:password -X POST \ "https://savapage:8632/restful/v1/reports/accounttrx" \ -H "Content-Type: application/json" \ -d '{"select":{"account_type":"USER","account_name":"rijk"}}' > AccountTrxList.csv The POSTed data is a JSON string. See the annotated example below. .. callout:: .. code-block:: json :caption: annotated example { "select" : { "account_type" : "USER", # <1> "account_name" : "rijk", # <2> "text" : null, # <3> "trx_type" : "PRINT_OUT", # <4> "date_from" : { # <5> "ccyy" : 2023, "mm" : 1, "dd" : 1, "zzz" : "+01" }, "date_to" : { # <6> "ccyy" : 2023, "mm" : 6, "dd" : 1, "zzz" : "+02" } }, "sort" : { # <7> "field" : "TRX_DATE", # <8> "ascending" : true # <9> }, "media_type" : "CSV" # <10> } .. annotations:: :1: USER | GROUP | SHARED :2: optional for USER (all users), mandatory for GROUP | SHARED :3: (optional) transaction comment snippet :4: (optional) ADJUST | DEPOSIT | GATEWAY | INITIAL | PDF_OUT | PRINT_IN | PRINT_OUT | PURCHASE | TRANSFER | VOUCHER :5: (optional) Sun Jan 01 00:00:00 CET 2023 :6: (optional) Thu Jun 01 00:00:00 CEST 2023 :7: (optional) :8: TRX_DATE (default) | TRX_TYPE :9: true (default)| false :10: CSV (default) | PDF .. note:: The output of this service is identical to the PDF and CSV reports from :ref:`Transactions `. .. _app-restful-user: RESTful User Services ^^^^^^^^^^^^^^^^^^^^^ .. contents:: :depth: 1 :local: Access to User Services is controlled by :ref:`User ID ` and :ref:`UUID `. .. _app-restful-user-print: POST /documents/print ''''''''''''''''''''' .. code-block:: bash :caption: sample print # Print file "lorem-ipsum.txt" to SavaPage as user "janet" with UUID credentials curl -v -k -u janet:97008e2c-d8b2-11e9-aa13-406186940c49 \ -H "Content-Type: multipart/form-data" -H "Accept: application/json" \ -F "file=@lorem-ipsum.txt" \ https://savapage:8632/restful/v1/documents/print You can add a selection of IPP options just like they would be distilled from a driver printed job. See :ref:`IPP Options from PostScript `. .. code-block:: text :caption: IPP options in JSON format -F "file=@lorem-ipsum.txt" \ -F 'ipp_options={"copies":"2","print-color-mode":"monochrome","sides":"one-sided"}' .. important:: A |RESTFULPRINT| maps to the reserved :ref:`Queue ` ``/webservice`` by default. An alternative *non-reserved* Queue can be specified by adding an extra ``-F`` parameter, like this: .. code-block:: bash :caption: alternative queue # Print two collated copies to alternative queue "test" -F "file=@lorem-ipsum.txt" -F "queue=test" -F 'ipp_options={"copies":"2","sheet-collate":"collated"}' If :ref:`IPP Routing ` is enabled for the alternative Queue, the RESTful ``ipp_options`` have priority over and are merged with the IPP Routing options. To exclusively accept prints from specific IP addresses see :ref:`Edit Queue `. .. note:: |RESTFULPRINT| is used by the :ref:`SavaPage Android Print App `. .. _app-restful-user-get-financial-balance: GET /financial/balance '''''''''''''''''''''' .. code-block:: bash :caption: sample request # GET JSON balance of user account "janet" curl -k -u janet:97008e2c-d8b2-11e9-aa13-406186940c49 -X GET \ "https://savapage:8632/restful/v1/financial/balance" .. code-block:: bash :caption: response (success) { "succes" : true, "result" : "5.350000" } .. code-block:: bash :caption: response (failure) { "succes" : false, "error" : "error message" } See :ref:`Financial `. .. _app-restful-user-post-financial-transfer: POST /financial/transfer '''''''''''''''''''''''' .. code-block:: bash :caption: sample request # Transfers balance amount from user "janet" to "rijk" curl -k -u janet:97008e2c-d8b2-11e9-aa13-406186940c49 -X POST \ "https://savapage:8632/restful/v1/financial/transfer?name=rijk&amount=15.00" .. code-block:: bash :caption: response (success) { "succes" : true, } .. code-block:: bash :caption: response (failure) { "succes" : false, "error" : "error message" } See :numref:`{number}. {name} `. .. |image78| image:: ../images/manual/savapage-feature-preview-75x100.png :width: 50px