mws-advanced
MWS-Advanced is a modern Javascript library to make use of the Amazon Merchant Web Service (MWS). It uses ES6+ Javascript, and is intended for use with Node v9.0 or better. It provides a much cleaner interface to MWS, translating the mess of XML based results that Amazon provides into something that is much closer to what you're expecting in a Javascript environment. In the future, it will handle most all of the behind-the-scenes dirty work involved in creating a functional MWS application, such as throttling API calls.
Example usage - Single instance
const mws = require('@ericblade/mws-advanced');
mws.init({
accessKeyId: 'Your Amazon AWS access key',
secretAccessKey: 'Your Amazon AWS secret access key',
merchantId: 'Your Amazon AWS Merchant ID',
});
(async function () {
// get a list of all marketplaces the account participates in
const marketplaces = await mws.getMarketplaces();
console.log(`Markets: ${JSON.stringify(marketplaces, null, 4)}`);
// get a list of all orders in the last 7 days, on the North American (US) market
const startDate = new Date();
startDate.setDate(startDate.getDate() - 7);
const orders = await mws.listOrders({
CreatedAfter: startDate,
MarketplaceId: [ 'ATVDPKIKX0DER' ],
});
console.log(`Orders: ${JSON.stringify(orders, null, 4)}`);
})();
Example usage - Multiple instance capability
const MWS = require('@ericblade/mws-advanced');
(async function() {
const mws = new MWS({
accessKeyId: 'Your Amazon AWS access key',
secretAccessKey: 'Your Amazon AWS secret access key',
merchantId: 'Your Amazon AWS Merchant ID',
});
const marketplaces = await mws.getMarketplaces();
console.log(`Markets: ${JSON.stringify(marketplaces, null, 4)}`);
})();
Parameter validation
A large portion of the function of this library is to deal with parameter transformation and validation -- allowing you to use familiar and convenient data types to interface to MWS, as well as ensuring that your parameters are lexically correct, so that you don't waste time, bandwidth, etc firing off requests to the MWS servers that simply cannot be fulfilled. The MWS API for example, has a rather unique implementation of List data, expecting parameters to be specified in a form such as:
ASINList.1='ASIN1'
ASINList.2='ASIN2' ...
A function call requiring an ASIN List from this library, would accept this as a normal array:
const results = await mws.callEndpoint('GetCompetitivePricingForASIN', {
MarketplaceId: 'ATVPDKIKX0DER',
ASINList: ['142210284X', '1844161668', '0989391108', 'B009NOF57C'],
});
Additionally, you can use data types such as a Javascript Date object to specify a time/date stamp to MWS, and that will be automatically converted into the ISO-8601 date string that MWS expects.
Similarly, if you attempt to pass un-parseable strings as dates, strings for integers, integers that are out of the bounds MWS expects, negative numbers where only positives are allowed, etc, then requests with that data will be failed with a ValidationError before ever being transmitted to MWS.
Basic Throttling Support
When a request has been throttled by Amazon, the library will attempt to automatically retry that request until it does succeed. Please see the Queue.js file for specifics as to how that works. (the documentation will be updated to cover the new Queue mechanism in the future)
Please see the Getting Started page for more info.
Getting Started
Prerequisites
Getting your MWS credentials
To use the MWS API, you will need to obtain your MWS API credentials. Amazon will supply three items that you will need to provide: Access Key Id, Secret Access Key, and Merchant ID.
If you do not have an Amazon Seller Central "Professional" account, you will need that to get started. Signing up for Seller Central and information related to that is beyond the scope of this manual, see Amazon Seller Central for specifics.
When your Amazon Seller Central account is setup, navigate to the Settings menu (upper-right-corner) and select "User Permissions" from the drop-down menu. After a few moments of waiting for the entire page to finish loading, you should see a section titled "Amazon MWS Developer Permissions". Note your Seller ID under the "Your Account Information" heading. Then, under the "Current Authorizations" heading, you should see as the first line, your Developer ID, Store Name, the date you created your API authorization, and a link titled "View your credentials".
Click "View your credentials", and a pop-up will appear with your Access Key ID. Make note of this, then click "View" next to the "Secret Key" field. Make note of your Secret Access Key.
Now that you have your Access Key Id, Secret Access Key, and Merchant ID, you can begin using the MWS API.
Official MWS API documentation
You may find yourself wanting to refer to the official Amazon documentation, to determine how, when, or why to use an API, or to find out information about what it returns, or what it is used for:
Amazon MWS Web Service API Documentation
Installation
from npm:
npm install --save @ericblade/mws-advanced
from github:
npm install --save github:ericblade/mws-advanced
Creating the connection to MWS
Before you are able to use the mws-advanced API, you must initialize it with your MWS credentials.
const mws = require('@ericblade/mws-advanced');
mws.init({
accessKeyId: 'Your Amazon MWS Access Key ID',
secretAccessKey: 'Your Amazon MWS Secret Access Key',
merchantId: 'Your Amazon MWS Merchant ID',
});
Multiple Instances
If you need multiple instances of the MWS API, such as if you are running a service that may be making requests for multiple SellerIDs over time, you can now do:
const MWS = require('@ericblade/mws-advanced');
const mws = new MWS({
accessKeyId: 'Your Amazon MWS Access Key ID',
secretAccessKey: 'Your Amazon MWS Secret Access Key',
merchantId: 'SellerID',
authToken: 'Auth Token provided by other Seller',
});
Calling mws-advanced APIs
mws-advanced implements several wrappers around the actual MWS API, which parse and process the XML responses from MWS into a response format that is more easily readable in Javascript.
(async function() {
const result = await mws.getMarketplaces();
console.log(result);
})();
will return data that should look something like this sample data from an account that is registered in the United States and Canadian markets:
{ A2EUQ1WTGCTBG2:
{ marketplaceId: 'A2EUQ1WTGCTBG2',
defaultCountryCode: 'CA',
domainName: 'www.amazon.ca',
name: 'Amazon.ca',
defaultCurrencyCode: 'CAD',
defaultLanguageCode: 'en_CA',
sellerId: 'SELLERIDSTRING',
hasSellerSuspendedListings: 'No' },
ATVPDKIKX0DER:
{ marketplaceId: 'ATVPDKIKX0DER',
defaultCountryCode: 'US',
domainName: 'www.amazon.com',
name: 'Amazon.com',
defaultCurrencyCode: 'USD',
defaultLanguageCode: 'en_US',
sellerId: 'SELLERIDSTRING',
hasSellerSuspendedListings: 'No' } }
This looks, in my opinion, far, far better than the raw result data that results from calling MWS "ListMarketplaceParticipations" directly, which you will see an example for in the next section.
Calling MWS APIs directly
For APIs that have not been wrapped, or if you wish to receive the raw data output from a direct MWS API call for some reason, you can do that with the callEndpoint function:
(async function() {
const result = await mws.callEndpoint('ListMarketplaceParticipations');
console.log(result);
})();
For the same user that we called in the above "getMarketplaces" API, we receive the following data back:
{
"ListMarketplaceParticipationsResponse": {
"$": {
"xmlns": "https://mws.amazonservices.com/Sellers/2011-07-01"
},
"ListMarketplaceParticipationsResult": [
{
"ListParticipations": [
{
"Participation": [
{
"MarketplaceId": [
"A1MQXOICRS2Z7M"
],
"SellerId": [
"YOUR_SELLER_ID"
],
"HasSellerSuspendedListings": [
"No"
]
},
{
"MarketplaceId": [
"A2EUQ1WTGCTBG2"
],
"SellerId": [
"YOUR_SELLER_ID"
],
"HasSellerSuspendedListings": [
"No"
]
},
{
"MarketplaceId": [
"A2ZV50J4W1RKNI"
],
"SellerId": [
"YOUR_SELLER_ID"
],
"HasSellerSuspendedListings": [
"No"
]
},
{
"MarketplaceId": [
"ATVPDKIKX0DER"
],
"SellerId": [
"YOUR_SELLER_ID"
],
"HasSellerSuspendedListings": [
"No"
]
}
]
}
],
"ListMarketplaces": [
{
"Marketplace": [
{
"MarketplaceId": [
"A1MQXOICRS2Z7M"
],
"DefaultCountryCode": [
"CA"
],
"DomainName": [
"siprod.stores.amazon.ca"
],
"Name": [
"SI CA Prod Marketplace"
],
"DefaultCurrencyCode": [
"CAD"
],
"DefaultLanguageCode": [
"en_CA"
]
},
{
"MarketplaceId": [
"A2EUQ1WTGCTBG2"
],
"DefaultCountryCode": [
"CA"
],
"DomainName": [
"www.amazon.ca"
],
"Name": [
"Amazon.ca"
],
"DefaultCurrencyCode": [
"CAD"
],
"DefaultLanguageCode": [
"en_CA"
]
},
{
"MarketplaceId": [
"A2ZV50J4W1RKNI"
],
"DefaultCountryCode": [
"US"
],
"DomainName": [
"sim1.stores.amazon.com"
],
"Name": [
"Non-Amazon"
],
"DefaultCurrencyCode": [
"USD"
],
"DefaultLanguageCode": [
"en_US"
]
},
{
"MarketplaceId": [
"ATVPDKIKX0DER"
],
"DefaultCountryCode": [
"US"
],
"DomainName": [
"www.amazon.com"
],
"Name": [
"Amazon.com"
],
"DefaultCurrencyCode": [
"USD"
],
"DefaultLanguageCode": [
"en_US"
]
}
]
}
]
}
],
"ResponseMetadata": [
{
"RequestId": [
"9994df75-e1ec-4a59-ae71-68538df26b65"
]
}
]
}
}
... what a big difference, right?
Using your API access for a different Amazon Seller (authToken)
Amazon provides the ability to use the MWS API for different Amazon sellers, provided that they have authorized you with the ability to access their API account, and have provided you with an Authorization Token to do so. They can do this authorization via the same page that you received your credentials from in the section titled "Getting your MWS Credentials". Once they provide you with the Authorization Token and THEIR Merchant ID, then you can use mws-advanced to access their account:
mws.init({
accessKeyId: 'Your Amazon MWS Access Key ID',
secretAccessKey: 'Your Amazon MWS Secret Access Key',
merchantId: 'THEIR MWS Merchant ID',
authToken: 'THEIR authorization token for you',
});
Usage
Basic Usage
It is expected that you will use either async/await or Promise syntax to operate the mws-advanced API.
async/await Example
const marketplaces = (async () => await mws.getMarketplaces())();
console.log(marketplaces);
Promises Example
mws.getMarketplaces().then(marketplaces => {
console.log(marketplaces);
});
Most mws-advanced functions will require at least one, if not several, parameters to function correctly. Most, if not all, parameters will be passed in as an object:
Example of passing parameters in as an object
const getLastSevenDaysOrders = async () => {
const startDate = new Date();
startDate.setDate(startDate.getDate() - 7);
return await mws.listOrders({
CreatedAfter: startDate,
MarketplaceId: [ 'A2ZV50J4W1RKNI' ],
});
};
Obtaining Marketplace Values
One of the first things you should probably do after calling init, is figure out what marketplace(s) you want your calls to operate on. Many of the MWS calls accept either a "MarketplaceId" string parameter to operate on a single marketplace, or a "MarketplaceIdList" Array parameter to provide operation across multiple marketplaces simultaneously.
You can do this by calling getMarketplaces. You probably want to store the values returned by this call somewhere for future use.
See also Using multiple marketplaces in the Amazon MWS documentation.
Advanced Usage
Using an authToken to operate on someone else's MWS account
See Using your API access for a different Amazon Seller
Report Processing
A large document can be written on Report Processing, and probably will in the future. For right now, please see the official MWS documentation: Reports Overview
Also, please note that the reporting functions are currently mostly just stubs, and will likely undergo significant changes, as we use them, and discover where they are lacking.
API call caching
For a brief period of time, this library did it's own result caching, but that was not a very good idea. For an approach you can take to caching data for long-running services, check out [cache: replace ...] https://github.com/ericblade/mws-advanced/issues/52
Submitting data feeds
The library does support submitting data feeds, although it is in very early stages.
You can dynamically create your own feed data, and submit it using callEndpoint, by doing something like:
const results = await mws.callEndpoint('SubmitFeed', {
'MarketplaceIdList.Id.1': 'ATVPDKIKX0DER',
FeedType: '_POST_FLAT_FILE_PRICEANDQUANTITYONLY_UPDATE_DATA_',
feedContent:
`sku\tprice\tminimum-seller-allowed-price\tmaximum-seller-allowed-price\tquantity\thandling-time\tfulfillment-channel
PO-TON5-ZUPT\t39.99\t9.99\t199.99\t0\t\t`,
});
console.warn('* results', JSON.stringify(results, null, 4));
There is a discussion thread up to determine some approaches to improving upon this. See [Discussion: Dynamic feed generation] (https://github.com/ericblade/mws-advanced/issues/59)
Samples
Please see the [Samples] (https://github.com/ericblade/mws-advanced/tree/master/samples) directory in the source repository for a large number of simple uses for the library