Skip to main content

When a call fails

Every failure comes back in the same envelope:

{ "ok": false, "kind": "bad_request", "friendly": "...", "message": "...",
  "amazon_error_code": "InvalidInput", "status": 400 }

Branch on kind, not on the HTTP status. friendly is safe to show a person as-is. message is the specific reason, and it is the field to read when you are trying to fix something.

The only question that matters first: whose problem is it?

Retrying the wrong kind of failure is the most common way to lose an afternoon here, so the answer is meant to be obvious from the response alone.

| You get | Whose problem | Retry? | | --- | --- | --- | | 400 bad_request | Yours. Amazon rejected the request itself. | No. It is deterministic and will fail identically forever. Change the request. | | 403 restricted_report | An access or role gap. | No. Re-authorize the merchant, or use a different operation. | | 409 reauth_required | The merchant's Amazon connection lapsed. | Re-connect the account first, then yes. | | 404 merchant_not_found | The merchant selector matched nothing. | No. See Identify a merchant. | | 429 throttled | Rate limiting, ours or Amazon's. | Yes, after backing off. Honour Retry-After. | | 502 upstream_unavailable or host_unreachable | Amazon's, or the network. | Yes, later. For writes, check whether it applied first. | | 500 unknown | Ours, and now rare. | Once. If it persists, tell us. |

The write caveat on 502 is worth reading twice: a server error does not prove Amazon rejected your change before acting on it. Re-read the entity before you re-send, or you can apply the same change twice.

bad_request: what Amazon actually said

This is the one to know, because it used to be the confusing one. A request Amazon refused because of its own parameters used to come back as a 500, which reads as an outage and invites a retry that could never work. It now comes back as a 400 and carries Amazon's own words:

  • amazon_error_code is Amazon's code, such as InvalidInput or InvalidParameterValue.
  • status is Amazon's own HTTP status, separate from ours.
  • responsePayload is Amazon's full response, when we captured it.

In the plugin, the same information prints to the terminal, and --json carries amazon_error_code, amazon_status and amazon_response. Scripts get exit code 12, which is distinct from the generic failure code precisely so a script can stop instead of retrying.

Most of the time this means a parameter is missing, misspelled, or in the wrong case. The operation catalog (GET /api/amazon/spapi/operations) documents the required parameters and the casing rules for each call, and it is the first thing to check.

Reporting a failure, and why it is worth your thirty seconds

Sometimes the request was wrong because our documentation said to make it that way.

The operation catalog is maintained by hand. Amazon occasionally enforces a parameter it does not document, or requires two parameters only in combination, and until someone hits it our notes look complete. When our notes are wrong, every caller walks into the same wall.

Here is the asymmetry that makes your report valuable: we can see that a call failed and which operation it was. We cannot see your parameters. You are holding the half we are missing.

So please send three things:

  1. the operation id, for example fulfillment_inbound.get_shipments
  2. the amazon_error_code and the message from the envelope
  3. the parameters you sent, minus anything you consider sensitive

Where to send it:

  • Plugin users: run mixshift feedback. It attaches the context for you.
  • Everyone else: support@mixshift.io.

We record the Amazon error code against the operation, so the same code repeating on the same call surfaces as a pattern on our side. A confirmed gap normally turns into a catalog note that the next caller never trips over. That is the whole loop, and it starts with someone bothering to tell us.

Still have questions?
Ask Shifty

Shifty is the MixShift docs assistant. Pick a question or open the chat for anything else.