MSR Distribution Feed API
Welcome to the Distribution Feed API.
This document will guide you on how to consume the API to Get details of Products, Price, Inventory, Push Orders, View Order Status and Track Shipments. This document is to assist you in integrating your existing sales platform to our eOrdering System to provide your customers with a seamless experience. Please reach out to us at [email protected] for any queries you have.
Important! : You will need to provide your public IP address from where you intend to access our API. Only this IP will be authorized to access our API.
Authorization
The Distribution Feed API uses a simple token authorization. First you create a new token (or acquire an existing one). After you have acquired your token you can use it to access other resources within the token’ scope..
Orders
When a Dealer needs to place an Order on behalf of a customer, they need to prepare the order information in JSON and POST it to the orders API with the Authorization token in the header. The API then performs validations based upon the request that it recieved in json form. After completion of the request the api sends back the response data in json format.
Media Types
Requests with a message-body are using plain JSON to set or update resource states.
Error States
The common HTTP Response Status Codes are used.
Invalid Json
If you get a response stating "Invalid JSON" please validate the json payload you’re using on JSONLint.
Orders ¶
The following are the API helps to manage orders in Distribution Feed.
Order Creation ¶
- User can send multiple order for creation at a time.
- Distribution Feed checks the following rules
- Order Id must be unique
- Items stock status must be allocated, else it won’t be added to order.
- Shipping Method must be Ground, 3 Day Select, 2nd Day Air, Next Day Air
- If Method is Ground or 3 Day Select and item is AirOnly, then don’t add the item to final order.
- If Method is 2nd Day Air or Next Day Air and Item is GroundOnly, then don’t add the item to final order.
- If Inventory is less than ordered amount and user does not accept partial order, then skip the item.
- If Shipping State is restricted for any item then, skip that item.
- If final order contains a at least a single item and user accepts partial order then submit that order.
- Billing address will always be your billing address from your MSR website account.
- Shipping address will be supplied in your API call – this should be the customer’s shipping address.
- If order contains FFL items, supply the FFL details in the FFLDealerName, FFLDealerLicense, FFLDealerZipCode fields.
- If you do not want the order to be drop shipped and want it delivered to you, please set the "NoDropShip" field to "true".
- Once all these checks and tasks are performed, a response is generated with appropriate error codes and messages for all the orders that were submitted.
Order CreationPOSTapi/Order/Create
Status: Available
This API is used to place the orders. The only authorization type that is required is Bearer Token.
Example URI
/api/Order/Create
Header
Content-Type: application/json
Authorization: application/json
Body
{
"PageNo": 0,
"Records": 1,
"Orders": [
{
"OrderId" : "12001",
"Name" : "Jhon Doe",
"Address" : "Address1",
"Address2" : " Address2",
"City" : "Nevada",
"State" : "LA",
"ZipCode" : "89180",
"Phone" : "123456789",
"Email" : "[email protected]",
"FFLDealerName" : "Dealer Name",
"FFLDealerLicense" : "License",
"FFLDealerZipCode" : "Dealer Zip",
"OrderItems" : [
{
"SKU" : "BK-001",
"QuantityOrdered" : "10",
"ShippingCarrier" : "UPS",
"ShippingMethod" : "Ground",
"NoDropShip" : false
},
{
"SKU" : "CRUX-CA-001A",
"QuantityOrdered" : "15",
"ShippingCarrier" : "UPS",
"ShippingMethod" : "Next Day Air",
"NoDropShip" : false
}
]
}
]
}
200Success Response
{"PageNo": 0,
"Records": 1,
"TotalPages": 0,
"Orders": [
{
"OrderId": "12003",
"status": true,
"Message": [
{
"Code": "10000",
"Message": "Order Successfully Placed."
}
]
}
]
}
200Partial Success Response
{
"PageNo": 0,
"Records": 1,
"TotalPages": 0,
"Orders": [
{
"OrderId": "12001",
"status": false,
"Message": [
{
"Code": "10006",
"Message": "Product BK-001 is ClosedOut"
},
{
"Code": "10000",
"Message": "Partial Order Successfully Placed."
}
]
}
]
}
200Error Response
{
"PageNo": 0,
"Records": 1,
"TotalPages": 0,
"Orders": [
{
"OrderId": "12001",
"status": false,
"Message": [
{
"Code": "10006",
"Message": "Product BK-001 is ClosedOut"
},
{
"Code": "10002",
"Message": "Product CRUX-CA-001A is Out Of Stock"
},
{
"Code": "10007",
"Message": "Order 12001 had errors and Partial Order are deactivated."
}
]
}
]
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System;
using System.Net.Http;
using System.Web;
using System.Net;
using System.IO;
namespace ConsoleProgram
{
public class Class1
{
private const string URL = "https://sub.domain.com/objects.json?api_key=123";
private const string DATA = @"{""object"":{""name"":""Name""}}";
static void Main(string[] args)
{
Class1.CreateObject();
}
private static void CreateObject()
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
request.Method = "POST";
request.ContentType = "application/json";
request.ContentLength = DATA.Length;
StreamWriter requestWriter = new StreamWriter(request.GetRequestStream(), System.Text.Encoding.ASCII);
requestWriter.Write(DATA);
requestWriter.Close();
try {
WebResponse webResponse = request.GetResponse();
Stream webStream = webResponse.GetResponseStream();
StreamReader responseReader = new StreamReader(webStream);
string response = responseReader.ReadToEnd();
Console.Out.WriteLine(response);
responseReader.Close();
} catch (Exception e) {
Console.Out.WriteLine("-----------------");
Console.Out.WriteLine(e.Message);
}
}
}
}
//The url you wish to send the POST request to
$url = $file_name;
//The data you want to send via POST
$fields = [
'__VIEWSTATE ' => $state,
'__EVENTVALIDATION' => $valid,
'btnSubmit' => 'Submit'
];
//url-ify the data for the POST
$fields_string = http_build_query($fields);
//open connection
$ch = curl_init();
//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
//So that curl_exec returns the contents of the cURL; rather than echoing it
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
//execute post
$result = curl_exec($ch);
Get Order
The following are the details of Get Order API
- User can request details for multiple orders.
- All the orders which belong to the user are returned,
- If order ids are passed, then all the order which meet the criteria are returned.
Get OrderPOSTapi/Order/Orders
Status: Available
This API is used to get order status and to confirm details of the order.
Example URI
/api/Order/Orders
Request
Content-Type: application/json
Authorization: application/json
Body
{
"PageNo": 0,
"Records": 3,
"Orders": ["12001", "12002"]
}
200Body
{
"PageNo": 0,
"Records": 3,
"TotalPages": 1,
"Orders": [
{
"OrderId": "12001",
"Name": "12001",
"Address": "12001",
"Address2": "12001",
"City": "12001",
"State": "12001",
"ZipCode": "12001",
"Phone": "12001",
"Email": "12001",
"InvoiceNumber": null,
"OrderItems": [
{
"SKU": "CRUX-CA-001A",
"QuantityOrdered": 15,
"QunantityCommitted": 0,
"ShippingCarrier": "UPS",
"ShippingMethod": "Next Day Air"
}
],
"OrderStatus": 2,
"Shipments": []
},
{
"OrderId": "12002",
"Name": "Jhon Doe",
"Address": "A 436",
"Address2": "Sector 46",
"City": "Noida",
"State": "LA",
"ZipCode": "89180",
"Phone": "8800776943",
"Email": "[email protected]",
"InvoiceNumber": null,
"OrderItems": [
{
"SKU": "CRUX-CA-001A",
"QuantityOrdered": 15,
"QunantityCommitted": 15,
"ShippingCarrier": "UPS",
"ShippingMethod": "Next Day Air"
}
],
"OrderStatus": 2,
"Shipments": []
}
]
}
Shipped Orders
The following are the details of Shipped Order API
- User can request details for multiple orders.
- All shipments of the orders that are requested are returned,
- If the order doesn’t belong to the authenticated user, then it will be skipped.
Shipped OrderPOSTapi/Order/ShippedOrders
Status: available
This API gives us information regarding the shipped orders.
Example URI
/api/Order/ShippedOrders
Content-Type: application/json
Authorization: application/json
URL Parameters
{
"PageNo": 0,
"Records": 3,
"Orders": ["12001", "12002"]
}
200
Body
{
"PageNo": 0,
"Records": 1,
"TotalPages": 0,
"Orders": [
{
"OrderId": "12003",
"Name": "Jhon Doe",
"Address": "A 436",
"Address2": "Sector 46",
"City": "Noida",
"State": "LA",
"ZipCode": "89180",
"Phone": "8800776943",
"Email": "[email protected]",
"InvoiceNumber": null,
"OrderItems": [
{
"SKU": "CRUX-CA-001A",
"QuantityOrdered": 15,
"QunantityCommitted": 15,
"ShippingCarrier": "UPS",
"ShippingMethod": "Next Day Air"
}
],
"OrderStatus": 2,
"Shipments": [
{
"TrackingNumber": "ABCD123#123",
"ShippingCarrier": "Next Day Air",
"ShippingCost": "",
"HandlingFee": "",
"MSROrderId": null,
"InvoiceNumber": null,
"DateShipped": "01/19/2019 19:16:08",
"Items": [
{
"SKU": "CRUX-CA-001A",
"QuantityOrdered": 15,
"QuantityShipped": 15
}
]
}
]
}
]
}
Products ¶
You may use our ftp feed to get details of all the Products available with us. It is accessible at feed.msrdistribution.com, and provides files with complete details of the Products.
You may also use the following API to get incremental info of Products based on their modification date, and also track the changes in prices or inventory .
Get Products ¶
This API gives us information regarding the products. If the "LastSyncedSku" filter is used, it will provide the list of items created after this SKU (including this SKU).
- All the fields in request are used as a filter and are not required.
- Based on the filters, products are processed and response is generated.
Get ProductsPOSTapi/Product/Products
Status: available
Example URI
/api/Product/Products
Content-Type: application/json
Authorization: application/json
URL Parameters
{
"LastSyncedSku": "SKU of Last Product Synced",
"LastModifiedDate": "MM/dd/yyyy, All products modified after this date",
"Records": "Number of records to fetch. Must have an integer value.",
"PageNo" : "Page number to paginate results. Note first page is zero.",
"LastCreatedDate": "MM/dd/yyyy, Products created after this date"
}
200
Body
{
"ErrorMessage": "",
"Records": 1,
"PageNo": 0,
"TotalPages": 0,
"Products":
[
{
"Id": 1,
"SKU": "BK-001",
"Name": "\"The World's Assault Rifles\" by Gary Paul Johnston and Thomas B. Nelson,89",
"Description": "in.The World's Assault Riflesin. by Gary Paul Johnston and Thomas B. Nelson,",
"LongDescription": "The Worlds Assault Rifles [Hardcover], By Gary Paul Johnston and Thomas B. Nelson Covering more than 500 Assault Rifles from more than 51 countries, this is one of the most complete books ever written on the topic. In fact, it is so packed with information, even prototypes that precede some of the of the firearms get mentions. All that
",
"Manufacturer": "",
"MfgPartNo": null,
"UPCcode": null,
"Inventory": 0,
"StockStatus": "ClosedOut",
"GroundOnly": true,
"AirOnly": false,
"HazardousMaterial": true,
"DropshipBlocked": true,
"ShippingLength": 0,
"ShippingWidth": 0,
"ShippingHeight": 0,
"ShippingWeight": 7.97,
"Image1": "http://msrdistribution.com/content/images/thumbs/0000527_the-worlds-assault-rifles-by-gary-paul-johnston-and-thomas-b-nelson89.jpeg",
"Image2": "",
"Image3": "",
"Price": 0,
"MAP": 0,
"MSRP": 69.95,
"Category": "Books",
"ParentCategoryName": "Accessories",
"productType": "SimpleProduct",
"ProductGroupSku": null,
"CreatedOn": "12/03/2018 17:06:10",
"ModifiedOn": "01/18/2019 13:18:46",
"LastSyncedOn": "01/19/2019 11:48:32",
"PriceModidedOn": "12/14/2018 17:55:20",
"InventoryModifiedOn": "12/07/2018 18:55:07"
}
]
}
Stocks API
This API gives us information regarding the price and inventory. If the "LastSyncedSku" filter is used, it will provide the list of items created after this SKU (including this SKU).
- All the fields in request are used as a filter and are not required.
- Based on the filters, products are processed and response is generated.
Stocks APIPOSTapi/Product/Stock
Status: available
Example URI
/api/Product/Stock
Content-Type: application/json
Authorization: application/json
Body
{
"LastSyncedSku": "SKU of Last Product Synced",
"LastModifiedDate": "MM/dd/yyyy, All products modified after this date",
"Records": "Number of records to fetch. Must have an integer value."
"PageNo" : "Page number to paginate results. Note first page is zero."
"LastCreatedDate": "MM/dd/yyyy, Products created after this date"
}
200
Body
{
"ErrorMessage": "",
"Records": 1,
"PageNo": 0,
"TotalPages": 0,
"Products": [
{
"Sku": "BK-001",
"Price": 0,
"MSRP": 69.95,
"MAP": 0,
"Quantity": 0,
"Status": "ClosedOut"
}
]
}