Making a call to the API is simply a matter of opening a session connection to the Web Services gateway endpoint and passing credentials and requests in XML.

You can make a call to the Web Services API using various mechanisms, such by using Postman (a third-party app), or by using one of the Sage Intacct SDKs. You can even create an application using your preferred programming language natively.

When making API calls, be aware that you aren’t interacting directly with the Sage Intacct database. Instead you are going through the Sage Intacct business layer, which saves you a lot of work. For example, when you post an invoice, you don’t need to make all the related journal entries and so forth. The business layer performs those updates for you.

This document outlines the different mechanisms for interacting with the gateway and also provides examples of test applications using various programming languages.


Use Postman

Postman is a popular API test tool that lets you send HTTP requests to a server and review the responses. Postman supports collections of commonly-used requests that can be reused and modified. You can download the Sage Intacct API collection, which provides a set of API calls by application:

Postman with collection loaded

See Your First XML API Calls to learn how to use Postman to send requests to the gateway and to download the Sage Intacct API collection.


Use an SDK

Using one of the Sage Intacct SDKs is preferable to using a native programming language as the SDK nicely wraps functionality and provides session management under the hood.


Use Programming Languages

Any programming language that lets you post HTTP requests can be used to create a Web Services application. This section provides some sample test applications using different languages.

Note: The examples provided here are for demonstration purposes and are not intended to be used directly in application code.

Having a separate request-generating program is recommended in order to maintain consistent calls. Accordingly, each test application is set up with:

The examples provide placeholders for your Web Services credentials as myWebSenderId and myWebPassword. In addition, the examples are set up to accept a hardcoded session ID as mySessionId for simplicity.

Important: You should always protect/encrypt your passwords. In addition, when you are working with production code, using the getAPISession function to get a session ID and endpoint is always the recommended approach.

The Python and Java third-party libraries/modules used in the examples were chosen largely for ease of use and compatibility with given versions of programming languages. Feel free to use other approaches.


Python 2.7 Example

Construct the Request and Call Post

The following test program creates an XML request using the ElementTree module. The program then uses a static method on the XMLRequestClient class (description further down) to post the request to the gateway using the urllib2 module.

from elementtree.ElementTree import Element, SubElement, dump

from XMLRequestClient import XMLRequestClient

# Provide values for these variables for testing purposes. Never store
# these in your application source code.
senderId = "myWebSenderId"
senderPassword = "myWebPassword"
sessionId = "mySessionId"

try:
    # Write the XML request with the ElementTree module
    # Download from http://effbot.org/downloads#elementtree
    request = Element("request")
    control = SubElement(request, "control")
    SubElement(control, "senderid").text = senderId
    SubElement(control, "password").text = senderPassword
    SubElement(control, "controlid").text = "testRequestId"
    SubElement(control, "uniqueid").text = "false"
    SubElement(control, "dtdversion").text = "3.0"
    SubElement(control, "includewhitespace").text = "false"

    operation = SubElement(request, "operation")

    authentication = SubElement(operation, "authentication")
    SubElement(authentication, "sessionid").text = sessionId

    content = SubElement(operation, "content")
    function = SubElement(content, "function")
    function.attrib["controlid"] = "testFunctionId"

    readByQuery = SubElement(function, "readByQuery")
    SubElement(readByQuery, "object").text = "VENDOR"
    SubElement(readByQuery, "fields").text = "RECORDNO,VENDORID,NAME"
    SubElement(readByQuery, "query").text = ""  # All records

    # Post the request
    response = XMLRequestClient.post(request)

    # Print the XML response to the console
    dump(response)
    except Exception, e:
    print "Uh oh, something is wrong"
    print e
    print type(e)
    print e.args

Post the Request and Return the Response

The XMLRequestClient class provides a post method that accepts an Element instance, opens a connection using urllib2, posts the request, and returns the response.

import urllib2
from elementtree.ElementTree import tostring, fromstring

ENDPOINT_URL = "https://api.intacct.com/ia/xml/xmlgw.phtml"
TIMEOUT = 30

class XMLRequestClient:

    def __init__(self):
        pass

    @staticmethod
    def post(request):
        # Set up the url Request class
        conn = urllib2.Request(ENDPOINT_URL)
        # Use this Content Type to avoid urlencoding everything
        conn.add_header("Content-type", "application/xml")

        # Post the request
        result = urllib2.urlopen(conn, tostring(request), TIMEOUT)

        # Check that the HTTP code is 200-OK
        if result.getcode() != 200:
            # Log some of the info for debugging
            raise Exception("Received HTTP status code, " + result.getcode())

        # Load the XML into the response
        response = fromstring(result.read())

        return response

Python 3.5 Example

Construct the Request and Call Post

The following test program creates an XML request using the minidom module. The program then uses a static method on the XMLRequestClient class (description further down) to post the request to the gateway using the urllib module.

from xml.dom.minidom import Document
from XMLRequestClient import XMLRequestClient

# Provide values for these variables for testing purposes. Never store
# these in your application source code.
senderId = "myWebSenderId"
senderPassword = "myWebPassword"
sessionId = "mySessionId"

try:
    # Write the XML request with the minidom  module
    newdoc = Document();
    request = newdoc.createElement('request')
    newdoc.appendChild(request)
    control = newdoc.createElement('control')
    request.appendChild(control)
    senderid = newdoc.createElement('senderid')
    control.appendChild(senderid).appendChild(newdoc.createTextNode(senderId))
    senderpassword = newdoc.createElement('password')
    control.appendChild(senderpassword).appendChild(newdoc.createTextNode(senderPassword))
    controlid = newdoc.createElement('controlid')
    control.appendChild(controlid).appendChild(newdoc.createTextNode("testRequestId"))
    uniqueid = newdoc.createElement('uniqueid')
    control.appendChild(uniqueid).appendChild(newdoc.createTextNode("false"))
    dtdversion = newdoc.createElement('dtdversion')
    control.appendChild(dtdversion).appendChild(newdoc.createTextNode("3.0"))
    includewhitespace = newdoc.createElement('includewhitespace')
    control.appendChild(includewhitespace).appendChild(newdoc.createTextNode("false"))

    operation = newdoc.createElement('operation')
    request.appendChild(operation)

    authentication = newdoc.createElement('authentication')
    operation.appendChild(authentication)

    sessionid = newdoc.createElement('sessionid')
    authentication.appendChild(sessionid).appendChild(newdoc.createTextNode(sessionId))

    content = newdoc.createElement('content')
    operation.appendChild(content)
    function = newdoc.createElement('function')
    content.appendChild(function).setAttributeNode(newdoc.createAttribute('controlid'))
    function.attributes["controlid"].value = "testFunctionId"

    readByQuery = newdoc.createElement('readByQuery')
    function.appendChild(readByQuery)
    object = newdoc.createElement('object')
    readByQuery.appendChild(object).appendChild(newdoc.createTextNode("VENDOR"))
    fields = newdoc.createElement('fields')
    readByQuery.appendChild(fields).appendChild(newdoc.createTextNode("RECORDNO,VENDORID,NAME"))
    query = newdoc.createElement('query')
    readByQuery.appendChild(query).appendChild(newdoc.createTextNode("")) # All records

    # Post the request
    result = XMLRequestClient.post(request)

    # Print the XML response to the console
    print(result.toprettyxml())

except Exception as inst:
    print("Uh oh, something is wrong")
    print(type(inst))
    print(inst.args)

Post the Request and Return the Response

The XMLRequestClient class provides a post method that accepts an minidom Document instance, opens a connection using urllib, posts the request, and returns the response.

import urllib.request
from xml.dom.minidom import parse

ENDPOINT_URL = "https://api.intacct.com/ia/xml/xmlgw.phtml"
TIMEOUT = 30

class XMLRequestClient:

    def __init__(self):
        pass

    @staticmethod
    def post(request):
        # Set up the url Request class and use this Content Type
        # to avoid urlencoding everything
        header = {'Content-type': 'application/xml'}
        conn = urllib.request.Request(ENDPOINT_URL, headers = header, method='POST')

        # Post the request
        result = urllib.request.urlopen(conn, request.toxml(encoding="ascii"), TIMEOUT)

        # Check the HTTP code is 200-OK
        if result.getcode() != 200:
            # Log some of the info for debugging
            raise Exception("Received HTTP status code, " + result.getcode())

        # Load the XML into the response
        response = parse(result)
        return response

Java 8 Example

Construct the Request and Call Post

The following test program creates an XML request using the DocumentBuilder package. The program then uses a method available on an XMLRequestClient instance (class description further down) to post the request to the gateway using the HttpsURLConnection package.

package com.intacct.sample;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class Test{
  /**
   * Provide values for these variables for testing purposes. Never store
   * these in your application source code.
   *
   * /
	static String senderId = "myWebSenderId";
	static String senderPassword = "myWebPassword";
	static String sessionId = "mySessionId";

    /**
     * @param args
     */
    public static void main(String[] args) {
        // Write the request using the DocumentBuilder package.
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder dBuilder;
        try {
            dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.newDocument();
            Element rootElement = doc.createElement("request");
            doc.appendChild(rootElement);

            Element control = doc.createElement("control");
            rootElement.appendChild(control);
            Element senderid = doc.createElement("senderid");
            senderid.appendChild(doc.createTextNode(senderId));
            control.appendChild(senderid);
            Element password = doc.createElement("password");
            password.appendChild(doc.createTextNode(senderPassword));
            control.appendChild(password);
            Element controlid = doc.createElement("controlid");
            controlid.appendChild(doc.createTextNode("testRequestId"));
            control.appendChild(controlid);
            Element uniqueid = doc.createElement("uniqueid");
            uniqueid.appendChild(doc.createTextNode("false"));
            control.appendChild(uniqueid);
            Element dtdversion = doc.createElement("dtdversion");
            dtdversion.appendChild(doc.createTextNode("3.0"));
            control.appendChild(dtdversion);

            Element operation = doc.createElement("operation");
            rootElement.appendChild(operation);

            Element authentication = doc.createElement("authentication");
            operation.appendChild(authentication);
            Element sessionid = doc.createElement("sessionid");
            sessionid.appendChild(doc.createTextNode(sessionId));
            authentication.appendChild(sessionid);

            Element content = doc.createElement("content");
            operation.appendChild(content);
            Element function = doc.createElement("function");
            function.setAttribute("controlid", "testFunctionId");
            content.appendChild(function);

            Element readByQuery = doc.createElement("readByQuery");
            function.appendChild(readByQuery);
            Element object = doc.createElement("object");
            object.appendChild(doc.createTextNode("VENDOR"));
            readByQuery.appendChild(object);
            Element query = doc.createElement("query");
            readByQuery.appendChild(query);

            Element fields = doc.createElement("fields");
            fields.appendChild(doc.createTextNode("*"));
            readByQuery.appendChild(fields);

            // Post the request
            XMLRequestClient intacct = new XMLRequestClient();
            Document response = intacct.post(doc);

            // Pretty print response to the console
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            DOMSource source = new DOMSource(response);
            StreamResult console = new StreamResult(System.out);
            transformer.transform(source, console);

            System.out.println("DONE");

        } catch (Exception e) {
            System.err.println("Uh oh, something is wrong - " + e.getMessage());
        }
    }
}

Post the Request and Return the Response

The XMLRequestClient class sets the Sage Intacct Web Services endpoint and provides a post method that accepts a Document, opens a connection using HttpsURLConnection, posts the request, and returns the response.

package com.intacct.sample;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import javax.net.ssl.HttpsURLConnection;
import java.net.URL;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;

public class XMLRequestClient {
	public final String ENDPOINT_URL = "https://api.intacct.com/ia/xml/xmlgw.phtml";
	public final int TIMEOUT = 30;

	/**
	 * @param   Document request
	 * @return  Document response
	 * @throws  Exception
	 *
	 */
	public Document post(Document request)
	{
		request.getDocumentElement().normalize();
		Document response = null;

		try
		{
			final String END_POINT = "https://api.intacct.com/ia/xml/xmlgw.phtml";
			URL obj = new URL(END_POINT);

			// Set up the connection
			HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
			con.setRequestMethod("POST");
			con.setRequestProperty("Content-Type", "application/xml");
			con.setDoOutput(true);
			con.setDoInput(true);

			// Set up output stream for the POST content
			StringWriter writer = new StringWriter();
			StreamResult requestString = new StreamResult(writer);
			TransformerFactory tf = TransformerFactory.newInstance();
			Transformer transformer = tf.newTransformer();
			transformer.transform(new DOMSource(request), requestString);

			// Write to the output stream
			OutputStreamWriter wr = new OutputStreamWriter(con.getOutputStream());
			wr.write(writer.toString());
			wr.flush();
			wr.close();

			// Get the response
			InputStream rd = con.getInputStream();
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			DocumentBuilder parser = factory.newDocumentBuilder();
			response = parser.parse(rd);
			rd.close();

			// Check the HTTP code is 200-OK
			int responseCode = con.getResponseCode();
			if (responseCode != 200) {
				throw new Exception("Received HTTP status code, " + responseCode);
			}
		}
		catch (Exception e) {
				System.err.println("Uh oh, something is wrong - " + e.getMessage());
		}
		return response;
	}
}

Provide feedback