Skip to main content
Skip table of contents

API documentation

The Greentree API (application programming interface) provides a standard integration medium which can both read and write data in the Greentree Jade database. 

The Greentree API aims to cover the breadth and depth of features available in Greentree and  make them accessible from external systems and interfaces.  There is too much functionality to be developed and released in one go, as a result functional areas will be developed and released based on demand.

Whilst other integration technologies do exist for Greentree (including FREE, SOAP, JHP and selective data import/export functions), they are quite restrictive in their accessibility (FREE requires COM, SOAP access can be awkward and is very heavy, data imports are not suitable for real time integration), are limited to a subset of Greentree features .

Graphical presentation of Greentree API

How Does It Work ?

The Greentree API is a RESTful HTTP interface. 

In a nutshell, this means that you can use descriptive URL’s to access “things” in Greentree.  The structure of the URL’s is a vital part of the API and assists in its discoverability.  The transport mechanism is HTTP which makes it accessible from almost any platform and technology.  The standard HTTP verbs used by web servers are also used to determine what you want to do with the data (GET is used to read, POST is used to write, DELETE is used to delete).  Based on this, the same URL can be used with different verbs to achieve different behavior.

The Greentree API itself acts as a web server and services the queries against the database.  There is no requirement for IIS or any other web server technology.

The basic URL structure of an API call is as follows:

http://<server><port>/<company>/<entity>/<identifier>

SegmentDefinitionExample
<server>Server name or IP address

203.44.22.12 or greentree.site.com

<port>

Port that Greentree will listen on (default is 9000)

9000

<company>

Greentree company

01                     

<entity>

The type of object in Greentree you are referencing.  This is usually the name of the Jade Class.

SOPackingSlip

<identifier>

The primary key to identify the object you are referencing.  Optional.

The reference of a Packing Slip – eg 243333.01

The order of these parameters is important, they MUST be in this sequence.

An example of this call would be:

http://greentree.site.com:9000/01/SOPackingSlip/24333.01

  • A GET request on this URL would return the details of the Pack Slip with a reference 24333.01. 
  • A POST request on this same URL would accept a packet of data to update Pack Slip with a reference 24333.01.
  • A DELETE request on this URL would delete the Packing Slip with reference 24333.01

Parameters

Following the base URL, you can append various query parameters to influence the behaviour of the API call.  Most of these parameters are specific to the particular request, however some of them are common amongst the various API calls.  The query parameters are passed across with the URL and preceded by a "?" character, which separates the base URL from the parameters.  Following this are key=value pairs, which can be separated by "&" if multiple query parameters are required. 

A GET request with no <identifier> will result in a list of the particular entity being requested. 

GET requests like this are capped at 100 entities per request, but can be paged using the query parameters “page” and “pageSize”.  In this case you can continue to increment “page” after each call, until the resulting packet returns less than “pageSize” entities.

An example of this which will return the first 20 Packing Slips in the Greentree company 01 is:

http://greentree.site.com:9000/01/SOPackingSlip?page=1&pageSize=20

An example of not specifying page size which will return the first 100 Packing Slips in the Greentree company 01 is:

http://greentree.site.com:9000/01/SOPackingSlip?page=1

A POST request with no <identifier> will add a new <entity> to the Greentree company.  As a general rule as a client of the API you cannot specify the <identifier> for a newly created entity, as it is preferred to allow Greentree to allocate these.  Note there are exceptions to this which will be documented with their entity.

Global Search

Added in 2020.1 was the ability to access the Global Search functionality of Greentree.  All endpoints support the GET command to fetch a list of records using the query parameter of "globalSearch".

An example of this which will return any Customers with matching data from the Global Search configuration

http://greentree.site.com:9000/01/Customer?globalSearch=041

Authentication

The Greentree API used “Basic Authentication” to allow access to the database.  The authenticated user is a regular Greentree user, based on a typical Greentree username and password configuration. 

In conjunction with this each call to the API must provide an API key.  This can be a parameter of the URL (which is handy when using a web browser), or via a HTTP header if accessing programmatically.  The ApiKey is simply the sites Greentree serial number.

An example of passing the API Key via the URL:

http://greentree.site.com:9000/01/SOPackingSlip?page=1&pageSize=20&ApiKey=23440933

If passing as a HTTP Header:

ApiKey=34440933

Greentree Configuration

API configuration

The Greentree API reads its configuration options from the jadegt.ini file at startup.

API configuration

[GreentreeApi]
ListenPort=9002
QueueDepthLimit=2
QueueDepthLimitTimeout=2
WorkerIdleTimeout=120
MaxWorkerThreads=8
MinWorkerThreads=2
RetainXmlWhitespace=false
CallDurationLogTrigger=5
ReadTimeout=0
SettingPurposeDefaultAvailable
ListenPortTCP port that the API will accept connections on.  Default value is 90009000
QueueDepthLimitThe number of ready connections are waiting to be processed before another Worker Thread is started2
QueueDepthLimitTimeoutThe number of seconds the queue will sit at its QueueDepthLimit before another Worker Thread is started2
WorkerIdleTimeoutThe number of seconds that a Worker Thread has been sitting idle before it is shutdown.120
MaxWorkerThreads

The maximum number of worker threads to process incoming requests.  If you are anticipating a lot of traffic, increase this figure to handle more concurrent connections.

5
MinWorkerThreadsThe minimum number of worker threads to process incoming requests.  When traffic has ceased, all worker threads will be terminated leaving behind MinWorkerThreads.  To get faster ramp up time when traffic arrives, increase this value1
RetainXmlWhitespace

If set to true, CR, LF, CRLF and TAB characters will be retained in text values posted through in XML data.  If left out or set to false, these characters will be converted into spaces.

Note that such values should be encoded when posted through eg: 

  • CR = &#x0d;  
  • LF = &#x0a;
false
CallDurationLogTrigger

Used in conjunction with the Debugging and Tracing to highlight in the log files API calls that are taking a long time

The value is in seconds

Calls that exceed this value are prefixed with *** when written to the log file

0Post 2018.3
ReadTimeout

Reading data sent to the API respects the Content-Length, on occasion the amount of data sent is less than the Content-Length, in which case the API sits waiting indefinitely for the remaining bytes to arrive.  This value will cause the API to timeout after the number of seconds configured if it has not been able to receive the data.

The value is in seconds

0 indicates wait indefinitely

02019.3

Debugging and Tracing

Introduced in Greentree 4@11 was support for logging API calls at the server to observe what is being called and what is being responded, this can be invaluable when diagnosing problems.  This is configured through the jadegt.ini file in the JadeLog section, and is queried in real time, which means you don't have to stop and start the API service as you turn it on/off.  We do not recommend leaving it turned on in a production site for any length of time as it will generate log files that will eat up disk space.  The file generated will be named along the lines of apilog.log and will be found in the folder defined by the LogDirectory setting which is also contained in the JadeLog section of the jadegt.ini file.

API Logging configuration

[JadeLog]
..... ; Other settings that may already be in JadeLog
ApiTracing=0
ApiLogging=0
SettingPurposeValues
ApiTracingLow level logging, calls, URL's payload sizes, response times and management events0 = Off, 1 = On
ApiLoggingHigh level, simply track start/stop of API services/threads0 = Off, 1 = On

Starting as its own service

Running the API as it's own service cannot be done from Greentree Version 2021.4 and above.

The API can be configured as its own service on the same machine as the database server, or on another machine if desired.  In order to register the service a Windows shortcut or command/batch file can be created as described below.

Sample command line to register Greentree API as a service

C:\Greentree\Bin64\jadclient.exe service=install nodeName=GreentreeAPI nodeNameDescription="Greentree API" path=C:\Greentree\system ini=C:\Greentree\jadegt.ini app=ApiStartup schema=ApiSchema


The nodeName and nodeNameDescription determine what appears in the Service Control Manager and can be changed to anything that makes sense.  If you are updating your Greentree batch files to Stop/Start the services manually, you can "net start <nodeName>" and "net stop <nodeName>". 

Starting as part of the database service

To start as part of the database service simply add the following line to the [JadeServer] section (where <n> is the next available number) :

ServerApplication<n>=ApiSchema,ApiStartup

Data format

The HTTP Headers are used by the API to determine the format of data coming in during a POST, and the format to return in the response.  Of particular relevance are the Content-Type and Accept headers.  Typically these should be “text/xml” or “application/xml” when XML is used as the data format for transfer and  “application/json” when sending and receiving JSON (handling of POST data in application/json supported from Greentree 4@8-5).

Typical header could look like this:

Accept: application/xml;q=0.9,*/*;q=0.8
Authorization: Basic c3VwZXI6c3VwZXI=
Content-Length: 3616
Content-Type: text/xml; charset=UTF-8

Attachments

In Greentree attachments can be added to any object, as a result the API provides the ability to :

  • Query the attachments for a particular entity
  • Download an attachment from an entity by its name
  • Upload an attachment to an existing entity

For any GET request, you have the option to pass a query parameter on the URL of "includeAttachments=true", this will include in the response a collection of attachments in the format of :

Attachment XML response

<Attachments collection='true' count='2'>
    <Attachment>
        <Name>desktop.jpg</Name>
        <Edition>3</Edition>
        <OidString>3456.768</OidString>
        <FileName>desktop.jpg</FileName>
        <FileSize>4421</FileSize>
        <ModifiedTimeStamp>2013-08-28T16:19:04</ModifiedTimeStamp>
        <Type>Image</Type>
    </Attachment>
    <Attachment>
        <Name>packman</Name>
        <Edition>1</Edition>
        <OidString>3456.769</OidString>
        <FileName>packman.exe</FileName>
        <FileSize>1101312</FileSize>
        <ModifiedTimeStamp>2013-10-02T14:57:22</ModifiedTimeStamp>
        <Type>Any</Type>
   </Attachment>
</Attachments>


To download an actual attachment for an entity you pass a query parameter on the URL of "action=attachment&name=<name of attachment>".  Using the above as an example which is from StockItem A0002, I can download the first attachment using the following URL :

http://greentree.site.com:9000/01/StockItem/A0002?action=attachment&name=desktop.jpg


To upload an attachment submit a POST request to the entity you wish to attach to with a query parameter on the URL of "action=attachment".  The content must be posted as "multipart/form-data" and an entire file can be uploaded to Greentree.  The attachment name and file name are taken from the Content-Disposition segment of the posted form data.  Note that the "name" is defined by the key for the uploaded file.

Upload modifiers.

ModifierDefinitionExampleAvailable
actionattachment

action=attachment


name

Name of the attachment in Greentree to replace (note do not use this when uploading a new attachment)

name=JobApplication


type

The Attachment Type in Greentree

type=Applications                     


replaceIfExistsIf NOT passing the name modifier, you can replace an existing attachment for the entity if it does exist based on the name embedded in the payload.  Due to the expense of uploading files this is provided as a convenience method to avoid uploading the file only to find it already exists or that an update doesn't exist - you can use this to do it in a single call.replaceIfExists=true
modifiedSinceWhen requesting an attachment by name, you can also request to download the attachment ONLY if it has been modified since this specific date/timemodifiedSince=2014-06-21T23:34:00
summaryThe summary to be used for the attachmentsummary=A lovely photo taken yesterday
isPrimary

Indicate that this attachment should be the Primary attachment for its Attachment Type.

isPrimary=true2021.1
isWebAccessibleIndicate that this attachment should be set to Web AccessibleisWebAccessible=true2021.1

Sticky Notes

In Greentree sticky notes can be added to any object, as a result the API provides the ability to :

  • Query the Sticky Notes for a particular entity.
  • Create / Update Sticky Notes for a particular entity (2020.1)

For any GET request, you have the option to pass the following query parameters on the URL to include in the response a collection of Sticky Notes in the format below.  

Sticky Note Modifiers:

ModifierDefinitionExample
includeStickyNotesOutput the collection of Sticky Notes with each Greentree entity

includeStickyNotes=true

stickyNoteType

Only include Sticky Notes of a particular type in the output.

stickyNoteType=DN

Sticky Notes XML Response

<StickyNotes collection='true' count='2'>
    <StickyNote>
        <Edition>1</Edition>
        <OidString>8364.13</OidString>
        <Type>RN</Type>
        <Note>This item should be made inactive next Summer</Note>
        <IsActive>true</IsActive>
    </StickyNote>
    <StickyNote>
        <Edition>1</Edition>
        <OidString>8364.14</OidString>
        <Type>DN</Type>
        <Note>Please keep this item out of the warehouse</Note>
        <IsActive>true</IsActive>
        <SortDate>2019-10-11</SortDate>
    </StickyNote>
</StickyNotes>

Note that neither confidential nor inactive notes are able to be retrieved via the API.

For any POST request you can include the same structure as above as part of the POST data to create/update Sticky Notes.  

To update an existing Sticky Note you must include the OidString, that is used to locate the actual Sticky Note to update and it will be cross checked against the containing entity to ensure you do not update a Sticky Note for another entity.  

Sticky Notes XML Response

<StickyNotes collection='true' count='2'>
    <StickyNote>
        <OidString>8364.13</OidString>. <!-- Include this because I want to update it-->
        <Type>RN</Type>
        <Note>This is now being made inactive</Note>
        <IsActive>false</IsActive>
    </StickyNote>
    <StickyNote>
        <Type>DN</Type>
        <Note>This is a new Sticky Note</Note>
    </StickyNote>
</StickyNotes>

Plugin Properties

(Available 2020)

In Greentree Plugin Properties (including Dynamic Properties) can be added to any object, as a result the API provides the ability to include the Plugin Properties in the returned data

For any request, you have the option to pass the following query parameters on the URL to include in the response a collection of Plugin Properties in the format below.  

Plugin Property Modifiers:

ModifierDefinitionExample
includePluginPropertiesOutput the Plugin Properties with each Greentree entity

includePluginProperties=true

Plugin Properties

<PlugInProperties>
    <OID>3317.8</OID>
    <OID_AuditTrailNumber>8</OID_AuditTrailNumber>
    <bookmarkText>Job 5000, System for Kangan</bookmarkText>
</PlugInProperties>

Sorting GET requests

(Available 2021 as preview)

The API is adding the ability to sort the result set, initially on ARInvoice and then rolling through the rest of the endpoints.

Sorting can be performed on a GET request that returns a list of results.  Specification of the sort criteria is done as an incrementing integral list of property names on the URL, with the ability to include a matching parameter to sort in descending order.

The sort parameters can be combined with all the existing modifiers.

Sorting modifiers:

ModifierDefinitionExample
sortBy<n>Where n is an integer starting from 1, defines the name of the property to sort by

sortBy1=orderNumber

sortDesc<n>Where n is an integer starting from 1, defines true if require to sort the matching property in descending order.  This parameter is option, and the default sort order is ascending if not specified.sortDesc1=true

You can include any number of sort parameters, and you can also sort by reference properties.

Some worked examples :



Linked Objects

(Available 2020)

In Greentree generic Object Links can be created between any two objects, as a result the API provides the ability to include the Linked Objects in the returned data

For any request, you have the option to pass the following query parameters on the URL to include in the response a collection of Linked Objects in the format below.  

Linked Object Modifiers:

ModifierDefinitionExample
includeLinkedObjectsOutput the Linked Objects with each Greentree entity

includeLinkedObjects=true

Approvals

In Greentree approvals can be added to any object, as a result the API provides the ability to :

  • Query the Approvals for a particular entity.

For any GET request, you have the option to pass a query parameter on the URL of "includeApprovals=true", this will include in the response a collection of Approvals in the format of :

Sample Approval response

<Approvals collection='true' count='1'>
    <Approval>
        <Edition>6</Edition>
        <OidString>7361.35</OidString>
        <Code>CEO</Code>
        <Status>Approved</Status>
        <Reason/>
        <Approvers collection='true' count='2'>
            <Approver>
                <Status>Approved</Status>
                <ToBeApprovedBy>Managers</ToBeApprovedBy>
                <ApprovedBy>SUPER</ApprovedBy>
                <ApprovedTimeStamp>2013-12-20T16:32:02</ApprovedTimeStamp>
            </Approver>
            <Approver>
                <Status>Approved</Status>
                <ToBeApprovedBy>Executive</ToBeApprovedBy>
                <ApprovedBy>SUPER</ApprovedBy>
                <ApprovedTimeStamp>2013-12-20T16:32:02</ApprovedTimeStamp>
            </Approver>
        </Approvers>
    </Approval>
</Approvals>

Approving a record

For any POST request to a specific object, you have the option to pass a query parameter on the URL of "action=approve" and a payload to state the approver, if not specified the API user is the approver :

Sample Approval request

<Approval>
    <ApprovedBy>Steve Sampson</ApprovedBy>     
    <Narration>Please process this transaction</Narration>
</Approval>

Rejecting a record

For any POST request to a specific object, you have the option to pass a query parameter on the URL of "action=reject" and a payload to state the rejector, if not specified the API user is the rejector :

Sample Rejection request

<Rejection>
    <RejectedBy>Steve Sampson</RejectedBy>
    <Narration>request a credit</Narration>
</Rejection>

Clear Approvals for a record (post 2018.3 release)

For any POST request to a specific object, you have the option to pass a query parameter on the URL of "action=clearApproval".  There is no payload for this POST, and the result is to clear the approval status of the record.  Note this will remove all approval details from the specified record.

Reports 

(Available from 2019.2)

You can run any soft coded report (AHFormDefn) via the API by performing a POST operation to any entity using the query parameter of "action=report".  The payload for this POST is an AHFormDefn containing the report and values for the various parameters required to execute the report.

The response is a PDF as generated by the standard report processing, note that it is not at the mercy of the Task Queue.  

You have the ability to generate the report and have it attached directly against a record in Greentree.  If your POST is addressed to a particular instance you can include the <Attachment> detail as part of the payload, which as per the sample below includes 2 specific attributes:

AttributeValuesNotes
ReplaceIfExiststrue / falseIf there is already an attachment with the same name against the Object, determines if it will replace it or not
RespondWithAttachmenttrue/falseYou can elect to run the report and attach it to the Object, but not require the PDF to be returned to you


Posting the below payload to http://server:port/01/CRMSVRequest/1021?action=report will run the report named "CRM SV Inventory Requirements" with a from/to parameters of 1021 and create an Attachment by the name of "My Report" which will replace an existing attachment called "My Report" should one exist, and it will also return the generated PDF as a response to my call.

Sample payload to run a CRM report

<?xml version="1.0" encoding="UTF-8"?>
<AHFormDefn>
    <Name>CRM SV Inventory Requirements</Name>
    <Parameters collection='true' count='2'>
        <AHParameter>
            <Name>From Service Request Number</Name>
            <Value>1021</Value>
        </AHParameter>
        <AHParameter>
            <Name>To Service Request Number</Name>
            <Value>1021</Value>
        </AHParameter>
    </Parameters>
    <Attachment>
        <Name>My Report</Name>
        <Summary>A nice summary</Summary>
        <Type>Any</Type>
        <ReplaceIfExists>true</ReplaceIfExists>
        <RespondWithAttachment>true</RespondWithAttachment>
    </Attachment>
</AHFormDefn>

Beware that some reports may take significant time to execute, and your call to the API may timeout prior to the completion of the report execution.  The report execution itself has a default timeout of 60 seconds as it waits for the report to complete, you can override this by passing a query parameter of "timeout=n" where n is a value in seconds.

A future enhancement to this might be to allow for asynchronous execution, having the API return a token that can be used to check the progress of the report, and ultimately then either cancel it, or retrieve the finished report PDF.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.