CarrierService

A Carrier Service (also known as a Carrier Calculated Service or Shipping Service) provides real-time shipping rates to Shopify. Some common carrier services include: Canada Post, FedEx, UPS, and USPS. Note that the term "carrier" is often used interchangeably with the terms "shipping company" and "rate provider."

To access the Carrier Service API, a store must meet one of the following requirements:

  • It is on the Advanced Shopify plan or higher.
  • Its Shopify plan is paid annually.
  • It is a development store.

Using the Carrier Service API, you can register a new carrier service and provide endpoints to Shopify with a list of applicable shipping rates. With the Carrier Service API you can even use the cart data to adjust shipping rates and offer shipping discounts based on what is in the customer's cart.

When registering a new carrier service, you will need to provide a POST endpoint rooted in the callback_url where Shopify can retrieve applicable shipping rates. Your callback_url should be a public endpoint that expects these requests from Shopify.

Shopify provides server-side caching to reduce the number of external requests. Any shipping rate estimate request that identically matches the following fields will be retrieved from Shopify's cache of the initial response:

  • variant ids
  • default shipping box weight and dimensions
  • variant quantities
  • carrier service id
  • origin address
  • destination address
  • item weights and signatures

If any of these fields differ, or if the cache has expired since the original request, then new shipping rates will be requested from the external provider.

A sample Shopify request for shipping rates:

POST Your callback URL

Get a list of applicable shipping rates for the following...

Example Shipping Rate Request sent to a Carrier Service

        {
           "rate": {
               "origin": {
                   "country": "CA",
                   "postal_code": "K1S4J3",
                   "province": "ON",
                   "city": "Ottawa",
                   "name": null,
                   "address1": "520 Cambridge Street South",
                   "address2": null,
                   "address3": null,
                   "phone": null,
                   "fax": null,
                   "address_type": null,
                   "company_name": null
               },
               "destination": {
                   "country": "CA",
                   "postal_code": "K1S 3T7",
                   "province": "ON",
                   "city": "Ottawa",
                   "name": "Jason Normore",
                   "address1": "520 Cambridge Street South Apt. 5",
                   "address2": null,
                   "address3": null,
                   "phone": "7097433959",
                   "fax": null,
                   "address_type": null,
                   "company_name": null
               },
               "items": [
                   {
                       "name": "My Product 3",
                       "sku": null,
                       "quantity": 1,
                       "grams": 1000,
                       "price": 2000,
                       "vendor": "TestVendor",
                       "requires_shipping": true,
                       "taxable": true,
                       "fulfillment_service": "manual"
                   }
               ],
               "currency": "CAD"
           }
        }
                    
        {
           "rates": [
               {
                   "service_name": "canadapost-overnight",
                   "service_code": "ON",
                   "total_price": "1295",
                   "description": "This is the fastest option by far",
                   "currency": "CAD",
                   "min_delivery_date": "2013-04-12 14:48:45 -0400",
                   "max_delivery_date": "2013-04-12 14:48:45 -0400"
               },
               {
                   "service_name": "fedex-2dayground",
                   "service_code": "2D",
                   "total_price": "2934",
                   "currency": "USD",
                   "min_delivery_date": "2013-04-12 14:48:45 -0400",
                   "max_delivery_date": "2013-04-12 14:48:45 -0400"
               },
               {
                   "service_name": "fedex-priorityovernight",
                   "service_code": "1D",
                   "total_price": "3587",
                   "currency": "USD",
                   "min_delivery_date": "2013-04-12 14:48:45 -0400",
                   "max_delivery_date": "2013-04-12 14:48:45 -0400"
               }
           ]
        }
                    

Note that the address3, fax, address_type, and company_name fields are returned by specific ActiveShipping providers. For API-created Carrier Services, you can faithfully stick to shipping address fields only, i.e. address1, address2, city, zip, province, and country. Other values are not sent to the callback URL; they remain null.

Callback interface

When Shopify requests shipping rates using your configured carrier service callback_url, the response object rates must be a JSON array of objects with the following fields. Required fields must be included in the response for the carrier service integration to work properly.

Field Description
service_name The name of the rate, which customers will see at checkout. For example: "Expedited Mail". Required.
description A description of the rate, which customers will see at checkout. For example: "Includes tracking and insurance". Required.
service_code A unique code associated with the rate. For example: "expedited_mail". Required.
currency Currency of the shipping rate. Required.
total_price Total price based on the shipping rate currency. Required.
phone_required States whether or not the customer must provide a phone number on checkout.
min_delivery_date Earliest delivery date for the displyed rate.
max_delivery_date Latest delivery date for the displyed rate to still be valid.

Setting carrier service permissions

Add the write_shipping permission to your requested scopes.

What you can do with CarrierService

The Shopify API lets you do the following with the CarrierService resource. More detailed versions of these general actions may be available:

CarrierService properties

active
"active": true

States whether or not this carrier service is active. Valid values are "true" and "false".

callback_url
"callback_url": "http://myapp.com"

States the URL endpoint that shopify needs to retrieve shipping rates. This must be a public URL.

carrier_service_type
"carrier_service_type": "api"

Distinguishes between api or legacy carrier services.

name
"name": "My Carrier Service"

The name of the shipping service as seen by merchants and their customers.

service_discovery
"service_discovery": true

States if merchants are able to send dummy data to your service through the Shopify admin to see shipping rate examples. Valid values are "true" and "false"

format
"format": "json"

The format of the data returned by the URL endpoint. Valid values are "json" and "xml". If a format is not specified, it will default to json.

Endpoints

POST /admin/carrier_services.json

To create a carrier service, you can also use a cURL request that uses that carrier_service.json payload:

  curl -X POST -d @fulfillment_service.json -H"Accept:application/json" -H"Content-Type:application/json" -H"X-Shopify-Access-Token:THE_TOKEN_GOES_HERE" https://AUTHORIZED_SHOP.myshopify.com/admin/carrier_services
          

Where THE_TOKEN_GOES_HERE is replaced by the OAuth token given to you by Shopify and https://AUTHORIZED_SHOP.myshopify.com/admin/carrier_services is replaced by the authorized shop's URL.

Create a carrier service

POST /admin/carrier_services.json
{
  "carrier_service": {
    "name": "Shipping Rate Provider",
    "callback_url": "http:\/\/shippingrateprovider.com",
    "service_discovery": true
  }
}
View Response
HTTP/1.1 201 Created
{
  "carrier_service": {
    "id": 1006327364,
    "name": "Shipping Rate Provider",
    "active": true,
    "service_discovery": true,
    "carrier_service_type": "api",
    "format": "json",
    "callback_url": "http:\/\/shippingrateprovider.com\/"
  }
}
PUT /admin/carrier_services/1006327369.json

Update a carrier service

PUT /admin/carrier_services/#{id}.json
{
  "carrier_service": {
    "id": 1006327369,
    "name": "Some new name",
    "active": false
  }
}
View Response
HTTP/1.1 200 OK
{
  "carrier_service": {
    "id": 1006327369,
    "name": "Some new name",
    "active": false,
    "service_discovery": true,
    "carrier_service_type": "api",
    "format": "json",
    "callback_url": "http:\/\/example.com\/"
  }
}
GET /admin/carrier_services.json

List carrier services

GET /admin/carrier_services.json
View Response
HTTP/1.1 200 OK
{
  "carrier_services": [
    {
      "id": 1006327367,
      "name": "Purolator",
      "active": true,
      "service_discovery": true,
      "carrier_service_type": "api",
      "format": "json",
      "callback_url": "http:\/\/example.com\/"
    }
  ]
}
GET /admin/carrier_services/1006327368.json

Get a single carrier service by its ID

GET /admin/carrier_services/#{id}.json
View Response
HTTP/1.1 200 OK
{
  "carrier_service": {
    "id": 1006327368,
    "name": "Purolator",
    "active": true,
    "service_discovery": true,
    "carrier_service_type": "api",
    "format": "json",
    "callback_url": "http:\/\/example.com\/"
  }
}
DELETE /admin/carrier_services/1006327365.json

Destroy a carrier service

DELETE /admin/carrier_services/#{id}.json
View Response
HTTP/1.1 200 OK
{}