Categories
Core

New REST API based on the WP REST API in 2.6

During the development of WooCommerce 2.1 (Back in Feb 2014) we knew that one day WordPress would have it’s own REST API, but the demand was so great for such a thing in WooCommerce we had to roll our own.

We’ve learned a lot from this process and our API is now widely used, but given recent developments surrounding the actual WordPress REST API, and since it is now part of WordPress core (since version 4.4) we started work to replace ours with what is available in WordPress.

2.6 will contain this new API, and will require WordPress 4.4 or higher.

What API changes should we expect?

The first change is with endpoints, in our current API you can fetch your orders using:

https://your-woo-store.com/wc-api/v3/orders

The new REST API will instead use:

https://your-woo-store.com/wp-json/wc/v1/orders

Note that we use the wc/v1/, since it’s not our API v4, but a completely new REST API, and our first based on the WP REST API hence v1.

We had to make some changes to the data we offer through the API to reflect recent developments and changes in WC core, and to try to offer consistent data, but the largest and most notable change is the way that data is sent and received with the new API.

For example, in the current REST API, we use the format:

{
"orders": {
"id": 1
}
}

view raw
orders.json
hosted with ❤ by GitHub

But using the WP REST API we had to change this to:

{
"id": 1
}

view raw
orders.json
hosted with ❤ by GitHub

The WP REST API uses schemas to describe and self-document endpoints, so it’s easy to know what is needed to create an object or what to expect while fetching something. As an example, this would get the schema for coupons endpoint:

This returns the following response:

{
"namespace": "wc/v1",
"methods": [
"GET",
"POST"
],
"endpoints": [
{
"methods": [
"GET"
],
"args": {
"context": {
"required": false,
"default": "view",
"enum": [
"view",
"edit"
],
"description": "Scope under which the request is made; determines fields present in response."
},
"page": {
"required": false,
"default": 1,
"description": "Current page of the collection."
},
"per_page": {
"required": false,
"default": 10,
"description": "Maximum number of items to be returned in result set."
},
"search": {
"required": false,
"description": "Limit results to those matching a string."
},
"after": {
"required": false,
"description": "Limit response to resources published after a given ISO8601 compliant date."
},
"before": {
"required": false,
"description": "Limit response to resources published before a given ISO8601 compliant date."
},
"exclude": {
"required": false,
"default": [],
"description": "Ensure result set excludes specific ids."
},
"include": {
"required": false,
"default": [],
"description": "Limit result set to specific ids."
},
"offset": {
"required": false,
"description": "Offset the result set by a specific number of items."
},
"order": {
"required": false,
"default": "desc",
"enum": [
"asc",
"desc"
],
"description": "Order sort attribute ascending or descending."
},
"orderby": {
"required": false,
"default": "date",
"enum": [
"date",
"id",
"include",
"title",
"slug"
],
"description": "Sort collection by object attribute."
},
"slug": {
"required": false,
"description": "Limit result set to posts with a specific slug."
},
"filter": {
"required": false,
"description": "Use WP Query arguments to modify the response; private query vars require appropriate authorization."
},
"code": {
"required": false,
"description": "Limit result set to resources with a specific code."
}
}
},
{
"methods": [
"POST"
],
"args": {
"code": {
"required": true
},
"description": {
"required": false
},
"discount_type": {
"required": false,
"enum": [
"fixed_cart",
"percent",
"fixed_product",
"percent_product"
]
},
"amount": {
"required": false
},
"expiry_date": {
"required": false
},
"individual_use": {
"required": false
},
"product_ids": {
"required": false
},
"exclude_product_ids": {
"required": false
},
"usage_limit": {
"required": false
},
"usage_limit_per_user": {
"required": false
},
"limit_usage_to_x_items": {
"required": false
},
"free_shipping": {
"required": false
},
"product_categories": {
"required": false
},
"excluded_product_categories": {
"required": false
},
"exclude_sale_items": {
"required": false
},
"minimum_amount": {
"required": false
},
"maximum_amount": {
"required": false
},
"email_restrictions": {
"required": false
}
}
}
],
"schema": {
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "shop_coupon",
"type": "object",
"properties": {
"id": {
"description": "Unique identifier for the object.",
"type": "integer",
"context": [
"view",
"edit"
],
"readonly": true
},
"code": {
"description": "Coupon code.",
"type": "string",
"context": [
"view",
"edit"
]
},
"date_created": {
"description": "The date the coupon was created, in the site's timezone.",
"type": "date-time",
"context": [
"view",
"edit"
],
"readonly": true
},
"date_modified": {
"description": "The date the coupon was last modified, in the site's timezone.",
"type": "date-time",
"context": [
"view",
"edit"
],
"readonly": true
},
"description": {
"description": "Coupon description.",
"type": "string",
"context": [
"view",
"edit"
]
},
"discount_type": {
"description": "Determines the type of discount that will be applied.",
"type": "string",
"enum": [
"fixed_cart",
"percent",
"fixed_product",
"percent_product"
],
"context": [
"view",
"edit"
]
},
"amount": {
"description": "The amount of discount.",
"type": "float",
"context": [
"view",
"edit"
]
},
"expiry_date": {
"description": "UTC DateTime when the coupon expires.",
"type": "string",
"context": [
"view",
"edit"
]
},
"usage_count": {
"description": "Number of times the coupon has been used already.",
"type": "integer",
"context": [
"view",
"edit"
],
"readonly": true
},
"individual_use": {
"description": "Whether coupon can only be used individually.",
"type": "boolean",
"context": [
"view",
"edit"
]
},
"product_ids": {
"description": "List of product ID's the coupon can be used on.",
"type": "array",
"context": [
"view",
"edit"
]
},
"exclude_product_ids": {
"description": "List of product ID's the coupon cannot be used on.",
"type": "array",
"context": [
"view",
"edit"
]
},
"usage_limit": {
"description": "How many times the coupon can be used.",
"type": "integer",
"context": [
"view",
"edit"
]
},
"usage_limit_per_user": {
"description": "How many times the coupon can be user per customer.",
"type": "integer",
"context": [
"view",
"edit"
]
},
"limit_usage_to_x_items": {
"description": "Max number of items in the cart the coupon can be applied to.",
"type": "integer",
"context": [
"view",
"edit"
]
},
"free_shipping": {
"description": "Define if can be applied for free shipping.",
"type": "boolean",
"context": [
"view",
"edit"
]
},
"product_categories": {
"description": "List of category ID's the coupon applies to.",
"type": "array",
"context": [
"view",
"edit"
]
},
"excluded_product_categories": {
"description": "List of category ID's the coupon does not apply to.",
"type": "array",
"context": [
"view",
"edit"
]
},
"exclude_sale_items": {
"description": "Define if should not apply when have sale items.",
"type": "boolean",
"context": [
"view",
"edit"
]
},
"minimum_amount": {
"description": "Minimum order amount that needs to be in the cart before coupon applies.",
"type": "float",
"context": [
"view",
"edit"
]
},
"maximum_amount": {
"description": "Maximum order amount allowed when using the coupon.",
"type": "float",
"context": [
"view",
"edit"
]
},
"email_restrictions": {
"description": "List of email addresses that can use this coupon.",
"type": "array",
"context": [
"view",
"edit"
]
},
"used_by": {
"description": "List of user IDs who have used the coupon.",
"type": "array",
"context": [
"view",
"edit"
],
"readonly": true
}
}
},
"_links": {
"self": "https://woo.dev/wp-json/wc/v1/coupons"
}
}

view raw
coupons-schema.json
hosted with ❤ by GitHub

We will be offering our own documentation and updated API wrappers as well before the final release of 2.6, but as you can see, it’s very simple to query and inspect any endpoint if you want to use the new API now.

Things we won’t be changing…

Some things remain the same even with the introduction of this new API:

  • All WC REST API keys can be used in the WP REST API.
  • Our Authentication Endpoint still works like before.
  • Webhooks will continue to work.
  • Our entire current REST API will still be available.

Regarding authentication, it’s still possible to use Basic Auth and oAuth1.0a using current WC API keys, and we don’t have plans to remove our API key system, so this should make it easy to migrate Apps using our APIs. The new API allows more ways to authenticate users though; it supports all of the WP REST API authentication methods.

What API should I use in my Apps?

If possible, we recommend using the new WP based API as soon as it’s launched. It’s simpler, easier to use, and it makes use of WordPress core as much as possible.

We don’t have plans to deprecate our current REST API just yet, at least not before WooCommerce 3.0, so everyone has ample time to migrate to the new REST API once released.

To try the new API you can grab master branch from Github, or wait for beta 1 to be tagged within the next week or so. If you have feedback or find issues in the new API, please report them on Github with label “[API]”.

By Claudio Sanches

Developer on the WooCommerce team and member of the WordPress Brazilian community.

3 replies on “New REST API based on the WP REST API in 2.6”

Comments are closed.