Amazon SP-API sandbox Orders API returns 403 Unauthorized despite LWA token and SigV4 signing

I’m testing the Amazon Selling Partner API (SP-API) using the sandbox environment, specifically the GET /orders/v0/orders endpoint.

Despite including both the LWA access token and signing the request with SigV4 using temporary credentials from AssumeRole, I am still getting the following error:

{
  "errors": [
    {
      "code": "Unauthorized",
      "message": "Access to requested resource is denied.",
      "details": "Access token is missing in the request header."
    }
  ]
}

Request Details:
    •   Endpoint:
https://sandbox.sellingpartnerapi-na.amazon.com/orders/v0/orders?CreatedAfter=TEST_CASE_200&MarketplaceIds=ATVPDKIKX0DER

Headers:
x-amzn-access-token: <valid LWA token>
x-amz-security-token: <from AssumeRole>
x-amz-date: <in YYYYMMDD'T'HHMMSS'Z' format>
Host: sandbox.sellingpartnerapi-na.amazon.com
Accept: application/json
Authorization: AWS4-HMAC-SHA256 ... (generated with SigV4)

Auth flow:
    1.  Get LWA token using refresh token, client ID, and client secret.
    2.  AssumeRole using long-term AWS access key and secret key.
    3.  Sign the request with botocore’s SigV4Auth.


Code:

I’m following this basic structure:
# Get LWA token
# Assume role
# Sign request using SigV4Auth from botocore.auth
# Send with requests.Session().send()


What I’ve checked:
    •   LWA token is valid and not expired.
    •   Temporary credentials from AssumeRole include session token.
    •   All required headers (including x-amzn-access-token) are correctly set.
    •   Endpoint, query parameters, and service name are accurate.
    •   SigV4 signature is freshly generated for each request.

Questions:
    •   Is there any known issue with the sandbox and GET /orders/v0/orders?
    •   Is it possible the sandbox rejects requests even with proper headers for some TEST_CASE values?
    •   Could the issue stem from a missing permission even in the sandbox?

Any help or clarification is much appreciated!

You’re doing a lot of the right things — and this kind of error is frustrating because it appears to say your x-amzn-access-token is missing, even though you clearly include it.

Let’s walk through a refined checklist and known quirks to isolate the issue.


Key Things to Verify for SP-API Sandbox Access

1. Sandbox test case only supports TEST_CASE_200

You’re using:

CreatedAfter=TEST_CASE_200

That’s correct for the sandbox!

BUT Amazon’s sandbox only returns results for that exact value. Any other value will either return:

  • No results
  • Or an error — often confusing or misleading.

Make sure you URL encode the CreatedAfter value properly:

CreatedAfter=TEST_CASE_200

(This is not always the cause, but malformed query strings do trip things up.)


2. Required Headers Checklist

You need these headers:

Header Description
x-amzn-access-token Your LWA token (OAuth2)
x-amz-access-token Sometimes required (try both!)
x-amz-security-token STS session token (from AssumeRole)
Authorization SigV4 authorization
x-amz-date SigV4 timestamp
Host Always include explicitly
user-agent Required in some APIs (optional in Orders)

Important: Sometimes Amazon inconsistently parses headers — try including both:

x-amzn-access-token: <your LWA token>
x-amz-access-token: <your LWA token>

3. Auth Quirks: Access Token Placement

Even if you’re passing all headers correctly, the SigV4 canonical request (used in signing) must NOT include the access token.

Make sure:

  • You include x-amzn-access-token and x-amz-security-token in the actual request headers,
  • BUT do not sign them when creating the AWS Signature (canonical headers).

Otherwise, the server rejects the request due to mismatch.


4. Correct Signing Flow with AssumeRole

When using AssumeRole, ensure:

  • You include x-amz-security-token in both:
    • the headers you send
    • the canonical headers for signing

This is a common mistake — the session token must be signed and also sent.


5. Verify IAM Permissions Even in Sandbox

Even the sandbox checks IAM permissions.

Your assumed role needs:

{
  "Effect": "Allow",
  "Action": [
    "execute-api:Invoke"
  ],
  "Resource": "*"
}

Additionally:

  • You must register and link the role in Seller Central’s developer profile.
  • The SP-API app must list this role under IAM ARN and be in Active status.

Debug Tip: Try Replacing requests with http.client or Postman

If you’re still getting the same "Access token is missing" error:

  1. Try using a REST client like Postman to test the signed request — it helps isolate requests.Session() quirks.
  2. Add logging to your SigV4 signature string and compare against AWS SDK samples.

Summary of Fix Suggestions

  • Include both x-amzn-access-token and x-amz-access-token
  • Do not sign access token headers in SigV4
  • Make sure x-amz-security-token is both signed and sent
  • Ensure IAM role has execute-api:Invoke permission
  • Check that the role is linked to your app in Seller Central
  • Only use CreatedAfter=TEST_CASE_200 (and URL-encode it)