Shopify's 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.

    In this article:

  1. Wrapper libraries: make your pick or roll up your own
  2. Laboratory pages
  3. Your best friend when developing Ajax code is Firebug
  4. Shopify Ajax API Reference
  5. You're building a quick order form? Beware

Wrapper libraries: make your pick or roll up your own

You can use our Prototype wrapper library to submit your requests to Shopify, or you can use our jQuery one. You can also write your own wrapper / utility script.

To use our Prototype wrapper library, include it in the head element of your document in your theme.liquid layout file like so:

{{ 'prototype/1.6/prototype.js' | global_asset_url  | script_tag }}
{{ 'api.js' | shopify_asset_url | script_tag }}

To use our jQuery wrapper library, include it in the head element of your document in your theme.liquid layout file like so:

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

Laboratory pages

If you've opted to use the Prototype library, you may like to know that Shopify provides you with a labo page at yourstore.myshopify.com/shopify/api.html to play with the API. (Replace 'yourstore' with your store name.) This labo page will show you how to call the API using the Prototype wrapper library, so it serves as documentation for the Prototype wrapper library.

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

Your best friend when developing Ajax code is Firebug

When playing with the respective labo pages, or when integrating Ajax into your own Shopify theme, make sure to use Firebug with the 'Net' tab open and set to XHR. Firebug will show the Ajax requests you submit along with their responses.

#

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. .js stands for JSON.

4.1 GET /products/<product-handle>.js

Get the JSON of a product using the product handle.

  • Response The JSON of the product.

Example:

{
    "options": [
        {
            "name": "Size"
        }
    ],
    "handle": "amelia",
    "available": true,
    "price": 2000,
    "title": "amelia",
    "featured_image": "http://static.shopify.com/s/files/1/0040/7092/products/2766315_da1b.png?1268045506",
    "tags": [
        "colorful",
        "cute",
        "woman"
    ],
    "url": "/products/amelia",
    "type": "undies",
    "compare_at_price": 2000,
    "id": 11790322,
    "images": [
        "http://static.shopify.com/s/files/1/0040/7092/products/2766315_da1b.png?1268045506"
    ],
    "compare_at_price_varies": false,
    "compare_at_price_max": 2000,
    "price_varies": false,
    "description": "\u003Cp\u003E\u003Cstrong\u003EThe best underwear you\u0026#8217;ll ever wear!\u003C/strong\u003E\u003Cbr /\u003E\nThese artisan undies are made from a soft \u003Cem\u003Ebreathable\u003C/em\u003E microfibre that won\u0026#8217;t fade or shrink.\u003C/p\u003E",
    "variants": [
        {
            "option2": null,
            "option3": null,
            "options": [
                "small"
            ],
            "requires_shipping": true,
            "available": false,
            "weight": 181,
            "price": 2000,
            "title": "small",
            "inventory_quantity": 0,
            "taxable": true,
            "compare_at_price": 2000,
            "id": 30104002,
            "inventory_management": "shopify",
            "sku": "",
            "option1": "small"
        },
        {
            "option2": null,
            "option3": null,
            "options": [
                "medium"
            ],
            "requires_shipping": true,
            "available": true,
            "weight": 200,
            "price": 2000,
            "title": "medium",
            "inventory_quantity": 10,
            "taxable": true,
            "compare_at_price": 2000,
            "id": 30104012,
            "inventory_management": "shopify",
            "sku": "",
            "option1": "medium"
        },
        {
            "option2": null,
            "option3": null,
            "options": [
                "large"
            ],
            "requires_shipping": true,
            "available": true,
            "weight": 200,
            "price": 2000,
            "title": "large",
            "inventory_quantity": 10,
            "taxable": true,
            "compare_at_price": 2000,
            "id": 30104022,
            "inventory_management": "shopify",
            "sku": "",
            "option1": "large"
        }
    ],
    "price_max": 2000,
    "vendor": "the candi factory",
    "compare_at_price_min": 2000,
    "price_min": 2000
}

4.2 POST /cart/add.js

Use this to add a variant or variants to the cart.

  • Parameters (POST data)
quantity=2&id=30104012

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.

  • Response if successful The JSON of the line item associated with the added variant.

Example:

{
    "handle": "amelia",
    "line_price": 4000,
    "requires_shipping": true,
    "price": 2000,
    "title": "amelia - medium",
    "url": "/products/amelia",
    "quantity": 2,
    "id": 30104012,
    "grams": 200,
    "sku": "",
    "vendor": "the candi factory",
    "image": "http://static.shopify.com/s/files/1/0040/7092/products/2766315_da1b.png?1268045506",
    "variant_id": 30104012
}

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

  • Response if error

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": 500,
    "description": "We only have 10 item(s) of amelia - medium left.",
    "message": "Cart Error"
}

Note that the error too is formatted as JSON. The error code is:

500 Internal Server Error

4.3 GET /cart.js

Use this to get the cart as JSON.

  • Response The JSON of the cart.

Example:

{
    "items": [
        {
            "handle": "aquarius",
            "line_price": 6000,
            "requires_shipping": true,
            "price": 2000,
            "title": "aquarius - medium",
            "url": "/products/aquarius",
            "quantity": 3,
            "id": 30104042,
            "grams": 181,
            "sku": "",
            "vendor": "the candi factory",
            "image": "http://static.shopify.com/s/files/1/0040/7092/products/aquarius_1.gif?1268045506",
            "variant_id": 30104042
        },
        {
            "handle": "amelia",
            "line_price": 4000,
            "requires_shipping": true,
            "price": 2000,
            "title": "amelia - medium",
            "url": "/products/amelia",
            "quantity": 2,
            "id": 30104012,
            "grams": 200,
            "sku": "",
            "vendor": "the candi factory",
            "image": "http://static.shopify.com/s/files/1/0040/7092/products/2766315_da1b.png?1268045506",
            "variant_id": 30104012
        }
    ],
    "requires_shipping": true,
    "total_price": 10000,
    "attributes": null,
    "item_count": 5,
    "note": null,
    "total_weight": 947
}

Example of a response for an empty cart:

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

4.4 POST /cart/update.js

Use this to change cart attributes, the cart note, and quantities of line items in the cart. Take note that you cannot add an item to the cart using this.

  • Parameters (POST data)
quantity=2&id=30104012

Where quantity is the new quantity you want for a particular item already added to the cart, and id is the variant ID of that line item. You can also send a serialized Cart form.

Reminder

This is what you will use to submit cart attributes and / or a cart note.

  • Response if successful

The JSON of the amended cart.

If you're trying to change the quantity of an item that's not been added to the cart, there will be no error, and yet no change to the cart.

  • Response if error

If the desired change in quantity is not possible (say you have 60 items in the cart for item X, and item X stock is 80, and you're trying to change its quantity to a 100), then no change is made to the cart.

{
    "description": "We only have 80 item(s) of aquarius - medium left.",
    "status": 500,
    "message": "Error"
}

Note that the error too is formatted as JSON. The error code is:

500 Internal Server Error

4.4.1 POST /cart/update.js - multi update logic

If the cart is empty the following jQuery snippet will add 2 of variant 1234 and 3 of variant 5678

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

This version without magic jQuery serialization will yield the same result:

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

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

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

Finally you can destroy both 1234 and 5678 with the following:

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

4.5 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:

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

4.6 GET /cart/shipping_rates.json

Get estimated shipping rates.

Example of 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"
        }
    ]
}

You're building a quick order form? Beware

Caution

Ajax requests that updates to Shopify's cart must be queued and sent synchronously to the server. Meaning: you must wait for your 1st ajax callback, to send your 2nd request, and then wait for its callback to send your 3rd request, etc.

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({ 
    variant_id: jQuery(this).attr('title').remove('variant-'),
    quantity_id: parseInt(jQuery(this).val(), 10)
  });
});

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' a request from Shopify.queue (removes it) and then call Shopify.addItem with the variant_id 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.variant_id, request.quantity, Shopify.moveAlong);
  }
  // If the queue is empty, we will redirect to the cart page.
  else {
    jQuery('#' + Shopify.ButtonId).removeAttr('disabled');
    document.location.href = '/cart';
  }  
};

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

Ready to put what you've learned into action?

Build an online store with Shopify Try it Free

Experience the future of retail now

Shopify Point of Sale Try it Free