MoneyWorks Datacentre REST API

Synopsis

The MoneyWorks Datacentre REST API provides a simple, platform-neutral, high performance stateless network interface to MoneyWorks Datacentre.

Description

The MoneyWorks Datacentre REST server runs, by default, on port 6710. It can be enabled/disabled and the port configured in the Console app. SSL/TLS may also be enabled in the Console (If you will be exposing the REST port to the Internet, you SHOULD enable SSL/TLS). Make sure you communicate with the server using the protocol that you have selected.

The REST server is a very simple HTTP/1.1 implementation (in version 7 and earlier, the REST server was HTTP/1.0)

Internally, the server uses MoneyWorks command-line instances to service REST requests (hence the similarity of the REST API to the CLI). It keeps a pool of logged-in instances which stay alive for 60 seconds or so, so the latency cost (on the server) of making multiple requests over a short space of time is very low. Keep in mind, however, that if your requests are being issued from a host that has a high latency to the server, then you'll want to keep the frequency of requests to a minimum.

API

The available commands are:

versionlistexportimportevaluatepostdoreportdoform, post, and image

The URIs for the REST API generally take the form

/REST/documentname/command/params

Simple server information requests do not require a document name or parameters. The document name should be blank resulting in a double slash.

In the example server responses below, irrelevant headers are omitted for clarity.

Server information commands

version
Get the server version number.

GET /REST//version HTTP/1.1

Does not require any login credentials. Returns the Datacentre version number as text/plain. e.g.:

HTTP/1.1 200 OK
Server: MoneyWorks_Datacentre/6.1b49 REST/6.1b49 Login_Required
Content-Type: text/plain

6.1b49

Iff the server requires per-folder login, then the string Login_Required will appear in the Server header of the response.

list
List the documents (databases) on the server.

GET /REST//list HTTP/1.1

Returns a list of the available document names as text/xml. e.g.:

HTTP/1.1 200 OK
Content-Type: text/xml

<?xml version="1.0"?>
<documents>
        <document>Acme.mwd7</document>
        <document>CognitoAccountsv6.mwd7</document>
</documents>

If the server is set up to require folder-level login (The "Require Folder Name and Password to Connect (ASP mode)" option in the console), then you must supply a username and password either as an Authorization (sic) header for the realm "Datacentre", or in the URL (user:pass@server...). The Auth header must be Basic with base64 encoded Username:Datacentre:password where Username is the name of a password-protected subfolder in the Datacentre documents folder.

GET /REST//list HTTP/1.1
Authorization: Basic RnJlZDpEYXRhY2VudHJlOnMzY3JldAo=

This command can also be used with a document. See below.

 

Requests that operate on a document

These must include the document name.

Documentname is the name of the MoneyWorks document in the Datacentre that you are accessing. It can be prefixed with login credentials in the form user:password@. Non-alphanumeric characters in the username, password, and filename should be url-encoded by converting to %-prefixed hexadecimal. This includes any / path separators if the document is in a subfolder (/ = %2f)

e.g.

       Acme%20Widgets.mwd7
       Admin:fred@Acme%20Widgets.mwd7

Authorisation may also be supplied in an Authorization header for the "Document" realm. i.e. base64-encoded Username:Document:Password

Authorization: Basic QWRtaW46RG9jdW1lbnQ6cGFudHMhCg==

 

Requests with parameters

Params sections are a list of named parameters in the form paramname=paramvalue, separated by ampersands. Paramvalues must be url-encoded. Note that characters such as = in the paramvalue that are not normally url-encoded must be, since they are syntactically significant in the parameter list. i.e encode = as %3d

export
This is the principle means of extracting information from the database.

GET /REST/document/export/params

Parameters:

table=tablename --(see Appendix A of manual for table names)

search=expr --url-encoded search expression

format=xml|xml-terse|xml-verbose|format-expr --may be omitted for canonical text export

sort=expr --can be simply a field name or an arbitrary expression

direction=ascending|descending

start=N --optional start offset when format is xml

limit=N--optional limit of number of records returned when format is xml

If the search parameter is omitted, you'll get the entire table. BEWARE: it may be very large. Downloading entire tables without good reason should be avoided. Use the start and limit parameters to page through "windows" on the data.

Result will be text/plain or text/xml as per the requested format.

The XML format is fully compatible with the XML import format. Terse xml omits blank/zero values and non-importable system fields and detail line items for transactions. The verbose format includes that data, but with a system="true" attribute.

A format expression should be fully url-encoded. It defines the export format with anything inside square brackets considered an expression to be evaluated. Anything outside square brackets will be output verbatim for each record.

e.g. XML output

GET /REST/Acme.mwd7/export/table=name&search=Category1%3d%22NORTH%22&limit=2&format=xml
HTTP/1.1 200 OK
Content-Type: text/xml

<?xml version="1.0"?>
<table name="Name" count="2" start="0" found="6">
        <name>
                <code>AUTUMN</code>
                <name>Autumn Fabrix Ltd</name>
                ...
                <payaccount>2500</payaccount>
                <email>accounts@autumn.co</email>
                <productpricing>A</productpricing>
        </name>
        <name>
                <code>BROWN</code>
                <name>Brown Suppliers</name>
                <contact>Bronwyn</contact>
                <address1>PO Box 12</address1>
                ...
                <email2>fred@brown.co</email2>
                <productpricing>A</productpricing>
                <receiptmethod>2</receiptmethod>
        </name>
</table>

Canonical plain text output (default)

GET /REST/Admin:fred@Acme.mwd7/export/table=name&search=Category1%3d%22NORTH%22 
HTTP/1.1 200 OK
Content-Type: text/plain

0       2       24/09/11 7:44:58 PM     AUTUMN  Autumn Fabrix Ltd       Allan 
1       3       31/01/11 4:58:07 PM     BROWN   Brown Suppliers         Bronwyn 
4       6       31/01/11 4:35:56 PM     SMITH   J Smith & Sons Ltd      Simon   
7       9       31/01/11 4:58:28 PM     WHITE   White Contractors       Grey  
8       10      31/01/11 3:58:09 PM     WINTER  The Winter Bakery       William  
21      32      31/01/11 4:21:45 PM     BROWNX  Brown Suppliers         Bronwyn 
import
Create (or update) records in the database. Method must be POST.

POST /REST/document/import/params

Optional Parameters:

return_seq=true --get seqnum of last record updated, else get created: N; updated: M

Supply the data to be imported in the post data, formatted as an xml table. MoneyWorks will not import invalid records. You should prevalidate your data before attempting to import it, rather than relying on the error messages from the import command to be meaningful to end users who have supplied invalid data (such as an invoice for a non-existent customer, or that does not add up).

See the documentation on importing genreally and xml importing. It is important to understand what constitutes a valid, importable record.

The usual response is text/plain in the form

created N; updated M

Where N and M are the number of records created or updated, respectively. If you supply the return_seq=true parameter, then the response is text/plain containing the decimal representation of the last sequence number created or updated (not all tables respond to this option).

If there are errors in the data, the response will begin with the text [ERROR] followed by some information about the error(s). No records will be imported or updated in this case.

Extra import behaviours (such as posting the imported transactions) may be specified by passing the required parameters as attributes to the table element in the xml data. See the documentation on XML importing.

evaluate
Evaluate an expression

GET /REST/document/evaluate/expr=expression

Evaluates the given expression in the context of the document and returns the result. The expression should be fully url-encoded. The result will be text/plain.

e.g.

GET /REST/Acme.mwd7/evaluate/expr=Today%28%29 
HTTP/1.1 200 OK
Content-Type: text/plain

31/01/11
GET /REST/Acme.mwd7/evaluate/expr=Lookup%28%22SPRING%22%2C%22Name.DBalance%22%29 
HTTP/1.1 200 OK
Content-Type: text/plain

5678.12
post
Post an existing transaction, identified by its sequence number. Note the method must also be POST, since the database is changed by this operation.

POST /REST/document/post/seqnum=sequencenumber 

Posts the transaction. Sequence number should be decimal, without thousands separators. Result will be text/plain status, either "OK" or "not posted".

doreport
Run a report

GET /REST/document/doreport/params

Parameters:

report=name

format=html|text|pdf

from=yyyymmdd|nnnn

to=yyyymmdd|nnnn

font=fontname

size=pts

leading=pts

title=heading

control-id=value -- control values

The report can reside in custom or standard plugins on the server. All params except report are optional.

Default format is text, delivered as text/plain. You will probably usually want to specify html or pdf. From and To dates can be ISO dates (which effectively denote a period range) or period numbers.

User-defined identifiers will be entered into the name table and can be used to specify custom control values by name (which some custom reports may require). The proper control-ids to use may be obtained using the list command (see below).

Example

GET /REST/doreport/report=Balance%20Sheet&format=html&leading=8&font=Verdana&size=10 
HTTP/1.1 200 OK
Content-Type: text/html

<HTML>
<HEAD>
<META NAME=GENERATOR CONTENT="MoneyWorks">
<style type="text/css">
...
</HEAD>
<BODY style="background-color: #f7f6f2;">
<div>
<div>
... etc
list
When used for a document, the list command provides information about installed and available reports or forms.

Parameters

folder=reports|forms --one of these is required

filter=user|standard|all --default is all

For folder=forms, the type may be specified

type=invc|stmt|prod|job_|remt|rept --default is invc

For folder=reports, a report name may be specified to get details of the report name=reportname

GET /REST/Acme.mwd7/list/folder=forms 
HTTP/1.1 200 OK
Content-Type: text/xml

<?xml version="1.0"?>
<plugins type="invc">
        <form>
                <name>Business Check 104 (US)</name>
        </form>
        <form>
                <name>Business Check 105 (US)</name>
        </form>
        ...
GET /REST/Acme.mwd7/list/folder=reports 
HTTP/1.1 200 OK
Content-Type: text/xml

<?xml version="1.0"?>
<plugins type="crep">
        <report>
                <name>Balance Sheet</name>
        </report>
        <report>
                <name>Bank Balances</name>
        </report>
        ...

Querying for parameter details of a specific report. These are returned in html-compatible format. Theid of the input elements should be used as parameter names to the doreport command. Boolean parameters should be passed as 0 or 1. Select parameters should be passed the selected value.

Users for whom the report is signed are indicated in the signatures element. If you are connecting as a user who does not have privileges to run unsigned reports, then your username must appear in the signatures block, or else doreport will fail with a 403 for the report.

GET /REST/Acme.mwd7/list/folder=reports&name=Bank%20Balances 
HTTP/1.1 200 OK
Content-Type: text/xml

<?xml version="1.0"?>
<plugins type="crep">
        <report>
                <name>Bank Balances</name>
                <signatures>
                        <user>Admin2</user>
                </signatures>
                <controls>
                        <div>
                                <input id="Omit_Zero_Balances" type="checkbox" />
                                <label for="Omit_Zero_Balances">Omit Zero Balances</label>
                        </div>
                        <div>
                                <input id="Include_Unposted" type="checkbox" />
                                <label for="Include_Unposted">Include Unposted</label>
                        </div>
                        <div>
                                <input id="Print_Movements" type="checkbox" />
                                <label for="Print_Movements">Print Movements</label>
                        </div>
                        <div>
                                <input id="Cash_Basis" type="checkbox" />
                                <label for="Cash_Basis">Cash Basis</label>
                        </div>
                        <div>
                                <input id="Show_Departments" type="checkbox" />
                                <label for="Show_Departments">Show Departments</label>
                        </div>
                        <div>
                                <label for="sort">Sort</label>
                                <select id="sort">
                                        <option value="2">Code</option>
                                        <option value="3">Description</option>
                                        <option value="4">Accountant Code</option>
                                </select>
                        </div>
                        <div>
                                <label for="from">Period</label>
                                <select id="from">
                                        <option value="112">Mar:2008/09</option>
                                        ...
                                        <option value="310">Jan:2010/11</option>
                                </select>
                        </div>
                </controls>
        </report>
</plugins>

 

doform
Generate a PDF of a form

GET /REST/document/doform/params

Parameters

form=name

search=expr

Message=messagetext

Print_Copy=1|0

Include_Remit=1|0

Stmt_Date=yyyymmdd

Omit_Zero=1|0

Omit_Credit=1|0

The form can reside in custom or standard plugins on the server. All params except form and searchare optional.

Output format is pdf, delivered as application/pdf.

Example

GET REST/Acme.mwd7/doform/form=Plain%20Ruled%20Invoice&search=sequencenumber%3d1686&message=Thanks
image
Use GET to retrieve an image.

GET /REST/document/image/product=code 
GET /REST/document/image/transaction=seqnum 

Retrieves a product or transaction image. Response will be image/png, image/jpg or application/pdf.

Use PUT to upload an image and attach to an existing transaction or product. Any existing image will be replaced.

PUT /REST/document/image/product=code 
PUT /REST/document/image/transaction=seqnum 

Note that the PUT data must be binary (if using curl use the --data-binary option) and content type should be image/png or image/jpg for a product image. For a transaction image it may also be application/pdf. In actual fact, a Content-Type of application/octet-stream is fine, just make sure you are PUTting binary data.

The transaction flags field will be updated to indicate that the transaction has an image, provided that no user has the transaction locked. If the transaction is locked, an error is returned, even though the image has been uploaded (and may have replaced an existing image). If the transaction is locked, it may be that a user is editing the transaction and will subsequently overwrite your image when they save the transaction.

Concurrent users and availability

Most REST requests are performed by a worker process on the server. This process logs into the database with the credentials you provide. It may consume one of the concurrent logins allowed for the server or folder account. If there are no concurrent logins available, then the request will fail.

If the server is configured with a dedicated REST availability serial number, then this will never be a problem. If it is not, then you should take the possibility of concurrent login saturation into account.

Note also that, by default, these worker processes linger for a short time (on the order of 30 seconds), so that a subsequent request with the same credentials can be serviced much faster. These lingering processes will continue to consume a concurrent login. If you do not wish this to happen, as of v7.1.5 you can add a parameter no_linger=true to your requests to cause the worker process to die immediately after servicing your request (this will allow a subsequent request with different credentials to succeed where concurrent logins are in short supply).

History

MoneyWorks REST interface first appeared in MoneyWorks Datacentre 6.1
HTTPS support was added in v7.1
HTTP/1.1 support was added in v8.0

Posted in REST | Comments Off on MoneyWorks Datacentre REST API