Skip to main content

I am fairly new to Zapier Platform but I’m looking at building out an integration to Sage Intacct. I’m fairly familiar with Intacct’s APIs and have used them regularly in Postman but I’m not sure how to translate the XML requests to have them work in the Zapier Platform. 

The way Intacct’s APIs work, you can either first retrieve an API session ID with a request and pass that in subsequent requests, OR you can skip retrieving the API session ID and pass the login info in a request. 

I’m trying to use “Session Auth” to retrieve the session ID. Here’s what the working request body looks like in Postman:

<?xml version="1.0" encoding="UTF-8"?>
<request>
<control>
<senderid>{{sender_id}}</senderid>
<password>{{sender_password}}</password>
<controlid>{{$timestamp}}</controlid>
<uniqueid>false</uniqueid>
<dtdversion>3.0</dtdversion>
<includewhitespace>false</includewhitespace>
</control>
<operation>
<authentication>
<login>
<userid>{{user_id}}</userid>
<companyid>{{company_id}}</companyid>
<password>{{user_password}}</password>
</login>
</authentication>
<content>
<function controlid="{{$timestamp}}">
<getAPISession />
</function>
</content>
</operation>
</request>

and here’s how I currently have it translated in the code of “Step 2 Configure a Token Exchange Request”:
 

var options = {
url: bundle.authData.endpoint_url,
method: 'POST',
headers: {
'content-type': 'application/xml',
},

body: {

'request': {
'control': {
'senderid': bundle.authData.sender_id,
'password': bundle.authData.sender_password,
'controlid': '{{$timestamp}}',
'uniqueid': 'false',
'dtdversion': '3.0',
'includewhitespace': 'false'
},
'operation': {
'authentication': {
'login': {
'userid': bundle.authData.user_id,
'companyid': bundle.authData.company_id,
'password': bundle.authData.user_password
}
},
'content': {
'function': {
'getAPISession': '',
'controlid': ''
}
}
}
}
}

}

return z.request(options)
.then((response) => {
response.throwForStatus();
const results = response.json;

// You can do any parsing you need for results here before returning them

return {
'sessionKey': results.sessionKey
};
});

I haven’t worked my way to the actual operation yet but I’m getting the following error on the control. 

...ResponseError: {"status":401,"headers":{"content-type":"text/xml; charset=ISO-8859-1"},"content":"<?xml version=\"1.0\" encoding=\"UTF-8\"?><response><control><status>failure</status></control><errormessage><error><errorno>XMLGW_JPP0002</errorno><description>Sign-in information is incorrect. Please check your request.</description></error></errormessage></response>...

Any idea what I’m doing wrong? Not sure if I somehow need to include the xml version and encoding in my request. I tried a static string in place of the timestamp for the control ID. This works in Postman but it didn’t change anything in the platform when I was testing so I restored it to the $timestamp.

I’d like to keep adding onto this integration and eventually make it public. Intacct is pretty thorough with its APIs and the session authorization is by far the most confusing part of it. I’m not a programmer but I’m feeling the pain of needing an integration point to Intacct. I’d appreciate any help.

The first thing I’d want to look at here is to make sure you are expressly generating and parsing XML as you interact with the API.  Looks like you’re setting a content type of application/xml, but then sending a JSON body.  If the server responds with XML, you’ll need to explicitly parse that as well before returning data from your trigger/action/auth function.   

Most developers working with XML will use a library to help with the parsing.  In order to include 3rd party libraries you’ll need to make sure you are working with your project in the Zapier CLI.  If you’re currently working in the UI, it’s straightforward to install the tool, open your existing project in that environment and continue developing your project there.  https://platform.zapier.com/docs/export

Once you’re working in the CLI, use npm to install a parsing library of your choice and import it: https://platform.zapier.com/cli_docs/docs#does-zapier-support-xml-soap-apis

 

Also, with session auth, the platform relies on an HTTP response of 401 to tell us that the token is expired, and that we need to re-run the token exchange function and try the failed request again.  See https://platform.zapier.com/cli_docs/docs#stale-authentication-credentials

 

In general: The platform is built to support RESTful APIs by default.  It’s totally flexible enough to accommodate a wide variety of request/response protocols and encodings, but you’ll need to be mindful of where your API veers from REST and make sure to handle those things explicitly instead of relying on default handling.


Thanks Zane, I’m diving into this. I’ll reach back out to this thread when I’ve had some time to explore.

Joshua