[!WARNING] The Admin REST API has been deprecated. New apps should use the GraphQL Admin API. For more information see All in on GraphQL. New apps will be created with the config option
rest_disabled: true. This will raise aShopifyAPI::Errors::DisabledResourceErrorif you try to use the REST API.
Once OAuth is complete, we can use ShopifyAPI’s REST library to make authenticated API calls to the Shopify Admin API.
Every API request requires a valid ShopifyAPI::Auth::Session.
To instantiate a session, we recommend you either use the shopify_app if working in Rails, or refer to our OAuth docs on constructing a session:
ShopifyApp gem.ActiveResource, and follows our REST convention. Example:
# Update product title
product = ShopifyAPI::Product.find(id: <product_id>)
product.title = "My awesome product"
product.save!
rest_client = ShopifyAPI::Clients::Rest::Admin.new
body = { product: { title: “My cool product” } }
client.put to send your request to the specified Shopify Admin REST API endpoint.rest_client.put(path: “products/
We provide a templated class library to access REST resources similar to ActiveResource. Format of the methods closely resemble our REST API schema.
The version of REST resource that’s loaded and used is set from ShopifyAPI::Context.setup
Create an instance of the REST resource you’d like to use and optionally provide the following parameters.
| Parameter | Type | Notes |
| ———-|——|——-|
| session | ShopifyAPI::Auth::Session | Default value is nil.
When nil is passed in, active session information is inferred from ShopifyAPI::Context.active_session.
To set active session, use ShopifyAPI::Context.activate_session.
This is handled automatically behind the scenes if you use ShopifyApp’s session controllers. |
| from_hash | Hash | Default value is nil. Sets the resource properties to the values provided from the hash. |
Examples:
# To construct an Orders object using default session
# This creates a new order object with properties provided from the hash
order = ShopifyAPI::Orders.new(from_hash: {property: value})
order.save!
Typical methods provided for each resources are:
finddeleteallcountFull list of methods can be found on each of the resource class.
Order resource on 2024-01 version:
save methodThe save or save! method on a resource allows you to create or update that resource.
To create a new resource using the save or save! method, you can initialize the resource with a hash of values or simply assigning them manually. For example:
# Create a new product from hash
product_properties = {
title: "My awesome product"
}
product = ShopifyAPI::Product.new(from_hash: product_properties)
product.save!
# Create a new product manually
product = ShopifyAPI::Product.new
product.title = "Another one"
product.save!
To update an existing resource using the save or save! method, you’ll need to fetch the resource from Shopify first. Then, you can manually assign new values to the resource before calling save or save!. For example:
# Update a product's title
product = ShopifyAPI::Product.find(id: product_id)
product.title = "My new title"
product.save!
# Remove a line item from a draft order
draft_order = ShopifyAPI::DraftOrder.find(id: draft_order_id)
new_line_items = draft_order.line_items.reject { |line_item| line_item["id"] == 12345 }
draft_order.line_items = new_line_items
draft_order.save!
[!IMPORTANT] If you need to unset an existing value, please explicitly set that attribute to
nilor empty values such as[]or{}. For example:# Removes shipping address from draft_order draft_order.shipping_address = {} draft_order.save!This is because only modified values are sent to the API, so if
shipping_addressis not “modified” to{}. It won’t be part of the PUT request payload
When updating a resource, only the modified attributes, the resource’s primary key, and required parameters are sent to the API. The primary key is usually the id attribute of the resource, but it can vary if the primary_key method is overwritten in the resource’s class. The required parameters are identified using the path parameters of the PUT endpoint of the resource.
You can add custom headers to the HTTP calls made by methods like find, delete, all, count
by setting the headers attribute on the ShopifyAPI::Rest::Base class in an initializer, like so:
ShopifyAPI::Rest::Base.headers = { "X-Custom-Header" => "Custom Value" }
# `find` will call the API endpoint with the custom header
ShopifyAPI::Customer.find(id: customer_id)
⚠️ The API reference documentation contains more examples on how to use each REST Resources.
# Find and update a customer email
customer = ShopifyAPI::Customer.find(id: customer_id)
customer.email = "steve-lastnameson@example.com"
customer.save!
# Get all orders
orders = ShopifyAPI::Orders.all
# Retrieve a specific fulfillment order
fulfillment_order_id = 123456789
fulfillment_order = ShopifyAPI::FulfillmentOrder.find(id: fulfillment_order_id)
# Remove an existing product image
product_id = 1234567
image_id = 1233211234567
ShopifyAPI::Image.delete(product_id: product_id, id: image_id)
More examples can be found in each resource’s documentation on shopify.dev, e.g.:
Create an instance of ShopifyAPI::Clients::Rest::Admin using the current session to make requests to the Admin API.
| Parameter | Type | Notes |
| ———-|——|——-|
| session | ShopifyAPI::Auth::Session | Default value is nil.
When nil is passed in, active session information is inferred from ShopifyAPI::Context.active_session.
To set active session, use ShopifyAPI::Context.activate_session.
This is handled automatically behind the scenes if you use ShopifyApp’s session controllers. |
| api_version | String | Default value is nil. When nil is passed in, api version is inferred from ShopifyAPI::Context.setup.|
Examples:
# Create a default client with `ShopifyAPI::Context.api_version`
# and the active session from `ShopifyAPI::Context.active_session`
client = ShopifyAPI::Clients::Rest::Admin.new
# Create a client with a specific session "my_session"
client = ShopifyAPI::Clients::Rest::Admin.new(session: my_session)
# Create a client with active session from `ShopifyAPI::Context.active_session`
# and a specific api_version - "unstable"
client = ShopifyAPI::Clients::Rest::Admin.new(api_version: "unstable")
# Create a client with a specific session "my_session" and api_version "unstable"
client = ShopifyAPI::Clients::Rest::Admin.new(session: my_session, api_version: "unstable")
The ShopifyAPI::Clients::Rest::Admin client offers the 4 core request methods:
getdeletepostputEach method can take the parameters outlined in the table below.
| Parameter | Type | Required in Methods | Default Value | Notes |
|---|---|---|---|---|
path |
String |
all | none | The requested API endpoint path. This can be one of two formats:<ul><li>The path starting after the /admin/api/{version}/ prefix, such as products, which executes /admin/api/{version}/products.json</li><li>The full path, such as /admin/oauth/access_scopes.json</li></ul> |
body |
Hash(any(Symbol, String), untyped) |
put, post |
none | The body of the request |
query |
Hash(any(Symbol, String), any(String, Integer, Float)) |
none | none | An optional query object to be appended to the request url as a query string |
extraHeaders |
Hash(any(Symbol, String), any(String, Integer, Float)) |
none | none | Any additional headers you want to send with your request |
tries |
Integer |
None | 1 |
The maximum number of times to try the request (must be >= 0) |
Note: These parameters can still be used in all methods regardless of if they are required.
If the request is successful these methods will all return a ShopifyAPI::Clients::HttpResponse object, which has the following methods:
| Methods | Type | Notes |
|———|——|——-|
| code |Integer| HTTP Response code, e.g. 200|
| headers |Hash{String, [String]} | HTTP Response headers |
| body | Hash{String, Untyped} | HTTP Response body |
| prev_page_info | String | See Pagination|
| next_page_info | String | See Pagination|
If the request has failed, an error will be raised describing what went wrong.
You can rescue ShopifyAPI::Errors::HttpResponseError
and output error messages with errors.full_messages
See example:
client = ShopifyAPI::Clients::Rest::Admin.new(session: session)
response = client.get(path: "NOT-REAL")
some_function(response.body)
rescue ShopifyAPI::Errors::HttpResponseError => e
puts fulfillment.errors.full_messages
# {"errors"=>"Not Found"}
# If you report this error, please include this id: bce76672-40c6-4047-b598-46208ab076f0.
GET request# Create a new client.
client = ShopifyAPI::Clients::Rest::Admin.new(session: session)
# Use `client.get` to request the specified Shopify REST API endpoint, in this case `products`.
response = client.get(path: "products")
# Do something with the returned data
some_function(response.body)
For more information on the products endpoint, check out our API reference guide.
POST request# Create a new client.
client = ShopifyAPI::Clients::Rest::Admin.new(session: session)
# Build your post request body.
body = {
product: {
title: "Burton Custom Freestyle 151",
body_html: "\u003cstrong\u003eGood snowboard!\u003c\/strong\u003e",
vendor: "Burton",
product_type: "Snowboard",
}
}
# Use `client.post` to send your request to the specified Shopify Admin REST API endpoint.
# This POST request will create a new product.
client.post({
path: "products",
body: body,
});
For more information on the products endpoint, check out our API reference guide.
PUT request # Create a new client.
client = ShopifyAPI::Clients::Rest::Admin.new
# Update product title
body = {
product: {
title: "My cool product"
}
}
# Use `client.put` to send your request to the specified Shopify Admin REST API endpoint.
# This will update product title for product with ID <id>
client.put(path: "products/<id>.json", body: body)
For more information on the products endpoint, check out our API reference guide.
The REST resources have api_call_limit and retry_after can be found on the Resource class. These values correspond to the X-Shopify-Shop-Api-Call-Limit and Retry-After headers respectively.
product = ShopifyAPI::Product.find(session: session, id: 12345)
# X-Shopify-Shop-Api-Call-Limit: 32/40
request_count = ShopifyAPI::Product.api_call_limit[:request_count] # 32
bucket_size = ShopifyAPI::Product.api_call_limit[:bucket_size] # 40
retry_after = ShopifyAPI::Product.retry_request_after
This library also supports cursor-based pagination for REST Admin API requests. Learn more about REST request pagination.
After making a request, the next_page_info and prev_page_info can be found on the response object and passed as the page_info query param in other requests.
An example of this is shown below:
client = ShopifyAPI::Clients::Rest::Admin.new(session: session)
response = client.get(path: "products", query: { limit: 10 })
next_page_info = response.next_page_info
if next_page_info
next_page_response =client.get(path: "products", query: { limit: 10, page_info: next_page_info })
some_function(next_page_response)
end
Similarly, when using REST resources the next_page_info and prev_page_info can be found on the Resource class and passed as the page_info query param in other requests.
An example of this is shown below:
products = ShopifyAPI::Product.all(session: session, limit: 10)
loop do
some_function(products)
break unless ShopifyAPI::Product.next_page?
products = ShopifyAPI::Product.all(session: session, limit: 10, page_info: ShopifyAPI::Product.next_page_info)
end