Accessing the API with cURL

Using cURL can be a great way to quickly play around with the API and get an understanding of how the link based API navigation within a Hypermedia API works.

Requirements

As this tutorial will make use of cURL, you will need a command line tool that includes support for it. Terminal on OSX supports it out of the box, as it does for most Linux distributions. On Windows it's not available by default, but you can make use of something like Cygwin or if you have Git installed, its included Bash shell.

You will also need to get an Access Token for a Foxy Store so we can actually connect to the API. If you've already got a Foxy store, you can quickly generate an OAuth Client and a store_full_access token set for your existing store from the Foxy Administration. Check the quick start guide on the Authentication page for details on that.

If you don't have a store, you can sign up for one at foxycart.com - it's free!

Within this example, the Access Token used within the Authorization: Bearer header will be a7eIEB6o21jS937Snl4jg0BEP9827bgo3ngod21f, you'll need to substitute in your own.

Access the store

Unless you have some relation URIs already cached, you'll generally start from the API homepage - which allows you to access everything that the protected resource your token is authenticated for contains.

➔ curl -H "FOXY-API-VERSION: 1" -H "Authorization: Bearer a7eIEB6o21jS937Snl4jg0BEP9827bgo3ngod21f" https://api.foxycart.com

{
    "_links": {
        "curies": [
            {
                "name": "fx",
                "href": "https://api.foxycart.com/rels/{rel}",
                "templated": true
            }
        ],
        "self": {
            "href": "https://api.foxycart.com/",
            "title": "Your API starting point."
        },
        "fx:store": {
            "href": "https://api.foxycart.com/stores/41000",
            "title": "The current store for your authentication token"
        },
        "fx:token": {
            "href": "https://api.foxycart.com/token",
            "title": "The OAuth endpoint for obtaining a new access_token..."
        }
    },
    "message": "Welcome to the FoxyCart API!"
}

Within the API homepage response, you can see a number of links - but the majority of the information we're after will be found by loading the fx:store relation. Copy the href returned for your store and load the API again, but using that link.

➔ curl -H "FOXY-API-VERSION: 1" \
  -H "Authorization: Bearer a7eIEB6o21jS937Snl4jg0BEP9827bgo3ngod21f" \
  https://api.foxycart.com/stores/41000

{
    "_links": {
        "self": {
            "href": "https://api.foxycart.com/stores/41000",
            "title": "This Store"
        },
        "fx:transactions": {
            "href": "https://api.foxycart.com/stores/41000/transactions",
            "title": "Transactions for This Store"
        },
        "fx:item_categories": {
            "href": "https://api.foxycart.com/stores/41000/item_categories",
            "title": "Item Categories for This Store"
        },
        "fx:coupons": {
            "href": "https://api.foxycart.com/stores/41000/coupons",
            "title": "Coupons for This Store"
        }
        ...
    },
    "store_name": "Johns Test Store",
    "store_domain": "johnsteststore",
    ...
}

As you can see - this is a much bigger response - with a whole stack of links that cover all of the different aspects of a store. All aspects of the store can be managed through the URIs provided here. If this was within your integration, at this point you'd cache the fx:store URI so that you can easily use it again later on, without needing to re-request the API homepage.

Creating a Category

Now that we've got the basics of moving through the API - let's make a new category. Just to confirm what's there - let's request the fx:item_categories URI first:

➔ curl -H "FOXY-API-VERSION: 1" \
  -H "Authorization: Bearer a7eIEB6o21jS937Snl4jg0BEP9827bgo3ngod21f" \
  https://api.foxycart.com/stores/41000/item_categories

{
    "_embedded": {
        "fx:item_categories": [
            {
                "code": "DEFAULT",
                "name": "Default for all products",
                "item_delivery_type": "notshipped",
                "default_weight": 1,
                ...
            }
        ]
    },
    "total_items": "1",
    "returned_items": 1,
    "limit": 20,
    "offset": 0
}

Just the default category exists currently. Let's add in a new category whose products are shipping with a flat rate of $15. To do that we simply POST to the same fx:item_categories URI, passing through the needed parameters as detailed on the API reference page for this relation.

➔ curl -H "FOXY-API-VERSION: 1" \
  -H "Authorization: Bearer a7eIEB6o21jS937Snl4jg0BEP9827bgo3ngod21f" \
  https://api.foxycart.com/stores/41000/item_categories \
  -d "code=flat_rate&name=Flat+Rate+Shipping&item_delivery_type=flat_rate&shipping_flat_rate=15&shipping_flat_rate_type=per_order"

{
    "_links": {
        "self": {
            "href": "https://api.foxycart.com/item_categories/79460",
            "title": "flat_rate"
        }
    },
    "message": "item_category 79460 created successfully."
}

Success! Now let's load the fx:item_categories URI again and see all of our store categories. Our store now has two categories, the default category created with the store, and our brand new flat rate category we just created.

Modifying a category

We know we can create a resource - but what if we need to change a resource. The default category that was created with the store is currently set to a delivery type of notshipped. Let's say we actually wanted the default for our store to be for the products to be shipping using live rates, and for the default weight for our products to be 2.5lbs.

As we just need to modify a couple fields - we can make use of a PATCH request. The PATCH request allows us to just pass through the fields we want to change, compared to a PUT which would require that we pass all of the required fields for the resource. You'll need to consult how these are specified within your language, within a cURL request, you pass the request flag to specify.

For this request, we grab the self URI from within the default category in the previous response, and send our PATCH request there:

➔ curl -H "FOXY-API-VERSION: 1" \
  -H "Authorization: Bearer a7eIEB6o21jS937Snl4jg0BEP9827bgo3ngod21f" \
  -X PATCH https://api.foxycart.com/item_categories/79457 \
  -d "item_delivery_type=shipped&default_weight=2.5"

{
    "code": "DEFAULT",
    "name": "Default for all products",
    "item_delivery_type": "shipped",
    "default_weight": 2.5,
    ...
}

Viewing Transactions

Now we've set up our categories how we want - and some customers have placed some orders, so let's fetch those using the API. We'll need to GET the fx:transactions link from the API homepage as we fetched it earlier using our store_full_access token:

"fx:transactions": {
    "href": "https://api.foxycart.com/stores/41000/transactions",
    "title": "Transactions for This Store"
}

The GET request will return a response that includes recent transactions embedded within it. For the sake of this example, a parameter has been added to the URI to limit the returned transactions 1 per page by appending ?limit=1 (the default is 20):

➔ curl -H "FOXY-API-VERSION: 1" \
  -H "Authorization: Bearer a7eIEB6o21jS937Snl4jg0BEP9827bgo3ngod21f" \
  "https://api.foxycart.com/stores/41000/transactions?limit=1"

{
    "_embedded": {
        "fx:transactions": [
            {
                "id": 1105668353,
                "is_test": true,
                "transaction_date": "2016-09-13T22:26:42-07:00",
                "customer_first_name": "Montgomery",
                "customer_last_name": "Scott",
                "customer_email": "mscott@example.com",
                "total_item_price": 15,
                "total_tax": 0,
                "total_shipping": 15,
                "total_order": 30,
                ...
            }
        ]
    },
    "total_items": "26",
    "returned_items": 1,
    "limit": 1,
    "offset": 0
}

Zooming additional information

By default, the transaction request will just return the base transaction information - that which is associated with the transaction relation. As you can see though - the transaction has a whole stack of additional information included in relations which would be relevant. This is where zooming comes into play.

Zooming allows you to embed information connected to a given resource directly into the response, saving you separate requests to fetch that information. For a transaction, this includes the relations for customer, payments, items, applied_taxes, custom_fields, discounts, shipments, billing_addresses. Some zoomable relations have relations they can in turn zoom on as well, for example items has item_options and item_category. If you wanted to embed all of that information in the response to collect everything we can about this transaction - that would look like this:

?zoom=customer,payments,items,items:item_options,items:item_category,applied_taxes,custom_fields,discounts,shipments,billing_addresses

Re-using our previous request, let's say we just wanted to pull in the cart details - so items and its relations - that would look like this:

➔ curl -H "FOXY-API-VERSION: 1" \
  -H "Authorization: Bearer a7eIEB6o21jS937Snl4jg0BEP9827bgo3ngod21f" \
  "https://api.foxycart.com/stores/41000/transactions?limit=1&zoom=items,items:item_options,items:item_category"

You'll see within the response that the response has the same embedded fx:transactions object, but then it in turn has an embedded object containing fx:items which in turn has an embedded object containing fx:item_category and fx:item_options. From that response we now have a complete view of what this customer ordered in a single request.

Filtering

Along with zooming on related information, you can also filter the results of requests. The API supports a number of different filters, including exact, partial and range filters. For this example, let's find all transactions for the customer's email by using an exact filter of customer_email=mscott@example.com:

➔ curl -H "FOXY-API-VERSION: 1" \
  -H "Authorization: Bearer a7eIEB6o21jS937Snl4jg0BEP9827bgo3ngod21f" \
  "https://api.foxycart.com/stores/41000/transactions?limit=1&customer_email=mscott@example.com"

{
    "_embedded": {
        "fx:transactions": [
            {
                "id": 1105668353,
                "customer_email": "mscott@example.com",
                "total_order": 30,
                ...
            }
        ]
    },
    "total_items": "3",
    "returned_items": 1,
    "limit": "1",
    "offset": 0
}

While we're still limiting the response to 1 transaction per page - you can see from the total_items at the bottom of the response that this customer has placed 3 orders with the store.

And much more!

Hopefully these examples provide a quick overview for interacting with the Foxy API - obviously there is a whole lot more you can do. Take a look at the API Reference for a complete listing of its structure, and the Cheat Sheet for a quick overview of technical aspects of interacting with the API.