Hello,
Maybe someone can help me out here. This is my first Marketo post.
I'm not a user of Marketo but a SalesForce developer. I've been tasked with updating a form field picklist value across multiple Marketo forms. I've decided to use the Marketo REST API to do this. Ideally, I'll be given a list of Marketo form id's to cycle through to update a customer/prospect name field. Since we sell to school districts, this picklist will be over 10,000 records in length. Once the picklist is updated, I'll set visibility rules for this field based upon state.
I've studied very closely the Marketo Asset REST API documentation and have performed multiple Google searches to try to find the answer to my question.
I've used SOAP UI and my SalesForce code to perform some basic tests already. I can get the access token and make REST calls to update the field on a test form that I was given. This only works if the "content-type" on the request header is set to "application/x-www-form-urlencoded" and I supply a data package that looks like this:
values=[{"value":"Don XXXXXXXXXXX District","label":"Don XXXXXXXXXXX District"},{"value":"Jefferson Co School District","label":"Jefferson Co School District"}] This won't work in production for us, since the data package will need to contain >10,000 records. My research says that if the content-type is set to "application/x-www-form-urlencoded" , the data package is just added to the URL. I really need to have the application type set to "application/json".
When I change the content type to "application/json", and supply a properly formatted JSON package that looks like this:
{
"values":[{"value":"Don 333 District","label":"Don 333 District"},{"value":"Jefferson Co School District","label":"Jefferson Co School District"}]
}, the JSON response from Marketo says that it was success but non of the picklist values are updated. I can see this immediately in the JSON response from Marketo.
The Marketo REST API documentation for form field update defines the JSON package as this:
{
"blankFields": 0,
"defaultValue": "string",
"fieldType": "string",
"fieldWidth": 0,
"formPrefill": true,
"hintText": "string",
"initiallyChecked": true,
"instructions": "string",
"label": "string",
"labelToRight": true,
"labelWidth": 0,
"maskInput": "string",
"maxLength": 0,
"maxValue": 0,
"minValue": 0,
"multiSelect": true,
"required": true,
"validationMessage": "string",
"values": "string",
"visibleLines": 0
}
What's strange is that the values parameter is defined by Marketo as string instead of a list of label, value pairs. The only example given by Marketo for a form field update REST call specifies a content-type of "application/x-www-form-urlencoded" which does not work for me.
I've done REST integrations between SalesForce and at least two other platforms (Chargify and custom internal REST endpoints) and have never had any problems. Is there something wrong with Marketo's REST implementation and documentation?
Thanks for any help or Insight:
Don Martin
This won't work in production for us, since the data package will need to contain >10,000 records.
What do you mean it "won't work in production" for you? 10,000 records * 100 bytes + URL encoding is still < 2MB.
What's strange is that the values parameter is defined by Marketo as string instead of a list of label, value pair
Not strange, it is a string. It's a JSON string (JSON being a string serialization format) that's then URL-encoded (as are all string values in a URL-encoded payload). It wouldn't be right to imply that it's a full JSON payload, it's not.
The only example given by Marketo for a form field update REST call specifies a content-type of "application/x-www-form-urlencoded" which does not work for me.
Why is that? If you have a client app/framework that doesn't understand this ubiquitous format, time for a new app.
(REST does not demand application/json encoding. You can make powerful points about the non-RESTful quality of the Marketo API -- it's more like the not-SOAP API than a pure HATEOAS REST API -- but application/json isn't part of that debate.)
Now, I do see major problems with your approach, which someone should've vetted beforehand.
One minor one is that the Marketo REST API may return a spurious 6xx error on large payloads (even though the payload will still be committed to the back end, which is good; you have to re-GET the asset to know it's complete).
Much more important, you're loading up this form with 1.5MB of data before you add the Visibility Rules (which are going to have to repeat at least 1.5 MB of data in total). So your end users are going to be waiting for a 3MB+ descriptor to download before rendering the form. I wouldn't go about it this way. Rather, if the field values are relatively static (static enough to be updated using the REST API, at least) they shouldn't be part of the form descriptor, which is treated as moment-to-moment dynamic data. They should be stored in a static (thus cacheable) file and injected on the client side.
I am able to use a content-type of "application/x-www-form-urlencoded" in my REST calls to Marketo. But I know from multiple Google searches that this content-type typically has a length limit depending upon the end-point server implementation.
I ran a number of tests this weekend with content-type set to "application/x-www-form-urlencoded" . I WAS able to add the school districts in the states MO, AZ, and CA to the pick list value list on my test form. Even though the response back from Marketo looked this this: "districtResponse:[errors=(error:[code=611, message=System error]), requestId=bc50#16ea083efb5, result=null, success=false, warnings=()]", it apparently went through. When I edited my test form, I saw that there are 2179 records in the pick list for this field
When I try to send in the school districts for MO, AZ, CA, and TX to Marketo, I get a response back from Marketo that starts out looking like this: "districtResponse:[errors=(), requestId=a36f#16ea07d3343, result=(LpFormFieldResponse:[blankFields=null, columnNumber=0, dataType=select, defaultValue=[""], fieldMetaData=FieldMetaDataType:[multiSelect=false, values=(labelValue:[label=Kitikmeot School Operations......... When I edit my test form, I see that there's no change to the number of records in the pick list for this field.
This won't work in production for us, since the data package will need to contain >10,000 records.
So my conclusion is still valid. As the content-type "application/x-www-form-urlencoded" adds the package/payload as a query parameter on the URL request, there is obviously some unspoken limit on the length of the string as my testing has demonstrated. This limit is far below what we need it to be in production as we need to include all the school districts in the country--not just the school districts in a handful of states.
What I find particularly annoying with the Marketo REST API is that is returns an error code when it successfully processes the pick list values but returns NO error when it does not. That is clearly a bug to me.
As I explained above, the very concept of adding these values to the form descriptor is flawed and does not match best practices for form performance. Using the proper design sidesteps the concerns you have about the encoding format.