I’m trying to fetch a list of contact IDs from keap/IS that match a TAG of 33412 (for example). Using the example set out on xml-rpc - Keap Developer Portal I am having no luck . Has anyone used that dataservice.query via xml-rpc to fetch a list of contact ID’s ?
Use the ContactGroupAssign table
Query on [‘GroupId’=> [33412]]
Return ContactId
.. make sure that the tag id(s) are integers.
Check out the Schema doc for all of the return fields.
That worked perfectly. Thank you. The only remaining issue is the raw xml data that is coming back is not in any particular record set. I’m asking for 5 fields and what is coming back are 8 fields (sometimes) but the raw xml is not in any order. Meaning: I ask for contactID Email, Address1, Address2 (for example). The raw data comes back maybe the first 10 records in that proper order but then it starts skewing where one record would have 5 email addresses coming back, then the next record would have contactID, Email, Address1, Address1, Address1 (not belonging to the record), Address2. Seems odd for the raw data coming back to be like that. I’m using this as my baseline code: xml-rpc - Keap Developer Portal
Hi @John_Brogan,
Have you checked out the SDKs? If available for your environment then they will deal with these complexities.
If not, then you have to be aware of certain things.
- When providing a list of fields to be returned, they only appear in the results if data has been associated to them.
- If you do not provide the Order By and Sort Direction parameters, the order of the results will be based on how the database has stored that information. I usually query the “Id” field in Descending Order to get the latest records first.
- XML-RPC Responses will differ across the Endpoints, so some will be Struct, Integer, Value, etc.
How I query the Node for the DataService “query” results is the following.
methodResponse > params > param > value > array > data > value > struct
Then I would loop through the results. In each result I would loop through the Child Nodes to get the Field and Value and store that in an Array, which gets added into a Main Array. At the end you will have an array of all the results, regardless of what fields were present in each result.
Does that help you?
To add on to what @Pav said above. You’re probably better off sorting the ContactGroupAssign table using the DateCreated field. This table doesn’t have an exposed primary key and uses the ContactId and GroupId as the unique identifier.
Don’t rely on the returned results to match the same order you requested them in. You may have asked for [FirstName, LastName], but you could get [LastName => ‘Doe’, FirstName => ‘John] in the returned data.
I usually setup an empty array as my model for each record. As @Pav said at the end when you’ve got your array of all the results, I’ve added any missing fields in the returned record with an empty value.
When I parse the final array result all of my records, each record now has all of the requested fields, and I don’t have to write logic to determine if a field exists.
Thank you all so much. You’ve saved me days of guessing. I have it fetching perfectly now.
Is there a trick or something I’m missing to get around this type of response from the IS/Keap system when sending in a command via xml-rpc? I’m using the ContactService.removeFromGroup to remove a specific tag from a contact ID record….. (there are about 830 to 1100 records per day that I need to update by removing a tag when the customer engages.)
"code": "429",
"message": "Quota Exceeded",
"status": "Request Throttled",
"details": null
}
Are you using OAuth or a Service Account Key?
You should have plenty of capacity if you are just updating that many records per day. Unless you are doing a lot of API calls in one go, then you will be throttled.
I presume that your script is being called at random intervals? Are there moments when your script could be called multiple times in one go?
It runs at 2am daily. Basically goes thru a list of contacts and updates the records that match a condition. So if it finds 800 that match, I push the xml-rpc command in 800 times. Using oauth.
I’m running a few operations like this, and what I do is split the operations.
- Request the data
- Cached requested data
- Process cached data ~10 records every/5 mins w/ a .5s delay between requests.
This has worked over the last decade using both OAuth and API key.
Depending on what needs to happen, you can setup a campaign and trigger the AcheiveGoal method, and push the required operations back into Keap… however in your circumstance if you’re making the same number of calls as records you receive, there’s no difference in the API requests.
Depending on how complex your operation is you can look at the Exp Backoff approach linked to in the Keap docs.