Using the Shopify Ajax API

Shopify provides shop-owners with an Ajax API that returns JSON-encoded responses.

This Ajax API makes it possible to add items to the cart, update quantities in the cart, and fetch information about the cart, without a page refresh. With this API, you can also fetch information about a particular product using its handle.

Wrapper library: use one or not

You can use a jQuery wrapper library to submit your requests to Shopify.

To use our own jQuery wrapper library, include it like so:

{{ '//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js' | script_tag }}
{{ 'api.jquery.js' | shopify_asset_url | script_tag }}

Laboratory page

If you're using the jQuery wrapper library, head over to the laboratory page at http://mayert-douglas4935.myshopify.com/pages/api. This page serves as documentation for our jQuery wrapper library.

Shopify Ajax API Reference

The following calls can be submitted via Ajax to your Shopify shop. Note that all URLs end with a .js extension.

The coding examples provided below don't always use a callback for the sake of simplicity. It goes without saying that you'll almost always need to update the page (or do something, anything), after submitting a request, so you'll use a callback where none has been provided.

GET /products/<product-handle>.js

Get the JSON of a product using the product handle.

All monetary properties are returned in the customer's presentment currency. To check the customer's presentment currency, you can use the currency field of the /cart.js endpoint. To learn more about selling in multiple currencies, see Migrating to support multiple currencies.

Response

The JSON of the product.

Example:

{
  "id": 329678821,
  "title": "Red Rain Coat",
  "handle": "red-rain-coat",
  "description": "<p>Lorem Ipsum.</p>",
  "published_at": "2014-06-12T16:28:11-04:00",
  "created_at": "2014-06-12T16:28:13-04:00",
  "vendor": "Shopify",
  "type": "Coat",
  "tags": [
    "Spring"
  ],
  "price": 12900,
  "price_min": 12900,
  "price_max": 12900,
  "available": true,
  "price_varies": false,
  "compare_at_price": null,
  "compare_at_price_min": 0,
  "compare_at_price_max": 0,
  "compare_at_price_varies": false,
  "variants": [
    {
      "id": 794864229,
      "title": "Small",
      "options": [
        "Small"
      ],
      "option1": "Small",
      "option2": null,
      "option3": null,
      "price": 12900,
      "weight": 0,
      "compare_at_price": null,
      "inventory_management": "shopify",
      "available": true,
      "sku": null,
      "requires_shipping": true,
      "taxable": true,
      "barcode": "49738645"
    },
    {
      "id": 794864233,
      "title": "Medium",
      "options": [
        "Medium"
      ],
      "option1": "Medium",
      "option2": null,
      "option3": null,
      "price": 12900,
      "weight": 0,
      "compare_at_price": null,
      "inventory_management": "shopify",
      "available": true,
      "sku": null,
      "requires_shipping": true,
      "taxable": true,
      "barcode": "49738657"
    },
    {
      "id": 794864237,
      "title": "Large",
      "options": [
        "Large"
      ],
      "option1": "Large",
      "option2": null,
      "option3": null,
      "price": 12900,
      "weight": 0,
      "compare_at_price": null,
      "inventory_management": "shopify",
      "available": true,
      "sku": null,
      "requires_shipping": true,
      "taxable": true,
      "barcode": "49738673"
    }
  ],
  "images": [
    "//cdn.shopify.com/s/files/1/0040/7092/products/red-rain-coat.jpeg?v=1402604893"
  ],
  "featured_image": "//cdn.shopify.com/s/files/1/0040/7092/products/red-rain-coat.jpeg?v=1402604893",
  "options": [
    {
      "name": "Size",
      "position": 1
    }
  ],
  "url": "/products/red-rain-coat"
}

Example coding using jQuery:

jQuery.getJSON('/products/red-rain-coat.js', function(product) {
  alert('The title of this product is ' + product.title);
} );

(Return to top)

POST /cart/add.js

Use this to add a variant to the cart.

POST data

{
  quantity: 2,
  id: 794864229
}

Where quantity is how many you want to add of a particular variant, and id is the variant ID of that variant.

You can also send a serialized Add to Cart form:

jQuery.post('/cart/add.js', $('form[action="/cart/add"]').serialize());

You can add to the cart with Line Item Properties, not just a quantity and id:

jQuery.post('/cart/add.js', {
  quantity: 1,
  id: 794864229,
  properties: {
    'First name': 'Caroline'
  }
});

You cannot add different variants to the cart with a single Ajax request. You'll need to queue up several Ajax requests synchronously to add different variants to the cart.

Response

The JSON of the line item associated with the added variant.

Example:

{
  "id": 794864229,
  "title": "Red Rain Coat - Small",
  "key": "794864229:03af7a8cb59a4c3c45595c76fa8cb53c",
  "price": 12900,
  "line_price": 12900,
  "quantity": 1,
  "sku": null,
  "grams": 0,
  "vendor": "Shopify",
  "properties": null,
  "variant_id": 794864229,
  "gift_card": false,
  "url": "/products/red-rain-coat?variant=794864229",
  "image": "http://cdn.shopify.com/s/files/1/0040/7092/products/red-rain-coat.jpeg?v=1402604893",
  "handle": "red-rain-coat",
  "requires_shipping": true,
  "product_title":"Red Rain Coat",
  "product_description":"A bright red rain coat for rainy days!",
  "product_type":"Coat",
  "variant_title":"Red",
  "variant_options":["Red"]
}

If the item was already in the cart, the quantity will be equal to the new quantity for that item.

Error responses

If the exact quantity specified for the item cannot be added to the cart (say you were trying to add 9 items, 2 are already in the cart, and 10 are in stock), no item is added the cart. The error returned will be:

{
  "status": 422,
  "message": "Cart Error",
  "description": "You can only add 8 Messenger Bag to the cart."
}

Note that the error too is formatted as JSON.

The error code is:

422 (Unprocessable Entity)

If the product is entirely sold out, the error returned will say this:

The product #{item.name} is already sold out.

If the product is not sold out but the requested quantity exceeds what is available, yet at least 1 item can still be added to the cart, the error returned will specify how many more items can be added to the cart:

You can only add #{item.remaining_inventory} #{item.name} to the cart.

The #{item.remaining_inventory} value is equal to #{item.inventory_quantity} minus what's in the cart.

If the product is not sold out, but all of its stock is in the cart, the returned error will say:

All #{item.inventory_quantity} #{item.name} are in your cart.

(Return to top)

GET /cart.js

Use this to get the cart as JSON.

All monetary properties are returned in the customer's presentment currency. To check the customer's presentment currency, you can use the currency field in the response. To learn more about selling in multiple currencies, see Migrating to support multiple currencies.

Response

The JSON of the cart.

Example:

{
  "token": "1d19a32178501c44ef2223d73c54d16d",
  "note": "hello!",
  "attributes": {
  },
  "total_price": 9100,
  "total_weight": 0,
  "item_count": 3,
  "items": [
    {
      "id": 794864229,
      "title": "Red Rain Coat - Small",
      "price": 12900,
      "line_price": 12900,
      "final_price": 12900,
      "final_line_price": 12900,
      "quantity": 1,
      "sku": null,
      "grams": 0,
      "vendor": "Shopify",
      "properties": null,
      "variant_id": 794864229,
      "gift_card": false,
      "url": "/products/red-rain-coat?variant=794864229",
      "image": "http://cdn.shopify.com/s/files/1/0040/7092/products/red-rain-coat.jpeg?v=1402604893",
      "handle": "red-rain-coat",
      "requires_shipping": true,
      "product_title":"Red Rain Coat",
      "product_description":"A bright red rain coat for rainy days!",
      "product_type":"Coat",
      "variant_title":"Red",
      "variant_options":["Red"]
    },
    {
      "id": 794864101,
      "title": "Gray Fedora",
      "key": "794864101:816a55d9a53cd82281f8fdcfe967db14",
      "price": 2650,
      "line_price": 0,
      "final_price": 2650,
      "final_line_price": 5300,
      "quantity": 2,
      "sku": null,
      "grams": 0,
      "vendor": "Shopify",
      "properties": null,
      "variant_id": 794864101,
      "gift_card": false,
      "url": "/products/gray-fedora?variant=794864101",
      "image": "http://cdn.shopify.com/s/files/1/0040/7092/products/gray-fedora.jpeg?v=1402604885",
      "handle": "gray-fedora",
      "requires_shipping": true,
      "product_title":"Gray Fedora",
      "product_description":"A gray hat for looking cool!",
      "product_type":"Hats",
      "variant_title":"Gray",
      "variant_options":["Gray"],
      "line_level_discount_allocations": [
        {
          "amount": 500,
          "discount_application": {
            "type": "script",
            "key": "a8a3d7aa-7d00-4827-a2e1-b03c32160bf2",
            "title": "5 Dollar Off",
            "description": null,
            "value": "5.00",
            "created_at": "2019-04-10T20:49:10.023Z",
            "value_type": "fixed_amount",
            "allocation_method": "one",
            "target_selection": "explicit",
            "target_type": "line_item",
            "total_allocated_amount": 500
          }
        }
      ]
    }
  ],
  "requires_shipping": true,
  "currency": "CAD",
  "items_subtotal_price": 18200,
  "cart_level_discount_applications": [
    {
      "type": "automatic",
      "key": "059b5e54-3c5d-4e7e-b377-8e09d8376269",
      "title": "50% Summer Deal",
      "description": null,
      "value": "50.0",
      "created_at": "2019-04-10T20:49:00.148Z",
      "value_type": "percentage",
      "allocation_method": "across",
      "target_selection": "all",
      "target_type": "line_item",
      "total_allocated_amount": 9100
    }
  ]
}

Example response for an empty cart:

{
  "token": "1d19a32178501c44ef2223d73c54d16d",
  "note": null,
  "attributes": {},
  "total_price": 0,
  "total_weight": 0,
  "item_count": 0,
  "items": [],
  "requires_shipping": false,
  "currency": "CAD"
}

(Return to top)

POST /cart/update.js

Use this to change cart attributes, the cart note, and quantities of line items in the cart.

POST data

{
  quantity: 1,
  id: 794864053
}

quantity is the new quantity you want for a particular item, and id is the variant_id of that line item or the line item's key.

If you use line item properties, then it's best to use a line item's key since the cart might end up with several items that share the same variant ID.

{
  quantity: 1,
  id: 794864053:70ff98a797ed385f6ef25e6e974708ca
}

You can also send a serialized cart form, or submit updates to cart attributes and a cart note.

The following is an example of posting a note:

{
  note: 'This is a note about my order'
}

You can also submit an array of numbers to /cart/update.js, where the size of the array matches the number of line items in the cart.

For example, if you have 3 line items in the cart with quantities 1, 2, and 3, and you want to change those quantities to 3, 2, and 1, then you can use the following:

jQuery.post('/cart/update.js', {updates: [3, 2, 1]});

Response

The JSON of the cart.

If the cart is empty the following jQuery snippet will add 2 of variant 794864053 and 3 of variant 794864233:

jQuery.post('/cart/update.js', {updates: {794864053: 2, 794864233: 3}});

This version will yield the same result:

jQuery.post('/cart/update.js', "updates[794864053]=2&updates[794864233]=3");

If you send the following you will update the quantity of 794864053 to 5:

jQuery.post('/cart/update.js', {updates: {794864053: 5}});

Finally, you can remove both 794864053 and 794864233 from the cart with the following:

jQuery.post('/cart/update.js', {updates: {794864053: 0, 794864233: 0}});

Error responses

If a variant ID is provided that either doesn't exist or isn't available in the online store channel, then the endpoint returns the following error:

{
  "status": 404,
  "message": "Cart Error"
  "description": "Cannot find variant"
}

When a new variant is added to the cart and the quantity exceeds what's available, the result is a 422 error:

{
  "status": 422,
  "message": "Cart Error",
  "description": "You can only add 8 Messenger Bag to the cart."
}

(Return to top)

POST /cart/change.js

This call sets the quantity of an item already in the cart. The /cart/change.js controller is only able to update the quantity of one item at a time.

POST data

{
  quantity: 1,
  id: 794864053
}

quantity is the new quantity you want for a particular item, and id is the variant_id of that line item or the line item's key.

If you use line item properties, then it's best to use a line item's key since the cart might end up with several items that share the same variant ID.

{
  quantity: 1,
  id: 794864053:70ff98a797ed385f6ef25e6e974708ca
}

You can also change a line item's quantity based on its position in the cart. Use the line property instead of id and provide the 1-based index of the item in the cart.

{
  quantity: 1,
  line: 2
}

Response

The JSON of the cart.

jQuery.post('/cart/change.js', { quantity: 1, line: 2 });

Error responses

If the item that you're attempting to change isn't already in the cart, then /cart/change.js doesn't add it. Instead, it returns a 404 error.

(Return to top)

POST /cart/clear.js

This call sets all quantities of all line items in the cart to zero.

Response

The JSON of an empty cart. This does not remove cart attributes nor the cart note.

Example:

{
  "token": "1d19a32178501c44ef2223d73c54d16d",
  "note": null,
  "attributes": {},
  "total_price": 0,
  "total_weight": 0,
  "item_count": 0,
  "items": [],
  "requires_shipping": false
}

(Return to top)

GET /cart/shipping_rates.json

Get estimated shipping rates.

Example call:

/cart/shipping_rates.json?shipping_address%5Bzip%5D=K1N+5T2&shipping_address%5Bcountry%5D=Canada&shipping_address%5Bprovince%5D=Ontario

Response

Example:

{
  "shipping_rates": [
    {
      "name": "Ground Shipping",
      "price": "8.00",
      "delivery_date": null,
      "source": "shopify"
    },
    {
      "name": "Expedited Shipping",
      "price": "15.00",
      "delivery_date": null,
      "source": "shopify"
    },
    {
      "name": "Express Shipping",
      "price": "30.00",
      "delivery_date": null,
      "source": "shopify"
    }
  ]
}

(Return to top)

For a given product, display recommended products on the product page.

Query parameters

product_id (required): Id of the product that you want to show recommended products for.

limit (optional): Limits number of results, up to a maximum of ten. Using the limit parameter cannot increase the number of results over ten. A maximum of ten results are given when this is not used.

To get the most out of your recommended products section, read Showing product recommendations on product pages.

Example call using jQuery:

jQuery.getJSON("/recommendations/products.json?product_id=17&limit=4", function(
 response
) {
 var recommendedProducts = response.products;
 if (recommendedProducts.length > 0) {
   var firstRecommendedProduct = recommendedProducts[0];
   alert(
     "The title of the first recommended product is: " +
       firstRecommendedProduct.title
   );
 }
});

Example call using Fetch:

fetch("/recommendations/products.json?product_id=17&limit=4")
 .then(response => response.json())
 .then(({ products }) => {
   if (products.length > 0) {
     const firstRecommendedProduct = products[0];
     alert(
       `The title of the first recommended product is: ${
         firstRecommendedProduct.title
       }`
     );
   }
 });

Response

Example:

{
 "products": [
   {
     "id": 35,
     "title": "Gorgeous Silk Coat",
     "handle": "gorgeous-silk-coat",
     "description": null,
     "published_at": "2019-02-26T11:34:58-05:00",
     "created_at": "2019-02-26T11:34:58-05:00",
     "vendor": "Marge Group",
     "type": "Outdoors",
     "tags": [],
     "price": 380000,
     "price_min": 380000,
     "price_max": 790000,
     "available": true,
     "price_varies": true,
     "compare_at_price": null,
     "compare_at_price_min": 0,
     "compare_at_price_max": 0,
     "compare_at_price_varies": false,
     "variants": [
       {
         "id": 69,
         "title": "Small Aluminum Knife",
         "option1": "Small Aluminum Knife",
         "option2": null,
         "option3": null,
         "sku": "",
         "requires_shipping": true,
         "taxable": true,
         "featured_image": null,
         "available": true,
         "name": "Gorgeous Silk Coat - Small Aluminum Knife",
         "public_title": "Small Aluminum Knife",
         "options": [
           "Small Aluminum Knife"
         ],
         "price": 790000,
         "weight": 9500,
         "compare_at_price": null,
         "inventory_management": "shopify",
         "barcode": null
       },
       {
         "id": 70,
         "title": "Heavy Duty Bronze Shoes",
         "option1": "Heavy Duty Bronze Shoes",
         "option2": null,
         "option3": null,
         "sku": "",
         "requires_shipping": true,
         "taxable": true,
         "featured_image": null,
         "available": true,
         "name": "Gorgeous Silk Coat - Heavy Duty Bronze Shoes",
         "public_title": "Heavy Duty Bronze Shoes",
         "options": [
           "Heavy Duty Bronze Shoes"
         ],
         "price": 380000,
         "weight": 2200,
         "compare_at_price": null,
         "inventory_management": "shopify",
         "barcode": null
       }
     ],
     "images": [],
     "featured_image": null,
     "options": [
       {
         "name": "Color or something",
         "position": 1,
         "values": [
           "Small Aluminum Knife",
           "Heavy Duty Bronze Shoes"
         ]
       }
     ],
     "url": "/products/gorgeous-silk-coat?pr_choice=default&pr_prod_strat=copurchase&pr_rec_pid=35&pr_ref_pid=17&pr_seq=alternating"
   },
   {
     "id": 13,
     "title": "Gorgeous Wooden Computer",
     "handle": "gorgeous-wooden-computer",
     "description": null,
     "published_at": "2019-02-26T11:34:15-05:00",
     "created_at": "2019-02-26T11:34:15-05:00",
     "vendor": "Purdy Inc",
     "type": "Garden",
     "tags": [],
     "price": 930000,
     "price_min": 930000,
     "price_max": 1730000,
     "available": true,
     "price_varies": true,
     "compare_at_price": null,
     "compare_at_price_min": 0,
     "compare_at_price_max": 0,
     "compare_at_price_varies": false,
     "variants": [
       {
         "id": 25,
         "title": "Mediocre Silk Bottle",
         "option1": "Mediocre Silk Bottle",
         "option2": null,
         "option3": null,
         "sku": "",
         "requires_shipping": true,
         "taxable": true,
         "featured_image": null,
         "available": true,
         "name": "Gorgeous Wooden Computer - Mediocre Silk Bottle",
         "public_title": "Mediocre Silk Bottle",
         "options": [
           "Mediocre Silk Bottle"
         ],
         "price": 1730000,
         "weight": 5700,
         "compare_at_price": null,
         "inventory_management": "shopify",
         "barcode": null
       },
       {
         "id": 26,
         "title": "Lightweight Paper Shirt",
         "option1": "Lightweight Paper Shirt",
         "option2": null,
         "option3": null,
         "sku": "",
         "requires_shipping": true,
         "taxable": true,
         "featured_image": null,
         "available": true,
         "name": "Gorgeous Wooden Computer - Lightweight Paper Shirt",
         "public_title": "Lightweight Paper Shirt",
         "options": [
           "Lightweight Paper Shirt"
         ],
         "price": 930000,
         "weight": 6600,
         "compare_at_price": null,
         "inventory_management": "shopify",
         "barcode": null
       }
     ],
     "images": [],
     "featured_image": null,
     "options": [
       {
         "name": "Color or something",
         "position": 1,
         "values": [
           "Mediocre Silk Bottle",
           "Lightweight Paper Shirt"
         ]
       }
     ],
     "url": "/products/gorgeous-wooden-computer?pr_choice=default&pr_prod_strat=description&pr_rec_pid=13&pr_ref_pid=17&pr_seq=alternating"
   },
 ]
}

Error responses

In the absence of a product_id param, the endpoint returns the following error:

{
  "status": 422,
  "message": "Invalid parameter error",
  "description": "A product_id value is missing"
}

If the product_id is for a product that doesn't exist, or that isn't published in the “online store” channel, then the endpoint returns the following error:

{
  "status": 404,
  "message": "Product not found",
  "description": "No product with id <product-id> is published in the online store"
}

(Return to top)

You're building a quick order form? Beware

Your request queue can be a very simple JavaScript array:

Shopify.queue = [];

As you examine your quantity fields, you will add requests to that queue:

jQuery('.quantity').each(function() {
  Shopify.queue.push( {
    variantId: jQuery(this).data('variant-id'),
    quantity: parseInt(jQuery(this).val(), 10) || 0
  } );
});

When you are done, you start your engine, using for instance Shopify.addItem.

The callback of this Ajax request should call a function that shifts (removes) a request from Shopify.queue and then call Shopify.addItem with the variantId and quantity stored in the next request. Of course, you'll check if the queue has any requests left in it. If it's empty, you must cheerfully redirect to the cart page.

Something like this:

Shopify.moveAlong = function() {
  // If we still have requests in the queue, let's process the next one.
  if (Shopify.queue.length) {
    var request = Shopify.queue.shift();
    Shopify.addItem(request.variantId, request.quantity, Shopify.moveAlong);
  }
  // If the queue is empty, we will redirect to the cart page.
  else {
    document.location.href = '/cart';
  }
};

Shopify.moveAlong must be called within the callback of each Ajax request.

Ready to start selling with Shopify?

Try it free