amzn / selling-partner-api-models

This repository contains OpenAPI models for developers to use when developing software to call Selling Partner APIs.
Apache License 2.0
612 stars 736 forks source link

POST request: "Missing or invalid request parameters: [marketplaceIds]", #772

Closed flalex closed 3 years ago

flalex commented 4 years ago

Could you please help with work example of POST request? How should be passed marketplaceIds parameter? What Content-Type should be here? Also tried to use json content-type and pass it as query parameter. Nothing works for me.

Request

POST https://sellingpartnerapi-na.amazon.com/solicitations/v1/orders/{my-amazon-order-id}/solicitations/productReviewAndSellerFeedback user-agent: MyUserAgent Accept-Encoding: gzip, deflate Accept: / Connection: keep-alive host: sellingpartnerapi-na.amazon.com x-amz-date: 20201113T202604Z Authorization: AWS4-HMAC-SHA256 Credential=*/20201113/us-east-1/execute-api/aws4_request, SignedHeaders=host;user-agent;x-amz-access-token;x-amz-date, Signature=ad31a29d81b0cd8867ed291fe8fb7df6f9fe70a3d1bd94b1904a0c127ffe1d4d x-amz-access-token: Atza|MyToken Content-Length: 28 Content-Type: application/x-www-form-urlencoded

marketplaceIds=ATVPDKIKX0DER

Response:

{'Date': 'Fri, 13 Nov 2020 20:26:05 GMT', 'Content-Type': 'application/json', 'Content-Length': '136', 'Connection': 'keep-alive', 'x-amzn-RequestId': 'c37a3073-75fb-4b4d-a1b3-4ffe04ba246d', 'x-amzn-ErrorType': 'BadRequestException', 'x-amz-apigw-id': 'V9nKjH-UIAMF3AQ='}

->Content:{ "errors": [ { "message": "Missing or invalid request parameters: [marketplaceIds]", "code": "InvalidInput" } ] }

rogersv commented 4 years ago

Look at the post-example in this python script https://docs.aws.amazon.com/general/latest/gr/sigv4-signed-request-examples.html

I think the problem is that you are missing the payload header.

flalex commented 4 years ago

Hi @rogersv, thanks for reply, but could you clarify what header are you referring? Not sure if it's payload_hash that used in building canonical_request, because wrong payload_hash leads to InvalidSignatureException.

Also, at the link above POST request uses amz_target and content-type as signed_headers, but official guide hasn't mentioned that and it looks confusing. https://github.com/amzn/selling-partner-api-docs/blob/main/guides/developer-guide/SellingPartnerApiDeveloperGuide.md#step-3-add-headers-to-the-uri

rogersv commented 4 years ago

Look for x-amz-content-sha256 in https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html

That helped me in another post call. I have not try this specific call.

rodrigojob commented 3 years ago

You send data in json? try convert and if dont work : Content-Type: application/json

FexusZ commented 3 years ago

Same problem, I try to send a POST request, but nothing works.

flalex commented 3 years ago

@rogersv

Look for x-amz-content-sha256 in https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html

That helped me in another post call. I have not try this specific call.

It didn't help. Also, I'm really curious why it could be related to another service.

Request

POST https://sellingpartnerapi-na.amazon.com/solicitations/v1/orders/MY_ORDER_ID/solicitations/productReviewAndSellerFeedback user-agent: MY_USER_AGENT/0.1 (Language=Python) Accept-Encoding: gzip, deflate Accept: / Connection: keep-alive host: sellingpartnerapi-na.amazon.com x-amz-date: 20201118T115356Z Authorization: AWS4-HMAC-SHA256 Credential=/20201118/us-east-1/execute-api/aws4_request, SignedHeaders=host;user-agent;x-amz-access-token;x-amz-content-sha256;x-amz-date, Signature=9dad9b71951da0df0fecabeab2d68175cf79020809cb87bb2c62fb32127fe101 x-amz-access-token: Atza|MY_TOKEN Content-Type: application/json Content-Length: 35

b'{"marketplaceIds": "ATVPDKIKX0DER"}'

Response:

{'Date': 'Wed, 18 Nov 2020 11:53:57 GMT', 'Content-Type': 'application/json', 'Content-Length': '136', 'Connection': 'keep-alive', 'x-amzn-RequestId': '6b13452b-9bca-48d6-b88b-31a5c11e69ba', 'x-amzn-ErrorType': 'BadRequestException', 'x-amz-apigw-id': 'WM61YFEKoAMFkRg='}

{ "errors": [ { "message": "Missing or invalid request parameters: [marketplaceIds]", "code": "InvalidInput" } ] }

@rodrigojob I tried to send it as json, url-encoded, as query string. Nothing works. @FexusZ Do you have samples?

Could amazon team helps with that? It takes minutes to find the answer for API developers and not hours for making experiments.

FexusZ commented 3 years ago

for : https://sellingpartnerapi-eu.amazon.com/fba/smallAndLight/v1/feePreviews

and body : { "marketplaceIds":"A13V1IB3VIYZZH", "Items": [ { "asin":"B0794VMZ8G", "price": [ { "amount":10, "currencyCode":"EUR" } ] } ] }

i get error response : { "errors": [ { "code": "InvalidInput", "message": "Invalid Input", "details": "" } ] }

Get request work correctly, but i can't make POST or other request, i use postman and body is in raw

FexusZ commented 3 years ago

I added other header parameter in the request, I am using php and curl, and it also doesn't work too..

header :

rogersv commented 3 years ago

I just tested the call and it seems to work fine. It is quite clear in the documentation that the marketplaceIds is a query parameter. There is no body for this request.

flalex commented 3 years ago

Hi @rogersv, Could you please share example of your request. It's better to see it once, right. Thank you!

rogersv commented 3 years ago

Method: POST Request:

https://sellingpartnerapi-eu.amazon.com/solicitations/v1/orders/{myorderid}/solicitations/productReviewAndSellerFeedback?marketplaceIds={marketplaceId}

Headers:

{
    "x-amz-date": "20201118T144755Z",
    "x-amz-access-token": "mytoken",
    "x-amz-security-token": "anothertoken",
    "host": "sellingpartnerapi-eu.amazon.com",
    "Authorization": "AWS4-HMAC-SHA256 Credential=XXX/20201118/eu-west-1/execute-api/aws4_request,SignedHeaders=host;x-amz-access-token;x-amz-date;x-amz-security-token, Signature=YYY"
}

Edit: this was an example of a successful request.

GenderAPI commented 3 years ago

the method must POST but the marketplace parameter will send as GET parameter

rodrigojob commented 3 years ago

Try: MarketplaceIds

intellifox-hq commented 3 years ago

Hi @flalex What did the trick for me was setting the content-type improperly for the request to pass.

I was using the following : 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',

but that led to the error

{
  errors: [
    {
      message: "When Content-Type:application/x-www-form-urlencoded, URL cannot include query-string parameters (after '?'): '/solicitations/v1/orders/{order_id}/solicitations/productReviewAndSellerFeedback?'",
      code: 'InvalidInput'
    }
  ]
}

Which is quite surprising.

By accident, I switched to another content-type (I was trying to pass the params as a json)

'Content-Type': 'application/json; charset=utf-8',

Which works fine...

Here is my complete code

const access_token = '' // access token

const key_id = '' // IAM user key id
const secret = '' // IAM user secret

const endpoint = '' // from https://github.com/amzn/selling-partner-api-docs/blob/main/guides/developer-guide/SellingPartnerApiDeveloperGuide.md#selling-partner-api-http-methods
const region = '' // from https://github.com/amzn/selling-partner-api-docs/blob/main/guides/developer-guide/SellingPartnerApiDeveloperGuide.md#selling-partner-api-endpoints
const market_place_id = '' // from https://github.com/amzn/selling-partner-api-docs/blob/main/guides/developer-guide/SellingPartnerApiDeveloperGuide.md#marketplaceid-values

const HTTP_method = 'POST'
const path = `/solicitations/v1/orders/${order_id}/solicitations/productReviewAndSellerFeedback`
const query_string = `marketplaceIds=${market_place_id}`

const service = 'execute-api'

const now = new Date()

const headers_to_sign = {
  host: endpoint,
  'x-amz-access-token': access_token,
  'x-amz-date': `${moment(now).toISOString()}`,
  'user-agent': 'intellifox-api-1.6',
}

const canonical_request = createCanonicalRequest(
  HTTP_method, path, query_string, headers_to_sign
)

const string_to_sign = createStringToSign(
  now, region, service, canonical_request,
)

const signature = createSignature(
  secret, now, region, service, string_to_sign,
)

await axios({
  method: HTTP_method,
  url: `https://${endpoint}${path}${query_string ? '?' + query_string : ''}`,
  headers: {
    Authorization: `AWS4-HMAC-SHA256 Credential=${key_id}/${moment(now).format('YYYYMMDD')}/${region}/${service}/aws4_request, SignedHeaders=host;user-agent;x-amz-access-token;x-amz-date, Signature=${signature}`,
    'Content-Type': 'application/json; charset=utf-8',
    ...headers_to_sign,
  },
})
kingsun-he commented 3 years ago

Hi @flalex What did the trick for me was setting the content-type improperly for the request to pass.

I was using the following : 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',

but that led to the error

{
  errors: [
    {
      message: "When Content-Type:application/x-www-form-urlencoded, URL cannot include query-string parameters (after '?'): '/solicitations/v1/orders/{order_id}/solicitations/productReviewAndSellerFeedback?'",
      code: 'InvalidInput'
    }
  ]
}

Which is quite surprising.

By accident, I switched to another content-type (I was trying to pass the params as a json)

'Content-Type': 'application/json; charset=utf-8',

Which works fine...

Here is my complete code

const access_token = '' // access token

const key_id = '' // IAM user key id
const secret = '' // IAM user secret

const endpoint = '' // from https://github.com/amzn/selling-partner-api-docs/blob/main/guides/developer-guide/SellingPartnerApiDeveloperGuide.md#selling-partner-api-http-methods
const region = '' // from https://github.com/amzn/selling-partner-api-docs/blob/main/guides/developer-guide/SellingPartnerApiDeveloperGuide.md#selling-partner-api-endpoints
const market_place_id = '' // from https://github.com/amzn/selling-partner-api-docs/blob/main/guides/developer-guide/SellingPartnerApiDeveloperGuide.md#marketplaceid-values

const HTTP_method = 'POST'
const path = `/solicitations/v1/orders/${order_id}/solicitations/productReviewAndSellerFeedback`
const query_string = `marketplaceIds=${market_place_id}`

const service = 'execute-api'

const now = new Date()

const headers_to_sign = {
  host: endpoint,
  'x-amz-access-token': access_token,
  'x-amz-date': `${moment(now).toISOString()}`,
  'user-agent': 'intellifox-api-1.6',
}

const canonical_request = createCanonicalRequest(
  HTTP_method, path, query_string, headers_to_sign
)

const string_to_sign = createStringToSign(
  now, region, service, canonical_request,
)

const signature = createSignature(
  secret, now, region, service, string_to_sign,
)

await axios({
  method: HTTP_method,
  url: `https://${endpoint}${path}${query_string ? '?' + query_string : ''}`,
  headers: {
    Authorization: `AWS4-HMAC-SHA256 Credential=${key_id}/${moment(now).format('YYYYMMDD')}/${region}/${service}/aws4_request, SignedHeaders=host;user-agent;x-amz-access-token;x-amz-date, Signature=${signature}`,
    'Content-Type': 'application/json; charset=utf-8',
    ...headers_to_sign,
  },
})

Hi intellifox-hq, don't you need the "AWS IAM Role ARN" to create your Signature? The key like "arn:aws:iam::123456789:role".

intellifox-hq commented 3 years ago

Hello @kingsun-he the code above is a functional one we use in our app. The only place we needed to use the "AWS IAM Role ARN" was in the Developer Central dashboard, but it is not used to sign the message directly. It is referenced by the following:

const key_id = '' // IAM user key id
const secret = '' // IAM user secret

Which points to the IAM user whose role must match what is entered in the Developer Central dashborad.

kingsun-he commented 3 years ago

Hello @kingsun-he the code above is a functional one we use in our app. The only place we needed to use the "AWS IAM Role ARN" was in the Developer Central dashboard, but it is not used to sign the message directly. It is referenced by the following:

const key_id = '' // IAM user key id
const secret = '' // IAM user secret

Which points to the IAM user whose role must match what is entered in the Developer Central dashborad.

Hi intellifox-hq, Do you mean you can call the method "productReviewAndSellerFeedback" though you didn't use the Role ARN key? I failed to call this method. It always return "Access to requested resource is denied." It make me depressed.

intellifox-hq commented 3 years ago

Dear @kingsun-he , I know exactly how you feel. This is not easy. You can read on my own journey on this issue: https://github.com/amzn/selling-partner-api-models/issues/805 I described all the steps I took to resolve it.

Just for the "Access to requested resource is denied." be careful of the route you use: check it and re-check it. This error is also returned if you use a wrong route (I paid the price for this error myself..)

Take care

kingsun-he commented 3 years ago

Dear @kingsun-he , I know exactly how you feel. This is not easy. You can read on my own journey on this issue: amzn/selling-partner-api-models#805 I described all the steps I took to resolve it.

Just for the "Access to requested resource is denied." be careful of the route you use: check it and re-check it. This error is also returned if you use a wrong route (I paid the price for this error myself..)

Take care

Hi intellifox-hq, It seems that it doesn't resolve my problem. I took self-authorize to my application. It has nothing to do with App Store. Actually, I can access to orders-api, catalogItem-api and get the data successfully. But when I used the 2 methods of solicitations-api, it will return "Access to requested resource is denied." always. So do you use the 2 methods successfully?

Even I tried it in postman, I failed. So I wonder if there is a problem of Amazon API.

====================================== Here is my http Info: POST /solicitations/v1/orders/123-1234567-1234567/solicitations/productReviewAndSellerFeedback?marketplaceIds=ATVPDKIKX0DER HTTP/1.1 Host: sandbox.sellingpartnerapi-eu.amazon.com x-amz-access-token: Atza|IXXXXXXXO8Rd8MBkai security_token: FwoGZXIvYXdzEOP//////////wXXXXXXXXXXXBALlAyCg/ll0/VnFuMANI14d/Nm6e0OK9rgPN6k4xPSolDnWmArfjDpuugE= Content-Type: application/json X-Amz-Content-Sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 X-Amz-Security-Token: FwoGZXIvYXdzEOP//////////wEaDFXXXXXX4xPSolDnWmArfjDpuugE= X-Amz-Date: 20210201T103142Z Authorization: AWS4-HMAC-SHA256 Credential=ASIXXXXXXXXG/20210201/eu-west-1/execute-api/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token, Signature=fa41a7fcXXXXXXXXXXXXXfec0081d2d9efc9178f9e42857cb

intellifox-hq commented 3 years ago

Hi intellifox-hq, It seems that it doesn't resolve my problem. I took self-authorize to my application. It has nothing to do with App Store. Actually, I can access to orders-api, catalogItem-api and get the data successfully. But when I used the 2 methods of solicitations-api, it will return "Access to requested resource is denied." always. So do you use the 2 methods successfully?

Even I tried it in postman, I failed. So I wonder if there is a problem of Amazon API.

====================================== Here is my http Info: POST /solicitations/v1/orders/123-1234567-1234567/solicitations/productReviewAndSellerFeedback?marketplaceIds=ATVPDKIKX0DER HTTP/1.1 Host: sandbox.sellingpartnerapi-eu.amazon.com x-amz-access-token: Atza|IXXXXXXXO8Rd8MBkai security_token: FwoGZXIvYXdzEOP//////////wXXXXXXXXXXXBALlAyCg/ll0/VnFuMANI14d/Nm6e0OK9rgPN6k4xPSolDnWmArfjDpuugE= Content-Type: application/json X-Amz-Content-Sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 X-Amz-Security-Token: FwoGZXIvYXdzEOP//////////wEaDFXXXXXX4xPSolDnWmArfjDpuugE= X-Amz-Date: 20210201T103142Z Authorization: AWS4-HMAC-SHA256 Credential=ASIXXXXXXXXG/20210201/eu-west-1/execute-api/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token, Signature=fa41a7fcXXXXXXXXXXXXXfec0081d2d9efc9178f9e42857cb

I checked the code I use for this: the route seems correct, the query string also, I don't see why it would fail. The only thing that could trigger this issue is if the order_id is not related to your account. If that's not the case, reach out to the support, they take some time but they solve issues as soon as they can.

Good day to you

Drageir commented 3 years ago

Try making marketplaceIds a list (marketplaceIds = [ATVPDKIKX0DER]). This solved it for me for uploading feeds and other documents on Python, maybe it works on you too.