Automate your Print on Demand business

    Overview

    This documentation describes various ways to access Printify services by using the Printify API. Each section has a detailed description as well as code examples to help you easily start creating products and fulfilling orders.

    API Usage Guidelines

    All integrations must comply with the Printify Terms and Printify API Terms. Please see these pages for more details:

    The Printify public endpoints are powered by the same underlying technology that powers the core Printify Platform. As a result, Printify engineering closely monitors usage of the public APIs to ensure a quality experience for users of the Printify platform.

    Below, you'll find the limits by which a single integration (identified per account and not per access token) can consume the Printify APIs. If you have any questions, please email apiteam@printify.com.

    Printify has the following limits in place for API requests:

    This daily limit resets at midnight based on the time zone setting of the Printify account. Customers exceeding either of those limits will receive error responses with a 429 response code.

    Integrations that use Printify's API to create products and generate mockups have additional daily limits. The product publishing endpoint has a limit of 200 requests per 30 minutes, product creation as a result of Order creation is not limited. If your application will require heavy usage of the Product or Mockup generation functions, please contact apiteam@printify.com with more information and we will contact you shortly.

    Requests resulting in an error response may not exceed 5% of your total requests.

    We reserve the right to change or deprecate the APIs over time - we will provide developers ample notification in those cases. These notifications will be sent to the email provided in your API settings.

    API features

    REST API

    Printify's REST API allows your application to manage a Printify shop on behalf of a Printify Merchant. Create products, submit orders, and more...

    Check out all available methods: API Reference

    Webhooks and Events

    Webhooks allow you to get an instant notification after an event occurrs in a Printify shop.

    Send information to accounting right after an order was placed, send tracking to end customers as soon as it's available, sync product descriptions, etc... - it's totally up to you.

    More information: Webhooks

    Access the Printify API

    You can access the Printify API as an individual merchant or as a platform. Both of them require different types of authentication. Learn about each of them below.

    Individual Accounts

    Connect to a single Printify Merchant account and the shops that are a part of that account. Create products, submit artwork, create and receive orders and more. Authentication is achieved through a Personal Access Token.

    See more details in Authentication.

    Platforms

    Connect applications that offer services to multiple merchants each with different Printify merchant accounts. Manage orders for multiple Printify Merchants, offer merchants the option to sell on your platform, and more. Authentication is achieved through OAuth 2.0

    See more details in Authentication

    Use cases

    Create orders with user-generated content

    Regardless of whether you use your own mockup generator, or you capture user generated content. Through the Printify API you can easily place those images on any products in our catalog, offer them for purchase, and fulfill.

    Connect your own E-commerce channel

    Don't use Etsy, Shopify, Woocommerce, or any of our other available E-commerce solutions? Connect your own with the Printify API. Enjoy the same benefits of automation that merchants using our existing integrations do.

    Support existing integrations with more functionality

    Already using one of our integrations such as Shopify or Woocommerce? Build any additional functionality you need and connect via Printify API to continue to get all of your sales and order data in your existing shop.

    Start offering merchandise sales to your community

    Do you have an application or platform with an engaged community. Connect to the Printify API and easily start monetizing your community by allowing them to sell Print on Demand merchandise through your platform.

    Authentication

    The Printify platform provides two ways of integrating. You can integrate with a Personal Access Token that you can use to manage a single Printify account, or you can integrate through OAuth 2.0 as a platform that will be managing multiple Printify Merchant accounts.

    Unless otherwise mentioned in the documentation for a specific endpoint, all endpoints support both OAuth 2.0 and Personal Access Token.

    Create a personal access token

    A personal access token allows your application to connect to a single Printify Merchant account and the shops created within that account.

    Step 1

    Before creating your personal access token, you will first need a Printify account. If you haven't created an account yet, please do so here and complete the onboarding procedure.

    Step 2

    Now that you have your Printify account, navigate to My Profile, then Connections. In the Connections section you will be able to generate your Personal Access Tokens and set your Token Access Scopes.

    Step 3

    You will be able to generate multiple tokens. Tokens can be set to have different Access Scopes.

    Please note that for security purposes, this token will only be visible immediately after generating only. Please make sure you store it in a secure location.

    If you lose your access token, you will need to generate a new one.

    Generate token

    Step 4

    Once generated, you can use that token as credentials for API requests in place of a user name and password.

    All requests must also specify a User-Agent header. The value of this header should either be the type of client, such as "NodeJS" or "PHP," or the name of your application.

    After you have authenticated to the API, you can send requests to the API using any programming language or program that can send HTTP requests. The base URL for all endpoints is https://api.printify.com/.

    Here is an example:

    curl -X GET https://api.printify.com/v1/shops.json --header "Authorization: Bearer $PRINTIFY_API_TOKEN"

    Step 5

    Once you’ve set the API up, go to your store by clicking on My Stores, then Add new store. You should see Shopify, Etsy, WooCommerce, and the new option, API.

    Click connect to connect your store to Printify via the API.

    OAuth 2.0

    Using OAuth 2.0 you will be able to offer your application to the growing community of Printify Merchants.

    On this page:

    Prerequisites

    1. Authentication for your integration starts with registering your app. This link takes you to an application form where you will answer some questions about your business, expected integration timeline and your applications functionality. If your application is approved, you will receive instructions via email for how to receive your app ID, and how to set the required access scopes your application will need.
    2. You'll use the app ID to initiate the OAuth handshake between Printify and your integration.

    Note: Reviewing applications can take up to 1 week.

    Register your app

    Connecting your app to Printify

    There are 4 steps to connecting your integration to a Merchant's Printify account using OAuth:

    1. The Printify merchant will be presented with a screen that allows them to grant access to your integration.
    2. After the Merchant grants access, they'll be returned to your app, with a code appended to the URL. Use that code and your app ID to get an access_token and refresh_token.
    3. Use that access_token to authenticate any API calls that you make for that Printify account.
    4. Once that access_token expires, use the refresh_token from Step 2 to generate a new access_token.

    Getting grant codes

    Initiating OAuth access is the first step for having merchants grant your application access to their Printify account. In order to initiate OAuth connection for your App, you'll first need to send a Printify merchant to an authorization page, where that merchant will need to grant access to your app. When your app sends a merchant to that authorization page, you'll use the query parameters detailed below to identify your app, and to also specify the scopes that your apps requires.

    Merchants must be signed into Printify to grant access, so any user that is not logged into Printify will be directed to a login screen before being directed back to the authorization page. The authorization screen will show the details of your app, and the permissions being requested (based on the scopes you include in the URL).

    Depending on whether or not the merchant grants access, they will be redirected to the accept_url or decline_url that you specified, if access was granted, a code query parameter is appended to the URL and you'll use that code to get an access token from Printify.

    URL fields

    app_id REQUIRED app_id=x The app ID provided to you after registering your app.
    accept_url REQUIRED accept_url=x The URL that you want the visitor redirected to after granting access to your app. A code that can be used to exchange for tokens will be appended to the end of the URL.
    decline_url REQUIRED decline_url=x The URL that you want the visitor redirected to after denying access to your app.
    scope OPTIONAL scope=x%20x A space separated set of scopes that your app will need access to. Scopes listed in this parameter will be treated as required for your app, and the user will see an error if they select an account that does not have access to the scope you've included. Any scopes that you have checked in your app settings will be treated as required scopes, and you'll need to include any selected scopes in this parameter or the authorization page will display an error.
    state RECOMMENDED OPTIONAL state=123 Persistent variable during connection flow.
    For security reasons, the accept and decline URL must use https in production. When testing using localhost, http can be used. Also, you must use a domain, as IP addresses are not supported.

    Getting tokens

    Use the grant code you get after a user authorizes your app to exchange for an access token and refresh token. The access token will be used to authenticate requests that your app makes. When you get the Access tokens, you also get expiration time for the token. When token expires you have to use Refresh token to get a new Access token.

    Request parameters

    app_id REQUIRED app_id=x The app ID provided to you after registering your app.
    code REQUIRED code=y The code parameter returned to your accept_url when the user authorized your app, it is returned by the GET /app/oauth/accept endpoint and passed back to the consumer app.
    Printify access tokens will fluctuate in size as we change the information that is encoded in the tokens. We recommend allowing for tokens to be up to 3,000 characters to account for any changes we may make.

    Refreshing access tokens

    Use a previously obtained refresh token to generate a new access token. Access tokens expire after 6 hours, so if you need offline access to data in Printify, you'll need to store the refresh token you get when initiating your OAuth integration, and use that to generate a new access token once the initial access token expires.

    Request parameters

    app_id REQUIRED app_id=x The app ID provided to you after registering your app.
    refresh_token REQUIRED refresh_token=x The refresh token returned by POST /app/oauth/tokens in the previous step.

    Using access tokens

    OAuth 2.0 access tokens are provided as a bearer token, in the Authorization http header.

    The header format is: Authorization: Bearer {token}

    Endpoints

    Get grant code

    This request is made to the base URL https://printify.com/.

    GET /app/oauth/authorize?{URL_fields}
    Authorization request
    URL fields app_id=x &scope=shops.read &accept_url=https://example.com &decline_url=https://example.com &state=123
    Possible outcomes
    If access is granted, a URL redirect will follow with a grant code appended to the url https://www.example.com/?code=aabbccxxeeaabbccxxeeaabbccxxee If there are any problems with the authorization, error parameters will be received instead of the code https://www.example.com/?error=error_code &error_description=Human%20readable%20description%20of%20the%20error

    Convert grant code to tokens

    Requests after authentication are made to the base URL https://api.printify.com/.

    POST /app/oauth/tokens
    Convert grant code to tokens
    Request parameters app_id=x &code=y
    Possible responses
    If successful, a JSON response with the tokens will be received View Response

    If there are any problems with the request, a 400 response will be received with an error message View Response

    Refresh access token

    POST /app/oauth/tokens/refresh
    Refresh access token
    Request parameters app_id=x &refresh_token={from-the-get-tokens-request}
    Possible responses
    If successful, a JSON response with the tokens will be received View Response

    If there are any problems with the request, a 400 response will be received with an error message View Response

    Access scopes

    Scopes are permissions that identify the scope of access your application requests from the Printify Merchant Account. Below you can see the names of access scopes that exist in Printify and their description.

    Access Scope Notes
    shops.read Access shops in a Merchant's account
    shops.manage Disconnect shops in a Merchant's account
    catalog.read See Products and Print Providers from the Printify Product Catalog
    products.read See products created in a Merchant's shop
    products.write Create products in a Merchant's shop
    orders.read See orders created in a Merchant shop
    orders.write Create orders in a Merchant's shop
    webhooks.read Read installed webhooks
    webhooks.write Install, update and delete Webhooks
    uploads.read See uploaded files in a Merchant's account
    uploads.write Upload image files and archive them
    print_providers.read See available print providers

    API Reference

    The Printify API is organized around REST.

    Our API has predictable resource-oriented URLs, accepts form-encoded request bodies, returns JSON-encoded responses, and uses standard HTTP response codes, authentication, and verbs.

    API basics

    Shops

    All product creation and order submission in a Printify Merchant's account happens through a shop. Merchant's can have multiple shops in one Printify account. Each of these shops can be connected to different sales channels and each has independent products, orders, and analytics.

    On this page:

    What you can do with the shops resource

    The shops resource serves one purpose, it allows you to view the list of existing shops in a Printify account.

    Shop properties

    id READ-ONLY "id": 12345 A unique int identifier for the shop. Each id is unique across the Printify system.
    title READ-ONLY "title": "Shop's title" The name of the shop.
    sales_channel READ-ONLY "sales_channel": "Sales channel name" The name of the associated sales channel. If none are connected it defaults to "disconnected".

    Endpoints

    Retrieve list of shops in a Printify account

    GET /v1/shops.json
    Retrieve a list of shops in a Printify account
    GET /v1/shops.json
    View Response

    Disconnect a shop

    DELETE /v1/shops/{shop_id}/connection.json
    Disconnect a shop
    DELETE /v1/shops/{shop_id}/connection.json
    View Response

    Catalog

    Through the Catalog resource you can see all of the products, product variants, variant options and print providers available in the Printify catalog.

    Products in the Printify catalog are referred to as blueprints (only after user artwork has been added, are they referred to as products).

    Every blueprint in the printify catalog has multiple Print Providers that offer that blueprint. In addition to general differences between Print Providers including location and print technology employed, each Print Provider also offers different colors, sizes, print areas and prices.

    Each Print Provider's blueprint has specific size and color combinations known as variants. Variants also contain information on a products available print areas and sizes.

    On this page:

    What you can do with the catalog resource

    The Printify Public API lets you do the following with the Catalog resource:

    Blueprint properties

    id READ-ONLY "id": 5 A unique int identifier for the blueprint. Each id is unique across the Printify system.
    title READ-ONLY "title": "Blueprint's title" The name of the blueprint.
    brand READ-ONLY "brand": "Blueprint's brand" The brand of the blueprint (i.e. the name of the blank product's manufacturer).
    model READ-ONLY "model": "Blueprint's brand model" The specific model of the blueprint's brand (i.e. the unique identifier of the blank product's model or style).
    images READ-ONLY "images": [ "https://images.example.com/869549a1a0894a4692371b1f9928e14a.png", "https://images.example.com/878331a2b0876c9801746d2e2454f14a.png" ] Links to the title image wrappers displayed on the catalog.
    id READ-ONLY "id": 3 A unique int identifier for the print provider. Each id is unique across the Printify system.
    title READ-ONLY "title": "Print provider's title" The name of the print provider.
    location READ-ONLY "location": { "address1": "89 Weirfield St", "address2": "", "city": "Brooklyn", "country": "US", "region": "NY", "zip": "11221-5120" } The return address of the print provider.

    Variant properties

    id READ-ONLY "id": 17390 A unique int identifier for the blueprint variant. Each id is unique across the Printify system.
    title READ-ONLY "title": "Variant's title" The name of the variant.
    options READ-ONLY "options": { "color": "Heather Grey", "size": "XS" } Options are read only values and describes blueprint variant options. There can be up to 3 options for a blueprint.
    placeholders READ-ONLY "placeholders": [{ "position": "back", "height": 3995, "width": 3153 }, { "position": "front", "height": 3995, "width": 3153 }] Placeholders describe the available printable areas for a blueprint. See placeholder properties for reference.

    Placeholder properties

    position READ-ONLY "position": "front" Position states the available printable areas for a blueprint fulfilled by a specific print provider.
    height READ-ONLY "height": 3995 Integer value for printable area height in pixels.
    width READ-ONLY "width": 3153 Integer value for printable area width in pixels.

    Shipping properties

    handling_time READ-ONLY "handling_time": { "value":10, "unit": "day" } The standard shipping timeframe for a blueprint from a specific print provider.
    profiles READ-ONLY "profiles": [ { "variant_ids": [1,2], "first_item": { "currency": "USD", "cost": 1000 }, "additional_items": { "currency": "USD", "cost": 1000 }, "countries":["US"] }, { "variant_ids": [1,2], "first_item": { "currency": "USD", "cost": 1000 }, "additional_items": { "currency": "USD", "cost": 1000 }, "countries":["REST_OF_THE_WORLD"] } ] The list of shipping locations and flat shipping costs for all variants of a blueprint from a specific print provider. See profile properties for reference.

    Profile properties

    variant_ids READ-ONLY "variant_ids": [ 1,2,3,4,5,6,7 ] Lists the ids of all blueprint variants the specific profile is associated to in an array.
    first_item READ-ONLY "first_item": { "currency": "USD", "cost": 1000 } The currency and flat cost of shipping for a line item if identified as the first item in an order.
    additional_items READ-ONLY "additional_items": { "currency": "USD", "cost": 1000 } The currency and flat cost of shipping for all other line items of the specific blueprint and print provider in the same order.
    countries READ-ONLY "countries": [ US ] Lists the countries or delivery locations the shipping profile applies to.
    print_on_side OPTIONAL "print_on_side": "regular" States the type of side print. "regular" for expanding print area to the sides of canvas and "mirror" to keep original print area and mirror it to the sides.

    Endpoints

    Retrieve a list of available blueprints

    GET /v1/catalog/blueprints.json
    Retrieve a list of available blueprints
    GET /v1/catalog/blueprints.json
    View Response

    Retrieve a specific blueprint

    GET /v1/catalog/blueprints/{blueprint_id}.json
    Retrieve a specific blueprint
    GET /v1/catalog/blueprints/{blueprint_id}.json
    View Response

    Retrieve a list of all print providers that fulfill orders for a specific blueprint

    GET /v1/catalog/blueprints/{blueprint_id}/print_providers.json
    Retrieve a list of all print providers that fulfill orders for a specific blueprint
    GET /v1/catalog/blueprints/{blueprint_id}/print_providers.json
    View Response

    Retrieve a list of variants of a blueprint from a specific print provider

    GET /v1/catalog/blueprints/{blueprint_id}/print_providers/{print_provider_id}/variants.json
    Retrieve a list of variants of a blueprint from a specific print provider
    GET /v1/catalog/blueprints/{blueprint_id}/print_providers/{print_provider_id}/variants.json
    View Response

    Retrieve shipping information

    GET /v1/catalog/blueprints/{blueprint_id}/print_providers/{print_provider_id}/shipping.json
    Retrieve shipping information
    GET /v1/catalog/blueprints/{blueprint_id}/print_providers/{print_provider_id}/shipping.json
    View Response

    Retrieve a list of available print providers

    GET /v1/catalog/print_providers.json
    Retrieve a list of available print providers
    GET /v1/catalog/print_providers.json
    View Response

    Retrieve a specific print provider

    GET /v1/catalog/print_providers/{print_provider_id}.json
    Retrieve a specific print provider and a list of associated blueprint offerings
    GET /v1/catalog/print_providers/{print_provider_id}.json
    View Response

    Products

    The Product resource lets you list, create, update, delete and publish products to a store.

    On this page:

    What you can do with the product resource

    The Printify Public API lets you do the following with the Product resource:

    Product properties

    id READ-ONLY "id": "5cb87a8cd490a2ccb256cec4" A unique string identifier for the product. Each id is unique across the Printify system.
    title REQUIRED "title": "Product's title" The name of the product.
    description REQUIRED "description": "Product's description" A description of the product. Supports HTML formatting.
    tags OPTIONAL "tags": ["T-shirt", "Men's"] Tags are also published to sales channel.
    options READ-ONLY "options": [{ "name": "Colors", "type": "color", "values": [{ "id": 751, "title": "Solid White", "colors": [ "#F9F9F9" ] }] }] Options are read only values and describes product options. There can be up to 3 options for a product.
    variants REQUIRED "variants": [{ "id": 123, "price": 1000, "title": "Solid Dark Gray / S", "sku": "PRY-123", "grams": 120, "is_enabled": true, "is_default": false, "options": [751, 2] }] A list of all product variants, each representing a different version of the product. But during product creation, only the variant id and price are necessary. See variant properties for reference.
    images READ-ONLY "images": [{ "src": "http://example.com/tee.jpg", "variant_ids": [123, 124], "position": "front", "is_default" : false, }] Mock-up images are read only values. The mock-up images are grouped by variants and position. See mock-up image properties for reference.
    created_at READ-ONLY "created_at": "2017-04-18 13:24:28+00:00" The date and time when a product was created.
    update_at READ-ONLY "update_at": "2017-04-18 13:24:28+00:00" The date and time when a product was last updated.
    visible READ-ONLY "visible": true Used for publishing. Visibility in sales channel. Can be true or false, defaults to true.
    blueprint_id REQUIRED READ-ONLY "blueprint_id": 5 Required when creating a product, but is read only after. See catalog for how to get blueprint_id.
    print_provider_id REQUIRED READ-ONLY "print_provider_id": 5 Required when creating a product, but is read only after. See catalog for how to get print_provider_id.
    user_id READ-ONLY "user_id": 5 User id that a product belongs to.
    shop_id READ-ONLY "shop_id": 1 Shop id that a product belongs to.
    print_areas REQUIRED "print_areas": [{ "variant_ids": [123, 124], "placeholders": [{ "position": "front", "images": [] }], }] All print area values are required. Each variant has a print area attached to it. Each print area has placeholders which represent printable areas on a product. For example the front of the t-shirt, back of the t-shirt etc. Each placeholder has images and their positions, where they need to be printed in the printable area. See placeholder properties for reference.
    print_details OPTIONAL "print_details": { "print_on_side": "regular" } }] "print_on_side" key is used to set the type of side printing for canvases. There are three possible values:
    • "regular" - to extend print area to the sides of canvas
    • "mirror" - to keep original print area and mirror it to the sides
    • "off" - stop printing on sides
    external CONDITIONAL "external": [{ "id": "A123abceASd", "handle": "/path/to/product" }] Updated by sales channel with publishing succeeded endpoint. Id and handle are external references in the sales channel. See publishing succeeded endpoint for more reference.
    is_locked READ-ONLY "is_locked": true A product is locked during publishing. Locked products can't be updated until unlocked.
    sales_channel_properties READ-ONLY "sales_channel_properties": [] Lists product properties specific to the sales channel associated with the product, if the sales channel has such custom properties, the attributes are listed in the array and may be actionable, but for all custom integrations, it will either be null or an empty array.

    Variant properties

    id REQUIRED READ-ONLY "id": 123 A unique int identifier for the product variant from the blueprint. Each id is unique across the Printify system. See catalog for instructions on how to get variant ids.
    sku OPTIONAL "sku": "SKU-123" Optional unique string identifier for the product variant. If one is not provided, one will be generated by Printify.
    price REQUIRED "price": 1000 Price in cents, integer value.
    cost READ-ONLY "cost": 400 Product variant's fulfillment cost in cents, integer value.
    title READ-ONLY "title": "Solid Dark Gray / S" Variant title.
    grams READ-ONLY "grams": 120 Weight in grams for a product variant
    is_enabled OPTIONAL "is_enabled": true Used for publishing, the value is true if one has the variant in question selected as an offering and wants it published.
    in_stock OPTIONAL DEPRECATED "in_stock": true Used for publishing, out of stock items will be set to out of stock on a sales channel or skipped during publishing, depends on the particular sales channel integration. This property will be removed at a later date, use the "is_enabled" property instead.
    is_default OPTIONAL "is_default": true Only one variant can be default. Used when publishing to sales channel. Default variant's image will be the title image of the product.
    is_available READ-ONLY "is_available": true Actual stock status of the variant, if false, the variant is out of stock and vice versa.
    options READ-ONLY "options": [751, 2] Reference to options by id.

    Placeholder properties

    position REQUIRED "position": "front" See blueprint placeholder properties from the catalog endpoint for reference on how to get positions.
    images REQUIRED "images": [] Array of images. See image properties for reference.

    Image properties

    id REQUIRED "id": 123 See upload images for reference on how to upload images and get all needed properties.
    name READ-ONLY "name": "image.jpg" Name of an image file.
    type READ-ONLY "type": "image/png" Type of an image. Valid image types are image/png, image/jpg, image/jpeg.
    height READ-ONLY "height": 100 Integer value for image height in pixels. See upload images for reference on how to upload images and get all needed properties.
    width READ-ONLY "width": 100 Integer value for image width in pixels. See upload images for reference on how to upload images and get all needed properties.
    x REQUIRED "x": 100 Float value to position an image on the x axis. See image positioning for reference on how to position images.
    y REQUIRED "y": 100 Float value to position an image on the y axis. See image positioning for reference on how to position images.
    scale REQUIRED "scale": 1 Float value to scale image up or down. See image positioning for reference on how to position images.
    angle REQUIRED "angle": 180 Integer value used to rotate image. See image positioning for reference on how to position images.

    Mock-up image properties

    src READ-ONLY "src": "https://images.printify.com/mockup/5d39b159e7c48c000728c89f/33719/145/mug-11oz.jpg" Url of a mock-up image.
    variant_ids READ-ONLY "variant_ids": [ 61618, 61619, 61620, 61621, 61622 ] Array of integer ids for variants illustrated by the mock-up image.
    position READ-ONLY "position": "front" Camera position of a mockup (i.e. what part of the product is being displayed).
    is_default READ-ONLY "is_default": true Used by the sales channel. If set to true, The specific mockup is the title image. Can be used to decide the first image displayed when a product's page is accessed.

    Publishing properties

    The "publish" button in the Printify app only locks the product on the Printify app and triggers the product:publish:started event if you are subscribed to it, see See Product events for reference. To publish a product, you need to create it manually on your store from the data you can obtain from the product resource or develop a system to automate that. Once done, you can use the Publish succeeded endpoint or Publish failed endpoint to unlock the product.

    images REQUIRED "images": true Used by the sales channel. If set to false, Images will not be published, and existing images will be used instead.
    variants REQUIRED "variants": true Used by the sales channel. If set to false, product variations will not be published.
    title REQUIRED "title": true Used by sales channel. If set to false, product title will not be updated.
    description REQUIRED "description": true Used by sales channel. If set to false, product description will not be updated.
    tags REQUIRED "tags": true Used by sales channel. If set to false, product tags will not be updated.

    Endpoints

    Retrieve a list of products

    GET /v1/shops/{shop_id}/products.json
    limit OPTIONAL
    Results per page
    (default: 10, maximum: 100)
    page OPTIONAL Paginate through list of results
    Retrieve all products
    GET /v1/shops/{shop_id}/products.json
    View Response
    Retrieve specific page from results
    GET /v1/shops/{shop_id}/products.json?page=2
    View Response
    Retrieve limited results
    GET /v1/shops/{shop_id}/products.json?limit=1
    View Response

    Retrieve a product

    GET /v1/shops/{shop_id}/products/{product_id}.json
    Retrieve a product
    GET /v1/shops/{shop_id}/products/{product_id}.json
    View Response

    Create a new product

    POST /v1/shops/{shop_id}/products.json
    Create a new product
    POST /v1/shops/{shop_id}/products.json
    { "title": "Product", "description": "Good product", "blueprint_id": 384, "print_provider_id": 1, "variants": [ { "id": 45740, "price": 400, "is_enabled": true }, { "id": 45742, "price": 400, "is_enabled": true }, { "id": 45744, "price": 400, "is_enabled": false }, { "id": 45746, "price": 400, "is_enabled": false } ], "print_areas": [ { "variant_ids": [45740,45742,45744,45746], "placeholders": [ { "position": "front", "images": [ { "id": "5d15ca551163cde90d7b2203", "x": 0.5, "y": 0.5, "scale": 1, "angle": 0 } ] } ] } ] } View Response

    Update a product

    A product can be updated partially or as a whole document. When updating variants, all variants must be present in the request.

    PUT /v1/shops/{shop_id}/products/{product_id}.json
    Update a product
    PUT /v1/shops/{shop_id}/products/{product_id}.json
    { "title": "Product" } View Response

    Delete a product

    DELETE /v1/shops/{shop_id}/products/{product_id}.json
    Delete a product
    DELETE /v1/shops/{shop_id}/products/{product_id}.json
    View Response

    Publish a product

    This does not implement any publishing action unless the Printify store is connected to one of our other supported sales channel integrations, if your store is custom and is subscribed to the product::pubish::started event, that event will be triggered and the properties that are set in the request body will be set in the event payload for your store to react to if implemented. The case is the same for attempting to publish a product from the Printify app. See product events for reference.

    POST /v1/shops/{shop_id}/products/{product_id}/publish.json
    Publish a product
    POST /v1/shops/{shop_id}/products/{product_id}/publish.json
    { "title": true, "description": true, "images": true, "variants": true, "tags": true } View Response

    Set product publish status to succeeded

    Using this endpoint removes the product from the locked status on the Printify app and sets the the it's external property with the handle you provide in the request body.

    POST /v1/shops/{shop_id}/products/{product_id}/publishing_succeeded.json
    Set product publish status to succeeded
    POST /v1/shops/{shop_id}/products/{product_id}/publishing_succeeded.json
    { "external": { "id": "5941187eb8e7e37b3f0e62e5", "handle": "https://example.com/path/to/product" } } View Response

    Set product publish status to failed

    Using this endpoint removes the product from the locked status on the Printify app.

    POST /v1/shops/{shop_id}/products/{product_id}/publishing_failed.json
    Set product publish status to failed
    POST /v1/shops/{shop_id}/products/{product_id}/publishing_failed.json
    { "reason": "Request timed out" } View Response

    Notify that a product has been unpublished

    POST /v1/shops/{shop_id}/products/{product_id}/unpublish.json
    Notify that a product has been unpublished
    POST /v1/shops/{shop_id}/products/{product_id}/unpublish.json
    View Response

    Image positioning

    Rule of thumb: if you use artwork with width equal to print area placeholder width, set scale to 1,00 and position it at x=0,5 y=0,5 - your design will be horizontally and vertically aligned and fill all the print area fully.

    Common error cases

    You may receive errors when trying to create or update a product. A common error is due failing dpi validation because the image is low quality. If this happens, you will receive a detailed error message similar to the one shown here.

    POST /v1/shops/{shop_id}/products.json
    Common error cases
    POST /v1/shops/{shop_id}/products.json
    400 Image has low quality error example (See HTTP Status Codes below) View Response
    PUT /v1/shops/{shop_id}/products/{product_id}.json
    Common error cases
    PUT /v1/shops/{shop_id}/products/{product_id}.json
    400 Image has low quality error example (See HTTP Status Codes below) View Response

    Orders

    Printify API lets your application manage orders in a Merchants shop. You can submit orders for existing products in a merchant's shop or you can create new products with every order as in the case with merchandise created with customizable user-generated content.

    Ordering existing products or creating products with orders will require different line item entries so that should be kept in mind.

    On this page:

    What you can do with the order resource

    The Printify Public API lets you do the following with the Order resource:

    Order properties

    id READ-ONLY "id": "5a96f649b2439217d070f507" A unique string identifier for the order. Each id is unique across the Printify system.
    address_to REQUIRED READ-ONLY "address_to": { "first_name": "John", "last_name": "Smith", "region": "", "address1": "ExampleBaan 121", "city": "Retie", "zip": "2470", "email": "example@msn.com", "phone": "0574 69 21 90", "country": "BE", "company": "MSN" } The delivery details of the order's recipient.
    line_items REQUIRED READ-ONLY "line_items": [{ "product_id": "5b05842f3921c9547531758d", "quantity": 1, "variant_id": 17887, "print_provider_id": 5, "cost": 1050, "shipping_cost": 400, "status": "pending", "metadata": { "title": "18K gold plated Necklace", "price": 2200, "variant_label": "Golden indigocoin", "sku": "168699843", "country": "United States" }, "sent_to_production_at": "2017-04-18 13:24:28+00:00", "fulfilled_at": "2017-04-18 13:24:28+00:00" }] A list of all line items in the order. See line item properties for reference.
    metadata READ-ONLY "metadata": { "order_type": "external", "shop_order_id": 1370762297, "shop_order_label": "1370762297", "shop_fulfilled_at": "2017-04-18 13:24:28+00:00" } Other data about the order. See metadata properties for reference.
    total_price READ-ONLY "total_price": 2200 Retail price in cents, integer value.
    total_shipping READ-ONLY "total_shipping": 400 Shipping price in cents, integer value.
    total_tax READ-ONLY "total_tax": 0 Tax cost in cents, integer value.
    status READ-ONLY "status": "pending" Production status of the entire order in string format, it can be any of the following: pending, on-hold, checking-quality, quality-declined, quality-approved, ready-for-production, sending-to-production, in-production, cancelled, fulfilled, partially-fulfilled, payment-not-received, callback-received, or has-issues.
    shipping method REQUIRED READ-ONLY "shipping_method": 1 Method of shipping selected for the order, "1" is for standard shipping and "2" is for express shipping.
    shipments READ-ONLY "shipments": [{ "carrier": "usps", "number": "94001116990045395649372", "url": "http://example.com/94001116990045395649372", "delivered_at": "2017-04-18 13:24:28+00:00" }] Tracking details of the order after fulfillment. See shipment properties for reference.
    created_at READ-ONLY "created_at": "2017-04-18 13:24:28+00:00" The date and time the order was created. It is stored in ISO date format.
    sent_to_production_at READ-ONLY "sent_to_production_at": "2017-04-18 13:24:28+00:00" The date and time the order was sent to production. It is stored in ISO date format.
    fulfilled_at READ-ONLY "fulfilled_at": "2017-04-18 13:24:28+00:00" The date and time the order was fulfilled. It is stored in ISO date format.

    Line item properties

    product_id READ-ONLY "product_id": "5b05842f3921c9547531758d" A unique string identifier for the product. Each id is unique across the Printify system.
    variant_id REQUIRED READ-ONLY "variant_id": 17887 A unique int identifier for the product variant from the blueprint. Each id is unique across the Printify system.
    quantity REQUIRED "quantity": 1 Describes the number of said product ordered as an integer.
    print_provider_id REQUIRED READ-ONLY "print_provider_id": 5 A unique int identifier for the print provider. Each id is unique across the Printify system.
    cost READ-ONLY "cost": 1050 Product variant's fulfillment cost in cents, integer value.
    shipping_cost READ-ONLY "shipping_cost": 400 Product variant's shipment cost in cents, integer value.
    status READ-ONLY "status": "pending" Specific line item fulfillment status, can be pending, cancelled, or fulfilled.
    metadata READ-ONLY "metadata": { "title": "18K gold plated Necklace", "price": 2200, "variant_label": "Golden indigocoin", "sku": "168699843", "country": "United States" } Other details about the specific product variant. See line item metadata properties for reference.
    sent_to_production_at READ-ONLY "sent_to_production_at": "2017-04-18 13:24:28+00:00" The date and time the product variant was sent to production. It is stored in ISO date format.
    fulfilled_at READ-ONLY "fulfilled_at": "2017-04-18 13:24:28+00:00" The date and time the product variant was fulfilled. It is stored in ISO date format.

    Line item metadata properties

    title READ-ONLY "title": "Product's title" The name of the product.
    price READ-ONLY "price": 1000 Retail price in cents, integer value.
    variant_label READ-ONLY "variant_label": "Golden indigocoin" Name of the product variant.
    sku READ-ONLY "sku": "168699843" A unique string identifier for the product variant.
    country READ-ONLY "country": "United States" Location of print provider handling fulfillment.

    Metadata properties

    order_type READ-ONLY "order_type": "external" Describes the order type, can be external, manual, or sample.
    shop_order_id READ-ONLY "shop_order_id": 1370762297 A unique integer identifier for the order in the external sales channel.
    shop_order_label READ-ONLY "shop_order_id": "1370762297" A unique string identifier for the order in the external sales channel.
    shop_fulfilled_at READ-ONLY "shop_fulfilled_at": "2017-04-18 13:24:28+00:00" The date and time the order was fulfilled. It is stored in ISO date format.

    Shipment properties

    carrier READ-ONLY "carrier": "usps" Name of the shipping courier used to deliver the order to its recipient.
    number READ-ONLY "number": "123" A unique string tracking number from the shipping courier used to track the status of the shipment.
    url READ-ONLY "url": "http://example.com/94001116990045395649372" A unique string tracking link from the shipping courier used to track the status of the shipment.
    delivered_at READ-ONLY "delivered_at": "2017-04-18 13:24:28+00:00" The date and time the order was delivered. It is stored in ISO date format.

    Order submission properties

    external_id REQUIRED "external_id": "2750e210-39bb-11e9-a503-452618153e4a" A unique string identifier from the sales channel specifying the order name or id.
    label OPTIONAL "label": "000012" Optional value to specify order label instead of using "external_id"
    line_items REQUIRED "line_items": [{ "product_id": "5bfd0b66a342bcc9b5563216", "variant_id": 17887, "quantity": 1 }] Required for ordering existing products. Provide the product_id (Printify Product ID), variant_id (selected variant, e.g. 'White / XXL') and desired item quantity. If creating a product from the order is required, then additional attributes will need to be provided, specifically the blueprint_id and print_areas. "line_items": [{ "print_provider_id": 5, "blueprint_id": 9, "variant_id": 17887, "print_areas": { "front": "https://images.example.com/image.png" }, "quantity": 1 }] See product properties and variant properties for reference. Also, see print area properties for reference on print_areas for product creation during order submission. It is also possible to order existing products by providing the product variant's SKU alone. "line_items": [{ "sku": "MY-SKU", "quantity": 1 }] See variant properties for reference.
    shipping_method REQUIRED "shipping_method": 1 Required to specify what method of shipping is desired, "1" means standard shipping, "2" means express shipping. It is stored as an integer.
    send_shipping_notification BOOLEAN "send_shipping_notification": false A boolean for choosing whether or not to receive email notifications after an order is shipped.
    address_to REQUIRED "address_to": { "first_name": "John", "last_name": "Smith", "email": "example@msn.com", "phone": "0574 69 21 90", "country": "BE", "region": "", "address1": "ExampleBaan 121", "address2": "45", "city": "Retie", "zip": "2470" } The delivery details of the order's recipient.
    placeholder position and image url REQUIRED "print_areas": { "front": "https://images.example.com/image.png", "back": "https://images.example.com/image.png" } Required for creating products during order submission, See placeholder properties for reference. Instead of specifing the url, it is also possible to provide an array with image objects that have additional keys for the advanced positioning: "print_areas": { "front": [ { "src": "https://images.example.com/image.png", "scale": 0.15, "x": 0.80, "y": 0.34, "angle": 215 }, { "src": "https://images.example.com/image2.png", "scale": 1, "x": 0.5, "y": 0.5, "angle": 0 } ], "back": [ { "src": "https://images.example.com/image3.png", "scale": 1, "x": 0.5, "y": 0.5, "angle": 0 } ] }
    Special print options OPTIONAL "print_details": { "print_on_side": "mirror" } Used to store properties for special cases like printing on canvas sides, See print details properties for reference.

    Endpoints

    Retrieve a list of orders

    GET /v1/shops/{shop_id}/orders.json
    limit OPTIONAL
    Results per page
    (default: 10, maximum: 10)
    page OPTIONAL Paginate through list of results
    status OPTIONAL Filter results by order status
    Retrieve all orders
    GET /v1/shops/{shop_id}/orders.json
    View Response
    Retrieve limited results
    GET /v1/shops/{shop_id}/orders.json?limit=1
    View Response
    Retrieve specific page from results.
    GET /v1/shops/{shop_id}/orders.json?page=2
    View Response
    Filter results by order status.
    GET /v1/shops/{shop_id}/orders.json?status=fulfilled
    View Response

    Get order details by ID

    GET /v1/shops/{shop_id}/orders/{order_id}.json
    Get order details by ID
    GET /v1/shops/{shop_id}/orders/{order_id}.json
    View Response

    Submit an order

    POST /v1/shops/{shop_id}/orders.json
    Order an existing product
    POST /v1/shops/{shop_id}/orders.json
    { "external_id": "2750e210-39bb-11e9-a503-452618153e4a", "label": "00012", "line_items": [ { "product_id": "5bfd0b66a342bcc9b5563216", "variant_id": 17887, "quantity": 1 } ], "shipping_method": 1, "send_shipping_notification": false, "address_to": { "first_name": "John", "last_name": "Smith", "email": "example@msn.com", "phone": "0574 69 21 90", "country": "BE", "region": "", "address1": "ExampleBaan 121", "address2": "45", "city": "Retie", "zip": "2470" } } View Response
    Create a product with an order (simple image positioning)
    POST /v1/shops/{shop_id}/orders.json
    { "external_id": "2750e210-39bb-11e9-a503-452618153e5a", "label": "00012", "line_items": [ { "print_provider_id": 5, "blueprint_id": 9, "variant_id": 17887, "print_areas": { "front": "https://images.example.com/image.png" }, "quantity": 1 } ], "shipping_method": 1, "send_shipping_notification": false, "address_to": { "first_name": "John", "last_name": "Smith", "email": "example@msn.com", "phone": "0574 69 21 90", "country": "BE", "region": "", "address1": "ExampleBaan 121", "address2": "45", "city": "Retie", "zip": "2470" } } View Response
    Create a product with an order (advanced image positioning)
    POST /v1/shops/{shop_id}/orders.json
    { "external_id": "2750e210-39bb-11e9-a503-452618153e5a", "label": "00012", "line_items": [ { "print_provider_id": 5, "blueprint_id": 9, "variant_id": 17887, "print_areas": { "front": [ { "src": "https://images.example.com/image.png", "scale": 0.15, "x": 0.80, "y": 0.34, "angle": 0.34 }, { "src": "https://images.example.com/image.png", "scale": 1, "x": 0.5, "y": 0.5, "angle": 1 } ] }, "quantity": 1 } ], "shipping_method": 1, "send_shipping_notification": false, "address_to": { "first_name": "John", "last_name": "Smith", "email": "example@msn.com", "phone": "0574 69 21 90", "country": "BE", "region": "", "address1": "ExampleBaan 121", "address2": "45", "city": "Retie", "zip": "2470" } } View Response
    Create a product with an order (with specifying print details for printing on sides)
    POST /v1/shops/{shop_id}/orders.json
    { "external_id": "2750e210-39bb-11e9-a503-452618153e5a", "label": "00012", "line_items": [ { "print_provider_id": 5, "blueprint_id": 9, "variant_id": 17887, "print_areas": { "front": "https://images.example.com/image.png" }, "print_details": { "print_on_side": "mirror" }, "quantity": 1 } ], "shipping_method": 1, "send_shipping_notification": false, "address_to": { "first_name": "John", "last_name": "Smith", "email": "example@msn.com", "phone": "0574 69 21 90", "country": "BE", "region": "", "address1": "ExampleBaan 121", "address2": "45", "city": "Retie", "zip": "2470" } } View Response
    Order an existing product using only an SKU
    POST /v1/shops/{shop_id}/orders.json
    "external_id": "2750e210-39bb-11e9-a503-452618153e6a", "label": "00012", "line_items": [ { "sku": "MY-SKU", "quantity": 1 } ], "shipping_method": 1, "send_shipping_notification": false, "address_to": { "first_name": "John", "last_name": "Smith", "email": "example@msn.com", "phone": "0574 69 21 90", "country": "BE", "region": "", "address1": "ExampleBaan 121", "address2": "45", "city": "Retie", "zip": "2470" } } View Response

    Send an existing order to production

    POST /v1/shops/{shop_id}/orders/{order_id}/send_to_production.json
    Send an existing order to production
    POST /v1/shops/{shop_id}/orders/{order_id}/send_to_production.json
    View Response

    Calculate the shipping cost of an order

    POST /v1/shops/{shop_id}/orders/shipping.json
    Calculate the shipping cost of an order
    POST /v1/shops/{shop_id}/orders/shipping.json
    { "line_items": [{ "product_id": "5bfd0b66a342bcc9b5563216", "variant_id": 17887, "quantity": 1 },{ "print_provider_id": 5, "blueprint_id": 9, "variant_id": 17887, "quantity": 1 },{ "sku": "MY-SKU", "quantity": 1 }], "address_to": { "first_name": "John", "last_name": "Smith", "email": "example@msn.com", "phone": "0574 69 21 90", "country": "BE", "region": "", "address1": "ExampleBaan 121", "address2": "45", "city": "Retie", "zip": "2470" } } View Response

    Cancel an order

    This request will only be accepted if the order to be canceled has the status "on-hold" or "payment-not-received".

    POST /v1/shops/{shop_id}/orders/{order_id}/cancel.json
    Cancel an order
    POST /v1/shops/{shop_id}/orders/{order_id}/cancel.json
    View Response

    Common error cases

    POST /v1/shops/{shop_id}/orders.json
    Common error cases
    POST /v1/shops/{shop_id}/orders.json
    400 Invalid address validation error example (See HTTP Status Codes below) View Response

    Uploads

    Artwork added to a Printify Product can be saved in the Media library to be reused on additional products.

    You can use this API to directly add files to the media library, and later use image IDs when creating or modifying products.

    On this page:

    What you can do with the uploads resource

    The Printify Public API lets you do the following with the Uploads resource:

    Image properties

    id READ-ONLY "id": "5e16d66791287a0006e522b2" A unique string identifier for the image. Each id is unique across the Printify system.
    file_name READ-ONLY "file_name": "Image's file name" The file name of the image.
    height READ-ONLY "height": 5979 The height of the image in pixels.
    width READ-ONLY "width": 17045 The width of the image in pixels.
    size READ-ONLY "size": 1138575 The file size of the image in bytes.
    mime_type READ-ONLY "mime_type": "image/png" The media type of the image file.
    preview_url READ-ONLY "preview_url": "https://example.com/artwork" A url to preview the image.
    upload_time READ-ONLY "upload_time": "2020-01-09 07:29:43" The date and time the image was uploaded in ISO date format.

    Endpoints

    Retrieve a list of uploaded images

    GET /v1/uploads.json
    limit OPTIONAL
    Results per page
    (default: 10, maximum: 100)
    page OPTIONAL Paginate through list of results
    Retrieve all uploaded images
    GET /v1/uploads.json
    View Response
    Retrieve specific page from results
    GET /v1/uploads.json?page=2
    View Response
    Retrieve limited results
    GET /v1/uploads.json?limit=1
    View Response

    Retrieve an uploaded image by id

    GET /v1/uploads/{image_id}.json
    Retrieve an uploaded image by id
    GET /v1/uploads/{image_id}.json
    View Response

    Upload an image

    Upload image files either via image URL or image file base64-encoded contents. The file will be stored in the Merchant's account Media Library.

    POST /v1/uploads/images.json
    Upload image to a Printify account's media library
    POST /v1/uploads/images.json Body parameter (upload image by URL) { "file_name": "1x1-ff00007f.png", "url": "http://png-pixel.com/1x1-ff00007f.png" } Body parameter (upload image by base64-encoded contents) { "file_name": "image.png", "contents": "base-64-encoded-content" } View Response

    Archive an uploaded image

    POST /v1/uploads/{image_id}/archive.json
    Archive an uploaded image
    GET /v1/uploads/{image_id}/archive.json
    View Response

    Common Error cases

    When uploading images to the library, you may encounter errors. These are commonly due to download errors, incorrect file formats, or your image being too large. If these are the case, you will receive messages similar to these outlined here.

    POST /v1/uploads/images.json
    Common error cases
    POST /v1/uploads/images.json 400 Image download error example (See HTTP Status Codes below) View Response

    400 Image too large error example (See HTTP Status Codes below) View Response

    400 Unsupported file format error example (See HTTP Status Codes below) View Response

    Events

    Events are generated by some resources when certain actions are completed, such as the creation of a product, the fulfillment of an order. By requesting events, your app can know when certain actions have occurred in the shop.

    On this page:

    Shop events

    Event Description
    shop:disconnected The shop was disconnected.

    Product events

    Event Description
    product:deleted The product was deleted.
    product:publish:started The product publishing was started.

    Order events

    Event Description
    order:created The order was created.
    order:updated The order's status was updated.
    order:sent-to-production The order was sent to production.
    order:shipment:created Some/all items have been fulfilled.
    order:shipment:delivered Some/all items have been delivered.

    Event properties

    id "id": "653b6be8-2ff7-4ab5-a7a6-6889a8b3bbf5" A unique string identifier for the event. Each id is unique across the Printify system.
    type "type": "order:created" The type of event that occurred. Different resources generate different types of event.
    created_at "created_at": "2017-04-18 13:24:28+00:00" The date and time when the event was triggered.
    resource "resource": { "id": "653b6be8-2ff7-4ab5-a7a6-6889a8b3bbf5", "type": "product", "data": { "shop_id": 1234567, "reason": "Request timed out" } } Information about the resource that triggered the event. Check Resource properties for reference.

    Resource properties

    id "id": "5cb87a8cd490a2ccb256cec4" A unique string identifier for the resource. Each id is unique across the Printify system.
    type "type": "product" Resource type, currently valid types are shop, product and order.
    data "data": { "shop_id": 1234567, "reason": "Request timed out" } For more information see Resource data examples.

    Resource data examples

    Shop events

    shop:disconnected No resource data is sent.

    Product events

    product:deleted No resource data is sent.
    product:publish:started The values for the action property determine the resource data payload, the values can be "create", "update", or "delete". For "create" and "update" actions, the payload is as follows: "data": { "shop_id": 1234567, "publish_details": { "title": true, "description": true, "images": true, "variants": true, "tags": true, }, "action": "create", } For the "delete" action, the payload is as follows: "data": { "action": "delete" } For reference on what other properties mean, check Publishing properties.

    Order events

    order:created No resource data is sent with this event.
    order:updated "data": { "shop_id": 815256, "status": "in-production" } For information on what production statuses can be expected, check Order properties for reference.
    order:shipment:created "data": { "shop_id": 815256, "shipped_at": "2017-04-18 13:24:28+00:00", "carrier": { "code": "USPS", "tracking_number": "9400110200828911663274" }, "skus": [ "6220" ] }
    order:shipment:delivered "data": { "shop_id": 815256, "delivered_at": "2017-04-18 13:24:28+00:00", "carrier": { "code": "USPS", "tracking_number": "9400110200828911663274" }, "skus": [ "6220" ] }
    order:sent-to-production No resource data is sent with this event.

    Webhooks

    You can use webhook subscriptions to receive notifications about particular events in a shop. After you've subscribed to a webhook, you can let your app execute code immediately after specific events occur in shops that have your app connected, instead of having to make API calls periodically to check their status. For example, you can rely on webhooks to trigger an action in your app when a merchant creates a new product in a store. By using webhooks subscriptions you can make fewer API calls overall, which makes sure that your apps are more efficient and update quickly. For more information what actually gets sent by a webhook check Event properties and Resource data examples.

    On this page:

    What you can do with the Webhooks resource

    The Printify Public API lets you do the following with the Webhook resource:

    Webhook properties

    id READ-ONLY "id": "5cb87a8cd490a2ccb256cec4" A unique string identifier for the webhook. Each id is unique across the Printify system.
    topic REQUIRED READ-ONLY "topic": "product:publish:started" Event that triggers the webhook. See Events for reference. Can't be changed.
    url REQUIRED "url": "https://example.com/webhook" URI where the webhook subscription should send the POST request when the event occurs.
    shop_id READ-ONLY "shop_id": 1 Id of merchant's store.
    secret OPTIONAL "secret": "optional-secret-value" Secret that will be used to sign requests for webhook. See Securing your webhooks for more information.

    Webhook endpoints

    Retrieve a list of webhooks

    GET /v1/shops/{shop_id}/webhooks.json
    Retrieve a list of webhooks
    GET /v1/shops/{shop_id}/webhooks.json
    View Response

    Retrieve a single webhook

    GET /v1/shops/{shop_id}/webhooks/{webhook_id}.json
    Retrieve a single webhook
    GET /v1/shops/{shop_id}/webhooks/{webhook_id}.json
    View Response

    Create a new webhook

    POST /v1/shops/{shop_id}/webhooks.json
    Create a new webhook
    POST /v1/shops/{shop_id}/webhooks.json
    { "topic": "order:created", "url": "https://example.com/webhooks/order/created" } View Response

    Modify a webhook

    PUT /v1/shops/{shop_id}/webhooks/{webhook_id}.json
    Modify a webhook
    PUT /v1/shops/{shop_id}/webhooks/{webhook_id}.json
    { "url": "https://example.com/callback/order/created" } View Response

    Delete a webhook

    DELETE /v1/shops/{shop_id}/webhooks/{webhook_id}.json
    Delete a webhook
    DELETE /v1/shops/{shop_id}/webhooks/{webhook_id}.json
    View Response

    Securing your Webhooks

    Once your server is configured to receive payloads, it'll listen for any payload sent to the endpoint you configured. For security reasons, you probably want to limit requests to those coming from Printify.

    There are a few ways to go about this - for example, you could opt to whitelist requests from Printify's IP address - but a far easier method is to set up a secret token and validate the information.

    Summary:

    Setting your shared secret with Printify

    You can generate the secret by running 'openssl rand -hex 20'.

    When your secret token is set, Printify will use it to create a hash signature with each payload body. Printify uses an HMAC hexdigest to compute the hash sha256 signature with your provided secret.

    Secret example 7afa37fd47d7a52ea644382e04962a83c16aef62

    This payload body signature is passed along with each request in the headers as X-Pfy-Signature. The signature format is: sha256={digest}.

    Signature example x-pfy-signature: sha256=4260d30ec4ee2a17181ae5072c846d8dfcb5ceb195e24de055fd9a21d8c6648f

    Accessing the Secret from your backend

    Next, set up a SECRET_TOKEN environment variable on your server that stores this token. Never hardcode the secret into your app!

    Setting the SECRET_TOKEN environment variable example $ export SECRET_TOKEN=your_token

    Validating payloads from Printify

    Next, compute a request body hash using your SECRET_TOKEN, and ensure that the hash from Printify matches. Printify uses an HMAC hexdigest to compute the hash. Always use "constant time" string comparisons, which renders it safe from certain timing attacks against regular equality operators.

    Validation sample (python) import os import hmac def sha256hash(request): hash = hmac.new(os.environ['SECRET_TOKEN'].encode('utf-8'), request.data.encode('utf-8'), 'sha256') return 'sha256=' + hash.hexdigest() def secure_compare(a, b): return hmac.compare_digest(a, b) print('%r' % secure_compare(request.headers['x-pfy-signature'], sha256hash(request)))

    HTTP Status Codes

    Printify API relies heavily on standard HTTP response codes codes. Please find the brief summary of status codes used below.

    Success

    Code Name Description
    200 OK Request completed successfully.
    201 Created The request has been fulfilled and has resulted in one or more new resources being created.
    202 Accepted The request has been accepted for processing, but the processing has not been completed.
    204 No Content Indicates that the server has successfully fulfilled the request and that there is no content to send in the response payload body.

    User error codes

    These errors generally indicate a problem on the client side. If you are getting one of these, check your code and the request details.

    Code Name Description
    400 Bad Request The request encoding is invalid; the request can't be parsed as a valid JSON.
    401 Unauthorized Accessing a protected resource without authorization or with invalid credentials.
    402 Payment Required The account associated with the API key making requests hits a quota that can be increased by upgrading the Printify API account plan.
    403 Forbidden Accessing a protected resource with API credentials that don't have access to that resource.
    404 Not Found Route or resource is not found. This error is returned when the request hits an undefined route, or if the resource doesn't exist (e.g. has been deleted).
    413 Request Entity Too Large The request exceeded the maximum allowed payload size. You shouldn't encounter this under normal use.
    422 Invalid Request The request data is invalid. This includes most of the base-specific validations. You will receive a detailed error message and code pointing to the exact issue.
    429 Too Many Requests Too Many Requests response status code indicates you have sent too many requests in a given amount of time ("rate limiting").

    Server error codes

    These errors generally represent an error on our side. In the event of a 5xx error code, detailed information about the error will be automatically recorded, and Printify's developers will be notified.

    Code Name Description
    500 Internal Server Error The server encountered an unexpected condition.
    502 Bad Gateway Printify's servers are restarting or an unexpected outage is in progress. You should generally not receive this error, and requests are safe to retry.
    503 Service Unavailable The server could not process your request in time. The server could be temporarily unavailable, or it could have timed out processing your request. You should retry the request with backoffs.

    History