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
(orapi-sandbox.foxycart.com
). Note: this endpoint is also linked to via API homepage hypermedia. - Authorization endpoint:
https://my.foxycart.com/authorize
(ormy-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
andPATCH
for updates.PUT
has to include the entire document (the hypermedia links and date_created/date_modified fields will be ignored). ForPATCH
, you just need to include one or more resource properties. For example, if you just want to update a customer first_name, you canPATCH
with{‘first_name’: ‘new’}
. As withPOST
, 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 withname=color
.transactions?attributes:name[color]=red
will return transactions that have an attribute withname=color
with avalue=red
. Note that this is not the same astransactions?attributes:name=color&attributes:value=red
, which could return transactions with 2 separate attributes, one withname=color&value=blue
and another withname=status&value=red
.transactions?attributes:name[color]:in=red,blue
will return transactions that have an attribute withname=color
with a value ofred
orblue
.
|
operator (Logical "OR")
It will match first or second value.
transactions?total_order=50|total_order=25
will return transactions that havetotal_order
of 50OR
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 wheretotal_order
is in the sequence50, 125
:not
operator (!=
)
This will match the opposite of the give value. Example:
transactions?total_order:not=50
this will return transactions wheretotal_order
isNOT
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 wheretotal_order
isgreatert 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 wheretotal_order
is greatert han or equal to 50OR
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 wheretotal_order
isless 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 wheretotal_order
isless 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 anattribute
namedis_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. TheT
between the date and the time is optional, but including theT
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, withZ
the shortcut forUTC
.- DEPRECATED:
transaction_date=2019-01-01T00:00:00Z..x
andtransaction_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.