This guide explains how to handle errors returned by the Merchant API. Understanding the error response structure and stability is crucial for building robust integrations that can automatically recover from failures or provide meaningful feedback to users.
Overview
When a Merchant API request fails, the API returns a standard HTTP status code
(4xx or 5xx) and a JSON response body containing details about the error.
The Merchant API follows the AIP-193 standard for
error details, providing machine-readable information that allows your
application to handle specific error scenarios programmatically.
Error response structure
The error response is a JSON object that contains standard fields like code,
message, and status. Crucially, it also includes a details array. To
handle errors programmatically, you should look for an object within details
where the @type is type.googleapis.com/google.rpc.ErrorInfo.
This ErrorInfo object provides stable, structured data about the error:
- domain: The logical grouping of the error, typically
merchantapi.googleapis.com. - metadata: A map of dynamic values related to the error. This includes:
- REASON: A specific, stable identifier for the exact error (e.g.,
INVALID_NAME_PART_NOT_NUMBER,PERMISSION_DENIED_ACCOUNTS). This field is always present. Use this field for fine grained error handling in your application logic. - HELP_CENTER_LINK: Provides additional context and instructions to fix the issue. This field is not present for all errors, but we plan to expand its coverage over time for the errors where more context might be needed.
- Other dynamic fields: Other keys providing context, such as the name
of the invalid field (
FIELD_LOCATION) or the value that caused the error (FIELD_VALUE).
- REASON: A specific, stable identifier for the exact error (e.g.,
Sample error responses
The following JSON demonstrates the structure of a Merchant API error where a resource name was malformed.
{
"error": {
"code": 400,
"message": "[name] The part `account` of the resource name in field `name` must be a number, but has value: `abcd`.",
"status": "INVALID_ARGUMENT",
"details": [
{
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "invalid",
"domain": "merchantapi.googleapis.com",
"metadata": {
"VARIABLE_NAME": "account",
"FIELD_LOCATION": "name",
"FIELD_VALUE": "abcd",
"REASON": "INVALID_NAME_PART_NOT_NUMBER"
}
}
]
}
}
Here is an example of an authentication error:
{
"error": {
"code": 401,
"message": "The caller does not have access to the accounts: [1234567]",
"status": "UNAUTHENTICATED",
"details": [
{
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "unauthorized",
"domain": "merchantapi.googleapis.com",
"metadata": {
"ACCOUNT_IDS": "[1234567]",
"REASON": "PERMISSION_DENIED_ACCOUNTS"
}
}
]
}
}
Stability of error fields
When writing error handling logic, it is important to know which fields are safe to rely on and which might change.
- Stable fields:
details.metadata.REASON: The specific error identifier. You should rely on this field for your application's control flow logic.details.metadatakeys: The keys within the metadata map (e.g.,FIELD_LOCATION,ACCOUNT_IDS) are stable.code: The high-level HTTP status code (e.g.,400,401,503) is stable.
Unstable fields:
message: The human-readable error message is not stable. It is intended for developer debugging only. Do not write code that parses or relies on the text content of themessagefield, as it may change without notice to improve clarity or add context.details.metadatavalues: While the keys are stable, the values for informational keys may change. For example, if aHELP_CENTER_LINKkey is provided, the specific URL it points to might be updated to a newer documentation page without prior notification. However, as mentioned earlier, the value ofdetails.metadata.REASONis stable.
Best practices
Follow these best practices to ensure your integration handles errors gracefully.
Use details.metadata.REASON for logic
Always use the specific REASON inside the metadata map to determine the
cause of an error. Don't rely on the HTTP status code alone, as multiple errors
may share the same status code.
Don't parse the error message
As noted in the stability section, the message field is for human consumption.
If you need dynamic information (like which field was invalid), extract it from
the metadata map using stable keys like FIELD_LOCATION, VARIABLE_NAME.
Implement exponential backoff
For errors indicating temporary unavailability or rate limiting, implement an exponential backoff strategy. This means waiting for a short period before retrying, and increasing the wait time with each subsequent failure.
quota/request_rate_too_high: This error indicates you have exceeded your minute quota for specific quota group. Slow down your request rate.internal_error: These are usually transient. Retry with exponential backoff. Note: Ifinternal_errorpersists after multiple retries with backoff, see How to contact Merchant API support.
How to contact Merchant API support
If you need to contact Merchant API support about a specific error, provide the following information in your request:
- The exact error response received
- The API method name
- The request payload
- Timestamps or the time range during which the method was called and errors were received