API Entry Points

  • Production: https://api.foxycart.com
  • Sandbox: https://api-sandbox.foxycart.com

Note that the sandbox entry point above is completely separate from development versions of Foxy stores that are accessible within the Foxy administration. To access those, use the production entry point.

Headers

Authorization: Bearer <token> (Required)
Authorized requests to the API should include the Authorization header with a value of Bearer <token>, where <token> is a valid access token obtained through the OAuth flow.

FOXY-API-VERSION: 1 (Required)
In order to facilitate any major, unforeseen breaking changes in the future, we require each request to include this header on its own line. We hope to rarely (never?) change it but by requiring it up front, we can ensure what you get today is what you’ll get tomorrow.

Content-Type: application/hal+json
The Content-Type header can be optionally included to set what format you want the API to respond in. Current valid values include application/hal+json (default), application/hal+xml and application/vnd.siren+json (to a limited degree).

Media Types

Response Media Types Supported: application/hal+json (default), application/hal+xml and application/vnd.siren+json (to a limited degree). We're also exploring application/collection+json support.

Request Media Types Supported: application/json (default), application/xml, application/x-www-form-urlencoded, multipart/form-data

Authentication

The Foxy API uses OAuth 2.0 with Bearer tokens for authentication. For a full overview of working with OAuth 2.0 for your Foxy API Integration, see the Authentication docs.

  • Token endpoint: https://api.foxycart.com/token (or api-sandbox.foxycart.com). Note: this endpoint is also linked to via API homepage hypermedia.
  • Authorization endpoint: https://my.foxycart.com/authorize (or my-sandbox.foxycart.com)
  • Allowed scopes: client_full_access, user_full_access, store_full_access
  • Token Lifetime: Access tokens expire after 7200 seconds (2 hours). Refresh tokens expire after 315360000 seconds (10 years). Refresh tokens are not reissued with each access token via the token endpoint.

HTTP Verbs

The Foxy API uses the following HTTP verbs that basically map to the normal CRUD operations approach:

  • Create: POST to a rel representing a collection (“stores”) with either json, xml or name-value pairs in the body and the corresponding Content-Type header.
  • Read: GET to a singular rel for an individual item (“store”) or to a collection of items to retrieve a list (“stores”).
  • Update: We support both PUT and PATCH for updates. PUT has to include the entire document (the hypermedia links and date_created/date_modified fields will be ignored). For PATCH, you just need to include one or more resource properties. For example, if you just want to update a customer first_name, you can PATCH with {‘first_name’: ‘new’}. As with POST, you’ll need to set the appropriate Content-Type header.
  • Delete: Where allowed, you can delete a resource with the HTTP verb… wait for it… DELETE.

Zooming

Some resources support a zoom feature which includes embedded resources in the same response. This allows you to minimise the number of calls you need to make for the API. You can zoom in on more than one resource at a time by using a comma separator. The maximum limit (currently 300) of resources you can retrieve at a time also applies to zoomed, embedded resources. If the number of resources returned matches 300, you should query for the rest of the resources directly.

For example, on a call to view a specific transaction, you could append zoom=items,payments,applied_taxes. This would include the products purchased in that transaction, the payment processor information and the taxes applied. Refer to the individual relations for details on possible zoomable resources. If the number of items returned is 300, you'd want to do additional requests to gather any additional items for that transaction.

Filtering

To filter a result set, you can append a URL parameter like <property>=<value> to the link relationship URI. The <property> should be the name of a field and <value> should be the value you want to filter on. There are a few different forms of filtering that you can apply:

Exact Match
This is the default filtering method, structured as <property>=<value>.

Example: first_name=John.

Partial Match
We also support partial matching using the * wild card.

Example: first_name=Jo*n.

Name/Value Pairs
For certain types of resources (attributes, item_options, and checkout custom fields) that are effectively name/value pairs, you may need to filter on resources of a certain name that have a specific value. Note that the "or", "in", and some other options below can be used as well. For instance:

  • transactions?attributes:name=color will return transactions that have an attribute with name=color.
  • transactions?attributes:name[color]=red will return transactions that have an attribute with name=color with a value=red. Note that this is not the same as transactions?attributes:name=color&attributes:value=red, which could return transactions with 2 separate attributes, one with name=color&value=blue and another with name=status&value=red.
  • transactions?attributes:name[color]:in=red,blue will return transactions that have an attribute with name=color with a value of red or blue.

| operator (Logical "OR")
It will match first or second value.

  • transactions?total_order=50|total_order=25 will return transactions that have total_order of 50 OR equal to 25

:in operator
This will match all values that are passed in the request seperated by ,. Examples:

  • transactions?total_order:in=50,125 this will return transactions where total_order is in the sequence 50, 125

:not operator (!=)
This will match the opposite of the give value. Example:

  • transactions?total_order:not=50 this will return transactions where total_order is NOT 50

:greaterthan operator (Greater Than)
This will match all values that are great than passed value in the request. Note that this will only work on numeric values. Examples:

  • transactions?total_order:greaterthan=50|total_order=25 this will return transactions that where total_order is greatert than 50 OR equal to 25

:greaterthanorequal operator
This will match all values that are greater than or equal to the passed value in the request. Note that this will only work on numeric values. Examples:

  • transactions?total_order:greaterthanorequal=50|total_order=25 this will return transactions that where total_order is greatert han or equal to 50 OR equal to 25

:lessthan operator
This will match all values that are less than the passed value in the request. Note that this will only work on numeric values. Examples:

  • transactions?total_order:lessthan=50 this will return transactions where total_order is less than 50

:lessthanorequal operator
This will match all values that are less than or equal to the passed value in the request. Note that this will only work on numeric values. Examples:

  • transactions?total_order:lessthanorequal=50 this will return transactions where total_order is less than or equal to 50

:isdefined operator
This allows filtering of collections based on whether a certain named attribute is or isn't defined. Note that this will only work on attributes. This can be extremely useful when an attribute may indicate external action has been taken on the resource, and you want to monitor any resources that weren't processed. This filter accepts true or false. Examples:

  • transactions?attributes:name[is_processed]:isdefined=true will return transactions that have an attribute named is_processed, regardless of the value.

Range Filters
If you're filtering numbers, you can filter for matches within a range using the .. notation. Note that you can accomplish the same with the greater than / less than filters above as well.

Example: order_total=10..100 to view transactions with an order total between 10 and 100 inclusive.

Date Range Filters
You can also filter by date using the .. notation. Dates, times, and timezones are huge amounts of fun to deal with, so there are some things to keep in mind, best illustrated with the examples below.

  • transaction_date=2019-01-01..2019-12-31 will assume the store's currently selected timezone as the offset. NOTE: This approach is not recommended. It's usually better to be explicit.
  • transaction_date=2019-01-01T00:00:00..2019-01-01T11:59:59 and
    transaction_date=2019-01-01 00:00:00..2019-01-01T11:59:59 will both return the same data. The T between the date and the time is optional, but including the T separator is recommended. Omitting an offset will assume the store's currently selected timezone. For this reason, this approach is also not recommended.
  • transaction_date=2019-01-01T00:00:00-0500..2019-01-01T11:59:59-0500 and
    transaction_date=2019-01-01T00:00:00+0100..2019-01-01T11:59:59+0100 will both return the specifically set offsets. Note that you may use different offsets for the start and end dates, though you probably shouldn't. Offsets are hard enough as is :).
  • transaction_date=2019-01-01T00:00:00Z..2019-01-01T11:59:59Z will work as well, with Z the shortcut for UTC.
  • DEPRECATED:
    transaction_date=2019-01-01T00:00:00Z..x and transaction_date=..2019-01-01T00:00:00Z will allow you to avoid setting upper or lower range limits, but this functionality is deprecated and should not be used.

Zoomed Resources
You can filter on a zoomable resource using a colon to separate each child resource.

Example: items:item_options:name=color

Sorting

You can adjust the sort order of the collection response by appending order=<field> <direction>. You can append multiple fields to sort by, separated with a comma. <field> is obviously the name of the field, <direction> is an optional field, and can be either asc or desc, defaulting to asc.

Example: order=<field1>,<field2> asc,<field3> desc

Pagination

Out of the box, the API includes pagination links to move between pages of results via the rels first, prev, next and last. You can also control the number of results per page with a URL parameter of limit=<limit>. You can also specify a starting offset for the results with a URL parameter of offset=<offset>. The API returns 20 items per page by default, and currently the maximum results per page is 300.

Partial Resources

If you only need a small portion of a resource (such as a first and last name), you can specify fields by appending fields=<field1>,<field2> to the URI, separating each field with a comma.

Example: fields=first_name,last_name

Property Helpers

Some resource properties have values that must belong to a predefined set. You can view these resources via the API at https://api-sandbox.foxycart.com/property_helpers

Rels

The following registered rels are used by our system: self, first, prev, next, and last. All other rels (in accordance with the Web Linking RFC) are full URIs such as https://api.foxycart.com/rels/store (or the curied link fx:store when using hal+json)

Reporting

As an authenticated OAuth Client, you can hit the reporting endpoint, available as the reporting link relationship from the API home. From there, various reports will be added including being able to determine if an existing store_domain is in use by a store or an email is in use by a user.

Add to Cart Link/Form Encryption

As an authenticated OAuth Client with access to a store, you can POST HTML snippets to the the encode link relationship available from the API home or the template set or template resources to get back an HMAC signed version of the HTML in a result json property.