Skip navigation
All Places > Marketo Whisperer: Implementation Tips > Authors Kenny Elkington

Are you tired of opening lead database, opening a new lead page and replacing the ID with the one you actually want to see?  Just drag this link to your bookmark toolbar, click it(while on a page in your Marketo instance), type in the ID of the lead you want to see and press enter.

 

Find Lead

 

Bam, there's your lead in a new tab.

 

Here's the code:

(function () {
      (function () {
           var % 20lead = prompt("Enter%20Lead%20ID", 0);
           if (lead > 0) {
                var % 20host = document.location.host;
                var % 20url = "//" + host + "/leadDatabase/loadLeadDetail?leadId=" + lead;
                var % 20myWindow = window.open(url);
           } else {
                console.log(lead);
                alert("Invalid%20Lead%20ID.%20%20ID%20must%20be%20an%20integer%20greater%20than%20zero.")
           }
      })()
})();

PS:  If you can't drag the link, just create a new bookmark, and set this as the location:

javascript:(function(){(function(){var%20lead=prompt("Enter%20Lead%20ID",0);if(lead>0){var%20host=document.location.host;var%20url="//"+host+"/leadDatabase/loadLeadDetail?leadId="+lead;var%20myWindow=window.open(url);}else{console.log(lead);alert("Invalid%20Lead%20ID.%20%20ID%20must%20be%20an%20integer%20greater%20than%20zero.")}})()})();

These features will be added with the Winter 2016 release this evening:

REST API

Custom Objects

  • Custom Objects N:N relationships now supported
    • Lead or Account records may now have many-to-many relationships through custom objects via the definition of intermediate objects.  After creating a standalone custom object type, and intermediate object type can be created with link fields to both the standalone object and either leads or accounts.
    • There are no new API calls for this capability, but the object definitions must be configured correctly to leverage these relationships through the API.

SOAP API

This post originally appears here.

 

Last time, we took a look at triggering transactional emails from outside of Marketo.  This week we'll be looking at how to pass dynamic content to our emails via the Request Campaign API call.  Request Campaign not only allows the triggering of emails externally, but you can  also replace the content of My Tokens within an email.  My tokens are reusable content that can be customized at the program or marketing folder level.  These can also just exist as placeholders to be replaced through your request campaign call.  For instructions on configuring the smart campaign, see part one.

Building your Email

In order to customize our content, first we will need to configure a program and an email in Marketo.  To generate our custom content, we will need to create tokens inside of the program, and then place them into the email that we're going to be sending.  For simplicity's sake, we'll be using just one token in this example, but you can replace any number of tokens in an email, in the From Email, From Name, Reply-to or any piece of content in the email.  So let's create one token Rich Text for replacement and call it "bodyReplacement".  Rich Text allows us to replace any content in the token with arbitrary HTML that we want to input. create a new token

Tokens can't be saved while empty, so go ahead and insert some placeholder text here.  Now we need to insert our token into the email:

add token to email

This token will now be accessible for replacement through a Request Campaign call.  This token can be as simple as a single line of text which needs to be replaced on a per-email basis, or can include almost the entire layout of the email.

The Code

In previous posts, we've looked at authenticating and retrieving lead records, and then sending an email to those leads.  We'll be expanding on the code from last week to pass in customized tokens to our request campaign call.

package dev.marketo.blog_request_campaign;  import com.eclipsesource.json.JsonArray;  public class App { public static void main( String[] args ) { //Create an instance of Auth so that we can authenticate with our Marketo instance Auth auth = new Auth("Client ID - CHANGE ME", "Client Secret - CHANGE ME", "Host - CHANGE ME");  //Create and parameterize an instance of Leads Leads leadsRequest = new Leads(auth).setFilterType("email").addFilterValue("requestCampaign.test@marketo.com");  //get the inner results array of the response JsonArray leadsResult = leadsRequest.getData().get("result").asArray();  //get the id of the record indexed at 0 int lead = leadsResult.get(0).asObject().get("id").asInt();  //Set the ID of our campaign from Marketo int campaignId = 1578; RequestCampaign rc = new RequestCampaign(auth, campaignId).addLead(lead);  //Create the content of the token here, and add it to the request String bodyReplacement = "<div class=\"replacedContent\"><p>This content has been replaced</p></div>"; rc.addToken("{{my.bodyReplacement}}", bodyReplacement); rc.postData(); } } 

If the code looks familiar, that's because it only has two additional lines from the main method in the previous post.  This time we're creating the content of our token in the bodyReplacement variable and then using the addToken method to add it to the request.  addToken takes a key and a value and then creates a JsonObject representation and adds it to the internal tokens array.  This is then serialized during the postData method and creates a body that looks like this:

{"input":{"leads":[{"id":1}],"tokens":[{"name":"{{my.bodyReplacement}}","value":"<div class=\"replacedContent\"><p>This content has been replaced</p></div>"}]}}

Combined, our console output looks like this:

Token is empty or expired. Trying new authentication Trying to authenticate with ... Got Authentication Response: {"access_token":"19d51b9a-ff60-4222-bbd5-be8b206f1d40:st","token_type":"bearer","expires_in":3565,"scope":"apiuser@mktosupport.com"} Executing RequestCampaign call Endpoint: .../rest/v1/campaigns/1578/trigger.json?access_token=19d51b9a-ff60-4222-bbd5-be8b206f1d40:st Request Body: {"input":{"leads":[{"id":1}],"tokens":[{"name":"{{my.bodyReplacement}}","value":"&lt;div class=\"replacedContent\"&gt;&lt;p&gt;This content has been replaced&lt;/p&gt;&lt;/div&gt;"}]}} Result: {"requestId":"1e8d#14eadc5143d","result":[{"id":1578}],"success":true} 

Wrapping Up

This method is extensible in a multitude of ways, changing content in emails within individual layout sections, or outside emails, allowing custom values to be passed into tasks or interesting moments.  Anywhere a my token can be used from within a program can be customized using this method.  Similar functionality is also available with the Schedule Campaign call which will allow you to process tokens across an entire batch campaign.  These can't be customized on a per lead basis, but are very useful for customizing content across a wide set of leads.

This post originally appears here.

 

A common use case for the Marketo API is to trigger the sending of transactional emails to specific records via the Request Campaign API call.  You can find an example covering this use case with the SOAP API here.  There are a few configuration requirements within Marketo in order to execute the required call with the Marketo REST API.

  • The recipient must have a record within Marketo
  • There needs to be a Transactional Email created and approved in your Marketo instance.
  • There needs to be an active trigger campaign with the Campaign is Requested, Source: Web Service API, that is set up to send the email

First create and approve your email.  If the email is truly transactional, you will likely need to set it to operational, but be sure that it legally qualifies as operational.  This is configured from with the Edit Screen under Email Actions > Email Settings:

Request Campaign - Email Settings

Request Campaign - Operational

Approve it and we’re ready to create our campaign:

RequestCampaign - Approve Draft

If you’re new to creating campaigns, check out the Create a New Smart Campaign article on docs.marketo.com.  Once you’ve created your campaign, we need to go through these steps.  Configure your Smart List with the Campaign is Requested trigger: Request Campaign - Smart List

Now we need to configure the flow to point a Send Email step to our email: Request Campaign - Flow

Before activation, you’ll need to decide on some settings in the Schedule tab.  If this particular email should only ever be sent once to a given record, then leave the qualification settings as is.  If it’s required that they receive the email multiple times, though, you’ll want to adjust this to either every time or to one of the available cadences: Qualification Rules

Now we’re ready to activate:

Request Campaign - Schedule

Sending the API Calls

Note: In the Java examples below, we’ll be using the minimal-json package to handle JSON representations in our code.  You can read more about this project here: https://github.com/ralfstx/minimal-json

The first part of sending a transactional email through the API is ensuring that a record with the corresponding email address exists in your Marketo instance and that we have access to its lead ID.  For the purposes of this post, we will assume that the email addresses are in Marketo already, and we only need to retrieve the ID of the record.  For this, we will be using the Get Multiple Leads by Filter Type call, and we will be reusing some of the Java code from the previous post on authenticating and retrieving lead data from Marketo. Let's take a look at our Main method for to request the campaign:

package dev.marketo.blog_request_campaign;  import com.eclipsesource.json.JsonArray;  public class App  {     public static void main( String[] args )     {          //Create an instance of Auth so that we can authenticate with our Marketo instance         Leads leadsRequest = new Leads(auth).setFilterType("email").addFilterValue("requestCampaign.test@marketo.com");          //Create and parameterize an instance of Leads         //Set your email filterValue appropriately         Leads leadsRequest = new Leads(auth).setFilterType("email").addFilterValue("test.requestCamapign@example.com");          //Get the inner results array of the response         JsonArray leadsResult = leadsRequest.getData().get("result").asArray();          //Get the id of the record indexed at 0         int lead = leadsResult.get(0).asObject().get("id").asInt();          //Set the ID of your campaign from Marketo         int campaignId = 0;         RequestCampaign rc = new RequestCampaign(auth, campaignId).addLead(lead);          //Send the request to Marketo         rc.postData();     } }

To get to these results from the JsonObject response of leadsRequest, we’ll need to write some code .  To retrieve the first result in the Array, we need to extract the Array from the JsonObject and get the object indexed at 0:

 

JsonArray leadsResult = leadsRequest.getData().get("result").asArray(); int leadId = leadsResult.get(0).asObject().get("id").asInt();

 

From here now all we need to do is the Request Campaign call.  For this, the required parameters are ID in the URL of the request, and an array of JSON objects containing one member, "id."  Let's take a look at the code for this:

package dev.marketo.blog_request_campaign; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.Reader; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import javax.net.ssl.HttpsURLConnection; import com.eclipsesource.json.JsonArray; import com.eclipsesource.json.JsonObject;  public class RequestCampaign {      private String endpoint;      private Auth auth;      public ArrayList leads = new ArrayList();      public ArrayList tokens = new ArrayList();            public RequestCampaign(Auth auth, int campaignId) {           this.auth = auth;           this.endpoint = this.auth.marketoInstance + "/rest/v1/campaigns/" + campaignId + "/trigger.json";      }      public RequestCampaign setLeads(ArrayList leads) {           this.leads = leads;           return this;      }      public RequestCampaign addLead(int lead){           leads.add(lead);           return this;      }      public RequestCampaign setTokens(ArrayList tokens) {           this.tokens = tokens;           return this;      }      public RequestCampaign addToken(String tokenKey, String val){           JsonObject jo = new JsonObject().add("name", tokenKey);           jo.add("value", val);           tokens.add(jo);           return this;      }      public JsonObject postData(){           JsonObject result = null;           try {                JsonObject requestBody = buildRequest(); //builds the Json Request Body                String s = endpoint + "?access_token=" + auth.getToken(); //takes the endpoint URL and appends the access_token parameter to authenticate                System.out.println("Executing RequestCampaign call\n" + "Endpoint: " + s + "\nRequest Body:\n"  + requestBody);                URL url = new URL(s);                 HttpsURLConnection urlConn = (HttpsURLConnection) url.openConnection(); //Return a URL connection and cast to HttpsURLConnection                urlConn.setRequestMethod("POST");                urlConn.setRequestProperty("Content-type", "application/json");             urlConn.setRequestProperty("accept", "text/json");             urlConn.setDoOutput(true);                OutputStreamWriter wr = new OutputStreamWriter(urlConn.getOutputStream());                wr.write(requestBody.toString());                wr.flush();                InputStream inStream = urlConn.getInputStream(); //get the inputStream from the URL connection                Reader reader = new InputStreamReader(inStream);                result = JsonObject.readFrom(reader); //Read from the stream into a JsonObject                System.out.println("Result:\n" + result);           } catch (MalformedURLException e) {                e.printStackTrace();           } catch (IOException e) {                e.printStackTrace();           }           return result;      }            private JsonObject buildRequest(){           JsonObject requestBody = new JsonObject(); //Create a new JsonObject for the Request Body           JsonObject input = new JsonObject();           JsonArray leadsArray = new JsonArray();           for (int lead : leads) {                JsonObject jo = new JsonObject().add("id", lead);                leadsArray.add(jo);           }           input.add("leads", leadsArray);           JsonArray tokensArray = new JsonArray();           for (JsonObject jo : tokens) {                tokensArray.add(jo);           }           input.add("tokens", tokensArray);           requestBody.add("input", input);           return requestBody;      }  }

This class has one constructor taking an Auth, and the Id of the campaign.  Leads are added to the object either by passing an ArrayList<Integer> containing the Ids of the records to setLeads, or by using addLead, which takes one integer and appends it to the existing ArrayList in the leads property.  To trigger the API call to pass the lead records to the campaign, postData needs to be called, which returns a JsonObject containing the response data from the request.  When request campaign is called, every lead passed to the call will be processed by the target trigger campaign in Marketo and be sent the email which was created previously. Congratulations, you've triggered an email through the Marketo REST API.  Keep an eye out for Part 2 where we'll look at dynamically customizing the content of an email through Request Campaign.

This post originally appears herehttp://developers.marketo.com/blog/quick-start-guide-for-marketo-rest-api/.

 

This guide will show you how to make your first call to the Marketo REST API in ten minutes.

We'll show you how to retrieve a single lead using the Get Lead by Id REST API endpoint. To do this, we will walk you through the authentication process to generate an access token, which you will use in making a GET request to Get Lead by Id. Then we'll provide you with the code to make the request that will return lead info formatted as JSON.

How to Generate an Authentication Token

A Custom Service in Marketo allows you to describe and define what data your application will have access to. You need to be logged in as a Marketo administrator to create a Custom Service and associate that service with a single API-Only user.

1. Navigate to the admin area of the Marketo application

navigate_to_admin

2. Click on the Users & Roles node on the left panel

users_and_roles

3. Create a new role

create_new_role

4. The next step is to create an API only user and associating it with the API role that you created in step 3. You can do so by checking the API-Only user checkbox at the time of user creation.

invite_new_user

5. A Custom service is required to uniquely identify your client application. To create a custom application, go to the Admin->LaunchPoint screen and create a new service.

launchpoint_new_service

6. Choose "Custom" Service type, provide the Display Name, Description and the user email address created in step 4. We recommend using a descriptive Display Name that represents either the company or purpose of this Custom REST API Service.

new_service

7. Click on "View Details" link on the grid to get the Client Id and Client Secret.

view_details

Your client application will be able to use the Client Id and Client Secret to generate an access token.

details

8. Copy and paste your authentication token into a text editor. Your authentication token will look similar to the example below.

cdf01657-110d-4155-99a7-f986b2ff13a0:int 

How to Determine Endpoint URL

In making a request to Marketo API, you will need to specify your Marketo instance in the endpoint URL. All requests to the Marketo REST API will follow the format below.

<REST API Endpoint URL>/rest/ 

The REST API Endpoint URL can be found within the Marketo Admin->Web Services panel.

rest_api_endpoint

Your Marketo endpoint URL structure should look similar to the example below.

http://100-AEK-913.mktorest.com/rest/v1/lead/{id}.json 

How to Use Authentication Token to Call Get Lead by Id API

In the previous sections, we generated an authentication token and found the endpoint URL. We will now make a request to REST API endpoint called Get Lead by Id.

The easiest way to make your request to Marketo REST API is to paste the URL into your web browser's address bar. Follow the format below.

Request

// Format http://<REST API Endpoint URL for your Marketo instance>/rest/v1/<API you are calling>?<access_token>  // Example http://100-AEK-913.mktorest.com/rest/v1/lead/318581.json?access_token=cdf01657-110d-4155-99a7-f986b2ff13a0:int 

If your call is successful, it will return JSON with the format below.

{ "requestId": "d82a#14e26755a9c", "result": [ { "id": 318581, "updatedAt": "2015-06-11T23:15:23Z", "lastName": "Doe", "email": "jdoe@marketo.com", "createdAt": "2015-03-17T00:18:40Z", "firstName": "John" } ], "success": true } 

If you are interested in learning more about the Marketo REST APIs, this is a good place to start.

* This article contains code used to implement custom integrations. Due to its customized nature, The Marketo Technical Support team is unable to troubleshoot custom work. Please do not attempt to implement the following code sample without appropriate technical experience, or access to an experienced developer.

This post originally appears here.

 

SoundCloud provides an incredible audio hosting platform, with rich analytics and functionality for everything from aspiring indie rock acts, to EDM artists at the top of the music industry, to storytelling podcasts.  Along with the incredible native functionality of the platform comes a world-class API program to move your data and track listening behavior.  This is especially useful for podcasters, and can allow you to correlate specific listening actions, like plays, pauses, and shares to specific content in the script and the audio.  Today we'll take a look at leveraging SoundCloud's widget API to send and track these activities in Marketo.  The pattern we'll be using may seem familiar if you've read our post on tracking YouTube video views.

First let's look at generating a Munchkin activity which will be recorded to a lead's activity log in Marketo.  At it's most basic, we make a call to Munchkin.munchkinFunction and pass "visitWebPage" as the first argument.  This will log a Visits Web Page activity with Marketo, and record any arbitrary URL and Query String data which we pass to the method.  The second argument accepts a JavaScript object with our data, which has two members, "url," and"params," both strings.  The url member corresponds to the Web Page of the activity in Marketo, while params corresponds to the Querystring.  For our purposes, we'll use the url as an identifier for SoundCloud related actions, "soundCloudInteraction," while params will contain additional data about the particular activity.  Here's the function we'll be using to track each action:

var trackActivity = function(action){           //set action param to be the string passed to the function           var qs = "action=" + action;           //use getCurrentSound callback to get the name of the current track           soundCloudMunchkin.widget.getCurrentSound(function(currentSound){                //add it to our querystring                qs = qs + "&sound=" + currentSound.title;                //use the getPosition callback to get the position of the track in ms                soundCloudMunchkin.widget.getPosition(function(position){                     //add it to the querystring                     qs = qs + "&position=" + position;                     //assemble our data object for the munchkin activity                     var dataObject = {                          "url": "soundCloudInteraction",                          "params": qs                     }                     //call the munchkinFunction to submit the activity                     Munchkin.munchkinFunction("visitWebPage", dataObject);                });           });                 }

Since the standard SoundCloud widget is embedded in an iframe, the widget uses post messages to communicate and callbacks need to be used to obtain data, as you can see with the currentSound and getPosition methods.

The SoundCloud widget API provides a set of JavaScript callbacks that we can use to respond to individual events in the player and submit these to Marketo.  The ones that we're interested are to what and how long the user listens, and interactions that they make with the player, so we're looking at the following events:

  • PLAY
  • PAUSE
  • FINISH
  • SEEK
  • CLICK_DOWNLOAD
  • CLICK_BUY
  • OPEN_SHARE_PANEL

We'll also need to use the bind() method from the widget to add callbacks to each of these events.  Let's look at one example:

widget.bind(SC.Widget.Events.PLAY, function(){  soundCloudMunchkin.trackPlay();  });

This will make it so that whenever a track is played, we'll fire the trackPlay method to send an event to Marketo with data about the current track.  You can find the full script here: https://gist.github.com/kelkingtron/6750bb07c1397d93d9c7#file-soundcloudmunchkin-js  the soundCloudMunchkin object has an init method, which accepts a SoundCloud widget object as it's only argument, which binds the tracking methods to the relevant callbacks, and will set up your widget to track activity down to Marketo.  Your page will need to have your Munchkin code loaded, as well as the SoundCloud API library.  You'll also need to initialize everything, in addition to embedding your actual SoundCloud widget:

window.onload=function(){      var iframe = document.getElementById(iframeId);      if(iframe) {         widget = SC.Widget(iframe);           soundCloudMunchkin.init(widget);      }; };

Check out a live demo here, and happy tracking!

Sometimes it's difficult to know which version of a Field Name that you need to use in a given place, so here's a quick reference for which source uses the SOAP or REST version of a field name:

 

WhereWhich
Munchkin APISOAP
Forms 2 APISOAP
List Import(UI)SOAP
List Import(REST API)REST
Webhooks Response MappingsSOAP
SOAP APISOAP
REST APIREST

 

Are there other places where you're confused about which field name you should use?  Let us know in the comments and we can help you out.

This post originally appears on the Marketo Developer's blog, here.

Read Part 1 here

For the most part, errors received back from the Marketo REST API will not be automatically recoverable.  However, there are a handful of cases where you can recover automatically, or ensure you never see a certain type of error.

Request-Size Errors

As we looked at in the last post of this series, Marketo will emit HTTP Status code 414 if your URI exceeds 8KiB in length, or 413 if your request body exceeds 1MB, or 10MB for Import Lead.  Though 414s will be rare, you might see them if you’re using Get Leads By Filter type to request records based on 300 separate GUIDs or similar criteria.  Say you have the following request:

https://AAA-BBB-CCC.mktorest.com/rest/v1/leads.json?filterType=customGUID&fields=email,company…firstName,lastName

When you submit the request, Marketo returns a status of 414 because the URI exceeds 8KiB.  To handle this, we need to alter the pattern of this request, and submit a POST instead of a GET, append ‘_method=GET’ to the URI, and pass the querystring in the request body as a x-www-form-urlencoded request instead:

URI:

https://AAA-BBB-CCC.mktorest.com/rest/v1/leads.json?_method=GET

Request Body:

filterType=customGUID&fields=email,company…firstName,lastName

Instead of catching this exception from the HTTP response, however, we can just check the total length of the request at runtime, and deploy this alternative pattern if the URI exceeds 8k.  Alternatively, you could use the POST Method in all cases for batch retrievals of records.

For 413s, we can follow a similar pattern, checking the length of the request body when adding records during the serialization step, and splitting the request into multiple parts if this limit would be exceeded.

Authentication Errors

Our next class of recoverable errors is related to authentication.  When a formerly valid access token is used after its expires_in period has elapsed, the first usage will return an error code of 602, “Access token expired.”  After this, using the same token will return a 601, “Access token invalid.”  Any other usage of a string which is not a valid access token for the target subscription will result in a 601.  In both cases, this error can be recovered from by reauthenticating and passing the new access token with a retry of the failed request.

Timeouts

In very rare circumstances, a call may return a 604, “Request timed out,” after the 30 second timeout period has elapsed.  For batched requests, such as Create/Update Leads, the request can be split up into smaller batches and retried until success is returned (if the batch is split to less than 100 records and the request is still timing out, you should probably file a support case).  The most common other case is with asset approval calls, where a lock may be held on the current approved record by another user or service, such as the case of an Email or Email Template.  In these cases, exponential backoff should be used for retries to allow for any existing locks to be resolved.

Check back in the coming weeks for the final part of the series where we’ll take a closer look at some specific, non-recoverable errors.

While the Marketo form builder is quite powerful, there are some edge cases where it doesn't produce quite the result that you're looking for.  A common request is to reposition fields after the progressive profiling box, which is a capability that isn't currently available natively.  Fortunately, with some javascript tweaks, we can reposition fields freely.  Let's take a look at the code:

/*

jQuery must be loaded on the page

use moveMktoField to position the field designated by FieldName relative to the field designated by pivotName

*/

 

 

function moveMktoField(fieldName, pivotName, beforeOrAfter){

  //find the label element for the field which we want to move

  var labelForFieldToMove = $('[for="' + fieldName + '"]');

  //find the label element for the field we want to position relative to

  var labelForPivot = $('[for="' + pivotName + '"]');

  //get the mktoFormRow parent of each

  var fieldToMove = getParentWithClass(labelForFieldToMove, "mktoFormRow");

  var pivot = getParentWithClass(labelForPivot, "mktoFormRow");

  //insert the field before or after the pivot based on the setting

  if (beforeOrAfter == "before"){

       fieldToMove.insertBefore(pivot);

  } else if (beforeOrAfter == "after"){

       fieldToMove.insertAfter(pivot);

  } else {

       console.log("argument 'beforeOrAfter' must be one of 'before' or 'after'");

       return null;

  }

}

//inserts multiple fields in order where the first in the fields array is adjacent to the pivot, and the last is furthest

function moveMktoFields(fields, pivotName, beforeOrAfter){

  moveMktoField(fields[0], pivotName, beforeOrAfter);

  for ( i = 1; i < array.length; i++ ){

       moveMktoField(fields[i], fields[i - 1], beforeOrAfter);

  }

}

function getParentWithClass(elem, withClass) {

  //Check the parent to see if it has the desired class

  if ( elem.parent().hasClass(withClass) ) {

       return elem.parent();

  } else {

       //if not, call self recursively on the immediate parent

       return (getParentWithClass(elem.parent(), withClass) );

  }

}

 

With the above, we can use the moveMktoField function to reposition one field relative to another.  You can also use moveMktoFields to move the fields as a group when you pass an array of field names to it.  Click here to see a live demo, moving First Name after Last Name.

This post originally appears on the Marketo Developer's Blog, here.

 

The Marketo REST API may return an exception or error, which, for convenience, we will just call errors from here on out.  Errors can occur at three different levels:

  • HTTP level, these errors are indicated by a 4xx code
  • Response level, these errors are included in the "errors" array of the JSON response
  • Record level, these errors are included in the "result" array of the JSON response, and are indicated on an individual record basis with the "status" field and "reasons" array

 

HTTP Errors

Under normal operating circumstances Marketo should only return two HTTP status errors, 413 Request Entity Too Large, and 414 Request URI Too Long.  These are both recoverable through catching the error, modifying the request and retrying, but with smart coding practices, you should never encounter these in the wild.

Marketo will return 413 if the Request Payload exceeds 1MB, or 10MB in the case of Import Lead.  In most scenarios it unlikely to hit these limits, but adding a check to the size of the request and moving any records which cause the limit to be exceeded to a new request should prevent any circumstances which lead to this error being returned by any endpoints.

 

414 will be returned when the URI of a GET request exceeds 8KiB.  To avoid it, check against the length of your query string to see if it exceeds this limit.  If it does change your request to a POST method, then input your query string as the request body with the additional parameter '_method=GET'.  This forgoes the limitation on URIs.  It's rare to hit this limit in most cases, but is somewhat common when retrieving large batches of records with long individual filter values such as a GUID.

 

Response-Level Errors

Response level errors are present when the "success" parameter of the response is set to false.  Each entry in "errors" has two members, "code" a number, either 6xx or 7xx, and a "message" giving the plaintext reason for the error.  6xx codes always indicate that a request failed completely and were not executed.  An example of this is a 601, "Access token invalid," which is recoverable by re-authenticating and passing the new access token with the request.  7xx errors indicate that the request failed, either because no data was returned, or the request was incorrectly parameterized, such as including an invalid date, or missing a required parameter.

 

Record-Level Errors

Record level errors indicate that an operation could not be completed for an individual record, but the request itself was valid.  These occur within individual record in the "result" array of a response.  The "status" field of these records will be "skipped" and a "reasons" array will be present.  Each reason contains a "code" member, and a "message" member.  The code will always be 1xxx, and the message will indicate why the record was skipped.  An example would be where a Create/Update Leads request has "action" set to "createOnly" but a lead already exists for one of the keys in the submitted records.  This case will return a code of 1005, and a message of "Lead already exists."

 

In the next few posts, we will take a look at recoverable errors, and some examples of how to handle these inside of your code.

This post originally appears on the Marketo Developers Blog

When your organization has many different platforms for hosting web content and customer data it becomes fairly common to need parallel submissions from a form so that the resulting data can be gathered in separate platforms. There are several strategies to do this, but the best one is often the simplest: Using the Forms 2 API to submit a hidden Marketo form. This will work with any new Marketo Form, but ideally you should create an empty form for this, which has no fields:

Empty Form

This will ensure that the form doesn’t load any more data than necessary, since we don’t need to render anything. Now just grab the embed code from your form and add it to the body of your desired page, making a small modification. You embed code includes a form element like this:

<form id="mktoForm_1068"></form>

You’ll want to add ‘style=”display:none”‘ to the element so it is not visible, like this:

<form id="mktoForm_1068" style="display:none"></form>

Once the form is embedded and hidden, the code to submit the form is really quite simple:

var myForm = MktoForms2.allForms()[0]; 
myForm
.addHiddenFields({
     //These are the values which will be submitted to Marketo
     "Email":"test@example.com",
     "FirstName":"John",
     "LastName":"Doe" });
myForm
.submit();

Forms submitted this way will behave exactly like if the lead had filled out and submitted a visible form. Triggering the submission will vary between implementations since each one will have a different action to prompt it, but you can make it occur on basically any action. The important part is setting your fields and values correctly. Be sure to use the SOAP API name of your fields which you can find with Export Field Names to esnure correct submission of values.

We've been busy over at developers.marketo.com creating content to help you develop and improve integrations with Marketo.  Here's what we've been up to over the past month:

 

How to Specify Lead Partitions Using the REST API

Developer Evangelist David Everly provides a how-to in managing lead partitions through the REST API.  A must read for anyone developing for Marketo Enterprise Edition instances.

 

Best Practices for API Users and Custom Services

I go over the best ways to manage your users and services with respect to API integrations.  Following these guidelines will allow you to isolate usage counts from your third-party services, and revoke or restrict access by a service without interrupting any other services.

 

Add SalesPerson Data to Marketo

I go through the basics of synching salesperson records to Marketo, along with some sample code.  This is essential knowledge for anyone working with non-native CRM integrations, streamlining the process of adding owner-level fields to your lead records in Marketo, and allowing you to keep changes local to individual salesperson records, instead of updating all of the leads owned by that person

 

Updating Lead Data in Marketo Using the API

Dave covers the use case of bidirectionally synching lead data with the REST API.  Incremental synching with REST has a new model, so if you're new to building one, or have experience with the SOAP API, you'll want to check this out. Sample program code in Java is provided.

 

In addition to the recent blog posts we've overhauled and polished the documentation for Munchkin, Webhooks, and Email Scripting.  You can get content updates from the developer's blog through our RSS Feed or by following us on Twitter, @MarketoDev.