Developer : Products

Manage applications

The /products resource contains information about the store's products and product options.

Resource URI

By default, the resource returns pages of 20 products each. Without any query parameters, the resource returns the first 20 products (page 0) in the store:

/api/v1/products

To get the next page of products, include a page query parameter:

/api/v1/products?page=1

To specify the number of products per page, include a count parameter:

/api/v1/products?count=50

The count and page parameters can be combined to create pages of arbitrary size:

/api/v1/products?count=10&page=0
/api/v1/products?count=10&page=1
/api/v1/products?count=10&page=2
... and so on ...
Method Scope Required
GET storefront
POST admin

Mass Edit

To edit multiple products with one API call, the PUT method can be used by setting the multi query string parameter:

/api/v1/products_multi

See Mass Edit below

Method Scope Required
PUT admin

Properties

Property Methods Description
categories GET, POST A list of categories to which the product belongs
cost GET, PUT, POST The product's cost of goods as a formatted string
cost_raw GET The product's cost of goods in float format
created GET Timestamp of when the product was created
currency GET The currency of the product's price
default_option_metadata PUT, POST A dictionary of metadata stored as hidden columns on the default product option. Must be a JSON-formatted string
description GET, PUT, POST The full product description
description_short GET, PUT, POST The short product description
digital_samples GET A list of digital samples (titles and URIs) if this product has any
extras GET, POST A list of extras available for the product. POST must be a JSON-formatted string. See options and extras for required data
fetch_sku GET, PUT, POST SKU used for a product's integration with FetchApp. The fetch_sku is actually recorded on the default product option and therefore ignored if the product has multiple options specified (since each option can have its own Fetch SKU)
form GET, PUT, POST A dictionary representing a product form. A product form must have at least one field. The dictionary structure is {'name': 'product form', 'fields': [{'label': 'Email', 'placeholder':'jane@doe.com', 'type':'text', 'required':true}]}. 'fields' is a list of dicts representing an input method. 'type' must be one of [checkbox, paragraph, text, date] and 'required' is false by default. When using PUT, any existing fields will be removed and replaced with the fields provided. PUT and POST must be a JSON-formatted string. Passing delete to this parameter removes the form from the product
images GET, POST A list of product images. Every image is available in a variety of sizes; each one has its own URI. When POSTing, a list of URIs with http protocol or local file paths are required.
key GET The unique key for the product
modified GET Timestamp of when the product was last modified
name GET, PUT, POST The product's name
name_short GET, PUT, POST A shortened version of the product's name that will appear in the product listing grids
options GET, POST A list of options available for the product. If you haven't specified any options for the product, there will be just one default option. POST must be a JSON-formatted string. See options and extras for required data
option_style GET, PUT, POST Either 'single' or 'separate', this parameter determines whether product options should be displayed in one dropdown, or multiple dropdowns with one for each option column.
order GET, PUT, POST The order in which this product appears on the store's product listing. A new product's default order is 1. The product will be inserted into the current ordering by incrementing/decrementing the necessary products' orders
price GET, PUT, POST The product's price as a formatted string
price_raw GET The product's price in float format
product_metadata PUT, POST A dictionary of metadata to be stored on the product. Must be a JSON-formatted string
quantity GET, PUT, POST The number of prouducts available. -1 represents unlimited quantity
regular_price GET The product's regular price (if the current sale price is different) as a formatted string
regular_price_raw GET The product's regular price in float format
reorder_products POST Default true, this flag is used to prevent the store's other products from reordering. Reordering may be unnecessary for an initial batch create and skipping it will save time.
sale_price GET, PUT, POST The product's sale price as a formatted string. Will be null if the product is not on sale
sale_price_raw GET The product's sale price in float format. Will be null if the product is not on sale
shipping_group GET, PUT, POST The Shipping Group to which the product belongs. Contains a list of available shipping options.
sku GET, PUT, POST The product's SKU
slug GET The product's URL slug
status GET, PUT, POST The product's availability status. One of available, on sale, hidden, sold out, or coming soon
tax_group GET, PUT, POST The Tax Group to which the product belongs. Contains a list of the applicable tax rates and their countries/regions
type GET, PUT, POST Either physical or digital
url GET The product's URL on Goodsie
videos GET, POST A list of product videos' thumbnails. Every image is available in a variety of sizes; each one has its own URI. POSTing requires a list of URIs with http protocol
weight GET, PUT, POST The product's weight

Subresources

Methods Path Description
GET, PUT, DELETE /api/v1/products/{key or slug} A product
GET, POST /api/v1/products/{key}/categories A list of product categories. See Handling categories
GET, DELETE /api/v1/products/{key}/categories/{category_slug} A product category
GET /api/v1/products/{category_slug} A list of products in the category
GET, POST /api/v1/products/{key}/options A list of product options. See options and extras
GET, PUT, DELETE /api/v1/products/{key}/options/{key} A product option. PUT can modify surcharge, quantity, cost, weight, and fetch_sku
GET, POST /api/v1/products/{key}/extras A list of product extras. See options and extras
GET, PUT, DELETE /api/v1/products/{key}/extras/{key} A product extra. PUT can modify surcharge, quantity, cost, and weight
GET, POST /api/v1/products/{key}/images A list of product images. See Uploading an image
GET, PUT, DELETE /api/v1/products/{key}/images/{img_key} A product image. img_key is the URI slug minus size and file extension. For example, for http://d12x84seoif7w5.cloudfront.net/...
...f881c83b69e04669afbd2a23a8fc738b_190x190.jpg
, the img_key is f881c83b69e04669afbd2a23a8fc738b. PUT can only modify order, which is shared with videos
GET, POST /api/v1/products/{key}/videos A list of product videos from either youtube or vimeo. See Fetching a video
GET, PUT, DELETE /api/v1/products/{key}/videos/{video_key} A product video. video_key is the URI slug. For example, for http://vimeo.com/73781961, the video_key is 73781961. PUT can only modify order, which is shared with images

Options and Extras

A list of dicts representing all of the product's options or extras

Property Method Description
options POST A comma separated list of dictionaries for the options where one dict represents one option's attributes in key-value pairs. The dictionary structure must include "quantity, "surcharge", and "metadata". "weight" and "cost" are optional for both options and extras. "fetch_sku" may be included for options. "metadata" is a dictionary representing option column names and values (e.g. Color, Size). A product option must have at least one (column name, value) pair in the "metadata" argument. Please see the example below.
extras POST A list of dictionaries with structure identical to options

Mass Edit

Multiple products can be edited with one API call by passing a nested dictionary structure to the products property of /api/v1/products_multi with the PUT method. Each product dictionary can include any of the aforementioned product properties such as price, sale_price, weight, name, order, etc.

Note that editing a product's order with mass edit will not update the order of other products. order is best used for a store-wide reorder here.

All product dictionaries must include the same product properties.

The higher-level dictionary keys will be product primary keys and the values will be dictionaries representing products. For example:

products = {
    "2ed8d673-2b18-11e1-90ce-002500a0451c": {
        "status": "available",
        "quantity": 30
    },
    "df18532e-145d-11e1-9dd6-002500a0451c": {
        "status": "sold out",
        "quantity": 0
    }
}

The response will be a list of dictionaries that are in the same format as a single product PUT or GET. Only products that have changed will be included in the response.

Simple Example GET

curl -H "Authorization: Bearer ba125ac086" \
    https://goodsie.com/api/v1/products
[
    {
        "categories": [
            "Ugly Stuff"
        ],
        "cost": "$35.00",
        "cost_raw": 35.0,
        "created": 1324391866,
        "currency": "USD",
        "description": "This sweater is horrendously ugly.",
        "description_short": "A seriously ugly sweater.",
        "digital_samples": [],
        "extras": [
            {
                "currency": "USD",
                "key": "2eeabf4c-2b18-11e1-97fe-002500a0451c",
                "metadata": {
                    "EXTRAS": "Gift Wrap"
                },
                "order": 0,
                "quantity": -1,
                "surcharge": "$2.00",
                "surcharge_raw": 2.0
            }
        ],
        "images": [
            {
                "tiny": "http://d12x84seoif7w5.cloudfront.net/f881c83b69e04669afbd2a23a8fc738b_tiny.jpg",
                "small": "http://d12x84seoif7w5.cloudfront.net/f881c83b69e04669afbd2a23a8fc738b_small.jpg",
                "medium": "http://d12x84seoif7w5.cloudfront.net/f881c83b69e04669afbd2a23a8fc738b_medium.jpg",
                "large": "http://d12x84seoif7w5.cloudfront.net/f881c83b69e04669afbd2a23a8fc738b_large.jpg",
                "huge": "http://d12x84seoif7w5.cloudfront.net/f881c83b69e04669afbd2a23a8fc738b_huge.jpg"
            }
        ],
        "key": "2ed8d673-2b18-11e1-90ce-002500a0451c",
        "modified": 1324391866,
        "name": "An ugly sweater",
        "options": [
            {
                "cost": "$35.00",
                "cost_raw": 35.0,
                "currency": "USD",
                "default": false,
                "fetch_sku": "",
                "key": "2ee684a3-2b18-11e1-8102-002500a0451c",
                "metadata": {
                    "Color": "Red"
                },
                "order": 0,
                "quantity": 10,
                "surcharge": "$0.00",
                "surcharge_raw": 0.0
            },
            {
                "cost": "$35.00",
                "cost_raw": 35.0,
                "currency": "USD",
                "default": false,
                "fetch_sku": "",
                "key": "2ee82df3-2b18-11e1-8865-002500a0451c",
                "metadata": {
                    "Color": "Blue"
                },
                "order": 1,
                "quantity": 10,
                "surcharge": "$0.00",
                "surcharge_raw": 0.0
            }
        ],
        "order": 0,
        "price": "$55.00",
        "price_raw": 55.0,
        "quantity": 20,
        "regular_price": "$55.00",
        "regular_price_raw": 55.0,
        "sale_price": null,
        "sale_price_raw": null,
        "shipping_group": {
            "id": 2,
            "name": "Default Shipping Group",
            "options": [
                {
                    "id": 1,
                    "name": "Quick Shipping",
                    "per_cart_rate": "2%",
                    "per_cart_rate_raw": 2.0,
                    "per_cart_type": "percentage",
                    "per_item_type": "none"
                },
                {
                    "currency": "USD",
                    "id": 3,
                    "name": "Slow Shipping",
                    "per_cart_rate": "$5.00",
                    "per_cart_rate_raw": 5.0,
                    "per_cart_type": "flat_fee",
                    "per_item_type": "none"
                }
            ]
        },
        "sku": "123UGLY",
        "slug": "an-ugly-sweater",
        "status": "available",
        "tax_group": {
            "id": 3,
            "name": "Physical Goods",
            "taxes": [
                {
                    "country": "CA",
                    "id": 2,
                    "rate": "2.30%",
                    "rate_raw": 2.3,
                    "region": "Northwest Territories"
                },
                {
                    "country": "US",
                    "id": 5,
                    "rate": "6%",
                    "rate_raw": 6.0,
                    "region": "MN"
                }
            ]
        },
        "type": "physical",
        "url": "http://example.com/an-ugly-sweater"
    },
    {
        "categories": [
            "Ugly Stuff"
        ],
        "created": 1321892920,
        "currency": "USD",
        "description": "60 minutes of instruction on how to knit sweaters so ugly they make you nauseous.",
        "description_short": "A podcast about ugly sweaters",
        "digital_samples": [],
        "extras": [],
        "images": [
            {
                "tiny": "http://d12x84seoif7w5.cloudfront.net/f881c83b69e04669afbd2a23a8fc738b_tiny.jpg",
                "small": "http://d12x84seoif7w5.cloudfront.net/f881c83b69e04669afbd2a23a8fc738b_small.jpg",
                "medium": "http://d12x84seoif7w5.cloudfront.net/f881c83b69e04669afbd2a23a8fc738b_medium.jpg",
                "large": "http://d12x84seoif7w5.cloudfront.net/f881c83b69e04669afbd2a23a8fc738b_large.jpg",
                "huge": "http://d12x84seoif7w5.cloudfront.net/f881c83b69e04669afbd2a23a8fc738b_huge.jpg"
            }
        ],
        "key": "df18532e-145d-11e1-9dd6-002500a0451c",
        "modified": 1324392189,
        "name": "The Ugly Sweaters Podcast",
        "options": [
            {
                "currency": "USD",
                "default": true,
                "fetch_sku": "10021",
                "key": "df19d185-145d-11e1-aa5e-002500a0451c",
                "metadata": {},
                "order": 0,
                "quantity": -1,
                "surcharge": "$0.00",
                "surcharge_raw": 0.0
            }
        ],
        "order": 1,
        "price": "$20.00",
        "price_raw": 20.0,
        "quantity": -1,
        "regular_price": "$20.00",
        "regular_price_raw": 20.0,
        "sale_price": null,
        "sale_price_raw": null,
        "shipping_group": null,
        "sku": "321UGLYPOD",
        "slug": "the-ugly-sweaters-podcast",
        "status": "available",
        "tax_group": null,
        "type": "physical",
        "url": "http://example.com/the-ugly-sweaters-podcast",
        'videos': [{
            "tiny": "http://d12x84seoif7w5.cloudfront.net/f881c83b69e04669afbd2a23a8fc738b_tiny.jpg",
            "small": "http://d12x84seoif7w5.cloudfront.net/f881c83b69e04669afbd2a23a8fc738b_small.jpg",
            "medium": "http://d12x84seoif7w5.cloudfront.net/f881c83b69e04669afbd2a23a8fc738b_medium.jpg",
            "large": "http://d12x84seoif7w5.cloudfront.net/f881c83b69e04669afbd2a23a8fc738b_large.jpg",
            "huge": "http://d12x84seoif7w5.cloudfront.net/f881c83b69e04669afbd2a23a8fc738b_huge.jpg"
        }],
        "weight": 3.333
    }
]

Uploading a product image

curl -H "Authorization: Bearer ba125ac086" -X POST \
    -F 'image=@/path/to/image.jpg' \
    https://goodsie.com/api/v1/products/an-ugly-sweater/images
{
    "tiny": "http://d12x84seoif7w5.cloudfront.net/f881c83b69e04669afbd2a23a8fc738b_tiny.jpg",
    "small": "http://d12x84seoif7w5.cloudfront.net/f881c83b69e04669afbd2a23a8fc738b_small.jpg",
    "medium": "http://d12x84seoif7w5.cloudfront.net/f881c83b69e04669afbd2a23a8fc738b_medium.jpg",
    "large": "http://d12x84seoif7w5.cloudfront.net/f881c83b69e04669afbd2a23a8fc738b_large.jpg",
    "huge": "http://d12x84seoif7w5.cloudfront.net/f881c83b69e04669afbd2a23a8fc738b_huge.jpg"
}

Asynchronously uploading multiple images at once

Multiple product images can be uploaded at once. Image ids will return right away while the actual images are uploaded in the background. Callback details may be provided so that successes and errors can be reported. callback_options is a dictionary that takes a url and will report successes and errors unless on_success is false, in which case the callback url will only be hit when an error occurs.
The format of data in the callback is a JSON-formatted string. Data returned in the callback's success dictionary entry will be in the format of the regular response, while error will provide the image ID of each failure and an exception message.

curl -H "Authorization: Bearer ba125ac086" -X POST \
    -F 'images=["@/path/to/image1.jpg", "@/path/to/image2.jpg"]' \
    -F 'callback_options={"url":"https://example.com/callback-url", "on_success": "false"}'
    https://goodsie.com/api/v1/products/an-ugly-sweater/images
[
    "3907b41435aa4feb8a0f01f0aefa9b9b",
    "4fea982bb70442ef8363f03e78d6dc20"
]

example callback data

{
    "success": [
        "3907b41435aa4feb8a0f01f0aefa9b9b"
    ],
    "error": {
        "4fea982bb70442ef8363f03e78d6dc20": "This file location could not be accepted"
    }
}

Deleting a product image

curl -H "Authorization: Bearer ba125ac086" -X DELETE \
    https://goodsie.com/api/v1/products/an-ugly-sweater/images/f881c83b69e04669afbd2a23a8fc738b
true

Changing image order

curl -H "Authorization: Bearer ba125ac086" -X PUT \
    -F "order=2"
    https://goodsie.com/api/v1/products/an-ugly-sweater/images/f881c83b69e04669afbd2a23a8fc738b
true

Fetching a product video

curl -H "Authorization: Bearer ba125ac086" -X POST \
    -F 'video=http://vimeo.com/73781961' \
    https://goodsie.com/api/v1/products/an-ugly-sweater/videos
{
    'id': '73781961',
    'thumb_url': 'c289482f955f423fafc574ccc6f93da8_%s.jpg',
    'type': 'vimeo',
    'url': 'http://vimeo.com/73781961'
}

Updating a product

This example shows how to modify the product's available quantity, move it to the tax group with id 123, and update the product with metadata

curl -H "Authorization: Bearer ba125ac086" -X PUT \
    -F 'quantity=42' \
    -F 'tax_group=123' \
    -F 'product_metadata={"external_id": "abc123"}' \
    https://goodsie.com/api/v1/products/an-ugly-sweater
[
    {
        ... product result ...
    }
]

Handling product options and extras

All options must be passed as arguments. Dictionaries representing existing options must include the "id" key.

Any existing options not included in this POST action will be deleted.

Creating a product option
curl -H "Authorization: Bearer ba125ac086" -X POST \
    -F 'options=[{"surcharge": 4, "quantity": -1, "metadata": {"Color": "Green", "Size": "Small"}}]' \
    https://goodsie.com/api/v1/products/an-ugly-sweater/options
[
    {
        ... list of all product options ...
    }
]
Updating existing and creating new options at the same time

Existing options are updated by including the option's key in dictionary with the "id" dictionary key.
The new options don't yet have a key.

curl -H "Authorization: Bearer ba125ac086" -X POST \
    -F 'options=[{"surcharge": 0, "quantity": -1, "metadata": {"Color": "Green", "Size": "Small"}, "id": "df19d185-145d-11e1-aa5e-002500a0451c"}, {"surcharge": 2, "quantity": -1, "metadata": {"Color": "Red", "Size": "Small"}}]' \
    https://goodsie.com/api/v1/products/an-ugly-sweater/options
[
    {
        ... list of all product options ...
    }
]
Delete all options

All options for this product are deleted when no dictionaries are passed.

curl -H "Authorization: Bearer ba125ac086" -X POST \
    -F 'options=' \
    https://goodsie.com/api/v1/products/an-ugly-sweater/options
[
    ... The default option or an empty list for extras ...
]
Creating a product extra
curl -H "Authorization: Bearer ba125ac086" -X POST \
    -F 'extras=[{"surcharge": 1, "quantity": -1, "metadata": "Glitter": "a lot"}}]' \
    https://goodsie.com/api/v1/products/an-ugly-sweater/extras
[
    {
        ... list of all product extras ...
    }
]

Updating a product option

curl -H "Authorization: Bearer ba125ac086" -X PUT \
    -F 'quantity=19' \
    -F 'surcharge=5.49' \
    https://goodsie.com/api/v1/products/an-ugly-sweater/options/2ee684a3-2b18-11e1-8102-002500a0451c
[
    {
        ... product option result ...
    }
]

Handling categories

All product categories must be passed as arguments. Those omitted will be deleted.

Creating new / changing existing categories
curl -H "Authorization: Bearer ba125ac086" -X POST \
    -F 'categories=sweater, warm, clothing' \
    https://goodsie.com/api/v1/products/an-ugly-sweater/categories
[
    {
        ... list of product categories ...
    }
]
Deleting all categories
curl -H "Authorization: Bearer ba125ac086" -X POST \
    -F 'categories=' \
    https://goodsie.com/api/v1/products/an-ugly-sweater/categories
[
    {
        []
    }
]

Deleting a product

curl -H "Authorization: Bearer ba125ac086" -X DELETE \
    https://goodsie.com/api/v1/products/an-ugly-sweater
true