The MoneyWorks Datacentre REST API provides a simple, platform-neutral, high performance stateless network interface to MoneyWorks Datacentre.
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.
The available commands are:
version, list, export, import, evaluate, post, doreport, doform, post, and image
The URIs for the REST API generally take the form
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.
- 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 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.
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)
Authorisation may also be supplied in an Authorization header for the "Document" realm. i.e. base64-encoded Username:Document:Password
Authorization: Basic QWRtaW46RG9jdW1lbnQ6cGFudHMhCg==
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
- This is the principle means of extracting information from the database.
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
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
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>email@example.com</email> <productpricing>A</productpricing> </name> <name> <code>BROWN</code> <name>Brown Suppliers</name> <contact>Bronwyn</contact> <address1>PO Box 12</address1> ... <email2>firstname.lastname@example.org</email2> <productpricing>A</productpricing> <receiptmethod>2</receiptmethod> </name> </table>
Canonical plain text output (default)
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
- Create (or update) records in the database. Method must be POST.
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 an 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.
HTTP/1.1 200 OK Content-Type: text/plain 31/01/11
HTTP/1.1 200 OK Content-Type: text/plain 5678.12
- Post an existing transaction, identified by its sequence number. Note the method must also be POST, since the database is changed by this operation.
Posts the transaction. Sequence number should be decimal, without thousands separators. Result will be text/plain status, either "OK" or "not posted".
- Run a report
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).
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
- When used for a document, the list command provides information about installed and available reports or forms.
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
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> ...
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.
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>
- Generate a PDF of a form
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.
- 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).
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