{"id":13748865,"url":"https://github.com/amz-tools/amazon-sp-api","last_synced_at":"2025-05-09T11:31:32.155Z","repository":{"id":37391809,"uuid":"313051143","full_name":"amz-tools/amazon-sp-api","owner":"amz-tools","description":"Amazon Selling Partner API Client","archived":false,"fork":false,"pushed_at":"2025-04-14T11:48:15.000Z","size":642,"stargazers_count":244,"open_issues_count":71,"forks_count":125,"subscribers_count":15,"default_branch":"main","last_synced_at":"2025-04-14T12:47:10.831Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/amz-tools.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-11-15T14:38:29.000Z","updated_at":"2025-04-13T13:18:02.000Z","dependencies_parsed_at":"2024-01-03T13:28:48.696Z","dependency_job_id":"c41baaed-0726-498c-9732-4bf90308809b","html_url":"https://github.com/amz-tools/amazon-sp-api","commit_stats":{"total_commits":317,"total_committers":30,"mean_commits":"10.566666666666666","dds":"0.33753943217665616","last_synced_commit":"f7db3be8b99dda91c9b53ba25a330037ecc22a3b"},"previous_names":[],"tags_count":62,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amz-tools%2Famazon-sp-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amz-tools%2Famazon-sp-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amz-tools%2Famazon-sp-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amz-tools%2Famazon-sp-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/amz-tools","download_url":"https://codeload.github.com/amz-tools/amazon-sp-api/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253240350,"owners_count":21876593,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-03T07:00:51.109Z","updated_at":"2025-05-09T11:31:32.119Z","avatar_url":"https://github.com/amz-tools.png","language":"JavaScript","readme":"# amazon-sp-api (client for the Amazon Selling Partner API)\n\nThe client handles calls to the Amazon Selling Partner API. It wraps up all the necessary stuff such as requesting access tokens and providing (a simplified!) way of calling the API, but also provides some convenience, i.e. a wrapper for requesting and downloading reports and an internal handling of rate limits when calls are throttled.\n\n```diff\n- Please note: There are a few breaking changes if you are\n- upgrading from version 0.x.x to 1.x.x. Please see the link below.\n```\n\n[List of breaking changes when upgrading to version 1.x.x](#breaking-changes)\n\n## Contents\n\n- [Prerequisites](#prerequisites)\n- [Installation](#installation)\n- [Getting Started](#getting-started)\n  - [Setting credentials from environment variables](#setting-credentials-from-environment-variables)\n  - [Setting credentials from file](#setting-credentials-from-file)\n  - [Setting credentials from constructor config object](#setting-credentials-from-constructor-config-object)\n- [Usage](#usage)\n  - [Config params](#config-params)\n  - [Use a proxy agent](#use-a-proxy-agent)\n  - [Exchange an authorization code for a refresh token](#exchange-an-authorization-code-for-a-refresh-token)\n  - [Request access token](#request-access-token)\n- [Call the API](#call-the-api)\n  - [Examples](#examples)\n  - [Endpoints](#endpoints)\n  - [Versions](#versions)\n    - [Version specific operation implementations](#version-specific-operation-implementations)\n    - [Defining endpoints versions on class level](#defining-endpoints-versions-on-class-level)\n    - [Fallback](#fallback)\n  - [Unsupported endpoints/versions/operations](#unsupported-endpointsversionsoperations)\n  - [Grantless operations](#grantless-operations)\n  - [Restore rates](#restore-rates)\n  - [Timeouts](#timeouts)\n- [Download reports](#download-reports)\n  - [Download reports as stream](#download-reports-as-stream)\n- [Upload feeds](#upload-feeds)\n- [TypeScript Support](#typescript-support)\n- [Sandbox mode](#sandbox-mode)\n- [Known Issues](#known-issues)\n- [Seller Support](#seller-support)\n- [Breaking Changes](#breaking-changes)\n\n## Prerequisites\n\nMake sure that you followed the [Selling Partner API Developer Guide](https://developer-docs.amazon.com/sp-api/docs) and have successfully completed the steps [Registering as a developer](https://developer-docs.amazon.com/sp-api/docs/registering-as-a-developer), [Registering your application](https://developer-docs.amazon.com/sp-api/docs/registering-your-application) and have a valid refresh token (if you use the client only for your own seller account the easiest way is using the self authorization as described in the developer guide).\n\n## Installation\n\n```bash\nnpm install amazon-sp-api\n```\n\n## Getting Started\n\nBefore you can use the client you need to add your app client and secret.\n\n### Setting credentials from environment variables\n\n- `SELLING_PARTNER_APP_CLIENT_ID`=\u003cYOUR_APP_CLIENT_ID\u003e ([see SP Developer Guide \"Viewing your application information and credentials\"](https://developer-docs.amazon.com/sp-api/docs/viewing-your-application-information-and-credentials))\n- `SELLING_PARTNER_APP_CLIENT_SECRET`=\u003cYOUR_APP_CLIENT_SECRET\u003e ([see SP Developer Guide \"Viewing your application information and credentials\"](https://developer-docs.amazon.com/sp-api/docs/viewing-your-application-information-and-credentials))\n\n### Setting credentials from file\n\nInstead of setting the credentials via environment variables you may load them from a credentials file. The default path to the file is `~/.amzspapi/credentials` (path can be changed when creating a client) and you add the credentials one per line:\n\n```bash\nSELLING_PARTNER_APP_CLIENT_ID=\u003cYOUR_APP_CLIENT_ID\u003e\nSELLING_PARTNER_APP_CLIENT_SECRET=\u003cYOUR_APP_CLIENT_SECRET\u003e\n```\n\n### Setting credentials from constructor config object\n\nAlthough the most convenient and recommended way of setting the credentials is via environment variables or config file it is also possible to pass the credentials inside the config object when creating an instance of the client (i.e. if you have no means of using env vars or a config file). The structure of the constructor config object will be explained below.\n\n## Usage\n\nRequire library:\n\n```javascript\n// commonjs\nconst SellingPartner = require('amazon-sp-api');\n\n// esm\nimport {SellingPartner} from 'amazon-sp-api';\n```\n\nCreate client and call API:\n\n```javascript\n(async () =\u003e {\n  try {\n    const spClient = new SellingPartner({\n      region: 'eu', // The region to use for the SP-API endpoints (\"eu\", \"na\" or \"fe\")\n      refresh_token: '\u003cREFRESH_TOKEN\u003e' // The refresh token of your app user\n    });\n    let res = await spClient.callAPI({\n      operation: 'getMarketplaceParticipations',\n      endpoint: 'sellers'\n    });\n    console.log(res);\n  } catch (e) {\n    console.log(e);\n  }\n})();\n```\n\n### Config params\n\nThe class constructor takes a config object with the following structure as input:\n\n```javascript\n{\n  region:'\u003cREGION\u003e',\n  refresh_token:'\u003cREFRESH_TOKEN\u003e',\n  access_token:'\u003cACCESS_TOKEN\u003e',\n  endpoints_versions:{\n    ...\n  },\n  credentials:{\n    SELLING_PARTNER_APP_CLIENT_ID:'\u003cAPP_CLIENT_ID\u003e',\n    SELLING_PARTNER_APP_CLIENT_SECRET:'\u003cAPP_CLIENT_SECRET\u003e'\n  },\n  options:{\n    credentials_path:'~/.amzspapi/credentials',\n    auto_request_tokens:true,\n    auto_request_throttled:true,\n    version_fallback:true,\n    use_sandbox:false,\n    only_grantless_operations:false,\n    user_agent:'amazon-sp-api/\u003cCLIENT_VERSION\u003e (Language=Node.js/\u003cNODE_VERSION\u003e; Platform=\u003cOS_PLATFORM\u003e/\u003cOS_RELEASE\u003e)',\n    debug_log:false,\n    timeouts:{\n      ...\n    },\n    retry_remote_timeout:true,\n    https_proxy_agent:\u003cHttpsProxyAgent\u003e\n  }\n}\n```\n\nValid properties of the config object:\n\n| Name                                 |  Type  | Default | Description                                                                                                                                                                                                                                                                                                                   |\n| :----------------------------------- | :----: | :-----: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| **region**\u003cbr\u003e_required_             | string |    -    | The region to use for the SP-API endpoints.\u003cbr\u003eMust be one of: `eu`, `na` or `fe`                                                                                                                                                                                                                                             |\n| **refresh_token**\u003cbr\u003e_optional_      | string |    -    | The refresh token of your app user.\u003cbr\u003eRequired if `only_grantless_operations` option is set to `false`.                                                                                                                                                                                                                      |\n| **access_token**\u003cbr\u003e_optional_       | string |    -    | The temporary access token requested with the refresh token of the app user.                                                                                                                                                                                                                                                  |\n| **endpoints_versions**\u003cbr\u003e_optional_ | object |    -    | Defines the version to use for an endpoint as key/value pairs, i.e. `\"reports\":\"2021-06-30\"`. If none given the client is using the first (meaning the oldest) version for an endpoint.\u003cbr\u003eCall `.endpoints` on class instance to retrieve a complete list of all endpoints, versions and operations supported by the client. |\n| **credentials**\u003cbr\u003e_optional_        | object |    -    | The app client credentials. Must include the two credentials properties `SELLING_PARTNER_APP_CLIENT_ID` and `SELLING_PARTNER_APP_CLIENT_SECRET`\u003cbr\u003eNOTE: Should only be used if you have no means of using environment vars or credentials file!                                                                              |\n| **options**\u003cbr\u003e_optional_            | object |    -    | Additional options, see table below for all possible options properties.                                                                                                                                                                                                                                                      |\n\nValid properties of the config options:\n\n| Name                                        |  Type   |                                                Default                                                | Description                                                                                                                                                    |\n| :------------------------------------------ | :-----: | :---------------------------------------------------------------------------------------------------: | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| **credentials_path**\u003cbr\u003e_optional_          | string  |                                        ~/.amzspapi/credentials                                        | A custom absolute path to your credentials file location.                                                                                                      |\n| **auto_request_tokens**\u003cbr\u003e_optional_       | boolean |                                                 true                                                  | Whether or not the client should retrieve new access token if non given or expired.                                                                            |\n| **auto_request_throttled**\u003cbr\u003e_optional_    | boolean |                                                 true                                                  | Whether or not the client should automatically retry a request when throttled.                                                                                 |\n| **version_fallback**\u003cbr\u003e_optional_          | boolean |                                                 true                                                  | Whether or not the client should try to use an older version of an endpoint if the operation is not defined for the desired version.                           |\n| **use_sandbox**\u003cbr\u003e_optional_               | boolean |                                                 false                                                 | Whether or not to use the sandbox endpoint.                                                                                                                    |\n| **only_grantless_operations**\u003cbr\u003e_optional_ | boolean |                                                 false                                                 | Whether or not to only use grantless operations.                                                                                                               |\n| **user_agent**\u003cbr\u003e_optional_                | string  | amazon-sp-api/\u003cCLIENT_VERSION\u003e (Language=Node.js/\u003cNODE_VERSION\u003e; Platform=\u003cOS_PLATFORM\u003e/\u003cOS_RELEASE\u003e) | A custom user-agent header ([see desired format in docs](https://developer-docs.amazon.com/amazon-shipping/docs/include-a-user-agent-header-in-all-requests)). |\n| **debug_log**\u003cbr\u003e_optional_                 | boolean |                                                 false                                                 | Whether or not the client should print console logs for debugging purposes.                                                                                    |\n| **timeouts**\u003cbr\u003e_optional_                  | object  |                                                   -                                                   | Allows to set timeouts for requests. Valid keys are `response`, `idle` and `deadline`. Please see detailed information in the [Timeouts](#timeouts) section.   |\n| **retry_remote_timeout**\u003cbr\u003e_optional_      | boolean |                                                 true                                                  | Whether or not the client should retry a request to the remote server that failed with an ETIMEDOUT error                                                      |\n| **https_proxy_agent**\u003cbr\u003e_optional_         | object  |                                                   -                                                   | Possibility to add your own HTTPS Proxy Agent. Please see detailed information in the [Using Proxy Agent](#use-a-proxy-agent) section.                         |\n\n### Use a proxy agent\n\nIf you are behind a firewall and would like to use a proxy server then you can pass a custom proxy agent to the options object. See the following example:\n\n```javascript\nconst {HttpsProxyAgent} = require('hpagent');\nconst agent = new HttpsProxyAgent({proxy: 'http://x.x.x.x:zzzz'});\nconst spClient = new SellingPartner({\n  region: 'eu',\n  refresh_token: '\u003cREFRESH_TOKEN\u003e',\n  options: {\n    https_proxy_agent: agent\n  }\n});\n```\n\n### Exchange an authorization code for a refresh token\n\nIf you already have a refresh token you can skip this step. If you only want to use the API for your own seller account you can just use the [self authorization](https://developer-docs.amazon.com/amazon-shipping/docs/self-authorization) to obtain a valid refresh token.\n\nIf you want to exchange an authorization code of a seller you can use the `.exchange()` function of the client. The neccessary authorization code is returned to your callback URI as `spapi_oauth_code` when a seller authorizes your application ([see authorization workflow in docs](https://developer-docs.amazon.com/amazon-shipping/docs/authorizing-selling-partner-api-applications)).\n\nOnce you have obtained the authorization_code you can exchange it for a refresh token:\n\n```javascript\nconst spClient = new SellingPartner({\n  region: 'eu',\n  options: {\n    only_grantless_operations: true\n  }\n});\nlet res = await spClient.exchange('\u003cSELLER_AUTHORIZATION_CODE\u003e');\nconsole.log(res.refresh_token);\n```\n\nNOTE: You will have to create a new class instance once you have obtained the `refresh_token` and pass it inside the constructor in order to make calls to the API.\n\n### Request access token\n\nIf you only provide the `region` and `refresh_token` parameters the client will automatically request an `access_token` for you (with a TTL of 1 hour) and reuse it for future api calls for the class instance.\n\nInstead of having the client handle the `access_token` requests automatically, you may also refresh them manually:\n\n```javascript\nconst spClient = new SellingPartner({\n  region: 'eu',\n  refresh_token: '\u003cREFRESH_TOKEN\u003e',\n  options: {\n    auto_request_tokens: false\n  }\n});\nawait spClient.refreshAccessToken();\n```\n\nIf you want to use the same credentials for multiple instances you can retrieve them via getters and use them as input for a new instance:\n\n```javascript\nlet access_token = spClient.access_token;\n\nconst spClient = new SellingPartner({\n  region: 'eu',\n  refresh_token: '\u003cREFRESH_TOKEN\u003e',\n  access_token: access_token\n});\n```\n\n## Call the API\n\nAll calls to the SP-API will be triggered by using the `.callAPI()` function, which takes an object with the following structure as input:\n\n```javascript\n{\n  operation:'\u003cOPERATION_TO_CALL\u003e',\n  endpoint:'\u003cENDPOINT_OF_OPERATION\u003e',\n  path:{\n    ...\n  },\n  query:{\n    ...\n  },\n  body:{\n    ...\n  },\n  api_path:'\u003cFULL_PATH_OF_OPERATION\u003e',\n  method:'GET',\n  headers:{\n    ...\n  },\n  restricted_data_token:'\u003cRESTRICTED_DATA_TOKEN\u003e',\n  options:{\n    version:'\u003cOPERATION_ENDPOINT_VERSION\u003e',\n    restore_rate:'\u003cRESTORE_RATE_IN_SECONDS\u003e',\n    raw_result:false,\n    timeouts:{\n      ...\n    }\n  }\n}\n```\n\nValid properties of the object:\n\n| Name                                    |  Type  | Default | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |\n| :-------------------------------------- | :----: | :-----: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| **operation**\u003cbr\u003e_optional_             | string |    -    | The operation you want to request, [see SP API Developer Guide](https://developer-docs.amazon.com/sp-api/docs).\u003cbr\u003eMay also include endpoint as shorthand dot notation.\u003cbr\u003eCall `.endpoints` on class instance to retrieve a complete list of all endpoints, versions and operations supported by the client.\u003cbr\u003eRequired if `api_path` is not defined.                                                                                                                                                                       |\n| **endpoint**\u003cbr\u003e_optional_              | string |    -    | The endpoint of the operation, ([see Endpoints](#endpoints)).\u003cbr\u003eCall `.endpoints` on class instance to retrieve a complete list of all endpoints, versions and operations supported by the client.\u003cbr\u003eRequired if endpoint is not part of `operation` as shorthand dot notation and `api_path` is not defined.                                                                                                                                                                                                               |\n| **path**\u003cbr\u003e_optional_                  | object |    -    | The input paramaters added to the path of the operation.                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |\n| **query**\u003cbr\u003e_optional_                 | object |    -    | The input paramaters added to the query string of the operation.                                                                                                                                                                                                                                                                                                                                                                                                                                                              |\n| **body**\u003cbr\u003e_optional_                  | object |    -    | The input paramaters added to the body of the operation.                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |\n| **api_path**\u003cbr\u003e_optional_              | string |    -    | The full api path of an operation. Can be used to call operations that are not yet supported or have a new version that is not yet supported by the client.\u003cbr\u003eRequired if `operation` is not defined.                                                                                                                                                                                                                                                                                                                        |\n| **method**\u003cbr\u003e_optional_                | string |    -    | The HTTP method to use.\u003cbr\u003eRequired only if `api_path` is defined.\u003cbr\u003eMust be one of: `GET`, `POST`, `PUT`,`DELETE` or `PATCH`.                                                                                                                                                                                                                                                                                                                                                                                               |\n| **headers**\u003cbr\u003e_optional_               | object |    -    | Additional headers that will be added to the call.                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |\n| **restricted_data_token**\u003cbr\u003e_optional_ | string |    -    | A token received from a `createRestrictedDataToken` operation. Neccessary to include PII (Personally Identifiable Informaton) for some restricted operations, [see Tokens API use case guide](https://developer-docs.amazon.com/sp-api/docs/tokens-api-use-case-guide) for a list of restricted operations.\u003cbr\u003eNOTE: Your developer account must be approved for PII by Amazon in order to be able to receive PII, otherwise the token will have no effect, meaning the result of restricted operations will not include PII. |\n| **options**\u003cbr\u003e_optional_               | object |    -    | Additional options, see table below for all possible options properties.                                                                                                                                                                                                                                                                                                                                                                                                                                                      |\n\nValid properties of the config options:\n\n| Name                           |  Type   | Default | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                          |\n| :----------------------------- | :-----: | :-----: | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| **version**\u003cbr\u003e_optional_      | string  |    -    | The endpoint's version that should be used when calling the operation. Will be preferred over an `endpoints_versions` setting.\u003cbr\u003eNOTE: The call might still use an older version of the endpoint if the operation is not available for the specified version and `version_fallback` is set to `true`.                                                                                                                                                               |\n| **restore_rate**\u003cbr\u003e_optional_ | number  |    -    | The restore rate (in seconds) that should be used when calling the operation. Will be preferred over the default restore rate of the operation.                                                                                                                                                                                                                                                                                                                      |\n| **raw_result**\u003cbr\u003e_optional_   | boolean |  false  | Whether or not the client should return the \"raw\" result, which will include the raw body, buffer chunks, statuscode and headers of the result and also the request object with method, hostname, path, headers and body of the request.\u003cbr\u003eNOTE: Setting `raw_result` to `true` will skip the internal formatting or error checking, but might be helpful when you need additional information besides the payload or when the client encounters JSON.parse errors. |\n| **timeouts**\u003cbr\u003e_optional_     | object  |    -    | Allows to set timeouts for requests. Valid keys are `response`, `idle` and `deadline`. Please see detailed information in the [Timeouts](#timeouts) section.                                                                                                                                                                                                                                                                                                         |\n\n### Examples\n\nTo call an operation of an API endpoint you pass in the operation and the endpoint it belongs to. See the following example:\n\n```javascript\nlet res = await spClient.callAPI({\n  operation: 'getMarketplaceParticipations',\n  endpoint: 'sellers'\n});\n```\n\nInstead of using the endpoint property you may also prepend the endpoint to the operation as shorthand dot notation:\n\n```javascript\nlet res = await spClient.callAPI({\n  operation: 'sellers.getMarketplaceParticipations'\n});\n```\n\nHere are a few examples that use some more properties:\n\n```javascript\nlet res = await spClient.callAPI({\n  operation: 'getOrderMetrics',\n  endpoint: 'sales',\n  query: {\n    marketplaceIds: ['A1PA6795UKMFR9'],\n    interval: '2020-10-01T00:00:00-07:00--2020-10-01T20:00:00-07:00',\n    granularity: 'Hour'\n  }\n});\n```\n\n```javascript\nlet res = await spClient.callAPI({\n  operation: 'catalogItems.getCatalogItem',\n  path: {\n    asin: 'B084J4QQFT'\n  },\n  query: {\n    marketplaceIds: ['A1PA6795UKMFR9']\n  },\n  options: {\n    version: '2022-04-01'\n  }\n});\n```\n\n```javascript\nlet res = await spClient.callAPI({\n  operation: 'createReport',\n  endpoint: 'reports',\n  body: {\n    reportType: 'GET_FLAT_FILE_OPEN_LISTINGS_DATA',\n    marketplaceIds: ['A1PA6795UKMFR9']\n  }\n});\n```\n\n```javascript\nlet res = await spClient.callAPI({\n  operation: 'finances.listFinancialEvents',\n  query: {\n    PostedAfter: '2020-03-01T00:00:00-07:00',\n    PostedBefore: '2020-03-02T00:00:00-07:00'\n  },\n  options: {\n    raw_result: true\n  }\n});\n```\n\n```javascript\ntry {\n  let res = await spClient.callAPI({\n    operation: 'getCompetitivePricing',\n    endpoint: 'productPricing',\n    query: {\n      Asins: ['B00Z7T970I', 'B01BHHE9VK'],\n      ItemType: 'Asin',\n      MarketplaceId: 'A1PA6795UKMFR9'\n    },\n    options: {\n      version: 'v0',\n      raw_result: true,\n      timeouts: {\n        response: 5000,\n        idle: 10000,\n        deadline: 30000\n      }\n    }\n  });\n} catch (err) {\n  if (err.code) {\n    if (err.code === 'API_RESPONSE_TIMEOUT')\n      console.log('SP-API ERROR: response timeout: ' + err.timeout + 'ms exceeded.', err.message);\n    if (err.code === 'API_IDLE_TIMEOUT')\n      console.log('SP-API ERROR: idle timeout: ' + err.timeout + 'ms exceeded.', err.message);\n    if (err.code === 'API_DEADLINE_TIMEOUT')\n      console.log('SP-API ERROR: deadline timeout: ' + err.timeout + 'ms exceeded.', err.message);\n  }\n}\n```\n\n### Endpoints\n\nThe exact endpoint's name of an operation will be the references name ([see SP API Developer Guide](https://developer-docs.amazon.com/sp-api/docs)) without `API` and all spaces removed and continued with a capital letter. So the `Catalog Items API` endpoint's name will be `catalogItems`, `Fulfillment Inbound API` will be `fulfillmentInbound`, `Sellers API` will be `sellers` and so on. You can also retrieve the endpoint names and their operations and versions by calling `spClient.endpoints`.\n\n### Versions\n\nEvery operation belongs to an endpoint that consists of one or more versions and each version consists of one or more operations. You will find a complete list of the endpoints with all versions and operations [in the SP API Developer Guide](https://developer-docs.amazon.com/sp-api/docs). For a complete list of all currently by the client supported endpoints with versions and operations you can just call `spClient.endpoints`.\n\n#### Version specific operation implementations\n\nThe client uses the first (in fact the oldest) endpoint version if no version is provided since new versions of some operations are not backward compatible. So in order to prevent breaking changes we can't enable latest endpoint versions by default. I.e. the two different implementations of the `getCatalogItem` operation (see [catalogItemsV0](https://developer-docs.amazon.com/sp-api/docs/catalog-items-api-v0-reference#getcatalogitem) vs. [catalogItems_2020-12-01](https://developer-docs.amazon.com/sp-api/docs/catalog-items-api-v2020-12-01-reference#getcatalogitem)) expect different input parameters and return different results.\n\nThe implementation of the `getCatalogItem` operation in the `v0` version expects an `asin` and a `MarketplaceId` as input:\n\n```javascript\nlet res = await spClient.callAPI({\n  operation: 'getCatalogItem',\n  endpoint: 'catalogItems',\n  query: {\n    MarketplaceId: 'A1PA6795UKMFR9'\n  },\n  path: {\n    asin: 'B084DWG2VQ'\n  },\n  options: {\n    version: 'v0'\n  }\n});\n```\n\nIn contrast, the implementation of the `getCatalogItem` operation in the `2020-12-01` version expects an `asin`, a `marketplaceIds` array and an `includedData` array as input:\n\n```javascript\nlet res = await spClient.callAPI({\n  operation: 'getCatalogItem',\n  endpoint: 'catalogItems',\n  query: {\n    marketplaceIds: ['A1PA6795UKMFR9'],\n    includedData: ['identifiers', 'images', 'productTypes', 'salesRanks', 'summaries', 'variations']\n  },\n  path: {\n    asin: 'B084DWG2VQ'\n  },\n  options: {\n    version: '2020-12-01'\n  }\n});\n```\n\nTrying to call the new `2020-12-01` version without explicitly setting it would result in an `InvalidInput` error as the required `MarketplaceId` parameter is missing.\n\n#### Defining endpoints versions on class level\n\nThere are different ways of specifying the version to use for endpoints and their corresponding operations. You can specify the `version` directly inside the `options` object of the `.callAPI()` function as seen in the examples above. But you can also enable a newer version for all operations of an endpoint by using the `endpoints_versions` setting in the constructor config object.\nI.e. you can tell the class instance to use the new `2020-12-01` version for the `catalogItems` endpoint and thus enabling it for all operations of the endpoint throughout the class instance like this:\n\n```javascript\nconst spClient = new SellingPartner({\n  region: 'eu',\n  refresh_token: '\u003cREFRESH_TOKEN\u003e',\n  endpoints_versions: {\n    catalogItems: '2020-12-01'\n  }\n});\n```\n\nBy doing so you can skip setting the `version` inside the `options` object each time when you are using `.callAPI()` with the new version of the `getCatalogItem` operation.\n\n#### Fallback\n\nIf trying to call an operation that is not part of the endpoint's version you specified, the client will automatically try to find the operation in an earlier endpoint's version and use that implementation if `version_fallback` is set to `true` (which is the default).\nI.e. the `listCatalogCategories` operation is not part of the new `catalogItems` endpoint version. So if the new version was set as in the example code above, the following call would still work, because it will automatically fallback to the operation's implementation in version `v0`:\n\n```javascript\nlet res = await spClient.callAPI({\n  operation: 'listCatalogCategories',\n  endpoint: 'catalogItems',\n  query: {\n    MarketplaceId: 'A1PA6795UKMFR9',\n    ASIN: 'B084DWG2VQ'\n  }\n});\n```\n\n### Unsupported endpoints/versions/operations\n\nThe newest client version should always have full support for all endpoints, versions and operations on release, however it might lack support for very recently added new endpoints, versions or operations. If you need an endpoint/version/operation that is not yet supported you can still call it by using the `api_path` parameter. I.e. if the new `catalogItems` version `2020-12-01` would not be supported yet we could still use the new implementation of the `getCatalogItem` operation by using the `api_path` and `method` properties:\n\n```javascript\nlet res = await spClient.callAPI({\n  api_path: '/catalog/2020-12-01/items/B084DWG2VQ',\n  method: 'GET',\n  query: {\n    marketplaceIds: ['A1PA6795UKMFR9'],\n    includedData: ['identifiers', 'images', 'productTypes', 'salesRanks', 'summaries', 'variations']\n  }\n});\n```\n\nNOTE: If your `api_path` includes special characters that require encoding (i.e. an SKU that contains UTF-8 characters) you will have to encode these characters manually before passing your `api_path` to `.callAPI()`.\n\n### Grantless operations\n\nSome operations don't require an explicit authorization by a seller, [see list of grantless operations](https://developer-docs.amazon.com/sp-api/docs/grantless-operations). A grantless operation needs another access token than other operations and as such a grantless token is NOT the `access_token` you can provide in the constructor config object. However if the `auto_request_tokens` option is set to `true` the client should handle everything for you.\n\nIf you do the token request manually you need to create a grantless token by calling `refreshAccessToken` with the scope of the corresponding endpoint. Currently there are only two different scopes: `sellingpartnerapi::notifications` for notifications endpoint and `sellingpartnerapi::client_credential:rotation` for application management endpoint.\n\nIf you don't need or have a refresh token you may use the client with the `only_grantless_operations` option set to `true` which allows you to create an instance of the client without a `refresh_token`.\n\nTo sum up, please see the following example that will return the destinations for your notifications.\n\nFirst create a class instance that only allows to call grantless operations (no `refresh_token` included):\n\n```javascript\nconst spClient = new SellingPartner({\n  region: 'eu',\n  options: {\n    auto_request_tokens: false,\n    only_grantless_operations: true\n  }\n});\n```\n\nThen request a grantless token with the scope needed for the operation you want to call:\n\n```javascript\nawait spClient.refreshAccessToken('sellingpartnerapi::notifications');\n```\n\nFinally call the grantless operation:\n\n```javascript\nlet res = await spClient.callAPI({\n  operation: 'getDestinations',\n  endpoint: 'notifications'\n});\n```\n\n### Restore rates\n\nIf you set the `auto_request_throttled` option in the class constructor config object to `true` (which is the default), the client will automatically retry the call if its throttled. It will either use the restore rate from the result header field `x-amzn-ratelimit-limit` if given ([see Usage Plans and Rate Limits](https://developer-docs.amazon.com/sp-api/docs/usage-plans-and-rate-limits-in-the-sp-api)), or the value of `restore_rate` option in `.callAPI()` function if given, or otherwise use the default restore rate of the operation. For testing purposes you can also set `debug_log` to `true`, which will trigger a console log every time the client retries a call. If you set `auto_request_throttled` to `false` the client will throw a `QuotaExceeded` error when a request is throttled.\n\nNOTE: If you are using the same operation with the same seller account across multiple class instances the restore rate logic might NOT work correct or, even worse, result in an infinite quota exceeded loop. So if you're planning to do that you should probably set `auto_request_throttled` to `false`, catch the `QuotaExceeded` errors and handle the restore rate logic on your own.\n\n### Timeouts\n\nYou may set timeouts to stop requests, i.e. to prevent scripts from \"hanging\" forever because a request is not finishing. The three different timeout types are `response`, `idle` and `deadline`. You may set these inside the class constructor config options to be used for all requests started via `.callAPI()` or via the config options of the `.callAPI()` method for that specific call only. The latter will override the timeouts set via class config options.\n\nNOTE:\nThe `.download()` method will NOT use the timeouts defined in class constructor config options. You have to provide the timeouts to each `.download()` call inside its options object.\n\nSee the table below for valid properties of the timeouts object:\n\n| Name                       |  Type  | Default | Description                                                                                                                                                                                                                                                                                                                                    |\n| :------------------------- | :----: | :-----: | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| **response**\u003cbr\u003e_optional_ | number |    -    | Timeout (in milliseconds) until a response timeout is fired. If exceeded the request will abort with an `API_RESPONSE_TIMEOUT` error. Response timeout is the time between sending the request and receiving the first byte of the response. Includes DNS and connection time.                                                                 |\n| **idle**\u003cbr\u003e_optional_     | number |    -    | Timeout (in milliseconds) until an idle timeout is fired. if exceeded the request will abort with an `API_IDLE_TIMEOUT` error. Idle is the time between receiving the last chunk of the reponse and waiting for the next chunk to be received. Might be fired if a request is stalled before finished (i.e. when internet connection is lost). |\n| **deadline**\u003cbr\u003e_optional_ | number |    -    | Timeout (in milliseconds) until a deadline timeout is fired. If exceeded the request will abort with an `API_DEADLINE_TIMEOUT` error. Deadline is the time from the start of the request to receiving the response body in full. If the deadline is too short large responses may not load at all on slow connections.                         |\n\n## Download reports\n\nThe easiest way of downloading a report is to use the `.downloadReport()` function that will wrap up all operations needed to request and retrieve a report in a single call. The function internally calls the operations `createReport`, `getReport`, `getReportDocument` and the `.download()` function that will download the final report document in sequence.\n\nThe function takes a config object with the following parameters as input:\n\n| Name                           |  Type  |  Default   | Description                                                                                                                                                                                                                                                                                                                  |\n| :----------------------------- | :----: | :--------: | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| **body**\u003cbr\u003e_required_         | object |     -      | Includes the parameters necessary to request the report. These are the parameters usually passed in to the `createReport` operation (see [createReport 2021-06-30](https://developer-docs.amazon.com/sp-api/docs/reports-api-v2021-06-30-reference#createreportspecification)). The possible values will be described below. |\n| **version**\u003cbr\u003e_optional_      | string | 2021-06-30 | The report endpoint’s version that should be used when retrieving the report.                                                                                                                                                                                                                                                |\n| **interval**\u003cbr\u003e_optional_     | number |   10000    | The request interval (in milliseconds) that should be used for re-requesting the `getReport` operation when the report is still queued or in progress.                                                                                                                                                                       |\n| **cancel_after**\u003cbr\u003e_optional_ | number |     -      | Cancels a report request after the specified number of retries. Each re-request defined by the `interval` value counts as one retry.                                                                                                                                                                                         |\n| **download**\u003cbr\u003e_optional_     | object |     -      | Includes optional parameters for the download of the report, i.e. to enable a json result or to additionally save the report to a file. The possible values will be described below.                                                                                                                                         |\n\nThe `body` object may include the following properties:\n\n| Name                             |       Type       | Default | Description                                                                                                                                                                                                                           |\n| :------------------------------- | :--------------: | :-----: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| **reportType**\u003cbr\u003e_required_     |      string      |    -    | The report type.                                                                                                                                                                                                                      |\n| **marketplaceIds**\u003cbr\u003e_required_ | \u003c string \u003e array |    -    | A list of marketplace identifiers. The report document's contents will contain data for all of the specified marketplaces, unless the report type indicates otherwise.                                                                |\n| **dataStartTime**\u003cbr\u003e_optional_  |      string      |    -    | The start of a date and time range, in ISO 8601 date time format, used for selecting the data to report. The default is now. The value must be prior to or equal to the current date and time. Not all report types make use of this. |\n| **dataEndTime**\u003cbr\u003e_optional_    |      string      |    -    | The end of a date and time range, in ISO 8601 date time format, used for selecting the data to report. The default is now. The value must be prior to or equal to the current date and time. Not all report types make use of this.   |\n| **reportOptions**\u003cbr\u003e_optional_  |      object      |    -    | Additional information passed to reports. This varies by report type.                                                                                                                                                                 |\n\nThe `download` object may include the following properties:\n\n| Name                       |  Type   | Default | Description                                                                                                                                                                                                                                                          |\n| :------------------------- | :-----: | :-----: | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| **json**\u003cbr\u003e_optional_     | boolean |  false  | Whether or not the content should be transformed to json before returning it (from tab delimited flat-file or XML).                                                                                                                                                  |\n| **unzip**\u003cbr\u003e_optional_    | boolean |  true   | Whether or not the content should be unzipped before returning it.                                                                                                                                                                                                   |\n| **file**\u003cbr\u003e_optional_     | string  |    -    | The absolute file path to save the report to.\u003cbr\u003eNOTE: Even when saved to disk the report content is still returned.                                                                                                                                                 |\n| **charset**\u003cbr\u003e_optional_  | string  |  utf8   | The charset to use for decoding the content. If not defined, it uses per default the charset returned in `content-type` header or `utf8` if no charset found in `content-type` header.\u003cbr\u003eNOTE: Is ignored when content is compressed and `unzip` is set to `false`. |\n| **timeouts**\u003cbr\u003e_optional_ | object  |    -    | Allows to set timeouts for download requests. Valid keys are `response`, `idle` and `deadline`. Please see detailed information in the [Timeouts](#timeouts) section.                                                                                                |\n\nPlease see the following example that will request a `GET_FLAT_FILE_OPEN_LISTINGS_DATA` report for the current report endpoint version `2021-06-30`, re-request it every 8 seconds and, once its finished, will download the report, transform it to json and save it to disk:\n\n```javascript\nlet res = await sellingPartner.downloadReport({\n  body: {\n    reportType: 'GET_FLAT_FILE_OPEN_LISTINGS_DATA',\n    marketplaceIds: ['A1PA6795UKMFR9']\n  },\n  version: '2021-06-30',\n  interval: 8000,\n  download: {\n    json: true,\n    file: '\u003cABSOLUTE_FILE_PATH\u003e/report.json'\n  }\n});\n```\n\nInstead of using the `.downloadReport()` function you may as well call the necessary operations on your own and use the `.download()` function to retrieve the final report data. Please see the following information below:\n\nThe `.download()` function takes the download details received from a `getReportDocument` operation as input, downloads the content, unzips it (if result is compressed), decrypts it and returns it.\n\nRetrieve the download details from a `getReportDocument` operation:\n\n```javascript\nlet report_document = await spClient.callAPI({\n  operation: 'getReportDocument',\n  endpoint: 'reports',\n  path: {\n    reportDocumentId: '\u003cREPORT_DOCUMENT_ID\u003e' // retrieve the reportDocumentId from a \"getReport\" operation (when processingStatus of report is \"DONE\")\n  }\n});\n```\n\nThe structure of the returned `report_document` should look like this:\n\n```javascript\n{\n  reportDocumentId:'\u003cREPORT_DOCUMENT_ID\u003e',\n  compressionAlgorithm:'GZIP', // Only included if report is compressed\n  url: '\u003cREPORT_DOWNLOAD_URL\u003e' // Expires after 5 minutes!\n}\n```\n\nCall the `.download()` function to receive the content of the report. The default without any config options will download, decrypt and unzip the content and return it without reformatting or saving it to the disk:\n\n```javascript\nlet report = await spClient.download(report_document);\n```\n\nYou may also include an options object as a 2nd parameter to the `.download()` function, i.e. to enable a json result or to additionally save the report to a file. The possible parameters are the same as for the `download` object for the `.downloadReport()` function already documented above.\n\nThe following call will download the report, transform it to json and save it to disk:\n\n```javascript\nlet report = await spClient.download(report_document, {\n  json: true,\n  file: '\u003cABSOLUTE_FILE_PATH\u003e/report.json'\n});\n```\n\nSome reports may have an encoding other than UTF-8 and require special decoding with a different charset, i.e. the `GET_MERCHANT_LISTINGS_ALL_DATA` report is encoded as `cp1252` for eu region marketplaces. The right charset to use for decoding is taken from the return header `content-type`, but you may force the use of a specific charset for decoding by passing in the optional charset property:\n\n```javascript\nlet report = await spClient.download(report_document, {\n  charset: 'cp1252'\n});\n```\n\n### Download reports as stream\n\nIf you have a very extensive report you may use the `.downloadReportStream()` function. Instead of returning the report content it will return a stream instance allowing you to retrieve the individual buffer chunks:\n\n```javascript\nlet resStream = await sellingPartner.downloadReportStream({\n  body: {\n    reportType: \"GET_FLAT_FILE_OPEN_LISTINGS_DATA\",\n    marketplaceIds: [\"A1PA6795UKMFR9\"]\n  },\n  version: \"2021-06-30\",\n  interval: 8000\n});\nresStream.on(\"data\", (chunk) =\u003e {\n  // Receiving buffer chunk\n});\nresStream.on(\"error\", async (err) =\u003e {\n  // Error while streaming\n});\nresStream.on(\"end\", () =\u003e {\n  // Stream finished\n});\n```\n\nPlease note: For the `download` object you may only use the `unzip` property, all other properties (`json`, `file`, `charset`, `timeouts`) are not available when downloading a report as a stream.\n\n## Upload feeds\n\nThe `.upload()` function takes the feed upload details received from a `createFeedDocument` operation, the feed content and its content type to upload as input and uploads it.\n\nStart by creating a feed object with a contentType and the content either as a string or a file path to a document:\n\n| Name                          |  Type  | Default | Description                                                                                                                                                             |\n| :---------------------------- | :----: | :-----: | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| **content**\u003cbr\u003e_optional_     | string |    -    | The content to upload as a string.\u003cbr\u003eRequired if `file` is not provided.                                                                                               |\n| **file**\u003cbr\u003e_optional_        | string |    -    | The absolute file path to the feed content document to upload.\u003cbr\u003eRequired if `content` is not provided.                                                                |\n| **contentType**\u003cbr\u003e_required_ | string |    -    | The contentType of the content to upload.\u003cbr\u003eShould be one of `text/xml` or `text/tab-separated-values` and the charset of the content, i.e. `text/xml; charset=utf-8`. |\n\nThis will create an inventory feed (`POST_INVENTORY_AVAILABILITY_DATA`) that will update the quantity of a given SKU to 10:\n\n```javascript\nlet feed = {\n  content: `\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n    \u003cAmazonEnvelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"amzn-envelope.xsd\"\u003e\n      \u003cHeader\u003e\n        \u003cDocumentVersion\u003e1.02\u003c/DocumentVersion\u003e\n        \u003cMerchantIdentifier\u003eYOUR_MERCHANT_IDENTIFIER\u003c/MerchantIdentifier\u003e\n      \u003c/Header\u003e\n      \u003cMessageType\u003eInventory\u003c/MessageType\u003e\n      \u003cMessage\u003e\n        \u003cMessageID\u003e1\u003c/MessageID\u003e\n        \u003cInventory\u003e\n          \u003cSKU\u003eYOUR_SKU\u003c/SKU\u003e\n          \u003cQuantity\u003e10\u003c/Quantity\u003e\n        \u003c/Inventory\u003e\n      \u003c/Message\u003e\n    \u003c/AmazonEnvelope\u003e`,\n  contentType: 'text/xml; charset=utf-8'\n};\n```\n\nBefore you can upload the feed you need to retrieve the feed upload details from a `createFeedDocument` operation:\n\n```javascript\nlet feed_upload_details = await spClient.callAPI({\n  operation: 'createFeedDocument',\n  endpoint: 'feeds',\n  body: {\n    contentType: feed.contentType\n  }\n});\n```\n\nCall the `.upload()` function to upload the content of the feed:\n\n```javascript\nlet res = await spClient.upload(feed_upload_details, feed);\n```\n\nAfter uploading the feed you have to trigger the processing of the feed by calling the `createFeed` operation with the necessary params (`marketplaceIds`, `feedType` and `inputFeedDocumentId`):\n\n```javascript\nlet feed_creation_infos = await spClient.callAPI({\n  operation: 'createFeed',\n  endpoint: 'feeds',\n  body: {\n    marketplaceIds: ['A1PA6795UKMFR9'],\n    feedType: 'POST_INVENTORY_AVAILABILITY_DATA',\n    inputFeedDocumentId: feed_upload_details.feedDocumentId // retrieve the feedDocumentId from the \"createFeedDocument\" operation\n  }\n});\n```\n\nNOTE: Although uploading and creating the feed was successful it doesn't mean that the processing of the feed itself was also successful. You can check the result of the feed once it has been processed by downloading the processing result with the `.download()` function quite similar as how to download reports. Use the `feedId` returned by the `createFeed` operation and call the `getFeed` operation, which will include a `resultFeedDocumentId` if feed processing is already done. The `resultFeedDocumentId` can be used with a `getFeedDocument` operation that will return the feed download details needed for the feed result download.\n\n## TypeScript Support\n\nAll TypeScript related information can be found in [lib/typings](https://github.com/amz-tools/amazon-sp-api/tree/main/lib/typings). Currently types are not yet defined for all operations and/or params, so feel free to add new types following the readme. You are also welcome to create a pull request.\n\n## Sandbox mode\n\nYou can easily enable sandbox mode by setting `use_sandbox` in the constructor config options to `true`. General information on sandbox setup and behaviour can be found [in the corresponding section in the Selling Partner API Developer Guide](https://developer-docs.amazon.com/sp-api/docs/the-selling-partner-api-sandbox#how-to-make-a-static-sandbox-call-to-the-selling-partner-api).\n\nWhen using the sandbox you have to make sure to use the correct request parameters for the operation you want to test. You can find these inside the api models definitions in the docs by searching the corresponding json file for `x-amzn-api-sandbox`.\n\nFor example, this will test the `getPricing` operation in sandbox mode:\n\n```javascript\nlet res = await spClient.callAPI({\n  operation: 'getPricing',\n  endpoint: 'productPricing',\n  query: {\n    MarketplaceId: 'TEST_CASE_400'\n  }\n});\n```\n\n## Known Issues\n\nThere is an issue with values of arrays as part of the query, when a value contains a `,`. Due to Amazon expecting array values in query separated by `,` it will wrongfully split up values containing a `,` into two separate values. This is already a [known issue communicated to Amazon](https://github.com/amzn/selling-partner-api-docs/issues/2374).\n\n## Seller Support\n\nWe might be able to support you with everything else that can't be done with the API, i.e. a detailed sales dashboard, review management, automated reimbursements and more. Feel free to visit us at [https://getarthy.com](https://getarthy.com).\n\n## Breaking Changes\n\n- Removed `refreshRoleCredentials` function and the getter for `role_credentials`. As Amazon has removed the neccessity for signing requests to the SP API, role credentials are not needed anymore.\n\n- Trying to call an operation without specifying an endpoint now results in a `NO_ENDPOINT_GIVEN` error. Although deprecated since version 0.4.0 it was still possible to call an operation without an endpoint. This possibility has now been removed. However, it is still perfectly fine to omit the endpoint parameter and add it directly to the operation parameter via shorthand dot notation (i.e. `operation: \"sellers.getMarketplaceParticipations\"`)\n\n- The `reports` and `feeds` endpoint's version `2020-09-04` is deprecated since 27th June 2023 and has been removed. As a result, `encryptionDetails` for downloading of reports and uploading of feeds is not returned anymore and all en-/decryption logic for reports and feeds has been removed as well.\n","funding_links":[],"categories":["Docs"],"sub_categories":["Library"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famz-tools%2Famazon-sp-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Famz-tools%2Famazon-sp-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famz-tools%2Famazon-sp-api/lists"}