Download OpenAPI specification:Download
How to use new endpoints? Create or use an already created private token for authorization. Unless it's stated otherwise, the v2 version of Printful API may be used like the v1 version. All v2 endpoints use /v2 prefix and the specifics of each endpoint are explained in a dedicated section.
Test and provide feedback: Explore the new features, experiment with the enhancements, and share your feedback through our dedicated feedback form.
Printful implements rate limiting to ensure the stability of the API while keeping it fair for all users. Rate limiting is handled differently depending on the version and endpoint being used.
Printful uses the following header values to communicate rate limits:
X-Ratelimit-Limit
X-Ratelimit-Remaining
X-Ratelimit-Reset
X-Ratelimit-Policy
However, the meaning of these values changes depending on the algorithm used.
V1 used a very simple rate limiting mechanism, you had a limit of 120, every request would reduce that limit by 1, if it hits 0 you would receive a 429 error, every minute the limit of 120 would be restored. See: V1 Rate Limits.
This system is good, because it's easy to understand for most users. However, we found it had a number of disadvantages both for users and for Printful.
In V2 of the API Printful implements a Leaky Bucket rate limiting algorithm.
Note: The algorithm does not implement any queuing mechanisms in its current form so it can also be described as a Token Bucket algorithm.
Like with the old rate limiting algorithm, when you make a request to the API,
the X-Ratelimit-Remaining
header value will go down by one. However, the X-Ratelimit-Reset
does not work the same, it states how long it will take to "refill the bucket".
The bucket will be refilled one drop at a time instead of all at once, so the
X-Ratelimit-Reset
will be much smaller after the first request.
By default, after the first request the headers will look like this:
X-Ratelimit-Policy: 120;w=60;
X-Ratelimit-Limit: 120
X-Ratelimit-Remaining: 119
X-Ratelimit-Reset: 0.5
This means 120 requests can be made in a single burst, one request has already
been made and X-Ratelimit-Remaining
will reach 120 again in 0.5 seconds. The
X-Ratelimit-Policy
header indicates that in a window of 60 seconds 120 tokens
(or "quota units") will be added to the bucket.
The headers are inspired by the format in RateLimit header fields for HTTP Internet-Draft.
All endpoints are rate-limited with the leaky bucket rate limiter and the defaults. However, it is planned for future endpoints to have higher or lower limits depending on usage and the capacity of the API.
There are a number of strategies you can use to take advantage of rate limiting.
retry-after
header to check when the next
request can be made, then schedule a request to trigger at that time.X-Ratelimit-Policy
120 ÷ 60 = 0.5, so the queue should send requests out at a
rate of once every 500 milliseconds. X-Ratelimit-Reset
time has been met.Some of the resources returned by the API are translated into several languages. By default, they are returned in English in the API responses.
If you want to get a response with texts in another language, you can use the X-PF-Language
HTTP header. Its value should be the long version of the locale to use (e.g. es_ES
for Spanish).
Possible localisation parameters:
Product details (GET https://api.printful.com/products/71
) response with default locale (en_US
):
{
"code": 200,
"result": {
"product": {
"type_name": "T-Shirt",
"title": "Unisex Staple T-Shirt | Bella + Canvas 3001",
...
}
}
}
Product details response with Spanish locale (X-PF-Language: es_ES
):
{
"code": 200,
"result": {
"product": {
...
"type_name": "Camiseta",
"title": "Camiseta esencial unisex | Bella + Canvas 3001",
...
}
}
}
This endpoint will retrieve all OAuth scopes associated with the used token
required | Array of objects (OAuthScope) |
required | object HATEOAS links |
{- "data": [
- {
- "name": "View all orders",
- "value": "orders/read"
}
],
}
A catalog product refers to a blank product and its variants. Each variant can be used as the base for custom designs. Catalog product consists of multiple catalog variants each of which might be a combination of size and color or it might be a variation with e.g. tear away label. The entire hierarchy is shown in the diagram below:
Catalog variant might be a combination of size and color associated with the catalog product or additional variation of a product with certain features like tear away label. It can be thought of as an actual physical blank product. For example T-shirt Bella Canvas 3001 in White color and size M is considered to be a single variant. Catalog variants can have different availability as different regions could have different stock of some product colors and sizes.
Printful has a substantial catalog of blank Products and Variants. A Product can describe a specific type, model and manufacturer of the item, while the Variant specifies the more detailed attributes of the product like the exact size/color of a T-shirt or the dimensions of a poster. Moreover, each item in the Printful Catalog has a unique Variant ID. When managing Sync Products or orders, you will need to specify the Variant ID of the specific blank item, hence you can use this API resource to find the needed Variant ID.
You can also use this API resource to find out the types of print files. A product can be configured for as well as the additional price each print file would cost (e.g. the back print or inside label print for T-shirts). Moreover, some product types allow for additional options (e.g. embroidery type and thread colors) – these options are listed in the responses as well.
Important: Jewelry products are not supported via API.
Rate limiting: Up to 120 requests per 60 seconds. A 60 seconds lockout is applied if request count is exceeded.
This resource contains the list of all the products that are available in Printful for purchase and fulfillment. Apart from basic product data and availability it also contains the information about:
Filters can be used to search for particular set of products based on the provided values. Multiple filters can be used at the same time.
Filtering option name | Description | Where to find |
---|---|---|
colors | Filters products by variants containing specified colors | data[].color Catalog variants |
new | Filters products that are new | - |
placements | Filters products by available placements specified in the list | data[].placements[].placement Catalog products |
category_ids | Filters products by specified product categories | data[].id Catalog categories |
techniques | Filters products by specified techniques | data[].techniques[].key Catalog products |
types | Filters products by specified types of product e.g. T-Shirt. | data[].type Catalog products |
bestseller | Filters products that are bestsellers | - |
Requires providing two parameters in the URL: sort_type
And sort_direction
. Sort type determines a type of sorting that will be used e.g. sort by price and the sort direction determines if the result should be sorted ascending or descending.
Only one sort type can be used at a time.
Sorting option name | Description |
---|---|
new | Sorts resulting catalog products starting with new ones |
rating | Sorts resulting catalog products by their user-rating |
price | Sorts resulting catalog products by their base price |
bestseller | Sorts resulting catalog products starting with bestsellers |
Region name | Region name value |
---|---|
Worldwide | worldwide |
North America | north_america |
Canada | canada |
Europe | europe |
Spain | spain |
Latvia | latvia |
United Kingdom | uk |
France | france |
Germany | germany |
Australia | australia |
Japan | japan |
New Zealand | new_zealand |
Italy | italy |
Brazil | brazil |
Southeast Asia | southeast_asia |
Republic of Korea | republic_of_korea |
English speaking regions | english_speaking_regions |
Get Product Size Guide endpoint will return size guides for the specified product.
There are three types of size tables available, as described by the following table:
Table type | API name | Description |
---|---|---|
Measure yourself | measure_yourself |
Measurements of the product to measure the body provided by the supplier. |
Product measurements | product_measure |
Measurements of the product provided by the supplier. |
International size conversion | international |
International size conversion – e.g. US, EU or UK sizes corresponding to the product sizes. |
Not each table type might be available for the selected product.
Catalog categories are used to group products with similar characteristics such as t-shirts, hats etc.
Categories have purely informational purposes and cannot be edited by the customers. Categories can be nested e.g.
Apart from display purposes they can be also used for filtering the products in the API see Filtering options
This endpoint retrieves a list of the products available in Printful's catalog. The list is paginated and can be filtered using various filters. The information returned includes details on how each product can be designed, such as the available placements, techniques, and additional options.
For a visual representation of the design data, please see the following diagram:
category_ids | Array of integers Examples:
One or more category IDs to return only products in those categories. The IDs can be found in the response of the operation Get Categories. |
colors | Array of strings Examples:
One or more color names to return only products with variants of one the those colors. |
limit | integer [ 1 .. 100 ] Default: 20 The number of results to return per page. |
new | boolean Default: false Examples:
If true only new Products will be returned. |
offset | integer >= 0 Default: 0 Examples:
The number of results to not include in the response starting from the beginning of the list. This can be used to return results after the initial 100. For example, sending offset 100 |
placements | Array of strings Examples:
One or more identifiers of a placement to return only products with variants that have that placement. The complete list of placements can be found here. |
selling_region_name | string Default: "worldwide" Enum: "worldwide" "north_america" "canada" "europe" "spain" "latvia" "uk" "france" "germany" "australia" "japan" "new_zealand" "italy" "brazil" "southeast_asia" "republic_of_korea" "english_speaking_regions" "all" Only returns the products that can be sold in the specified region. If is set to 'all' returns each region availability for specified product. |
sort_direction | string Default: "descending" Enum: "ascending" "descending" This parameter only is used if sort_type is also present and it changes the order of the returned products.
The exact meaning varies depending on the value of
|
sort_type | string Enum: "new" "rating" "price" "bestseller" The sorting strategy to use when sorting the result. When it's not present, no specific order is guaranteed. |
techniques | Array of strings (TechniqueEnum) Items Enum: "dtg" "digital" "cut-sew" "uv" "embroidery" "sublimation" "dtfilm" Examples:
One or more techniques to return only products with variants that can be printed using one of the techniques. |
X-PF-Language | string Use this to specify which locale you would like to use in the responses, for some endpoints this can affect translations. |
required | Array of objects (Product) |
required | object (Paging) Paging information |
required | object (Product links) HATEOAS links |
{- "data": [
- {
- "id": 362,
- "main_category_id": 24,
- "type": "T-Shirt",
- "name": "Unisex Organic T-Shirt | Econscious EC1000",
- "brand": "Econscious",
- "model": "Unisex Organic T-Shirt",
- "variant_count": 10,
- "is_discontinued": false,
- "description": "string",
- "sizes": [
- "M"
], - "colors": [
- {
- "name": "Athletic Heather",
- "value": "#cbcbcb"
}
], - "techniques": [
- {
- "key": "embroidery",
- "display_name": "Embroidery",
- "is_default": true
}
], - "placements": [
- {
- "placement": "back",
- "technique": "embroidery",
- "print_area_width": 1600,
- "print_area_height": 2000,
- "layers": [
- {
- "type": "file",
- "layer_options": [
- {
- "name": "3d_puff",
- "techniques": [
- "embroidery"
], - "type": "boolean",
- "values": [
- true,
- false
]
}
]
}
], - "placement_options": [
- {
- "name": "unlimited_color",
- "techniques": [
- "embroidery"
], - "type": "boolean",
- "values": [
- true,
- false
]
}
], - "conflicting_placements": [
- "back",
- "label_inside"
]
}
], - "product_options": [
- {
- "name": "stitch_color",
- "techniques": [
- "cut-sew"
], - "type": "string",
- "values": [
- "White",
- "Black"
]
}
], - "_links": {
}
}
], - "paging": {
- "total": 100,
- "offset": 10,
- "limit": 100
}, - "_links": {
}
}
Returns information about a single specified catalog product. See catalog product
id required | integer Product ID. |
selling_region_name | string Default: "worldwide" Enum: "worldwide" "north_america" "canada" "europe" "spain" "latvia" "uk" "france" "germany" "australia" "japan" "new_zealand" "italy" "brazil" "southeast_asia" "republic_of_korea" "english_speaking_regions" "all" Only returns the products that can be sold in the specified region. If is set to 'all' returns each region availability for specified product. |
X-PF-Language | string Use this to specify which locale you would like to use in the responses, for some endpoints this can affect translations. |
required | object (Product) Information about the Catalog Product |
{- "data": {
- "id": 362,
- "main_category_id": 24,
- "type": "T-Shirt",
- "name": "Unisex Organic T-Shirt | Econscious EC1000",
- "brand": "Econscious",
- "model": "Unisex Organic T-Shirt",
- "variant_count": 10,
- "is_discontinued": false,
- "description": "string",
- "sizes": [
- "M"
], - "colors": [
- {
- "name": "Athletic Heather",
- "value": "#cbcbcb"
}
], - "techniques": [
- {
- "key": "embroidery",
- "display_name": "Embroidery",
- "is_default": true
}
], - "placements": [
- {
- "placement": "back",
- "technique": "embroidery",
- "print_area_width": 1600,
- "print_area_height": 2000,
- "layers": [
- {
- "type": "file",
- "layer_options": [
- {
- "name": "3d_puff",
- "techniques": [
- "embroidery"
], - "type": "boolean",
- "values": [
- true,
- false
]
}
]
}
], - "placement_options": [
- {
- "name": "unlimited_color",
- "techniques": [
- "embroidery"
], - "type": "boolean",
- "values": [
- true,
- false
]
}
], - "conflicting_placements": [
- "back",
- "label_inside"
]
}
], - "product_options": [
- {
- "name": "stitch_color",
- "techniques": [
- "cut-sew"
], - "type": "string",
- "values": [
- "White",
- "Black"
]
}
], - "_links": {
}
}
}
Returns information about single specified catalog variant. See catalog variant
id required | integer Variant ID |
X-PF-Language | string Use this to specify which locale you would like to use in the responses, for some endpoints this can affect translations. |
required | object (Variant) |
required | object HATEOAS links |
{- "data": {
- "id": 100,
- "catalog_product_id": 12,
- "name": "Gildan 64000 Unisex Softstyle T-Shirt with Tear Away (Black / 2XL)",
- "size": "2XL",
- "color": "Black",
- "color_code": "#14191e",
- "color_code2": "string",
- "_links": {
}
}, - "_links": {
}
}
Returns information about all catalog variants associated with the specified catalog product. See catalog variant
id required | integer Product ID. |
X-PF-Language | string Use this to specify which locale you would like to use in the responses, for some endpoints this can affect translations. |
required | Array of objects (Variant) |
required | object (Paging) Paging information |
required | object HATEOAS links |
{- "data": [
- {
- "id": 100,
- "catalog_product_id": 12,
- "name": "Gildan 64000 Unisex Softstyle T-Shirt with Tear Away (Black / 2XL)",
- "size": "2XL",
- "color": "Black",
- "color_code": "#14191e",
- "color_code2": "string",
- "_links": {
}
}
], - "paging": {
- "total": 100,
- "offset": 10,
- "limit": 100
}, - "_links": {
- "self": {
}, - "next": {
}, - "previous": {
}, - "last": {
},
}
}
Returns list of all categories that are present in the catalog. The categories specify the type of the product that is associated with it. For example, the category "Men’s T-shirts" indicates that the product is a subgroup of T-shirts specifically targeted at Men. Categories can be used to filter the product list by specific tags See categories_ids
required | Array of objects (Category) |
required | object HATEOAS links |
{- "data": [
- {
- "id": 24,
- "parent_id": 6,
- "title": "T-Shirts",
}
], - "_links": {
}
}
Returns information about a specific catalog category. The categories specify the type of the product that is associated with it. For example, the category "Men’s T-shirts" indicates that the product is a subgroup of T-shirts specifically targeted at Men. Categories can be used to filter the product list by specific tags See categories_ids
id required | integer Category ID |
required | object (Category) Information about the Category |
required | object HATEOAS links |
{- "data": {
- "id": 24,
- "parent_id": 6,
- "title": "T-Shirts",
},
}
To retrieve information about a particular products categories, use this feature. It returns details about the catalog categories associated with the catalog product. Categories help identify the type of product associated with them. For instance, the category "Men's T-shirts" denotes that the product is a subgroup of T-shirts intended for men.
id required | integer Product ID. |
selling_region_name | string Default: "worldwide" Enum: "worldwide" "north_america" "canada" "europe" "spain" "latvia" "uk" "france" "germany" "australia" "japan" "new_zealand" "italy" "brazil" "southeast_asia" "republic_of_korea" "english_speaking_regions" "all" Only returns the products that can be sold in the specified region. If is set to 'all' returns each region availability for specified product. |
required | Array of objects (Category) |
required | object (Paging) Paging information |
required | object HATEOAS links |
{- "data": [
- {
- "id": 24,
- "parent_id": 6,
- "title": "T-Shirts",
}
], - "paging": {
- "total": 100,
- "offset": 10,
- "limit": 100
}, - "_links": {
- "previous": {
},
}
}
Returns information about the size guide for a specific product.
id required | integer Product ID. |
unit | string Example: unit=inches,cm A comma-separated list of measurement unit in which size tables are to be returned ( |
X-PF-Language | string Use this to specify which locale you would like to use in the responses, for some endpoints this can affect translations. |
required | object (ProductSizeGuide) Size Guide information for the Product |
required | object HATEOAS links |
{- "data": {
- "catalog_product_id": 13,
- "available_sizes": [
- "S",
- "M",
- "L"
], - "size_tables": [
- {
- "type": "measure_yourself",
- "unit": "inches",
- "description": "<p>Measurements are provided by suppliers.<br /><br />US customers should order a size up as the EU sizes for this supplier correspond to a smaller size in the US market.</p>\\n<p>Product measurements may vary by up to 2\\\" (5 cm). </p>",
- "image_description": "<h6><strong>A Length</strong></h6>\\n<p dir=\\\"ltr\\\"><span id=\\\"docs-internal-guid-a3ac3082-7fff-5f98-2623-3eb38d5f43a1\\\">Place the end of the tape beside the collar at the top of the tee (Highest Point Shoulder). Pull the tape measure t</span><span id=\\\"docs-internal-guid-a3ac3082-7fff-5f98-2623-3eb38d5f43a1\\\">o the bottom of the shirt.</span></p>\\n<h6>B Chest</h6>\\n<p dir=\\\"ltr\\\">Measure yourself around the fullest part of your chest. Keep the tape measure horizontal.</p>",
- "measurements": [
- {
- "type_label": "Length",
- "values": [
- {
- "size": "S",
- "value": "24"
}, - {
- "size": "M",
- "value": "26"
}, - {
- "size": "L",
- "value": "28"
}
]
}, - {
- "type_label": "Chest",
- "values": [
- {
- "size": "S",
- "min_value": "14",
- "max_value": "16"
}, - {
- "size": "M",
- "min_value": "18",
- "max_value": "20"
}, - {
- "size": "L",
- "min_value": "22",
- "max_value": "24"
}
]
}
]
}, - {
- "type": "product_measure",
- "unit": "inches",
- "description": "<p dir=\\\"ltr\\\">Measurements are provided by our suppliers. Product measurements may vary by up to 2\\\" (5 cm).</p>\\n<p dir=\\\"ltr\\\">US customers should order a size up as the EU sizes for this supplier correspond to a smaller size in the US market.</p>\\n<p dir=\\\"ltr\\\">Pro tip! Measure one of your products at home and compare with the measurements you see in this guide.</p>",
- "image_description": "<h6><strong>A Length</strong></h6>\\n<p dir=\\\"ltr\\\"><span id=\\\"docs-internal-guid-a3ac3082-7fff-5f98-2623-3eb38d5f43a1\\\">Place the end of the tape beside the collar at the top of the tee (Highest Point Shoulder). Pull the tape measure t</span><span id=\\\"docs-internal-guid-a3ac3082-7fff-5f98-2623-3eb38d5f43a1\\\">o the bottom of the shirt.</span></p>\\n<h6>B Width</h6>\\n<p dir=\\\"ltr\\\">Place the end of the tape at the seam under the sleeve and pull the tape measure across the shirt to the seam under the opposite sleeve.</p>",
- "measurements": [
- {
- "type_label": "Length",
- "values": [
- {
- "size": "S",
- "value": "24"
}, - {
- "size": "M",
- "value": "26"
}, - {
- "size": "L",
- "value": "28"
}
]
}, - {
- "type_label": "Width",
- "values": [
- {
- "size": "S",
- "min_value": "14",
- "max_value": "16"
}, - {
- "size": "M",
- "min_value": "18",
- "max_value": "20"
}, - {
- "size": "L",
- "min_value": "22",
- "max_value": "24"
}
]
}
]
}, - {
- "type": "measure_yourself",
- "unit": "cm",
- "description": "<p>Measurements are provided by suppliers.<br /><br />US customers should order a size up as the EU sizes for this supplier correspond to a smaller size in the US market.</p>\\n<p>Product measurements may vary by up to 2\\\" (5 cm). </p>",
- "image_description": "<h6><strong>A Length</strong></h6>\\n<p dir=\\\"ltr\\\"><span id=\\\"docs-internal-guid-a3ac3082-7fff-5f98-2623-3eb38d5f43a1\\\">Place the end of the tape beside the collar at the top of the tee (Highest Point Shoulder). Pull the tape measure t</span><span id=\\\"docs-internal-guid-a3ac3082-7fff-5f98-2623-3eb38d5f43a1\\\">o the bottom of the shirt.</span></p>\\n<h6>B Chest</h6>\\n<p dir=\\\"ltr\\\">Measure yourself around the fullest part of your chest. Keep the tape measure horizontal.</p>",
- "measurements": [
- {
- "type_label": "Length",
- "values": [
- {
- "size": "S",
- "value": "60.96"
}, - {
- "size": "M",
- "value": "66.04"
}, - {
- "size": "L",
- "value": "71.12"
}
]
}, - {
- "type_label": "Chest",
- "values": [
- {
- "size": "S",
- "min_value": "35.56",
- "max_value": "40.64"
}, - {
- "size": "M",
- "min_value": "45.72",
- "max_value": "50.80"
}, - {
- "size": "L",
- "min_value": "55.88",
- "max_value": "60.96"
}
]
}
]
}, - {
- "type": "product_measure",
- "unit": "cm",
- "description": "<p dir=\\\"ltr\\\">Measurements are provided by our suppliers. Product measurements may vary by up to 2\\\" (5 cm).</p>\\n<p dir=\\\"ltr\\\">US customers should order a size up as the EU sizes for this supplier correspond to a smaller size in the US market.</p>\\n<p dir=\\\"ltr\\\">Pro tip! Measure one of your products at home and compare with the measurements you see in this guide.</p>",
- "image_description": "<h6><strong>A Length</strong></h6>\\n<p dir=\\\"ltr\\\"><span id=\\\"docs-internal-guid-a3ac3082-7fff-5f98-2623-3eb38d5f43a1\\\">Place the end of the tape beside the collar at the top of the tee (Highest Point Shoulder). Pull the tape measure t</span><span id=\\\"docs-internal-guid-a3ac3082-7fff-5f98-2623-3eb38d5f43a1\\\">o the bottom of the shirt.</span></p>\\n<h6>B Width</h6>\\n<p dir=\\\"ltr\\\">Place the end of the tape at the seam under the sleeve and pull the tape measure across the shirt to the seam under the opposite sleeve.</p>",
- "measurements": [
- {
- "type_label": "Length",
- "values": [
- {
- "size": "S",
- "value": "60.96"
}, - {
- "size": "M",
- "value": "66.04"
}, - {
- "size": "L",
- "value": "71.12"
}
]
}, - {
- "type_label": "Width",
- "values": [
- {
- "size": "S",
- "min_value": "35.56",
- "max_value": "40.64"
}, - {
- "size": "M",
- "min_value": "45.72",
- "max_value": "50.80"
}, - {
- "size": "L",
- "min_value": "55.88",
- "max_value": "60.96"
}
]
}
]
}, - {
- "type": "international",
- "unit": "none",
- "measurements": [
- {
- "type_label": "US size",
- "values": [
- {
- "size": "S",
- "min_value": "8",
- "max_value": "10"
}, - {
- "size": "M",
- "min_value": "12",
- "max_value": "14"
}, - {
- "size": "L",
- "min_value": "16",
- "max_value": "18"
}
]
}, - {
- "type_label": "EU size",
- "values": [
- {
- "size": "S",
- "min_value": "38",
- "max_value": "39"
}, - {
- "size": "M",
- "min_value": "40",
- "max_value": "41"
}, - {
- "size": "L",
- "min_value": "42",
- "max_value": "43"
}
]
}, - {
- "type_label": "UK size",
- "values": [
- {
- "size": "S",
- "min_value": "4",
- "max_value": "6"
}, - {
- "size": "M",
- "min_value": "8",
- "max_value": "10"
}, - {
- "size": "L",
- "min_value": "12",
- "max_value": "14"
}
]
}
]
}
]
}, - "_links": {
}
}
Calculates prices for specific catalog product based on selling region and specified currency. Calculations also include Store discounts. Selling region is used to specify product production currency, that is the price that the product is natively manufactured in. Different selling regions might affect the overall price amount. Currency parameter is used only to define the currency that the prices will be displayed in.
For more information on product pricing please refer to the information provided at https://www.printful.com/pricing
When developing against either API be sure to inform your customers that a placement will be included in the price of the product. If one placement is provided that placement will be included in the price, if multiple are provided the included placement will generally be the placement that comes earliest in the list of placements at `/v2/catalog-products/71` (though the discount will generally be up to the price of the first placement in that list). Certain placements come with additional service fees, such as large embroidery, this additional price will never be included even if the only placement is large embroidery.
There is a minor difference in the handling of prices for placements between V1 and V2. In V1 the price of the first placement is always null, this is because there is always a placement included in the price of each product. In V2 the price of placements is always displayed even if it is included in the price of the product because any placement can be included.
id required | integer Product ID. |
selling_region_name | string Example: selling_region_name=worldwide Specifies the region production currency that the product prices will be calculated in |
currency | string Example: currency=USD The currency (3-letter code) used to determine currency in which the prices will be displayed. The store currency will be used by default. The format is compliant with ISO 4217 standard. |
X-PF-Language | string Use this to specify which locale you would like to use in the responses, for some endpoints this can affect translations. |
required | object (ProductPrice) Product prices information |
required | object (Paging) Paging information |
required | object HATEOAS links |
{- "data": {
- "currency": "EUR",
- "product": {
- "id": 1,
- "placements": [
- {
- "id": "default",
- "title": "Print file",
- "type": "Digital printing",
- "technique_key": "digital",
- "price": "19.75",
- "discounted_price": "18.75",
- "placement_options": [
- {
- "name": "unlimited_color",
- "type": "array",
- "values": [
- true,
- false
], - "description": "Unlimited color",
- "price": {
- "false": "0.00",
- "true": "3.50"
}
}
], - "layers": [
- {
- "type": "file",
- "additional_price": "0.00",
- "layer_options": [
- {
- "name": "3d_puff",
- "type": "array",
- "values": [
- true,
- false
], - "description": "3D puff",
- "price": {
- "false": "0.00",
- "true": "1.50"
}
}
]
}
]
}
]
}, - "variants": [
- {
- "id": 1,
- "techniques": [
- {
- "technique_key": "digital",
- "technique_display_name": "Digital printing",
- "price": "9.50",
- "discounted_price": "8.50"
}
]
}
]
}, - "paging": {
- "total": 100,
- "offset": 10,
- "limit": 100
}, - "_links": {
}
}
Return pricing information from a single variant and the parent product
id required | integer Variant ID |
selling_region_name | string Example: selling_region_name=worldwide Specifies the region production currency that the product prices will be calculated in |
currency | string Example: currency=USD The currency (3-letter code) used to determine currency in which the prices will be displayed. The store currency will be used by default. The format is compliant with ISO 4217 standard. |
X-PF-Language | string Use this to specify which locale you would like to use in the responses, for some endpoints this can affect translations. |
required | object (VariantPrice) Variant prices information |
required | object HATEOAS links |
{- "data": {
- "currency": "EUR",
- "product": {
- "id": 1,
- "placements": [
- {
- "id": "default",
- "title": "Print file",
- "type": "Digital printing",
- "technique_key": "digital",
- "price": "19.75",
- "discounted_price": "18.75",
- "placement_options": [
- {
- "name": "unlimited_color",
- "type": "array",
- "values": [
- true,
- false
], - "description": "Unlimited color",
- "price": {
- "false": "0.00",
- "true": "3.50"
}
}
], - "layers": [
- {
- "type": "file",
- "additional_price": "0.00",
- "layer_options": [
- {
- "name": "3d_puff",
- "type": "array",
- "values": [
- true,
- false
], - "description": "3D puff",
- "price": {
- "false": "0.00",
- "true": "1.50"
}
}
]
}
]
}
]
}, - "variant": {
- "id": 1,
- "techniques": [
- {
- "technique_key": "digital",
- "technique_display_name": "Digital printing",
- "price": "9.50",
- "discounted_price": "8.50"
}
]
}
}, - "_links": {
}
}
This feature helps to fetch blank images for a catalog product. These blank images are always white and semi-transparent and can be colored by the user on the client-side as per the specified color in the data.images.background_color
field. For some mockups the data.images.background_image
could apply. The endpoint allows filtering of the result based on the type of the mockup, the placement, and the color of the product.
id required | integer Product ID. |
mockup_style_ids | integer Example: mockup_style_ids=1, 2, 3 Used to specify style of images For example:
|
colors | string Example: colors=black,red String values separated by comma. You can specify multiple variant colors filters. |
placement | string Example: placement=front Filters result by specified placement |
X-PF-Language | string Use this to specify which locale you would like to use in the responses, for some endpoints this can affect translations. |
required | Array of objects (VariantImages) |
required | object (Paging) Paging information |
required | object HATEOAS links |
{- "data": [
- {
- "catalog_variant_id": 4017,
- "color": "Turquoise",
- "primary_hex_color": "#15d0d2",
- "secondary_hex_color": null,
- "images": [
- {
- "placement": "front",
- "background_color": "#0f0f0f",
}
]
}
], - "paging": {
- "total": 100,
- "offset": 10,
- "limit": 100
}, - "_links": {
}
}
Returns images for a specified Variant.
id required | integer Variant ID |
mockup_style_ids | integer Example: mockup_style_ids=1, 2, 3 Used to specify style of images For example:
|
placement | string Example: placement=front Filters result by specified placement |
X-PF-Language | string Use this to specify which locale you would like to use in the responses, for some endpoints this can affect translations. |
required | Array of objects (VariantImages) |
required | object HATEOAS links |
{- "data": [
- {
- "catalog_variant_id": 4017,
- "color": "Turquoise",
- "primary_hex_color": "#15d0d2",
- "secondary_hex_color": null,
- "images": [
- {
- "placement": "front",
- "background_color": "#0f0f0f",
}
]
}
], - "_links": {
}
}
Returns information about available mockup styles for specified catalog product.
id required | integer Product ID. |
placements | Array of strings Examples:
One or more placement idenitifiers used to filter in mockup styles that match a given placement. The complete list of placements can be found here. |
selling_region_name | string Default: "worldwide" Enum: "worldwide" "north_america" "canada" "europe" "spain" "latvia" "uk" "france" "germany" "australia" "japan" "new_zealand" "italy" "brazil" "southeast_asia" "republic_of_korea" "english_speaking_regions" "all" Only returns the products that can be sold in the specified region. If is set to 'all' returns each region availability for specified product. |
offset | integer Result set offset |
limit | integer Number of items per page (max 100) |
X-PF-Language | string Use this to specify which locale you would like to use in the responses, for some endpoints this can affect translations. |
required | Array of objects (MockupStyles) |
required | object (Paging) Paging information |
required | object HATEOAS links |
{- "data": [
- {
- "placement": "front",
- "display_name": "Front print",
- "technique": "dtg",
- "print_area_width": 5,
- "print_area_height": 5,
- "print_area_type": "simple",
- "dpi": 150,
- "mockup_styles": [
- {
- "id": 1,
- "category_name": "Couple's",
- "view_name": "Front",
- "restricted_to_variants": [
- 4,
- 15032,
- 10750
]
}
]
}
], - "paging": {
- "total": 100,
- "offset": 10,
- "limit": 100
}, - "_links": {
- "self": {
}, - "next": {
}, - "previous": {
}, - "last": {
},
}
}
Returns positional data for specified catalog product mockups. The data from this endpoint could be used
to generate your own mockups without the need to use Printful's mockup generator.
id required | integer Product ID. |
placements | Array of strings Examples:
One or more identifiers of a placement to return only products with variants that have that placement. The complete list of placements can be found here. |
selling_region_name | string Default: "worldwide" Enum: "worldwide" "north_america" "canada" "europe" "spain" "latvia" "uk" "france" "germany" "australia" "japan" "new_zealand" "italy" "brazil" "southeast_asia" "republic_of_korea" "english_speaking_regions" "all" Only returns the products that can be sold in the specified region. If is set to 'all' returns each region availability for specified product. |
limit | integer [ 1 .. 100 ] Default: 20 The number of results to return per page. |
offset | integer >= 0 Default: 0 Examples:
The number of results to not include in the response starting from the beginning of the list. This can be used to return results after the initial 100. For example, sending offset 100 |
X-PF-Language | string Use this to specify which locale you would like to use in the responses, for some endpoints this can affect translations. |
required | Array of objects (MockupTemplates) |
object (Paging) Paging information | |
required | object HATEOAS links |
{- "data": [
- {
- "catalog_variant_ids": [
- 4011
], - "placement": "front",
- "technique": "dtg",
- "background_url": null,
- "background_color": null,
- "template_width": 560,
- "template_height": 295,
- "print_area_width": 520,
- "print_area_height": 202,
- "print_area_top": 18,
- "print_area_left": 20,
- "template_positioning": "overlay",
- "orientation": "any"
}
], - "paging": {
- "total": 100,
- "offset": 10,
- "limit": 100
}, - "_links": {
- "self": {
}, - "next": {
}, - "previous": {
}, - "last": {
},
}
}
Provides information about the catalog product stock status. Stock availability is grouped by variants → techniques → selling regions.
id required | integer Product ID. |
techniques | Array of strings (TechniqueEnum) Items Enum: "dtg" "digital" "cut-sew" "uv" "embroidery" "sublimation" "dtfilm" Examples:
One or more techniques to return only products with variants that can be printed using one of the techniques. |
selling_region_name | string Default: "worldwide" Enum: "worldwide" "north_america" "canada" "europe" "spain" "latvia" "uk" "france" "germany" "australia" "japan" "new_zealand" "italy" "brazil" "southeast_asia" "republic_of_korea" "english_speaking_regions" "all" Only returns the products that can be sold in the specified region. If is set to 'all' returns each region availability for specified product. |
limit | integer [ 1 .. 100 ] Default: 20 The number of results to return per page. |
offset | integer >= 0 Default: 0 Examples:
The number of results to not include in the response starting from the beginning of the list. This can be used to return results after the initial 100. For example, sending offset 100 |
X-PF-Language | string Use this to specify which locale you would like to use in the responses, for some endpoints this can affect translations. |
required | Array of objects (VariantStockAvailability) |
required | object (Paging) Paging information |
required | Array of objects (FilterSettings) The list of the filters that were used in the request |
required | object HATEOAS links |
{- "data": [
- {
- "catalog_variant_id": 4011,
- "techniques": [
- {
- "technique": "dtg",
- "selling_regions": [
- {
- "name": "worldwide",
- "availability": "in stock",
- "placement_option_availability": [
- {
- "name": "unlimited_color",
- "availability": true
}
]
}
]
}
],
}
], - "paging": {
- "total": 100,
- "offset": 10,
- "limit": 100
}, - "filter_settings": [
- {
- "name": "selling_region_name",
- "value": "worldwide"
}
], - "_links": {
- "previous": {
}, - "last": {
},
}
}
Provides information about the catalog variant stock status. Stock availability is grouped by variants → techniques → selling regions.
id required | integer Variant ID |
techniques | Array of strings (TechniqueEnum) Items Enum: "dtg" "digital" "cut-sew" "uv" "embroidery" "sublimation" "dtfilm" Examples:
One or more techniques to return only products with variants that can be printed using one of the techniques. |
selling_region_name | string Default: "worldwide" Enum: "worldwide" "north_america" "canada" "europe" "spain" "latvia" "uk" "france" "germany" "australia" "japan" "new_zealand" "italy" "brazil" "southeast_asia" "republic_of_korea" "english_speaking_regions" "all" Only returns the products that can be sold in the specified region. If is set to 'all' returns each region availability for specified product. |
X-PF-Language | string Use this to specify which locale you would like to use in the responses, for some endpoints this can affect translations. |
required | object (VariantStockAvailability) Stock availability data for a specific catalog variant |
required | Array of objects (FilterSettings) The list of the filters that were used in the request |
required | object HATEOAS links |
{- "data": {
- "catalog_variant_id": 4011,
- "techniques": [
- {
- "technique": "dtg",
- "selling_regions": [
- {
- "name": "worldwide",
- "availability": "in stock",
- "placement_option_availability": [
- {
- "name": "unlimited_color",
- "availability": true
}
]
}
]
}
],
}, - "filter_settings": [
- {
- "name": "selling_region_name",
- "value": "worldwide"
}
], - "_links": {
}
}
You can create a draft order without order items but you won’t be able to confirm it until at least one order item are added to that order. With this approach, you can create a draft order with all necessary recipient data and add items to it as you go (similar to a shopping cart) by using Create Order Item. After every order item addition, the order cost will be re-calculated.
A minimal DRAFT order can be created with just the address:
POST https://api.printful.com/v2/orders
Authorization: Bearer {{bearer_token}}
{
"recipient": {
"address1": "19749 Dearborn St",
"city": "Chatsworth",
"state_code": "CA",
"state_name": "California",
"country_code": "US",
"country_name": "United States",
"zip": "91311"
}
}
After the order is created the order items can be added one by one.
POST https://api.printful.com/v2/orders/{{order_id}}/order-items
Authorization: Bearer {{bearer_token}}
{
"catalog_variant_id": 4011,
"source": "catalog",
"quantity": 1,
"placements": [
{
"placement": "front",
"technique": "dtg",
"layers": [
{
"type": "file",
"url": "https://www.printful.com/static/images/layout/printful-logo.png"
}
]
}
]
}
It is also possible to create an order with all order items in a single request.
POST https://api.printful.com/v2/orders
Authorization: Bearer {{bearer_token}}
{
"recipient": {
"address1": "19749 Dearborn St",
"city": "Chatsworth",
"state_code": "CA",
"state_name": "California",
"country_code": "US",
"country_name": "United States",
"zip": "91311"
},
"order_items": [
{
"catalog_variant_id": 4011,
"source": "catalog",
"quantity": 1,
"placements": [
{
"placement": "front",
"technique": "dtg",
"layers": [
{
"type": "file",
"url": "https://www.printful.com/static/images/layout/printful-logo.png"
}
]
}
]
}
]
}
draft | At this stage, the order has been created but has not yet been submitted for fulfillment. It can be freely edited, changed, or deleted at this stage. The order will not charged or fulfilled until it has been confirmed. |
pending | The order has been submitted for fulfillment and it will be charged in this stage, but is not yet accepted for fulfillment. The order can be cancelled at this stage so long as it has not been charged yet. |
failed | Order was submitted for fulfillment but it had some errors preventing it from being fulfilled (problem with the address, missing printfiles, failed to charge the wallet, etc.). |
canceled | The order has been canceled and can no longer be processed. If the order was already charged then the cost of the order will be returned to your store. |
inprocess | The order is being fulfilled and can no longer be canceled or modified. Contact customer support if there are any issues with the order at this point. |
onhold | The order has encountered a problem during the fulfillment that needs to be resolved together with Printful customer service before fulfillment can continue. |
partial | The order is partially fulfilled (some items are shipped already, the rest will follow). |
fulfilled | All items have been shipped successfully. |
You are only charged for orders when they have been confirmed with the “Confirm Order” operation and have the status “pending” Confirm Order. If the order encounters a problem after it has been confirmed, then it is moved to the failed state so that the problem can be fixed and the order can be resubmitted.
For order status updates please subscribe to one of the webhook events following webhook events:
Order items are representations of the actual products that will come with an order.
In the sections below we explain each order item source and provide examples of how a simple request might look like for each source.
Catalog products are blank products available in Printful. Since they are blank you’ll need to specify design data during the order creation. This flow is intended if you allow your customers to specify their own designs which means that every order is unique.
To sell pre-defined products (Sync products) refer to Sync variant.
The following example request shows how an item structure might look in JSON.
POST https://api.printful.com/v2/orders/{{order_id}}/order-items
Authorization: Bearer {{bearer_token}}
{
"catalog_variant_id": 4012,
"source": "catalog",
"quantity": 1,
"placements": [
{
"placement": "front",
"technique": "dtg",
"layers": [
{
"type": "file",
"url": "https://www.printful.com/static/images/layout/printful-logo.png"
}
]
}
]
}
In contrast to the catalog source, the sync source uses sync variants which already hold information about design and retail costs. More information about the sync variants can be found at Sync V2.
This means that you don’t need to specify all of the data that would otherwise
be required when using the catalog source.
To order a sync variant you just need to specify the sync_variant_id
, quantity
and source properties.
POST https://api.printful.com/v2/orders/{{order_id}}/order-items
Authorization: Bearer {{bearer_token}}
{
"source": "sync",
"sync_variant_id": {{sync_variant_id}},
"quantity": 1
}
Design data is the information used to customize the product. A design consists
of placements, layers and unique product options. Placements refer to where a
design will be printed, for example, a T-Shirt might have the placements front
and left_sleeve
. Placements can also constrict what techniques can be used in
that area of the product, for example a product might have both front
and
embroidery_front
and embroidery can only be used in the second placement.
A layer is constrained to the print area of the placement that you’ve chosen.
A design that is outside of the print area won’t be visible.
Depending on the product, placement, and technique different layers might be available.
You can check which layers are available using the Retrieve a single catalog product operation.
The design data structure is the same regardless of the flow (making orders, creating sync products etc.). So the solution can be re-used in the different endpoints.
The product placement is the part of the product where design layers will be printed, different placements will also offer different options and techniques, they will also have different limitations. The available placement list will vary depending on the product. To get the available placements of a product use the Retrieve a single catalog product endpoint with the product ID that you want to check.
Layers are what is printed in each placement, and there can be up to 5 of them per one placement. The layers are printed on top of each other with the 0th layer being the furthest back and the 4th element being on top of all other layers.
API supports only one layer type - file
.
Layers are defined as an array per placement:
...
"layers": [
{
"type": "file",
"url": "https://picsum.photos/200",
"layer_options": [
{
"name": "thread_colors",
"value": [
"#FFFFFF"
]
}
],
"position": {
"width": 640,
"height": 640,
"left": 0,
"top": 0
}
}
]
...
You can specify the image position inside the print area by providing a position object.
Each print area has specific dimensions, by default our system will assume that your file has to fit into those limitations and not exceed them. The (0,0) point is always located in the top left corner of the print area.
Position | Mockup | Payload |
Top left | ![]() |
|
Top middle | ![]() |
|
Top right | ![]() |
|
Middle | ![]() |
|
Bottom left | ![]() |
|
Bottom middle | ![]() |
|
Bottom right | ![]() |
|
Apart from placement and layers you can also specify options.
# Example of option data.
{
"name": "unlimited_color",
"value": true
}
Option always consist of the name of the option and the value. Value of the option can be different depending on the option type but they are always predefined for the specified product. You can always check what options and what values are available for a specific product by checking Retrieve a single catalog product
Options can be specified on three levels:
inside_pocket
allows you to define if a product should be
fulfilled with an additional inside pocket. Or stitch_color
lets you choose the
stitch colors that will be used to stitch back All-Over print products.unlimited_color
which if specified causes the
placement to be fulfilled using Unlimited Color embroidery3d_puff
option if set to true causes that particular layer to use 3D puff embroidery.The packing slip information can be customized according to the store’s specific requirements. Some of the options are: a custom logo, the name of the store, customer service email/phone, and more.
The packing slip fields can be configured at the store level (in the Dashboard at Settings > Stores > Branding > Packing slip section.) and overridden for a specific order.
To override the packing slip settings for the order, you can use packing_slip
fields for each order.
POST https://api.printful.com/v2/orders
Authorization: Bearer {{bearer_token}}
{
"recipient": {
"address1": "19749 Dearborn St",
"city": "Chatsworth",
"state_code": "CA",
"state_name": "California",
"country_code": "US",
"zip": "91311"
},
"customization": {
"packing_slip": {
"email": "[email protected]",
"phone": "+48000000000",
"message": "this is a message",
"logo_url": "https://example.com/image.jpg",
"store_name": "a store"
}
}
}
Below you can find an example or a packing slip for a shipment with explained fields.
Field annotations:
packing_slip.logo_url
field.packing_slip.store_name
.packing_slip.phone
field.packing_slip.email
field.gift
field was provided in the order request.packing_slip.custom_order_id
field.packing_slip.message
field.The order gift option is part of the order customization and contains two properties: subject and message. This option allows users to add a custom note that will be seen by the final customer who receives the product.
POST https://api.printful.com/v2/orders
Authorization: Bearer {{bearer_token}}
{
"recipient": {
"address1": "19749 Dearborn St",
"city": "Chatsworth",
"state_code": "CA",
"state_name": "California",
"country_code": "US",
"zip": "91311"
},
"customization": {
"gift": {
"subject": "To John",
"message": "Happy birthday!"
}
}
}
The Orders endpoints for the V2 Beta are incomplete. Some V1 endpoints will still need to be used to achieve certain functionality.
DELETE https://api.printful.com/orders/{order_id}
https://developers.printful.com/docs/#operation/cancelOrderByIdPUT https://api.printful.com/orders/{order_id}
https://developers.printful.com/docs/#operation/updateOrderByIdOrder costs are calculated asynchronously. This means when you create or
update an order you are likely to see a response from the API with costs
and
retail_costs
fields set to null and "calculation_status": "calculating"
.
"costs": {
"calculation_status": "calculating",
"currency": null,
"subtotal": null,
"discount": null,
"shipping": null,
"digitization": null,
"additional_fee": null,
"fulfillment_fee": null,
"retail_delivery_fee": null,
"tax": null,
"vat": null,
"total": null
},
"retail_costs": {
"calculation_status": "calculating",
"currency": "USD",
"subtotal": "0.00",
"discount": "1.00",
"shipping": "0.00",
"tax": "0.00",
"vat": "0.00",
"total": null
},
Once the costs and retail costs are calculated the "calculation_status" will change the status to "done"
"costs": {
"calculation_status": "done",
"currency": "USD",
"subtotal": "107.50",
"discount": "0.00",
"shipping": "14.84",
"digitization": "0.00",
"additional_fee": "0.00",
"fulfillment_fee": "0.00",
"retail_delivery_fee": "0.00",
"tax": "11.20",
"vat": "0.00",
"total": "133.54"
},
"retail_costs": {
"calculation_status": "done",
"currency": "USD",
"subtotal": "0.00",
"discount": "1.00",
"shipping": "0.00",
"tax": "0.00",
"vat": "0.00",
"total": "134.54"
},
If you are subscribed to the order_updated
webhook event,
you will receive an event when the calculation is finished.
Retrieve a list of orders from a specific store. The order list will be paginated with twenty items per page by default.
limit | integer [ 1 .. 100 ] Default: 20 The number of results to return per page. |
offset | integer >= 0 Default: 0 Examples:
The number of results to not include in the response starting from the beginning of the list. This can be used to return results after the initial 100. For example, sending offset 100 |
X-PF-Store-Id | string Use this to specify which store you want to use (required only for account level token). The store IDs can be retrieved with the Get basic information about stores endpoint. |
required | Array of objects (OrderSummary) |
required | object (Paging) Paging information |
required | object HATEOAS links |
{- "data": [
- {
- "id": 123,
- "external_id": "4235234213",
- "store_id": 10,
- "shipping": "STANDARD",
- "status": "draft",
- "created_at": "2023-04-05T06:07:08Z",
- "updated_at": "2023-04-05T06:07:08Z",
- "recipient": {
- "name": "John Smith",
- "company": "John Smith Inc",
- "address1": "19749 Dearborn St",
- "address2": "string",
- "city": "Chatsworth",
- "state_code": "CA",
- "state_name": "California",
- "country_code": "US",
- "country_name": "United States",
- "zip": "91311",
- "phone": "2312322334",
- "tax_number": "123.456.789-10"
}, - "costs": {
- "calculation_status": "done",
- "currency": "USD",
- "subtotal": "14.95",
- "discount": "1.79",
- "shipping": "4.79",
- "digitization": "3.95",
- "additional_fee": "0.00",
- "fulfillment_fee": "0.00",
- "retail_delivery_fee": "0.00",
- "vat": "4.60",
- "tax": "0.00",
- "total": "26.50"
}, - "retail_costs": {
- "calculation_status": "done",
- "currency": "EUR",
- "subtotal": "26.55",
- "discount": "0.00",
- "shipping": "4.79",
- "vat": "0.00",
- "tax": "0.00",
- "total": "31.34"
}, - "order_items": [
- {
- "id": 1234,
- "type": "order_item",
- "source": "catalog",
- "catalog_variant_id": 4011,
- "external_id": "123_abc",
- "quantity": 1,
- "name": "Custom name",
- "price": "8.00",
- "retail_price": "10.00",
- "currency": "EUR",
- "retail_currency": "USD",
- "_links": {
- "self": {
- "href": "/v2/orders/123/items/123"
}
}
}
], - "_links": {
}
}
], - "paging": {
- "total": 100,
- "offset": 10,
- "limit": 100
}, - "_links": {
}
}
This endpoint allows the creation of a new order in which the default status will be draft
.
X-PF-Store-Id | string Use this to specify which store you want to use (required only for account level token). The store IDs can be retrieved with the Get basic information about stores endpoint. |
POST request body
external_id | string Order ID from the external system |
shipping | string Shipping method. Defaults to 'STANDARD' |
required | object (Address) The recipient data. |
required | Array of any Array of order items |
object (Customization) The Order's customization values | |
object (RetailCosts-2) Retail costs |
required | object (Order) Order |
{- "external_id": "4235234213",
- "shipping": "STANDARD",
- "recipient": {
- "name": "John Smith",
- "company": "John Smith Inc",
- "address1": "19749 Dearborn St",
- "address2": "string",
- "city": "Chatsworth",
- "state_code": "CA",
- "state_name": "California",
- "country_code": "US",
- "country_name": "United States",
- "zip": "91311",
- "phone": "2312322334",
- "tax_number": "123.456.789-10"
}, - "order_items": [
- {
- "source": "catalog",
- "catalog_variant_id": 4011,
- "external_id": "123_abc",
- "quantity": 1,
- "retail_price": "10.00",
- "name": "Custom name",
- "placements": [
- {
- "placement": "front",
- "technique": "dtg",
- "print_area_type": "simple",
- "layers": [
- {
- "type": "file",
- "url": "https://www.printful.com/static/images/layout/printful-logo.png",
- "layer_options": [
- {
- "name": "3d_puff",
- "value": true
}
], - "position": {
- "width": 10,
- "height": 10,
- "top": 0,
- "left": 0
}
}
], - "placement_options": [
- {
- "name": "unlimited_color",
- "value": true
}
]
}
], - "product_options": [
- {
- "name": "inside_pocket",
- "value": true
}
]
}
], - "customization": {
- "gift": {
- "subject": "To John",
- "message": "Happy birthday!"
}, - "packing_slip": {
- "phone": "+48000000000",
- "message": "This is a message",
- "store_name": "A store",
- "custom_order_id": "11235813"
}
}, - "retail_costs": {
- "currency": "EUR",
- "discount": "123.40",
- "shipping": "123.40",
- "tax": "123.40"
}
}
{- "data": {
- "id": 123,
- "external_id": "4235234213",
- "store_id": 10,
- "shipping": "STANDARD",
- "status": "draft",
- "created_at": "2023-04-05T06:07:08Z",
- "updated_at": "2023-04-05T06:07:08Z",
- "recipient": {
- "name": "John Smith",
- "company": "John Smith Inc",
- "address1": "19749 Dearborn St",
- "address2": "string",
- "city": "Chatsworth",
- "state_code": "CA",
- "state_name": "California",
- "country_code": "US",
- "country_name": "United States",
- "zip": "91311",
- "phone": "2312322334",
- "tax_number": "123.456.789-10"
}, - "costs": {
- "calculation_status": "done",
- "currency": "USD",
- "subtotal": "14.95",
- "discount": "1.79",
- "shipping": "4.79",
- "digitization": "3.95",
- "additional_fee": "0.00",
- "fulfillment_fee": "0.00",
- "retail_delivery_fee": "0.00",
- "vat": "4.60",
- "tax": "0.00",
- "total": "26.50"
}, - "retail_costs": {
- "calculation_status": "done",
- "currency": "EUR",
- "subtotal": "26.55",
- "discount": "0.00",
- "shipping": "4.79",
- "vat": "0.00",
- "tax": "0.00",
- "total": "31.34"
}, - "order_items": [
- {
- "id": 1234,
- "type": "order_item",
- "source": "catalog",
- "catalog_variant_id": 4011,
- "external_id": "123_abc",
- "quantity": 1,
- "name": "Custom name",
- "price": "8.00",
- "retail_price": "10.00",
- "currency": "EUR",
- "retail_currency": "USD",
- "_links": {
- "self": {
- "href": "/v2/orders/123/items/123"
}
}
}
], - "customization": {
- "gift": {
- "subject": "To John",
- "message": "Happy birthday!"
}, - "packing_slip": {
- "phone": "+48000000000",
- "message": "This is a message",
- "store_name": "A store",
- "custom_order_id": "11235813"
}
}, - "_links": {
}
}
}
Retrieve a single order from the specified store. The result object will contain links to the same resource, order items, and shipments.
required | integer or string Order ID (integer) or Order External ID (string prepended with "@" symbol) |
X-PF-Store-Id | string Use this to specify which store you want to use (required only for account level token). The store IDs can be retrieved with the Get basic information about stores endpoint. |
required | object (Order) Order |
{- "data": {
- "id": 123,
- "external_id": "4235234213",
- "store_id": 10,
- "shipping": "STANDARD",
- "status": "draft",
- "created_at": "2023-04-05T06:07:08Z",
- "updated_at": "2023-04-05T06:07:08Z",
- "recipient": {
- "name": "John Smith",
- "company": "John Smith Inc",
- "address1": "19749 Dearborn St",
- "address2": "string",
- "city": "Chatsworth",
- "state_code": "CA",
- "state_name": "California",
- "country_code": "US",
- "country_name": "United States",
- "zip": "91311",
- "phone": "2312322334",
- "tax_number": "123.456.789-10"
}, - "costs": {
- "calculation_status": "done",
- "currency": "USD",
- "subtotal": "14.95",
- "discount": "1.79",
- "shipping": "4.79",
- "digitization": "3.95",
- "additional_fee": "0.00",
- "fulfillment_fee": "0.00",
- "retail_delivery_fee": "0.00",
- "vat": "4.60",
- "tax": "0.00",
- "total": "26.50"
}, - "retail_costs": {
- "calculation_status": "done",
- "currency": "EUR",
- "subtotal": "26.55",
- "discount": "0.00",
- "shipping": "4.79",
- "vat": "0.00",
- "tax": "0.00",
- "total": "31.34"
}, - "order_items": [
- {
- "id": 1234,
- "type": "order_item",
- "source": "catalog",
- "catalog_variant_id": 4011,
- "external_id": "123_abc",
- "quantity": 1,
- "name": "Custom name",
- "price": "8.00",
- "retail_price": "10.00",
- "currency": "EUR",
- "retail_currency": "USD",
- "_links": {
- "self": {
- "href": "/v2/orders/123/items/123"
}
}
}
], - "customization": {
- "gift": {
- "subject": "To John",
- "message": "Happy birthday!"
}, - "packing_slip": {
- "phone": "+48000000000",
- "message": "This is a message",
- "store_name": "A store",
- "custom_order_id": "11235813"
}
}, - "_links": {
}
}
}
Delete the order if it can be deleted. An order can be deleted if it's status is
draft
, failed
or cancelled
. The order must also have not been charged yet
and there must be no payments pending.
required | integer or string Order ID (integer) or Order External ID (string prepended with "@" symbol) |
X-PF-Store-Id | string Use this to specify which store you want to use (required only for account level token). The store IDs can be retrieved with the Get basic information about stores endpoint. |
{- "code": 401,
- "result": "Malformed Authorization header.",
- "error": {
- "reason": "BadRequest",
- "message": "Malformed Authorization header."
}
}
Make a partial update of an order.
required | integer or string Order ID (integer) or Order External ID (string prepended with "@" symbol) |
X-PF-Store-Id | string Use this to specify which store you want to use (required only for account level token). The store IDs can be retrieved with the Get basic information about stores endpoint. |
PATCH request body
external_id | string Order ID from the external system |
shipping | string Shipping method. Defaults to 'STANDARD' |
object (Address) The recipient data. | |
Array of any Array of order items | |
object (Customization) The Order's customization values | |
object Retail costs |
required | object (Order) Order |
{- "external_id": "4235234213",
- "shipping": "STANDARD",
- "recipient": {
- "name": "John Smith",
- "company": "John Smith Inc",
- "address1": "19749 Dearborn St",
- "address2": "string",
- "city": "Chatsworth",
- "state_code": "CA",
- "state_name": "California",
- "country_code": "US",
- "country_name": "United States",
- "zip": "91311",
- "phone": "2312322334",
- "tax_number": "123.456.789-10"
}, - "order_items": [
- {
- "source": "catalog",
- "catalog_variant_id": 4011,
- "external_id": "123_abc",
- "quantity": 1,
- "retail_price": "10.00",
- "name": "Custom name",
- "placements": [
- {
- "placement": "front",
- "technique": "dtg",
- "print_area_type": "simple",
- "layers": [
- {
- "type": "file",
- "url": "https://www.printful.com/static/images/layout/printful-logo.png",
- "layer_options": [
- {
- "name": "3d_puff",
- "value": true
}
], - "position": {
- "width": 10,
- "height": 10,
- "top": 0,
- "left": 0
}
}
], - "placement_options": [
- {
- "name": "unlimited_color",
- "value": true
}
]
}
], - "product_options": [
- {
- "name": "inside_pocket",
- "value": true
}
]
}
], - "customization": {
- "gift": {
- "subject": "To John",
- "message": "Happy birthday!"
}, - "packing_slip": {
- "phone": "+48000000000",
- "message": "This is a message",
- "store_name": "A store",
- "custom_order_id": "11235813"
}
}, - "retail_costs": {
- "currency": "EUR",
- "discount": "123.40",
- "shipping": "123.40",
- "tax": "123.40"
}
}
{- "data": {
- "id": 123,
- "external_id": "4235234213",
- "store_id": 10,
- "shipping": "STANDARD",
- "status": "draft",
- "created_at": "2023-04-05T06:07:08Z",
- "updated_at": "2023-04-05T06:07:08Z",
- "recipient": {
- "name": "John Smith",
- "company": "John Smith Inc",
- "address1": "19749 Dearborn St",
- "address2": "string",
- "city": "Chatsworth",
- "state_code": "CA",
- "state_name": "California",
- "country_code": "US",
- "country_name": "United States",
- "zip": "91311",
- "phone": "2312322334",
- "tax_number": "123.456.789-10"
}, - "costs": {
- "calculation_status": "done",
- "currency": "USD",
- "subtotal": "14.95",
- "discount": "1.79",
- "shipping": "4.79",
- "digitization": "3.95",
- "additional_fee": "0.00",
- "fulfillment_fee": "0.00",
- "retail_delivery_fee": "0.00",
- "vat": "4.60",
- "tax": "0.00",
- "total": "26.50"
}, - "retail_costs": {
- "calculation_status": "done",
- "currency": "EUR",
- "subtotal": "26.55",
- "discount": "0.00",
- "shipping": "4.79",
- "vat": "0.00",
- "tax": "0.00",
- "total": "31.34"
}, - "order_items": [
- {
- "id": 1234,
- "type": "order_item",
- "source": "catalog",
- "catalog_variant_id": 4011,
- "external_id": "123_abc",
- "quantity": 1,
- "name": "Custom name",
- "price": "8.00",
- "retail_price": "10.00",
- "currency": "EUR",
- "retail_currency": "USD",
- "_links": {
- "self": {
- "href": "/v2/orders/123/items/123"
}
}
}
], - "customization": {
- "gift": {
- "subject": "To John",
- "message": "Happy birthday!"
}, - "packing_slip": {
- "phone": "+48000000000",
- "message": "This is a message",
- "store_name": "A store",
- "custom_order_id": "11235813"
}
}, - "_links": {
}
}
}
This endpoint allows customers to confirm the order and start the fulfillment in the production facility.
required | integer or string Order ID (integer) or Order External ID (string prepended with "@" symbol) |
X-PF-Store-Id | string Use this to specify which store you want to use (required only for account level token). The store IDs can be retrieved with the Get basic information about stores endpoint. |
required | object (Order) Order |
required | object HATEOAS links |
{- "data": {
- "id": 123,
- "external_id": "4235234213",
- "store_id": 10,
- "shipping": "STANDARD",
- "status": "draft",
- "created_at": "2023-04-05T06:07:08Z",
- "updated_at": "2023-04-05T06:07:08Z",
- "recipient": {
- "name": "John Smith",
- "company": "John Smith Inc",
- "address1": "19749 Dearborn St",
- "address2": "string",
- "city": "Chatsworth",
- "state_code": "CA",
- "state_name": "California",
- "country_code": "US",
- "country_name": "United States",
- "zip": "91311",
- "phone": "2312322334",
- "tax_number": "123.456.789-10"
}, - "costs": {
- "calculation_status": "done",
- "currency": "USD",
- "subtotal": "14.95",
- "discount": "1.79",
- "shipping": "4.79",
- "digitization": "3.95",
- "additional_fee": "0.00",
- "fulfillment_fee": "0.00",
- "retail_delivery_fee": "0.00",
- "vat": "4.60",
- "tax": "0.00",
- "total": "26.50"
}, - "retail_costs": {
- "calculation_status": "done",
- "currency": "EUR",
- "subtotal": "26.55",
- "discount": "0.00",
- "shipping": "4.79",
- "vat": "0.00",
- "tax": "0.00",
- "total": "31.34"
}, - "order_items": [
- {
- "id": 1234,
- "type": "order_item",
- "source": "catalog",
- "catalog_variant_id": 4011,
- "external_id": "123_abc",
- "quantity": 1,
- "name": "Custom name",
- "price": "8.00",
- "retail_price": "10.00",
- "currency": "EUR",
- "retail_currency": "USD",
- "_links": {
- "self": {
- "href": "/v2/orders/123/items/123"
}
}
}
], - "customization": {
- "gift": {
- "subject": "To John",
- "message": "Happy birthday!"
}, - "packing_slip": {
- "phone": "+48000000000",
- "message": "This is a message",
- "store_name": "A store",
- "custom_order_id": "11235813"
}
}, - "_links": {
}
}, - "_links": {
}
}
This endpoint retrieves the list of items that belong to the order.
required | integer or string Order ID (integer) or Order External ID (string prepended with "@" symbol) |
type | string Type of items returned (order_item, branding_item). By default all items are returned. |
limit | integer [ 1 .. 100 ] Default: 20 The number of results to return per page. |
offset | integer >= 0 Default: 0 Examples:
The number of results to not include in the response starting from the beginning of the list. This can be used to return results after the initial 100. For example, sending offset 100 |
X-PF-Store-Id | string Use this to specify which store you want to use (required only for account level token). The store IDs can be retrieved with the Get basic information about stores endpoint. |
required | Array of any |
required | object HATEOAS links |
{- "data": [
- {
- "source": "catalog",
- "catalog_variant_id": 4011,
- "id": 1234,
- "external_id": "123_abc",
- "quantity": 1,
- "retail_price": "10.00",
- "name": "Custom name",
- "placements": [
- {
- "placement": "front",
- "technique": "dtg",
- "layers": [
- {
- "type": "file",
- "url": "https://www.printful.com/static/images/layout/printful-logo.png",
- "layer_options": [
- {
- "name": "3d_puff",
- "value": true
}
], - "position": {
- "width": 10,
- "height": 10,
- "top": 0,
- "left": 0
}
}
], - "placement_options": [
- {
- "name": "unlimited_color",
- "value": true
}
], - "status": "ok",
- "status_explanation": "Product with ID: 656 cannot have disjointed design elements."
}
], - "product_options": [
- {
- "name": "inside_pocket",
- "value": true
}
], - "_links": {
- "self": {
- "href": "/v2/orders/123/order-items/123"
}
}
}
], - "_links": {
}
}
This endpoint allows the creation of a new item that will be added to an existing order.
required | integer or string Order ID (integer) or Order External ID (string prepended with "@" symbol) |
X-PF-Store-Id | string Use this to specify which store you want to use (required only for account level token). The store IDs can be retrieved with the Get basic information about stores endpoint. |
POST request body
source required | string Catalog source |
catalog_variant_id required | integer ID of catalog variant |
external_id | string or null (ItemExternalId) Item user specified external ID |
quantity | integer Item quantity |
retail_price | string Item retail price |
name | string Item custom name |
required | Array of objects (PlacementsList) Each entry in this list represents a placement on the physical product and the design that will be printed in that location. |
Array of any (ProductOptions) List of product options |
required | Array of any |
required | object HATEOAS links |
{- "source": "catalog",
- "catalog_variant_id": 4011,
- "external_id": "123_abc",
- "quantity": 1,
- "retail_price": "10.00",
- "name": "Custom name",
- "placements": [
- {
- "placement": "front",
- "technique": "dtg",
- "print_area_type": "simple",
- "layers": [
- {
- "type": "file",
- "url": "https://www.printful.com/static/images/layout/printful-logo.png",
- "layer_options": [
- {
- "name": "3d_puff",
- "value": true
}
], - "position": {
- "width": 10,
- "height": 10,
- "top": 0,
- "left": 0
}
}
], - "placement_options": [
- {
- "name": "unlimited_color",
- "value": true
}
]
}
], - "product_options": [
- {
- "name": "inside_pocket",
- "value": true
}
]
}
{- "data": [
- {
- "source": "catalog",
- "catalog_variant_id": 4011,
- "id": 1234,
- "external_id": "123_abc",
- "quantity": 1,
- "retail_price": "10.00",
- "name": "Custom name",
- "placements": [
- {
- "placement": "front",
- "technique": "dtg",
- "layers": [
- {
- "type": "file",
- "url": "https://www.printful.com/static/images/layout/printful-logo.png",
- "layer_options": [
- {
- "name": "3d_puff",
- "value": true
}
], - "position": {
- "width": 10,
- "height": 10,
- "top": 0,
- "left": 0
}
}
], - "placement_options": [
- {
- "name": "unlimited_color",
- "value": true
}
], - "status": "ok",
- "status_explanation": "Product with ID: 656 cannot have disjointed design elements."
}
], - "product_options": [
- {
- "name": "inside_pocket",
- "value": true
}
], - "_links": {
- "self": {
- "href": "/v2/orders/123/order-items/123"
}
}
}
], - "_links": {
}
}
This endpoint will retrieve a single order item specified in the request.
required | integer or string Item ID (integer) or Item External ID (string prepended with "@" symbol) |
required | integer or string Order ID (integer) or Order External ID (string prepended with "@" symbol) |
X-PF-Store-Id | string Use this to specify which store you want to use (required only for account level token). The store IDs can be retrieved with the Get basic information about stores endpoint. |
required | any |
required | object HATEOAS links |
{- "data": {
- "source": "catalog",
- "catalog_variant_id": 4011,
- "id": 1234,
- "external_id": "123_abc",
- "quantity": 1,
- "retail_price": "10.00",
- "name": "Custom name",
- "placements": [
- {
- "placement": "front",
- "technique": "dtg",
- "layers": [
- {
- "type": "file",
- "url": "https://www.printful.com/static/images/layout/printful-logo.png",
- "layer_options": [
- {
- "name": "3d_puff",
- "value": true
}
], - "position": {
- "width": 10,
- "height": 10,
- "top": 0,
- "left": 0
}
}
], - "placement_options": [
- {
- "name": "unlimited_color",
- "value": true
}
], - "status": "ok",
- "status_explanation": "Product with ID: 656 cannot have disjointed design elements."
}
], - "product_options": [
- {
- "name": "inside_pocket",
- "value": true
}
], - "_links": {
- "self": {
- "href": "/v2/orders/123/order-items/123"
}
}
}, - "_links": {
}
}
Make a partial update of an order item. NOTE that the source of the order item can't be changed via a PATCH request, to create an order item from another source you must delete the current one and add a new one.
required | integer or string Item ID (integer) or Item External ID (string prepended with "@" symbol) |
required | integer or string Order ID (integer) or Order External ID (string prepended with "@" symbol) |
X-PF-Store-Id | string Use this to specify which store you want to use (required only for account level token). The store IDs can be retrieved with the Get basic information about stores endpoint. |
PATCH request body
source required | string Catalog source |
catalog_variant_id required | integer ID of catalog variant |
external_id | string or null (ItemExternalId) Item user specified external ID |
quantity | integer Item quantity |
retail_price | string Item retail price |
name | string Item custom name |
required | Array of objects (PlacementsList) Each entry in this list represents a placement on the physical product and the design that will be printed in that location. |
Array of any (ProductOptions) List of product options |
required | Array of any |
required | object HATEOAS links |
{- "source": "catalog",
- "catalog_variant_id": 4011,
- "external_id": "123_abc",
- "quantity": 1,
- "retail_price": "10.00",
- "name": "Custom name",
- "placements": [
- {
- "placement": "front",
- "technique": "dtg",
- "print_area_type": "simple",
- "layers": [
- {
- "type": "file",
- "url": "https://www.printful.com/static/images/layout/printful-logo.png",
- "layer_options": [
- {
- "name": "3d_puff",
- "value": true
}
], - "position": {
- "width": 10,
- "height": 10,
- "top": 0,
- "left": 0
}
}
], - "placement_options": [
- {
- "name": "unlimited_color",
- "value": true
}
]
}
], - "product_options": [
- {
- "name": "inside_pocket",
- "value": true
}
]
}
{- "data": [
- {
- "source": "catalog",
- "catalog_variant_id": 4011,
- "id": 1234,
- "external_id": "123_abc",
- "quantity": 1,
- "retail_price": "10.00",
- "name": "Custom name",
- "placements": [
- {
- "placement": "front",
- "technique": "dtg",
- "layers": [
- {
- "type": "file",
- "url": "https://www.printful.com/static/images/layout/printful-logo.png",
- "layer_options": [
- {
- "name": "3d_puff",
- "value": true
}
], - "position": {
- "width": 10,
- "height": 10,
- "top": 0,
- "left": 0
}
}
], - "placement_options": [
- {
- "name": "unlimited_color",
- "value": true
}
], - "status": "ok",
- "status_explanation": "Product with ID: 656 cannot have disjointed design elements."
}
], - "product_options": [
- {
- "name": "inside_pocket",
- "value": true
}
], - "_links": {
- "self": {
- "href": "/v2/orders/123/order-items/123"
}
}
}
], - "_links": {
}
}
Remove a single item from the order.
required | integer or string Item ID (integer) or Item External ID (string prepended with "@" symbol) |
required | integer or string Order ID (integer) or Order External ID (string prepended with "@" symbol) |
X-PF-Store-Id | string Use this to specify which store you want to use (required only for account level token). The store IDs can be retrieved with the Get basic information about stores endpoint. |
{- "code": 400,
- "result": "Missing required parameters",
- "error": {
- "reason": "BadRequest",
- "message": "Missing required parameters"
}
}
Shipments contain information about how and when your orders items will be delivered and fulfilled.
required | integer or string Order ID (integer) or Order External ID (string prepended with "@" symbol) |
limit | integer [ 1 .. 100 ] Default: 20 The number of results to return per page. |
offset | integer >= 0 Default: 0 Examples:
The number of results to not include in the response starting from the beginning of the list. This can be used to return results after the initial 100. For example, sending offset 100 |
X-PF-Store-Id | string Use this to specify which store you want to use (required only for account level token). The store IDs can be retrieved with the Get basic information about stores endpoint. |
required | Array of objects (Shipment) |
required | object |
required | object (Paging) Paging information |
{- "data": [
- {
- "id": 1,
- "order_id": 2,
- "order_external_id": "my_custom_id_1234",
- "carrier": "USPS",
- "service": "USPS Priority Mail",
- "shipment_status": "canceled",
- "shipped_at": "2023-06-15T16:35:35Z",
- "delivery_status": "unknown",
- "delivered_at": "2023-06-15T16:35:35Z",
- "departure_address": {
- "country_name": "United States",
- "country_code": "US",
- "state_code": "CA"
}, - "is_reshipment": true,
- "tracking_url": "https://myorders.com/tracking/39925631",
- "tracking_events": [
- {
- "triggered_at": "2023-06-15T19:15:05Z",
- "description": "Arrived At Destination"
}
], - "estimated_delivery": {
- "from_date": "2023-06-15",
- "to_date": "2023-06-15",
- "calculated_at": "2023-06-15T16:35:35Z"
}, - "shipment_items": [
- {
- "id": 10,
- "order_item_id": 20,
- "order_item_external_id": "item-external-id",
- "order_item_name": "Item name",
- "quantity": 1,
- "_links": {
- "order_item": {
- "href": "https://api.printful.com/v2/orders/2/order-items/20"
}
}
}
], - "_links": {
- "self": {
- "href": "https://api.printful.com/v2/shipments/1"
}, - "order": {
- "href": "https://api.printful.com/v2/orders/2"
}
}
}
], - "_links": {
- "self": {
- "href": "https://api.printful.com/v2/orders/123/shipments?limit=20&offset=0"
}, - "next": {
- "href": "https://api.printful.com/v2/orders/123/shipments?limit=20&offset=20"
}, - "previous": {
- "href": "https://api.printful.com/v2/orders/123/shipments?limit=20&offset=0"
}, - "first": {
- "href": "https://api.printful.com/v2/orders/123/shipments?limit=20&offset=0"
}, - "last": {
- "href": "https://api.printful.com/v2/orders/123/shipments?limit=20&offset=20"
}
}, - "paging": {
- "total": 100,
- "offset": 10,
- "limit": 100
}
}