Error Codes
Below are lists of REST API error codes, and an explanation of how errors are returned back to applications.
Handling and Logging Exceptions
When developing for Marketo, it鈥檚 important that requests and responses get logged when an unexpected exception is encountered. While certain types of exceptions, such as expired authentication, can be safely handled by re-authentication, others may require support interactions, and requests and responses will always be requested in this scenario.
Error Types
The Marketo REST API can return three different types of errors under normal operation:
- HTTP-Level: These errors are indicated by a
4xx
code. - Response-Level: These errors are included in the 鈥渆rrors鈥 array of the JSON response.
- Record-Level: These errors are included in the 鈥渞esult鈥 array of the JSON response, and are indicated on an individual record basis with the 鈥渟tatus鈥 field and 鈥渞easons鈥 array.
For Response-Level and Record-Level error types, an HTTP status code of 200 is returned. For all error types, the HTTP reason phrase should not be evaluated as it is optional and subject to change.
HTTP-Level errors
Under normal operating circumstances Marketo should only return two HTTP status code 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 is 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 8KB. 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鈥檚 rare to hit this limit in most cases, but it is somewhat common when retrieving large batches of records with long individual filter values such as a GUID.
The endpoint can return a 401 Unauthorized error. This is typically due to an invalid Client Id or invalid Client Secret. HTTP-Level Error Codes
Response-Level errors
Response level errors are present when the success
parameter of the response is set to false, and are structured like:
{
"requestId": "e42b#14272d07d78",
"success": false,
"errors": [
{
"code": "601",
"message": "Unauthorized"
}
]
}
Each object in the 鈥渆rrors鈥 array has two members, code
, which is a quoted integer from 601 to 799 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 is a 601, 鈥淎ccess 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.
Response-Level Error Codes
An API call that returns this response code is not counted against your daily quota, or your rate limit.
- A date was specified that was not in the correct format
- An invalid dynamic content id was specified
The call cannot be fulfilled because it violates a requirement to create or update an asset, for example, trying to create an email without a template. It is also possible to get this error when trying to:
- Retrieve content for landing pages that contain social content.
- Clone a program that contains certain asset types (see Program Clone for more information).
- Approve an asset that has no draft (that is, has already been approved).
Record-Level record_level_errors
Record level errors indicate that an operation could not be completed for an individual record, but the request itself was valid. A response with record-level errors follows this pattern:
Response
{
"requestId":"e42b#14272d07d78",
"success":true,
"result":[
{
"id":50,
"status":"created"
},
{
"id":51,
"status":"created"
},
{
"status":"skipped",
"reasons":[
{
"code":"1005",
"message":"Lead already exists"
}
]
}
]
}
Records included in the result array of calls are ordered in the same way as the input array of a request.
Each record in a successful request may succeed or fail on an individual basis, which is indicated by the status field of each record included in the result array of a response. The 鈥渟tatus鈥 field of these records will be 鈥渟kipped鈥 and a 鈥渞easons鈥 array is present. Each reason contains a 鈥渃ode鈥 member, and a 鈥渕essage鈥 member. The code is always 1xxx, and the message indicates why the record was skipped. An example would be where a Sync Leads request has 鈥渁ction鈥 set to 鈥渃reateOnly鈥 but a lead already exists for one of the keys in the submitted records. This case returns a code of 1005, and a message of 鈥淟ead already exists鈥 as displayed above.