-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathopenapi.json
11995 lines (11995 loc) · 524 KB
/
openapi.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
{
"openapi": "3.0.0",
"info": {
"version": "2.0.0-beta",
"title": "API Documentation v2 | Printful",
"description": "# About the Printful API\n\n<div class=\"alert alert-info\">\n <h3>Welcome to API v2 BETA</h3> \n <ul>\n <li>\n We’re excited to inform you that the new major version of our API just went live, and we want to invite you to participate in the Open Beta test. \n Please keep in mind that this release is still in BETA, although all presented endpoints can be used in a production environment. \n Since this is a BETA release, we are keen on adopting any changes to our API (which we encourage you to pass via <a href=\"https://forms.gle/Yq4t1poQQR8Mwoyt5\">this feedback form</a>).\n We do not expect to introduce any breaking changes to the current form of endpoints, although the final form of each endpoint might slightly vary from the current version.\n </li>\n </ul>\n</div>\n<br>\n\n* **How to use new endpoints?**\n Create or use an already created private token for authorization. \n Unless it's stated otherwise, the v2 version of Printful API may be used like the v1 version.\n All v2 endpoints use **/v2** prefix and the specifics of each endpoint are explained in a dedicated section.\n \n* **Test and provide feedback:** Explore the new features, experiment with the enhancements, and share your feedback through our dedicated [feedback form](https://forms.gle/Yq4t1poQQR8Mwoyt5).\n\n### What is new in the V2s\n\n- The flexibility of order creation with itemized order building [(read more)](#tag/Orders-v2).\n- Simplifying embroidery orders: auto thread color detection as default, simplified thread colors definition on the layer level.\n- New, powerful design creation with multiple design layers support and positioning for order items and sync variants [(read more)](#tag/Orders-v2).\n- New, more secure Webhooks by enforcing HTTPS, added expiration date, and request signing.\n- More flexibility in webhook per event configuration. \n- New webhook events – a new event for catalog price change, and the stock update event is now real-time with a refresh rate every 5 minutes (previously every 24h).\n- More information in the Catalog about the products (images, discounted pricing, placement information).\n- More flexibility in the catalog (extensive filtering and sorting options, DSR support, pagination).\n- More information on the order shipment level – more precise EDT, departure country, and shipment tracking events.\n- Standardization of returned time in API – standardized format according to ISO 8601, UTC time zone.\n- Standardization of returned price formats in API. Prices are displayed as a string with up to 2 decimal points.\n- Uniform pagination parameters across all endpoints.\n- Performance improvements for all endpoints.",
"contact": {
"name": "Printful developer support",
"url": "https://www.printful.com/docs/support",
"email": "[email protected]"
},
"x-logo": {
"url": "https://static.cdn.printful.com/dist-pf/image-assets/off-center-full-color-black.1de1e822b15b8e74075c8d1fa631d4e3.svg",
"backgroundColor": "#FFFFFF",
"altText": "Printful"
}
},
"servers": [
{
"url": "https://api.printful.com",
"description": "The Printful API is a RESTful API, that uses the HTTP protocol for communication. HTTP GET, POST, PUT and DELETE methods are used to access the API."
}
],
"tags": [
{
"name": "Rate Limiting",
"description": "Printful implements rate limiting to ensure the stability of the API while\nkeeping it fair for all users. Rate limiting is handled differently depending\non the version and endpoint being used.\n\n### Header values\n\nPrintful uses the following header values to communicate rate limits:\n\n```\nX-Ratelimit-Limit\nX-Ratelimit-Remaining\nX-Ratelimit-Reset\nX-Ratelimit-Policy\n```\n\nHowever, the meaning of these values changes depending on the algorithm used.\n\n### V1 Rate limitting\n\nV1 used a very simple rate limiting mechanism, you had a limit of 120, every\nrequest would reduce that limit by 1, if it hits 0 you would receive a 429 error,\nevery minute the limit of 120 would be restored. See: [V1 Rate Limits](/docs/#rate-limits).\n\nThis system is good, because it's easy to understand for most users. However,\nwe found it had a number of disadvantages both for users and for Printful.\n\n- A burst in traffic could lead to 120 requests in the first second. This is\n harmful for Printful and will lead to a bad user experience as all end users\n wait for the rate limit to be reset.\n- Some users will have close to 120 requests a minute, but most sites don't have\n such uniform traffic.\n\n### V2 Rate Limiting\n\n#### Leaky Bucket\n\nIn V2 of the API Printful implements a [Leaky Bucket](https://en.wikipedia.org/wiki/Leaky_bucket)\nrate limiting algorithm.\n\n**Note:** The algorithm does not implement any queuing mechanisms in its\ncurrent form so it can also be described as a [Token Bucket](https://en.wikipedia.org/wiki/Token_bucket)\nalgorithm.\n\nLike with the old rate limiting algorithm, when you make a request to the API,\nthe `X-Ratelimit-Remaining` header value will go down by one. However, the `X-Ratelimit-Reset`\ndoes not work the same, it states how long it will take to \"refill the bucket\".\nThe bucket will be refilled one drop at a time instead of all at once, so the\n`X-Ratelimit-Reset` will be much smaller after the first request.\n\nBy default, after the first request the headers will look like this:\n\n```\nX-Ratelimit-Policy: 120;w=60;\nX-Ratelimit-Limit: 120\nX-Ratelimit-Remaining: 119\nX-Ratelimit-Reset: 0.5\n```\n\nThis means 120 requests can be made in a single burst, one request has already\nbeen made and `X-Ratelimit-Remaining` will reach 120 again in 0.5 seconds. The\n`X-Ratelimit-Policy` header indicates that in a window of 60 seconds 120 tokens\n(or \"quota units\") will be added to the bucket.\n\nThe headers are inspired by the format in [RateLimit header fields for HTTP](https://www.ietf.org/archive/id/draft-ietf-httpapi-ratelimit-headers-07.html) Internet-Draft.\n\n##### What is rate-limited in V2\n\nAll endpoints are rate-limited with the leaky bucket rate limiter and the defaults.\nHowever, it is planned for future endpoints to have higher or lower limits depending\non usage and the capacity of the API.\n\n##### Using the leaky bucket effectively\n\nThere are a number of strategies you can use to take advantage of rate limiting.\n\n- When receiving a 429 you can use the `retry-after` header to check when the next\n request can be made, then schedule a request to trigger at that time.\n- You can implement a queue that only sends out requests at the rate indicated\n in the policy. You can calculate the rate of requests using the\n `X-Ratelimit-Policy` 120 ÷ 60 = 0.5, so the queue should send requests out at a \n rate of once every 500 milliseconds. \n- Some combination of the two, for example, allow requests to trigger at any rate,\n start queuing after the first 429, then turn off the queue after no new requests\n are sent and the `X-Ratelimit-Reset` time has been met.\n\n"
},
{
"name": "Localisation",
"description": "Some of the resources returned by the API are translated into several languages. By default, they are returned in\nEnglish in the API responses.\n\nIf you want to get a response with texts in another language, you can use the `X-PF-Language`\nHTTP header. Its value should be the long version of the locale to use (e.g. `es_ES` for Spanish).\nPossible localisation parameters:\n- en_US\n- en_GB\n- en_CA\n- es_ES\n- fr_FR\n- de_DE\n- it_IT\n- ja_JP\n\n### Example\n\nProduct details (`GET https://api.printful.com/products/71`) response with default locale (`en_US`):\n\n```\n{\n \"code\": 200,\n \"result\": {\n \"product\": {\n \"type_name\": \"T-Shirt\",\n \"title\": \"Unisex Staple T-Shirt | Bella + Canvas 3001\",\n ...\n }\n }\n}\n```\n\nProduct details response with Spanish locale (`X-PF-Language: es_ES`):\n\n```\n{\n \"code\": 200,\n \"result\": {\n \"product\": {\n ...\n \"type_name\": \"Camiseta\",\n \"title\": \"Camiseta esencial unisex | Bella + Canvas 3001\",\n ...\n }\n }\n}\n```\n"
},
{
"name": "OAuth Scopes v2",
"description": "OAuth API allows receiving data for token"
},
{
"name": "Catalog v2",
"description": "## What is a catalog product?\nA 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:\n\n[<img src=\"images/catalog/catalog_product_diagram.png#center\" width=\"300\"/>](images/catalog/catalog_product_diagram.png)\n\n## What is a catalog variant?\nCatalog 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.\n\n[<img src=\"images/catalog/catalog_variant_diagram.png#center\" width=\"300\"/>](images/catalog/catalog_variant_diagram.png)\n\nPrintful 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 \nT-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 \nto find the needed Variant ID.\n\n<div class=\"alert alert-info\">\nIt is critically important to always refer to the Variant IDs (<strong>NOT Product IDs</strong>) when creating products or orders. Mixing up and using the Product ID instead of the Variant ID can lead to an entirely different product created or item ordered. \nThe Product entity is only meant to allow of easier browsing of what Printful offers.\n</div>\n\nYou can also use this API resource to find out the types of print files. A product can be configured for as well as the\nadditional price each print file would cost (e.g. the back print or inside label print for T-shirts). Moreover, some\nproduct types allow for additional options (e.g. embroidery type and thread colors) – these options are listed in the\nresponses as well.\n\n**Important**: Jewelry products are not supported via API.\n\n**Rate limiting**: Up to 120 requests per 60 seconds. A 60 seconds lockout is applied if\nrequest count is exceeded.\n\n## Catalog general information\n### General introduction\n\nThis 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:\n* [Product Prices](#operation/getProductPricesById)\n* [Product Size Guides](#operation/getProductSizeGuideById)\n* [Product Images](#operation/getProductImagesById)\n\n[<img src=\"images/catalog/catalog_diagram.png#center\" width=\"500\"/>](images/catalog/catalog_diagram.png)\n\n### Filtering options\n\nFilters can be used to search for particular set of products based on the provided values. Multiple filters can be used at the same time.\n\n| Filtering option name | Description | Where to find |\n|-----------------------|----------------------------------------------------------------|----------------------------------------------------------------------------|\n| colors | Filters products by variants containing specified colors | `data[].color` [Catalog variants](#operation/getProductVariantsById) |\n| new | Filters products that are new | - |\n| placements | Filters products by available placements specified in the list | `data[].placements[].placement` [Catalog products](#operation/getProducts) |\n| category_ids | Filters products by specified product categories | `data[].id` [Catalog categories](#operation/getCategories) |\n| techniques | Filters products by specified techniques | `data[].techniques[].key` [Catalog products](#operation/getProducts) |\n| types | Filters products by specified types of product e.g. T-Shirt. | `data[].type` [Catalog products](#operation/getProducts) |\n| bestseller | Filters products that are bestsellers | - |\n\n### Sorting\n\nRequires providing two parameters in the URL: `sort_type`\nAnd `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.\nOnly one sort type can be used at a time.\n\n| Sorting option name | Description |\n|---------------------|------------------------------------------------------------|\n| new | Sorts resulting catalog products starting with new ones |\n| rating | Sorts resulting catalog products by their user-rating |\n| price | Sorts resulting catalog products by their base price |\n| bestseller | Sorts resulting catalog products starting with bestsellers |\n\n### DSR\n\n* **What is DSR?** – DSR (Default Selling Region) is an option that lets you limit the results of a product catalog to products that could be shipped within a specified region. When choosing Worldwide, we'll display the entire Product Catalog. Delivery times depend on end-customer location and selected product.\n* **Where DSR can be set and how it affects response?** – DSR can be currently set in [Catalog products](#operation/getProducts) and [Product Prices](#operation/getProductPricesById).\n* **Available DSRs**\n\n| Region name | Region name value |\n|--------------------------|----------------------------|\n| Worldwide | `worldwide` |\n| North America | `north_america` |\n| Canada | `canada` |\n| Europe | `europe` |\n| Spain | `spain` |\n| Latvia | `latvia` |\n| United Kingdom | `uk` |\n| France | `france` |\n| Germany | `germany` |\n| Australia | `australia` |\n| Japan | `japan` |\n| New Zealand | `new_zealand` |\n| Italy | `italy` |\n| Brazil | `brazil` |\n| Southeast Asia | `southeast_asia` |\n| Republic of Korea | `republic_of_korea` |\n| English speaking regions | `english_speaking_regions` |\n\n### Size guides\n\n[<img src=\"images/catalog/size_guides_diagram.png#center\" width=\"600\"/>](images/catalog/size_guides_diagram.png)\n\n[Get Product Size Guide](#operation/getProductSizeGuideById) endpoint will return size guides for the specified product.\n\nThere are three types of size tables available, as described by the following table:\n\n| Table type | API name | Description |\n|-------------------------------|--------------------|---------------------------------------------------------------------------------------------|\n| Measure yourself | `measure_yourself` | Measurements of the product to measure the body provided by the supplier. |\n| Product measurements | `product_measure` | Measurements of the product provided by the supplier. |\n| International size conversion | `international` | International size conversion – e.g. US, EU or UK sizes corresponding to the product sizes. |\n\nNot each table type might be available for the selected product.\n\n[See examples](#section/Catalog-API-examples/Using-size-guides)\n\n## Categories\n\nCatalog categories are used to group products with similar characteristics such as t-shirts, hats etc.\n\nCategories have purely informational purposes and cannot be edited by the customers. Categories can be nested e.g.\n* Men’s clothing\n * All shirts\n * T-Shirts\n * Polo shirts\n * Jackets & vests\n\nApart from display purposes they can be also used for filtering the products in the API [see Filtering options](#filtering-options)"
},
{
"name": "Orders v2",
"description": "## Order Building\n\nYou 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.\nWith 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)\nby using [Create Order Item](#operation/createItemByOrderId). After every order item addition, the order cost will be re-calculated.\n\nA minimal DRAFT order can be created with just the address:\n\n```\nPOST https://api.printful.com/v2/orders\nAuthorization: Bearer {{bearer_token}}\n{\n \"recipient\": {\n \"address1\": \"19749 Dearborn St\",\n \"city\": \"Chatsworth\",\n \"state_code\": \"CA\",\n \"state_name\": \"California\",\n \"country_code\": \"US\",\n \"country_name\": \"United States\",\n \"zip\": \"91311\"\n }\n}\n```\n\nAfter the order is created the order items can be added one by one.\n\n```\nPOST https://api.printful.com/v2/orders/{{order_id}}/order-items\nAuthorization: Bearer {{bearer_token}}\n{\n \"catalog_variant_id\": 4011,\n \"source\": \"catalog\",\n \"quantity\": 1,\n \"placements\": [\n {\n \"placement\": \"front\",\n \"technique\": \"dtg\",\n \"layers\": [\n {\n \"type\": \"file\",\n \"url\": \"https://www.printful.com/static/images/layout/printful-logo.png\"\n }\n ]\n }\n ]\n}\n```\n\nIt is also possible to create an order with all order items in a single request.\n\n```\nPOST https://api.printful.com/v2/orders\nAuthorization: Bearer {{bearer_token}}\n{\n \"recipient\": {\n \"address1\": \"19749 Dearborn St\",\n \"city\": \"Chatsworth\",\n \"state_code\": \"CA\",\n \"state_name\": \"California\",\n \"country_code\": \"US\",\n \"country_name\": \"United States\",\n \"zip\": \"91311\"\n },\n \"order_items\": [\n {\n \"catalog_variant_id\": 4011,\n \"source\": \"catalog\",\n \"quantity\": 1,\n \"placements\": [\n {\n \"placement\": \"front\",\n \"technique\": \"dtg\",\n \"layers\": [\n {\n \"type\": \"file\",\n \"url\": \"https://www.printful.com/static/images/layout/printful-logo.png\"\n }\n ]\n }\n ]\n }\n ]\n}\n```\n\n## Order life cycle and statuses\n\n<table>\n <tr>\n <td><strong>draft</strong></td>\n <td>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.</td>\n </tr>\n <tr>\n <td><strong>pending</strong></td>\n <td>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.</td>\n </tr>\n <tr>\n <td><strong>failed</strong></td>\n <td>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.).</td>\n </tr>\n <tr>\n <td><strong>canceled</strong></td>\n <td>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.</td>\n </tr>\n <tr>\n <td><strong>inprocess</strong></td>\n <td>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.</td>\n </tr>\n <tr>\n <td><strong>onhold</strong></td>\n <td>The order has encountered a problem during the fulfillment that needs to be resolved together with Printful customer service before fulfillment can continue.</td>\n </tr>\n <tr>\n <td><strong>partial</strong></td>\n <td>The order is partially fulfilled (some items are shipped already, the rest will follow).</td>\n </tr>\n <tr>\n <td><strong>fulfilled</strong></td>\n <td>All items have been shipped successfully.</td>\n </tr>\n</table>\n\nYou are only charged for orders when they have been confirmed with the “Confirm Order” operation and have the status “pending” [Confirm Order](#operation/confirmOrder).\nIf 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.\n\nFor order status updates please subscribe to one of the webhook events following\nwebhook events:\n- [Order created](#tag/Webhook-v2/operation/orderCreated)\n- [Order updated](#tag/Webhook-v2/operation/orderUpdated)\n- [Order failed](#tag/Webhook-v2/operation/orderFailed)\n- [Order canceled](#tag/Webhook-v2/operation/orderCanceled)\n\n## Order items\n\nOrder items are representations of the actual products that will come with an order.\n\nIn the sections below we explain each order item source and provide examples of how a simple request might look like for each source.\n\n### Catalog Source\n\n[Catalog products](https://developers.printful.com/docs/v2-beta/#tag/Catalog-v2/What-is-a-catalog-product) are blank products available in Printful. Since they are blank you’ll need to specify design data during the order creation.\nThis flow is intended if you allow your customers to specify their own designs which means that every order is unique.\n\nTo sell pre-defined products (Sync products) refer to [Sync variant](#sync-source).\n\nThe following example request shows how an item structure might look in JSON.\n\n```\nPOST https://api.printful.com/v2/orders/{{order_id}}/order-items\nAuthorization: Bearer {{bearer_token}}\n{\n \"catalog_variant_id\": 4012,\n \"source\": \"catalog\",\n \"quantity\": 1,\n \"placements\": [\n {\n \"placement\": \"front\",\n \"technique\": \"dtg\",\n \"layers\": [\n {\n \"type\": \"file\",\n \"url\": \"https://www.printful.com/static/images/layout/printful-logo.png\"\n }\n ]\n }\n ]\n}\n```\n<img src=\"images/mockups/example_order_item_mockup.jpg#center\" width=\"300\" href=\"images/mockups/example_order_item_mockup.png\"/>\n\n### Sync Source\n\nIn contrast to the catalog source, the sync source uses sync variants which \nalready hold information about design and retail costs. More information about \nthe sync variants can be found at [Sync V2](#tag/Sync-v2).\n\nThis means that you don’t need to specify all of the data that would otherwise \nbe required when using the [catalog source](#catalog-source). \nTo order a sync variant you just need to specify the `sync_variant_id`, quantity\nand source properties.\n```\nPOST https://api.printful.com/v2/orders/{{order_id}}/order-items\nAuthorization: Bearer {{bearer_token}}\n{\n\t\"source\": \"sync\",\n\t\"sync_variant_id\": {{sync_variant_id}},\n\t\"quantity\": 1\n}\n```\n\n<div class=\"alert alert-info\">\n <b>Note</b> When an order item is created from the sync source the fulfilled\n item will have the design of the sync variant at the time the order item was\n created. If the design of the sync variant is changed after the order item is\n created those changes won’t be reflected in the order order unless the item is\n created again.\n</div>\n\n## Design specification\nDesign data is the information used to customize the product. A design consists\nof placements, layers and unique product options. Placements refer to where a \ndesign will be printed, for example, a T-Shirt might have the placements `front` \nand `left_sleeve`. Placements can also constrict what techniques can be used in \nthat area of the product, for example a product might have both `front` and \n`embroidery_front` and embroidery can only be used in the second placement.\nA layer is constrained to the print area of the placement that you’ve chosen. \nA design that is outside of the print area won’t be visible.\n\nDepending on the product, placement, and technique different layers might \nbe available. \n\nYou can check which layers are available using the [Retrieve a single catalog product](#tag/Catalog-v2/operation/getProductById)\noperation.\n\nThe design data structure is the same regardless of the flow (making orders,\ncreating sync products etc.). So the solution can be re-used in the different\nendpoints.\n\n[<img src=\"images/design-data/design-data.png#center\" width=\"600\"/>](images/design-data/design-data.png)\n\n### Placements\nThe product placement is the part of the product where design layers will be \nprinted, different placements will also offer different options and techniques, \nthey will also have different limitations. The available placement list will \nvary depending on the product. To get the available placements of a product use \nthe [Retrieve a single catalog product](#tag/Catalog-v2/operation/getProductById) \nendpoint with the product ID that you want to check.\n\n<figure style=\"display: flex; flex-direction: column; align-items: center;\">\n <figcaption>Front placement:</figcaption>\n <img src=\"images/design-data/placements/front.png\" width=\"300\" href=\"images/design-data/placements/front.png\"/>\n</figure>\n<figure style=\"display: flex; flex-direction: column; align-items: center;\">\n <figcaption>Left sleeve placement:</figcaption>\n <img src=\"images/design-data/placements/left_sleeve.png\" width=\"300\" href=\"images/design-data/placements/left_sleeve.png\"/>\n</figure>\n\n<div class=\"alert alert-info\">\n <b>Note</b> depending on the type and quantity of the placement additional fees might apply.\n</div>\n\n### Layers\nLayers are what is printed in each placement, and there can be up to 5 of them \nper one placement. The layers are printed on top of each other with the 0th \nlayer being the furthest back and the 4th element being on top of all other layers.\n\nAPI supports only one layer type - `file`.\n\n[<img src=\"images/design-data/layers/layer_diagram.png#center\" width=\"600\"/>](images/design-data/layers/layer_diagram.png)\n\nLayers are defined as an array per placement:\n```\n...\n \"layers\": [\n {\n \"type\": \"file\",\n \"url\": \"https://picsum.photos/200\",\n \"layer_options\": [\n {\n \"name\": \"thread_colors\",\n \"value\": [\n \"#FFFFFF\"\n ]\n }\n ],\n \"position\": {\n \"width\": 640,\n \"height\": 640,\n \"left\": 0,\n \"top\": 0\n }\n }\n ]\n...\n```\n\n#### Layer Positioning\nYou can specify the image position inside the print area by providing a position object.\n\nEach print area has specific dimensions, by default our system will assume that your file \nhas to fit into those limitations and not exceed them. The (0,0) point is always \nlocated in the top left corner of the print area.\n\n<div class=\"alert alert-info\">\n <b>Note</b> all values are in inches.\n</div>\n\n#### Example of positioning the 450x450 image on the front placement\n\n<table>\n <tr>\n <td> Position </td> \n <td> Mockup </td>\n <td> Payload </td>\n </tr>\n <tr>\n<td> Top left </td>\n<td> <img alt=\"Top left mockup\" src=\"images/position/top_left.png\" width=\"300\"/> </td>\n<td>\n\n```\n \"position\": {\n \"area_width\": 1800,\n \"area_height\": 2400,\n \"width\": 450,\n \"height\": 450,\n \"top\": 0,\n \"left\": 0\n }\n```\n\n</td>\n</tr>\n\n<tr>\n<td> Top middle </td>\n<td> <img alt=\"Top left mockup\" src=\"images/position/top_middle.png\" width=\"300\"/> </td>\n<td>\n\n```\n\"position\": {\n \"area_width\": 1800,\n \"area_height\": 2400,\n \"width\": 450,\n \"height\": 450,\n \"top\": 0,\n \"left\": 675\n}\n```\n\n</td>\n</tr>\n\n<tr>\n<td> Top right </td>\n<td> <img alt=\"Top left mockup\" src=\"images/position/top_right.png\" width=\"300\"/> </td>\n<td>\n\n```\n\"position\": {\n \"area_width\": 1800,\n \"area_height\": 2400,\n \"width\": 450,\n \"height\": 450,\n \"top\": 0,\n \"left\": 1350\n}\n```\n\n</td>\n</tr>\n\n<tr>\n<td> Middle </td>\n<td> <img alt=\"Top left mockup\" src=\"images/position/middle.png\" width=\"300\"/> </td>\n<td>\n\n```\n\"position\": {\n \"area_width\": 1800,\n \"area_height\": 2400,\n \"width\": 450,\n \"height\": 450,\n \"top\": 975,\n \"left\": 675\n}\n```\n\n</td>\n</tr>\n\n<tr>\n<td> Bottom left </td>\n<td> <img alt=\"Top left mockup\" src=\"images/position/bottom_left.png\" width=\"300\"/> </td>\n<td>\n\n```\n\"position\": {\n \"area_width\": 1800,\n \"area_height\": 2400,\n \"width\": 450,\n \"height\": 450,\n \"top\": 1950,\n \"left\": 0\n}\n```\n\n</td>\n</tr>\n\n<tr>\n<td> Bottom middle </td>\n<td> <img alt=\"Top left mockup\" src=\"images/position/bottom_middle.png\" width=\"300\"/> </td>\n<td>\n\n```\n\"position\": {\n \"area_width\": 1800,\n \"area_height\": 2400,\n \"width\": 450,\n \"height\": 450,\n \"top\": 1950,\n \"left\": 675\n}\n```\n\n</td>\n</tr>\n\n<tr>\n<td> Bottom right </td>\n<td> <img alt=\"Top left mockup\" src=\"images/position/bottom_right.png\" width=\"300\"/> </td>\n<td>\n\n```\n\"position\": {\n \"area_width\": 1800,\n \"area_height\": 2400,\n \"width\": 450,\n \"height\": 450,\n \"top\": 1950,\n \"left\": 1350\n}\n```\n\n</td>\n</tr>\n\n</table>\n\n### Options\nApart from placement and layers you can also specify options.\n```\n# Example of option data.\n{\n \"name\": \"unlimited_color\",\n \"value\": true\n}\n```\nOption always consist of the name of the option and the value. Value of the \noption can be different depending on the option type but they are always \npredefined for the specified product. You can always check what options and \nwhat values are available for a specific product by checking\n[Retrieve a single catalog product](#tag/Catalog-v2/operation/getProductById)\n\nOptions can be specified on three levels:\n- Product options - Those options specify additional design options for an \nentire product. E.g. `inside_pocket` allows you to define if a product should be \nfulfilled with an additional inside pocket. Or `stitch_color` lets you choose the \nstitch colors that will be used to stitch back All-Over print products.\n- Placement options - They specify options for an entire placement. Currently, \nthe only placement option is `unlimited_color` which if specified causes the \nplacement to be fulfilled using [Unlimited Color embroidery](https://www.printful.com/unlimited-color-embroidery)\n- Layer options - Specify additional parameters for a single layer. E.g. `3d_puff` \noption if set to true causes that particular layer to use [3D puff embroidery](https://www.printful.com/glossary/3d-puff-embroidery).\n\n## Order Customization\n### Packing Slip Customization\n\nThe packing slip information can be customized according to the store’s specific\nrequirements. Some of the options are: a custom logo, the name of the store,\ncustomer service email/phone, and more.\n\nThe packing slip fields can be configured at the store level (in the Dashboard \nat Settings > Stores > Branding > Packing slip section.) and overridden for a \nspecific order.\n\nTo override the packing slip settings for the order, you can use `packing_slip` \nfields for each order.\n\n```\nPOST https://api.printful.com/v2/orders\nAuthorization: Bearer {{bearer_token}}\n{\n \"recipient\": {\n \"address1\": \"19749 Dearborn St\",\n \"city\": \"Chatsworth\",\n \"state_code\": \"CA\",\n \"state_name\": \"California\",\n \"country_code\": \"US\",\n \"zip\": \"91311\"\n },\n \"customization\": {\n \"packing_slip\": {\n \"email\": \"[email protected]\",\n \"phone\": \"+48000000000\",\n \"message\": \"this is a message\",\n \"logo_url\": \"https://example.com/image.jpg\",\n \"store_name\": \"a store\"\n }\n }\n}\n```\n\nBelow you can find an example or a packing slip for a shipment with explained fields.\n\n\n\nField annotations:\n\n* **(1)** Barcode unique for the shipment.\n* **(2)** Store logo defined in the store settings or overridded using `packing_slip.logo_url` field.\n* **(3)** The date of the shipment.\n* **(4)** Packing slip number consisting of order and shipment IDs in Printful database, divided with a hyphen.\n* **(5)** The country from which the shipment is made. If the recipient is in the United States, this field will be\n absent.\n* **(6)** Recipient address with phone, without email address.\n* **(7)** Store name. This can be overridden using `packing_slip.store_name`.\n* **(8)** The address to which the shipment should be returned. By default it will be a Printful’s return address, but\n you can set your own address in the store settings (**Settings > Stores > Returns > Return address section**).\n* **(9)** The customer service phone number defined in the store settings or overridden using `packing_slip.phone`\n field.\n* **(10)** The customer service email address defined in the store settings or overridden using `packing_slip.email`\n field.\n* **(11)** Gift message. This is only present if the `gift` field was provided in the order request.\n* **(12)** The order creation date.\n* **(13)** Printful Order ID which can be overridden using `packing_slip.custom_order_id` field.\n* **(14)** The list of order items with quantities. The items’ display names are localized, using the recipient’s\n country and include variant information such as color and size e.g. „Unisex Staple T-Shirt | Bella + Canvas 3001 (\n Lilac / M)”.\n* **(15)** The packing slip message defined in the store settings or overridden using `packing_slip.message` field.\n\n### Gift\nThe order gift option is part of the order customization and contains two properties:\nsubject and message. This option allows users to add a custom note that will be seen \nby the final customer who receives the product.\n\n```\nPOST https://api.printful.com/v2/orders\nAuthorization: Bearer {{bearer_token}}\n{\n \"recipient\": {\n \"address1\": \"19749 Dearborn St\",\n \"city\": \"Chatsworth\",\n \"state_code\": \"CA\",\n \"state_name\": \"California\",\n \"country_code\": \"US\",\n \"zip\": \"91311\"\n },\n \"customization\": {\n \"gift\": {\n \"subject\": \"To John\",\n \"message\": \"Happy birthday!\"\n }\n }\n}\n```\n\n## Notes for Beta\n\nThe Orders endpoints for the V2 Beta are incomplete. Some V1 endpoints will\nstill need to be used to achieve certain functionality.\n\n- To cancel an order use `DELETE https://api.printful.com/orders/{order_id}`\n https://developers.printful.com/docs/#operation/cancelOrderById\n- Incomplete, or unsynced, items that were created via an integration store but\n haven't been synced with printful yet will not be visible via the V2 orders\n endpoints, if you need this functionality you will need to use V1\n https://developers.printful.com/docs/#tag/Orders-API\n- To update an existing order, use `PUT https://api.printful.com/orders/{order_id}`\n https://developers.printful.com/docs/#operation/updateOrderById\n\n## Order Cost Calculations\n\n**Order costs are calculated asynchronously**. This means when you create or \nupdate an order you are likely to see a response from the API with `costs` and \n`retail_costs` fields set to null and `\"calculation_status\": \"calculating\"`.\n\n```\n\"costs\": {\n \"calculation_status\": \"calculating\",\n \"currency\": null,\n \"subtotal\": null,\n \"discount\": null,\n \"shipping\": null,\n \"digitization\": null,\n \"additional_fee\": null,\n \"fulfillment_fee\": null,\n \"retail_delivery_fee\": null,\n \"tax\": null,\n \"vat\": null,\n \"total\": null\n},\n\"retail_costs\": {\n \"calculation_status\": \"calculating\",\n \"currency\": \"USD\",\n \"subtotal\": \"0.00\",\n \"discount\": \"1.00\",\n \"shipping\": \"0.00\",\n \"tax\": \"0.00\",\n \"vat\": \"0.00\",\n \"total\": null\n},\n```\n\nOnce the costs and retail costs are calculated the \"calculation_status\" will \nchange the status to \"done\"\n\n```\n\"costs\": {\n \"calculation_status\": \"done\",\n \"currency\": \"USD\",\n \"subtotal\": \"107.50\",\n \"discount\": \"0.00\",\n \"shipping\": \"14.84\",\n \"digitization\": \"0.00\",\n \"additional_fee\": \"0.00\",\n \"fulfillment_fee\": \"0.00\",\n \"retail_delivery_fee\": \"0.00\",\n \"tax\": \"11.20\",\n \"vat\": \"0.00\",\n \"total\": \"133.54\"\n},\n\"retail_costs\": {\n \"calculation_status\": \"done\",\n \"currency\": \"USD\",\n \"subtotal\": \"0.00\",\n \"discount\": \"1.00\",\n \"shipping\": \"0.00\",\n \"tax\": \"0.00\",\n \"vat\": \"0.00\",\n \"total\": \"134.54\"\n},\n```\n\nIf you are subscribed to the `order_updated` [webhook event](#tag/Webhook-v2/operation/orderUpdated), \nyou will receive an event when the calculation is finished. \n\n"
},
{
"name": "Files v2",
"description": "To avoid the need to upload every file again when the same item is ordered,\nyour print files are stored in the File Library and can be reused.\n\nYou can use this API to directly add files to the library, and later use\nFile IDs when creating orders. However, the more convenient way is to specify\nthe files by URL at the same time the order is created.\n\n<div class=\"alert alert-info\">\nMost probably you will never need to use this API - just specify the file URL\nwhen creating orders and the files will be added automatically.\n</div>\n\nFile processing can be very time-consuming, so they are processed\nasynchronously. After you add a file, it is saved with the status\n`waiting` and downloaded and processed later. Afterward, the status\nis changed to `ok` if the file was loaded successfully and was a valid\nimage file or `failed` if the process did not succeed. Some file\nmetadata fields like dimensions and resolution are only filled in\nafter the file has been processed.\n\nIf an order with a file has been confirmed before the file was processed,\nand the file turns out to be invalid, then the order is reverted to a failed\nstate and needs to be corrected and confirmed again.\n\nIf you try to add a file that has an identical URL to an already\nexisting file, then no new file is created, and the system returns\nthe old one without refreshing its contents.\n\n<div class=\"alert alert-info\">\n<strong>Remember</strong><br>\nIf you have changed the original, make sure that the URL is changed as well\nfor future orders, otherwise the old version will be reused.\n</div>\n\nYou can add a “last modified” timestamp to the end of the URL to ensure\nthat the URL is different for changed files.\n\nFiles that are added through the API can be set not to show up in the\nFile library on the web,\njust set the visible attribute to false when creating them.\n\n**Caution: API endpoint \"Get list of files\" (/files) is removed and can no longer be used. Calling this endpoint will return a HTTP 410 (Gone) response.**\n\n[See examples](#section/File-Library-API-examples)\n"
},
{
"name": "Countries v2",
"description": "To create an order, you have to use country and state codes to specify the recipient address. Both country code and state code are mandatory for orders to the USA, Canada and Australia. For other countries only the country code is needed to create an order.\n\nCountry codes are based on the ISO 3166-1 alpha-2 standard and are two letters long.\n\nState codes are based on the ISO 3166-2 standard by omitting the country code part of the code and are used only for the USA, Canada, Japan and Australia.\n\nAll state/country codes that Printful accepts can be listed by this API.\n"
},
{
"name": "Shipping Rates v2",
"description": "**Rate limiting:** The default rate limit is 120 requests per 60 seconds.\n\n<div class=\"alert alert-danger\">\n <strong>Warning:</strong> If the summary item quantity count exceeds 100 then the rate limit\nis changed to 5 requests per 60 seconds.\n</div>\n\nA 60 seconds lockout is applied if request count is exceeded."
},
{
"name": "Warehouse Products v2",
"description": "Warehouse Products v2"
},
{
"name": "Mockup Generator v2",
"description": "This resource is used to visualize how the designed products will look like. Since this is a resource-heavy operation we process the requests asynchronously. That means that you won't get the results\nimmediately, and instead you will get task ID which you could use to retrieve the mockups once they are done\nusing _[Retrieve mockup generator tasks](#operation/getMockupGeneratorTasks)_.\nYou can also subscribe to a webhook _[Mockup generator task finished event](#operation/mockupTaskFinished)_ to be\nnotified once the tasks finish processing.\n\nTo create a mockup you need to specify:\n* catalog product ID – _[Retrieve a list of catalog products](#operation/getProducts)_\n* catalog variant IDs – _[Retrieve information about catalog product variants](#operation/getProductVariantsById)_\n* design data – Data used to specify how the design should look like on the catalog product\n* mockup styles – _[Retrieve catalog product mockup styles](#operation/retrieveMockupStylesByProductId)_\n\nWhile `placements` specifies how the catalog product should look like, the `mockup_style_ids` define\nhow the mockups themselves should look like. You can find available mockup styles for a product by requesting\n_[Retrieve catalog product mockup styles](#operation/retrieveMockupStylesByProductId)_.\n\nTo give a little bit more context on how to use product mockup styles see the table below:\n\nThe example product is Bella Canvas 3001 with ID 71.\n\n\n<table>\n <tr>\n <td> Mockup styles </td> \n <td> Mockups </td>\n </tr>\n <tr>\n<tr>\n<td>\n\n```\n {\n \"style_id\": 1115,\n \"style_name\": \"Men's\",\n \"view_name\": \"Front\"\n }\n```\n\n</td>\n<td> <img alt=\"Men's front mockup\" src=\"images/mockup-styles/mens_front.png\" width=\"300\"/> </td>\n</tr>\n\n<tr>\n<td>\n\n```\n {\n \"style_id\": 1103,\n \"style_name\": \"Men's\",\n \"view_name\": \"Left sleeve\"\n }\n```\n\n</td>\n<td> <img alt=\"Men's left sleeve mockup\" src=\"images/mockup-styles/mens_left.png\" width=\"300\"/> </td>\n</tr>\n\n<tr>\n<td>\n\n```\n {\n \"style_id\": 1117,\n \"style_name\": \"Women's\",\n \"view_name\": \"Front\"\n }\n```\n\n</td>\n<td> <img alt=\"Women's front mockup\" src=\"images/mockup-styles/womens_front.png\" width=\"300\"/> </td>\n</tr>\n\n<tr>\n<td>\n\n```\n {\n \"style_id\": 1107,\n \"style_name\": \"Women's\",\n \"view_name\": \"Left sleeve\"\n }\n```\n\n</td>\n<td> <img alt=\"Women's left sleeve mockup\" src=\"images/mockup-styles/womens_left.png\" width=\"300\"/> </td>\n</tr>\n\n<tr>\n<td>\n\n```\n {\n \"style_id\": 768,\n \"style_name\": \"Women's Lifestyle\",\n \"view_name\": \"Front\"\n }\n```\n\n</td>\n<td> <img alt=\"Women's lifestyle front mockup\" src=\"images/mockup-styles/womens_lifestyle_front.png\" width=\"300\"/> </td>\n</tr>\n\n<tr>\n<td>\n\n```\n {\n \"style_id\": 770,\n \"style_name\": \"Women's Lifestyle\",\n \"view_name\": \"Left\"\n }\n```\n\n</td>\n<td> <img alt=\"Women's lifestyle left mockup\" src=\"images/mockup-styles/womens_lifestyle_left.png\" width=\"300\"/> </td>\n</tr>\n\n<tr>\n<td>\n\n```\n {\n \"style_id\": 849,\n \"style_name\": \"Flat\",\n \"view_name\": \"Front\"\n }\n```\n\n</td>\n<td> <img alt=\"Flat front mockup\" src=\"images/mockup-styles/flat_front.png\" width=\"300\"/> </td>\n</tr>\n\n<tr>\n<td>\n\n```\n {\n \"style_id\": 931,\n \"style_name\": \"On hanger\",\n \"view_name\": \"Front\"\n }\n```\n\n</td>\n<td> <img alt=\"On hanger front mockup\" src=\"images/mockup-styles/on_hanger_front.png\" width=\"300\"/> </td>\n</tr>\n</table>\n\n## Mockups from the product templates\n\nInstead of creating a mockups from catalog variants data you can generate them from a product template.\nIn that case all you need is:\n* product template ID\n* catalog variant IDs – _[Retrieve information about catalog product variants](#operation/getProductVariantsById)_\n* mockup styles – _[Retrieve catalog product mockup styles](#operation/retrieveMockupStylesByProductId)_\n\n**Important**: All the catalog variants specified in the request must also be defined in the product template,\notherwise an error will be returned.\n\n## Mockups from the sync variants\n\nCreating mockups from sync variants is also possible. \nIn that case you need to specify:\n* catalog product ID – _[Retrieve a list of catalog products](#operation/getProducts)_\n* sync variant IDs – _[Retrieve information about catalog product variants](#operation/getSyncProductVariants)_\n* mockup styles – _[Retrieve catalog product mockup styles](#operation/retrieveMockupStylesByProductId)_\n\n**Important**: All the sync variants must belong to the same catalog product. They also need to have the same design, otherwise\nyou will receive an error, and you would need to create a separate request for each sync variant that contains a different design.\n\n## Throttling and daily file limit\n\nAn account is allowed to make a number of mockup generation requests per minute. The limit is:\n\n* 2 requests per minute for new stores;\n* 10 requests per minute for stores with at least $10.00 worth of fulfilled orders.\n\nAdditionally, there is a limit of 20,000 files that can be generated daily by each environment.\n\n## Number of generated files\n\nThere will be one mockup file returned for each valid combination of Catalog Variant, mockup style and placement within\none product object.\n\nIf the same file would be generated for two or more combinations (for example, for different sizes of a T-Shirt in the\nsame color),\nit will only be generated once and the same URL will be returned for each of these combinations. If only one file is generated it will count\nas one file toward the daily limit."
},
{
"name": "Webhook v2",
"description": "Webhooks are an API feature that allows your system to receive notifications about certain events.\n\nWhen an event occurs, for example one of the products you use comes back in stock, the Printful server\nwill make a POST request to your defined\nURL that will contain a JSON object in the request body.\nYour server has to respond with HTTP status `2xx OK`,\notherwise, the request will be retried in increasing intervals\n(after 1, 4, 16, 64, 256 and 1024 minutes).\n\nThe JSON object will always contain these attributes:\n<table>\n <tr>\n <td><strong>type</strong></td>\n <td>string</td>\n <td>Event type</td>\n </tr>\n <tr>\n <td><strong>occurred_at</strong></td>\n <td>timestamp</td>\n <td>Event time</td>\n </tr>\n <tr>\n <td><strong>retries</strong></td>\n <td>integer</td>\n <td>Number of previous attempts to deliver this webhook event</td>\n </tr>\n <tr>\n <td><strong>store_id</strong></td>\n <td>integer</td>\n <td>ID of the store that the event occurred to</td>\n </tr>\n <tr>\n <td><strong>data</strong></td>\n <td>Object</td>\n <td>Additional data, depending on the event type</td>\n </tr>\n</table>\n\nCurrently, our [Webhook Simulator](https://www.printful.com/api/webhook-simulator) doesn't support the v2 webhooks.\n\n### Event signing\n\nSince the webhook URL used to accept the events needs to be publicly availably, it's important to be able to\nverify if the event originates from our servers or was sent by someone else who knows the URL.\n\nThat's why we introduced event signing in Webhook v2.\n\nWebhook settings are associated with a public and a secret key. The public key is used to identify the specific\nsettings (you may use the same URL for different configurations) and the secret key is used to generate\nand verify the event signature.\n\nWe're using HMAC-SHA256 hash to create the signature. For tests, you may find an online or offline tool\nand check if you get the same hash for the event data you receive and the configuration's secret key.\n\nFor actual usage, we strongly recommend to incorporate the signature verification in the event handling process.\n\nIf you find that you receive an event with invalid or missing signature, you should ignore the event.\n\nYou may investigate the situation, starting with verifying if your configuration is correct.\nIt's possible you used wrong secret key to generate the signature on your side or generated it for the formatted\nevent content instead of the raw content etc.\n\nIf you didn't find an explanation, you may contact us with the event details (content, your URL, event time)\nso we can check if we sent such an event and find out why the signature is invalid.\n\n### Expiration time\n\nIt's possible to specify the expiration time of the configuration. If you decide to use this option,\nyou will be forced to resubscribe which will generate a new key pair. You may simply send the GET request\nwhen the configuration is still valid and use the returned data to create the new configuration.\n\nIf the configuration is already expired and you don't have the data saved somewhere, a regular GET request\nwill result in a 404 Not Found response with a message explaining what needs to be done:\n\"The settings are expired. To view them, please use query param show_expired with value true.\"\n\nYou may then use `show_expired` param with value `true` to retrieve the configuration and use it to resubscribe.\n\nPlease note that once the new configuration is saved, the new secret key will be used to sign the events.\nIt needs to be updated in your code as soon as possible to avoid invalid signature warnings."
},
{
"name": "Stores v2",
"description": "Stores v2"
},
{
"name": "Approval Sheets v2",
"description": "Get information about approval sheets."
},
{
"name": "Examples",
"description": "# Catalog API examples\n\n## Using size guides\n\nIn this example, we'll fetch the size guides for the\n\"Women's Basic Organic T-Shirt | SOL'S 02077\" product (ID: 561).\n\nWe use the default `en_US` locale and don't provide the `unit` parameter, so the measurement values will be returned in\ninches.\n\nURL: https://api.printful.com/v2/catalog-products/561/sizes\n\n<details>\n <summary>Whole response body</summary>\n\n```javascript\n{\n \"data\": {\n \"product_id\": 561,\n \"available_sizes\": [\n \"S\",\n \"M\",\n \"L\",\n \"XL\",\n \"2XL\"\n ],\n \"size_tables\": [\n {\n \"type\": \"measure_yourself\",\n \"unit\": \"inches\",\n \"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>\",\n \"image_url\": \"https://s3-printful.stage.printful.dev/upload/measure-yourself/6a/6a4fe322f592f2b91d5a735d7ff8d1c0_t?v=1652962720\",\n \"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>\",\n \"measurements\": [\n {\n \"type_label\": \"Length\",\n \"values\": [\n {\n \"size\": \"S\",\n \"value\": \"25.2\"\n },\n {\n \"size\": \"M\",\n \"value\": \"26\"\n },\n {\n \"size\": \"L\",\n \"value\": \"26.7\"\n },\n {\n \"size\": \"XL\",\n \"value\": \"27.6\"\n },\n {\n \"size\": \"2XL\",\n \"value\": \"28.3\"\n }\n ]\n },\n {\n \"type_label\": \"Chest\",\n \"values\": [\n {\n \"size\": \"S\",\n \"min_value\": \"34\",\n \"max_value\": \"37\"\n },\n {\n \"size\": \"M\",\n \"min_value\": \"36\",\n \"max_value\": \"39\"\n },\n {\n \"size\": \"L\",\n \"min_value\": \"39\",\n \"max_value\": \"42\"\n },\n {\n \"size\": \"XL\",\n \"min_value\": \"41\",\n \"max_value\": \"44\"\n },\n {\n \"size\": \"2XL\",\n \"min_value\": \"43\",\n \"max_value\": \"46\"\n }\n ]\n }\n ]\n },\n {\n \"type\": \"product_measure\",\n \"unit\": \"inches\",\n \"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>\",\n \"image_url\": \"https://s3-printful.stage.printful.dev/upload/product-measure/85/857e7cc8b802da216e7f1a6114075a72_t?v=1652962720\",\n \"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>\",\n \"measurements\": [\n {\n \"type_label\": \"Length\",\n \"values\": [\n {\n \"size\": \"S\",\n \"value\": \"25.2\"\n },\n {\n \"size\": \"M\",\n \"value\": \"26\"\n },\n {\n \"size\": \"L\",\n \"value\": \"26.7\"\n },\n {\n \"size\": \"XL\",\n \"value\": \"27.6\"\n },\n {\n \"size\": \"2XL\",\n \"value\": \"28.3\"\n }\n ]\n },\n {\n \"type_label\": \"Width\",\n \"values\": [\n {\n \"size\": \"S\",\n \"value\": \"16.1\"\n },\n {\n \"size\": \"M\",\n \"value\": \"17.3\"\n },\n {\n \"size\": \"L\",\n \"value\": \"18.5\"\n },\n {\n \"size\": \"XL\",\n \"value\": \"19.7\"\n },\n {\n \"size\": \"2XL\",\n \"value\": \"20.9\"\n }\n ]\n }\n ]\n },\n {\n \"type\": \"international\",\n \"unit\": \"none\",\n \"image_url\": \"https://s3-printful.stage.printful.dev/upload/product-measure/85/857e7cc8b802da216e7f1a6114075a72_t?v=1652962720\",\n \"measurements\": [\n {\n \"type_label\": \"US size\",\n \"values\": [\n {\n \"size\": \"S\",\n \"min_value\": \"6\",\n \"max_value\": \"8\"\n },\n {\n \"size\": \"M\",\n \"min_value\": \"10\",\n \"max_value\": \"12\"\n },\n {\n \"size\": \"L\",\n \"min_value\": \"14\",\n \"max_value\": \"16\"\n },\n {\n \"size\": \"XL\",\n \"min_value\": \"18\",\n \"max_value\": \"20\"\n },\n {\n \"size\": \"2XL\",\n \"min_value\": \"22\",\n \"max_value\": \"24\"\n }\n ]\n },\n {\n \"type_label\": \"EU size\",\n \"values\": [\n {\n \"size\": \"S\",\n \"min_value\": \"36\",\n \"max_value\": \"38\"\n },\n {\n \"size\": \"M\",\n \"min_value\": \"40\",\n \"max_value\": \"42\"\n },\n {\n \"size\": \"L\",\n \"min_value\": \"44\",\n \"max_value\": \"46\"\n },\n {\n \"size\": \"XL\",\n \"min_value\": \"48\",\n \"max_value\": \"50\"\n },\n {\n \"size\": \"2XL\",\n \"min_value\": \"52\",\n \"max_value\": \"54\"\n }\n ]\n },\n {\n \"type_label\": \"UK size\",\n \"values\": [\n {\n \"size\": \"S\",\n \"min_value\": \"10\",\n \"max_value\": \"12\"\n },\n {\n \"size\": \"M\",\n \"min_value\": \"14\",\n \"max_value\": \"16\"\n },\n {\n \"size\": \"L\",\n \"min_value\": \"18\",\n \"max_value\": \"20\"\n },\n {\n \"size\": \"XL\",\n \"min_value\": \"22\",\n \"max_value\": \"24\"\n },\n {\n \"size\": \"2XL\",\n \"min_value\": \"26\",\n \"max_value\": \"28\"\n }\n ]\n }\n ]\n }\n ],\n \"_links\": {\n \"self\": {\n \"href\": \"https://api.printful.test/v2/catalog-products/561/sizes\"\n },\n \"product\": {\n \"href\": \"https://api.printful.test/v2/catalog-products/561\"\n }\n }\n },\n \"extra\": [],\n \"debug\": []\n}\n```\n\n</details>\n\nNow, we'll take a closer look at the objects related to all three types of size tables.\n\n### Measure yourself size table\n\nThis object provides all measurements for the end customers to be able to measure themselves and see what size they\nshould buy.\n\n<details>\n <summary>The corresponding response fragment</summary>\n\n```javascript\n...\n{\n \"type\": \"measure_yourself\",\n \"unit\": \"inches\",\n \"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>\",\n \"image_url\": \"https://s3-printful.stage.printful.dev/upload/measure-yourself/6a/6a4fe322f592f2b91d5a735d7ff8d1c0_t?v=1652962720\",\n \"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>\",\n \"measurements\": [\n {\n \"type_label\": \"Length\",\n \"values\": [\n {\n \"size\": \"S\",\n \"value\": \"25.2\"\n },\n {\n \"size\": \"M\",\n \"value\": \"26\"\n },\n {\n \"size\": \"L\",\n \"value\": \"26.7\"\n },\n {\n \"size\": \"XL\",\n \"value\": \"27.6\"\n },\n {\n \"size\": \"2XL\",\n \"value\": \"28.3\"\n }\n ]\n },\n {\n \"type_label\": \"Chest\",\n \"values\": [\n {\n \"size\": \"S\",\n \"min_value\": \"34\",\n \"max_value\": \"37\"\n },\n {\n \"size\": \"M\",\n \"min_value\": \"36\",\n \"max_value\": \"39\"\n },\n {\n \"size\": \"L\",\n \"min_value\": \"39\",\n \"max_value\": \"42\"\n },\n {\n \"size\": \"XL\",\n \"min_value\": \"41\",\n \"max_value\": \"44\"\n },\n {\n \"size\": \"2XL\",\n \"min_value\": \"43\",\n \"max_value\": \"46\"\n }\n ]\n }\n ]\n},\n...\n```\n\n</details>\n\nThe measurement image with the descriptions for the product as seen in the web version of the size guides:\n\n\n\nThe size chart from the web version:\n\n\n\n### Product measurements size table\n\nThis object provides all product measurements so the end customer can measure a product they own and see what size they\nshould buy.\n\n<details>\n <summary>The corresponding response fragment</summary>\n\n```javascript\n...\n{\n \"type\": \"product_measure\",\n \"unit\": \"inches\",\n \"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>\",\n \"image_url\": \"https://s3-printful.stage.printful.dev/upload/product-measure/85/857e7cc8b802da216e7f1a6114075a72_t?v=1652962720\",\n \"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>\",\n \"measurements\": [\n {\n \"type_label\": \"Length\",\n \"values\": [\n {\n \"size\": \"S\",\n \"value\": \"25.2\"\n },\n {\n \"size\": \"M\",\n \"value\": \"26\"\n },\n {\n \"size\": \"L\",\n \"value\": \"26.7\"\n },\n {\n \"size\": \"XL\",\n \"value\": \"27.6\"\n },\n {\n \"size\": \"2XL\",\n \"value\": \"28.3\"\n }\n ]\n },\n {\n \"type_label\": \"Width\",\n \"values\": [\n {\n \"size\": \"S\",\n \"value\": \"16.1\"\n },\n {\n \"size\": \"M\",\n \"value\": \"17.3\"\n },\n {\n \"size\": \"L\",\n \"value\": \"18.5\"\n },\n {\n \"size\": \"XL\",\n \"value\": \"19.7\"\n },\n {\n \"size\": \"2XL\",\n \"value\": \"20.9\"\n }\n ]\n }\n ]\n},\n...\n```\n\n</details>\n\nThe measurement image with the descriptions for the product as seen in the web version of the size guides:\n\n\n\nThe size chart from the web version:\n\n\n\n### International size conversion\n\nThis object provides information what international (US, EU, UK) sizes correspond to the product sizes.\n\n<details>\n <summary>The corresponding response fragment</summary>\n\n```javascript\n...\n{\n \"type\": \"international\",\n \"unit\": \"none\",\n \"measurements\": [\n {\n \"type_label\": \"US size\",\n \"values\": [\n {\n \"size\": \"S\",\n \"min_value\": \"6\",\n \"max_value\": \"8\"\n },\n {\n \"size\": \"M\",\n \"min_value\": \"10\",\n \"max_value\": \"12\"\n },\n {\n \"size\": \"L\",\n \"min_value\": \"14\",\n \"max_value\": \"16\"\n },\n {\n \"size\": \"XL\",\n \"min_value\": \"18\",\n \"max_value\": \"20\"\n },\n {\n \"size\": \"2XL\",\n \"min_value\": \"22\",\n \"max_value\": \"24\"\n }\n ]\n },\n {\n \"type_label\": \"EU size\",\n \"values\": [\n {\n \"size\": \"S\",\n \"min_value\": \"36\",\n \"max_value\": \"38\"\n },\n {\n \"size\": \"M\",\n \"min_value\": \"40\",\n \"max_value\": \"42\"\n },\n {\n \"size\": \"L\",\n \"min_value\": \"44\",\n \"max_value\": \"46\"\n },\n {\n \"size\": \"XL\",\n \"min_value\": \"48\",\n \"max_value\": \"50\"\n },\n {\n \"size\": \"2XL\",\n \"min_value\": \"52\",\n \"max_value\": \"54\"\n }\n ]\n },\n {\n \"type_label\": \"UK size\",\n \"values\": [\n {\n \"size\": \"S\",\n \"min_value\": \"10\",\n \"max_value\": \"12\"\n },\n {\n \"size\": \"M\",\n \"min_value\": \"14\",\n \"max_value\": \"16\"\n },\n {\n \"size\": \"L\",\n \"min_value\": \"18\",\n \"max_value\": \"20\"\n },\n {\n \"size\": \"XL\",\n \"min_value\": \"22\",\n \"max_value\": \"24\"\n },\n {\n \"size\": \"2XL\",\n \"min_value\": \"26\",\n \"max_value\": \"28\"\n }\n ]\n }\n ]\n}\n...\n```\n\n</details>\n\nThe international size conversion table from the web version:\n\n\n\n# Files API examples\n\n## Add a new file\n\nAdd file to the print file library, filename will be detected from URL. After creation file is not processed instantly.\n\nRequest body:\n\n```\n{\n \"url\": \"http://www.example.com/files/tshirts/example.png\"\n}\n```\n\nResponse data:\n\n```\n{\n \"data\": {\n \"id\": 11816,\n \"url\": \"http://www.example.com/files/tshirts/example.png\",\n \"hash\": null,\n \"filename\": null,\n \"mime_type\": null,\n \"size\": 0,\n \"width\": null,\n \"height\": null,\n \"dpi\": null,\n \"status\": \"waiting\",\n \"created\": \"2024-06-10T15:31:49Z\",\n \"thumbnail_url\": null,\n \"preview_url\": null,\n \"visible\": true,\n \"is_temporary\": false,\n \"_links\": {\n \"self\": {\n \"href\": \"https://api.printful.com/v2/files/11816\"\n }\n }\n }\n}\n```\n\nAdd file to the mockup library, and specify file name manually\n\nRequest body:\n\n```\n{\n \"type\": \"preview\",\n \"url\": \"http://www.example.com/files/tshirts/example.png\",\n \"filename\": \"shirt1.png\"\n}\n```\n\nAdd file to the library, but not show up in the web interface.\n\nRequest body:\n\n``` \n{\n \"url\": \"http://www.example.com/files/tshirts/example.png\",\n \"visible\": false\n}\n```\n\n# Shipping Rates API examples\n\n## Shipment information\n\nFor each entry in the response array, in addition to the basic information about the shipping rate (name, rate,\nestimated delivery time),\nan expected shipment split will be provided. Each shipment object will contain the following data:\n\n* departure country (2-letter code) – currently, this may be null for some branches. We plan to fix this in the\n foreseeable future;\n* shipment items included in the shipment (Catalog Variant ID and item quantity);\n* whether customs fees may be required for the shipment (`customs_fees_possible`).\n\nIt's possible the fees won't apply even if the value of the `customs_fees_possible` field is `true`, depending on the\ncharacteristics of the products and agreements between the countries. The value of `false` means the customs fees\nwon't be required for the shipment (e.g. shipment within the EU or the same country).\n\n### Example: Same-country shipment\n\nIn this example two shipping options are available. All items can be fulfilled in the US and they are split into two shipments because of large quantities. No customs fees will be charged.\n\n<details>\n <summary>Request body</summary>\n\n```\n{\n \"recipient\": {\n \"address1\": \"19749 Dearborn St\",\n \"city\": \"Chatsworth\",\n \"state_code\": \"CA\",\n \"country_code\": \"US\",\n \"zip\": \"91311\"\n },\n \"order_items\": [\n {\n \"source\": \"catalog\",\n \"quantity\": 20,\n \"catalog_variant_id\": 408\n },\n {\n \"source\": \"catalog\",\n \"quantity\": 20,\n \"catalog_variant_id\": 4011\n },\n {\n \"source\": \"catalog\",\n \"quantity\": 30,\n \"catalog_variant_id\": 4016\n },\n {\n \"source\": \"catalog\",\n \"quantity\": 40,\n \"catalog_variant_id\": 4020\n }\n ],\n \"currency\": \"USD\"\n}\n```\n\n</details>\n\n<details>\n <summary>Response data</summary>\n\n```\n{\n \"data\": [\n {\n \"shipping\": \"STANDARD\",\n \"shipping_method_name\": \"Flat Rate (Estimated delivery: Jan 20–27) \",\n \"rate\": \"60.74\",\n \"currency\": \"USD\",\n \"min_delivery_days\": 5,\n \"max_delivery_days\": 8,\n \"min_delivery_date\": \"2025-01-20\",\n \"max_delivery_date\": \"2025-01-27\",\n \"shipments\": [\n {\n \"departure_country\": \"US\",\n \"shipment_items\": [\n {\n \"catalog_variant_id\": 408,\n \"quantity\": 20\n },\n {\n \"catalog_variant_id\": 4011,\n \"quantity\": 20\n },\n {\n \"catalog_variant_id\": 4016,\n \"quantity\": 20\n }\n ],\n \"customs_fees_possible\": false\n },\n {\n \"departure_country\": \"US\",\n \"shipment_items\": [\n {\n \"catalog_variant_id\": 4016,\n \"quantity\": 10\n },\n {\n \"catalog_variant_id\": 4020,\n \"quantity\": 40\n }\n ],\n \"customs_fees_possible\": false\n }\n ]\n },\n {\n \"shipping\": \"STANDARD_CARBON_OFFSET\",\n \"shipping_method_name\": \"Standard rate with CO2 offsetting (Estimated delivery: Jan 20–27) \",\n \"rate\": \"70.64\",\n \"currency\": \"USD\",\n \"min_delivery_days\": 5,\n \"max_delivery_days\": 8,\n \"min_delivery_date\": \"2025-01-20\",\n \"max_delivery_date\": \"2025-01-27\",\n \"shipments\": [\n {\n \"departure_country\": \"US\",\n \"shipment_items\": [\n {\n \"catalog_variant_id\": 408,\n \"quantity\": 20\n },\n {\n \"catalog_variant_id\": 4011,\n \"quantity\": 20\n },\n {\n \"catalog_variant_id\": 4016,\n \"quantity\": 20\n }\n ],\n \"customs_fees_possible\": false\n },\n {\n \"departure_country\": \"US\",\n \"shipment_items\": [\n {\n \"catalog_variant_id\": 4016,\n \"quantity\": 10\n },\n {\n \"catalog_variant_id\": 4020,\n \"quantity\": 40\n }\n ],\n \"customs_fees_possible\": false\n }\n ]\n }\n ],\n \"extra\": []\n}\n```\n\n</details>\n\n### Example: shipments from different countries\n\nIn this example only one shipping option is available. One item can't be shipped from Europe, so it will be shipped from the US instead,\nprobably incurring customs fees.\n\n<details>\n <summary>Request body</summary>\n\n```\n{\n \"recipient\": {\n \"address1\": \"Warszawska 1\",\n \"city\": \"Gdańsk\",\n \"country_code\": \"PL\"\n },\n \"order_items\": [\n {\n \"source\": \"catalog\",\n \"quantity\": 1,\n \"catalog_variant_id\": 408\n },\n {\n \"source\": \"catalog\",\n \"quantity\": 1,\n \"catalog_variant_id\": 4011\n }\n ]\n}\n```\n\n</details>\n\n<details>\n <summary>Response data</summary>\n\n```\n{\n \"data\": [\n {\n \"shipping\": \"STANDARD\",\n \"shipping_method_name\": \"Flat Rate (Estimated delivery: Jan 21–28) \",\n \"rate\": \"5.54\",\n \"currency\": \"EUR\",\n \"min_delivery_days\": 8,\n \"max_delivery_days\": 14,\n \"min_delivery_date\": \"2025-01-21\",\n \"max_delivery_date\": \"2025-01-28\",\n \"shipments\": [\n {\n \"departure_country\": \"US\",\n \"shipment_items\": [\n {\n \"catalog_variant_id\": 408,\n \"quantity\": 1\n }\n ],\n \"customs_fees_possible\": true\n },\n {\n \"departure_country\": \"LV\",\n \"shipment_items\": [\n {\n \"catalog_variant_id\": 4011,\n \"quantity\": 1\n }\n ],\n \"customs_fees_possible\": false\n }\n ]\n }\n ],\n \"extra\": []\n}\n```\n\n</details>\n\n# Webhook API examples\n\n## Configuring webhooks\n\n### Enabling webhook support\n\nWe will use an endpoint allowing us to enable webhook support for a store specifying multiple events in one request.\n\nWe want to enable support for `order_put_hold`, `shipment_sent`, `shipment_returned`,\nand `catalog_stock_updated` events.\n\nWe want to receive the event at https://example.org/webhook/store for most events\nbut for `shipment_returned` we want to use https://example.org/webhook/catalog.\n\nYou may replace the URLs with your own. If you don't have a server software that will accept the events,\nyou may use a site like https://webhook.site/.\n\nWe don't want the configuration to expire.\n\nWe want to be notified of stock updates for the following product IDs: 1, 71.\n\nEndpoint: `POST https://api.printful.com/v2/webhooks`\n\nThe request needs to be authorized with a store-level token\nor an account-level token with the store ID specified in `X-PF-Store-ID` header.\n\n<details>\n <summary>Request body</summary>\n\n```\n{\n \"default_url\": \"https://example.org/webhook/store\",\n \"events\": [\n {\n \"type\": \"order_put_hold\"\n },\n {\n \"type\": \"shipment_sent\"\n },\n {\n \"type\": \"shipment_returned\",\n \"url\": \"https://example.org/webhook/catalog\"\n },\n {\n \"type\": \"catalog_stock_updated\",\n \"params\": [\n {\n \"name\": \"products\",\n \"value\": [\n {\n \"id\": 1\n },\n {\n \"id\": 71\n }\n ]\n }\n ]\n }\n ]\n}\n```\n\n</details>\n\n<details>\n <summary>Response data</summary>\n\n```\n{\n \"code\": 200,\n \"result\": {\n \"default_url\": \"https://example.org/webhook/store\",\n \"expires_at\": null,\n \"events\": [\n {\n \"type\": \"order_put_hold\",\n \"url\": null,\n \"params\": []\n },\n {\n \"type\": \"shipment_sent\",\n \"url\": null,\n \"params\": []\n },\n {\n \"type\": \"shipment_returned\",\n \"url\": \"https://example.org/webhook/catalog\",\n \"params\": []\n },\n {\n \"type\": \"catalog_stock_updated\",\n \"url\": null,\n \"params\": [\n {\n \"name\": \"products\",\n \"value\": [\n {\n \"id\": 1\n },\n {\n \"id\": 71\n }\n ]\n }\n ]\n }\n ],\n \"public_key\": \"somePublicKey\",\n \"secret_key\": \"0123456789abcdef...\"\n },\n \"extra\": []\n}\n```\n\n</details>\n\nThe public key will be used to distinguish between events coming from different configurations.\n\nFor example, if you use the same URL for different stores or create multiple configurations for the same store\nwith different tokens for the same URL, you may use the public key to know which configuration was used.\n\nThe secret key will be used to verify the signature of the received event.\n\n### Updating or adding event configuration\n\nIf you have the general settings created for the store, you may modify or update the settings for specific events.\n\nWe will now show how to add support for another event: `order_created`.\n\nEndpoint: `POST https://api.printful.com/v2/webhooks/{eventType}`\n\nIf you don't need to specify additional fields like URL, you may send the request without body.\nWe will send such a request in this example.\n\nRequest URL: https://api.printful.com/v2/webhooks/order_created\n\n<details>\n <summary>Response data</summary>\n\n```\n{\n \"code\": 200,\n \"result\": {\n \"type\": \"order_created\",\n \"url\": null,\n \"params\": []\n },\n \"extra\": []\n}\n```\n\n</details>\n\nThe endpoint may be used to replace existing event settings. It may be used for an already configured\nevent or a new one.\n\nRequest URL: https://api.printful.com/v2/webhooks/shipment_returned\n\nIf we omit the request body, we will replace the existing configuration with a custom URL\nwith a default one, using the store's `default_url`.\n\nHowever, we want to update the URL with another one.\n\n<details>\n <summary>Request body</summary>\n\n```\n{\n \"url\": \"https://example.org/webhook/another\"\n}\n```\n\n</details>\n\n<details>\n <summary>Response data</summary>\n\n```\n{\n \"code\": 200,\n \"result\": {\n \"type\": \"shipment_returned\",\n \"url\": \"https://example.org/webhook/another\",\n \"params\": []\n },\n \"extra\": []\n}\n```\n\n</details>\n\nNote it's not possible to omit the request body for an event requiring a parameter.\n\nSending a request without body to https://api.printful.com/v2/webhooks/catalog_stock_updated will result in an error.\n\n## Event example\n\nThis is an example of an `order_created` event sent to the specified URL:\n\n\n<details>\n <summary>Event content</summary>\n\n```\n{\n \"type\": \"order_created\",\n \"occurred_at\": \"2023-04-04T12:36:42Z\",\n \"retries\": 0,\n \"store_id\": 123456,\n \"data\": {\n \"order\": {\n \"id\": 11111,\n \"external_id\": null,\n \"status\": \"pending\",\n \"created\": 1680611801,\n \"updated\": 1680611802,\n \"dashboard_url\": \"https://www.printful.test/dashboard?order_id=90630659\",\n }\n }\n}\n```\n\n</details>\n\nIn headers, you will also receive:\n\n* The base64-encoded public key associated with the configuration used to trigger the event in `x-pf-webhook-public-key`\n header\n* The hexadecimal representation of the signature in `x-pf-webhook-signature` header.\n\nYou may use the secret key associated with the settings to calculate the HMAC-SHA256 hash for the event data\nand compare it to the value from header. You may create a script or use an online or offline tool to do this.\n\n# PATCH Partial Updates\n\nSee [RFC 7386](https://datatracker.ietf.org/doc/html/rfc7386).\n\nPATCH updates allows you to change only the fields that you've specified in the request.\n\nIf you'd like to update the value that is an array please keep in mind that in case of arrays the entire\narray is replaced with the value provided in the request. For example:\n\nCurrent array value:\n```\n{\n \"items\": [\n {\n \"catalog_variant_id\": 4011,\n \"placements\": [\n {\n \"placement\": \"front\",\n \"technique\": \"dtg\",\n \"layers\": [\n {\n \"type\": \"file\",\n \"url\": \"https://www.printful.com/static/images/layout/printful-logo.png\"\n }\n ]\n }\n ]\n },\n {\n \"catalog_variant_id\": 4012,\n \"placements\": [\n {\n \"placement\": \"front\",\n \"technique\": \"dtg\",\n \"layers\": [\n {\n \"type\": \"file\",\n \"url\": \"https://www.printful.com/static/images/layout/printful-logo.png\"\n }\n ]\n },\n {\n \"placement\": \"back\",\n \"technique\": \"dtg\",\n \"layers\": [\n {\n \"type\": \"file\",\n \"url\": \"https://www.printful.com/static/images/layout/printful-logo.png\"\n }\n ]\n }\n ]\n }\n ]\n}\n```\n\nPATCH request:\n```\n{\n \"items\": [\n {\n \"catalog_variant_id\": 4013,\n \"placements\": [\n {\n \"placement\": \"left_sleeve\",\n \"technique\": \"dtg\",\n \"layers\": [\n {\n \"type\": \"file\",\n \"url\": \"https://www.printful.com/static/images/layout/printful-logo.png\"\n }\n ]\n }\n ]\n }\n ]\n}\n```\n\nResults in:\n```\n{\n \"items\": [\n {\n \"catalog_variant_id\": 4013,\n \"placements\": [\n {\n \"placement\": \"left_sleeve\",\n \"technique\": \"dtg\",\n \"layers\": [\n {\n \"type\": \"file\",\n \"url\": \"https://www.printful.com/static/images/layout/printful-logo.png\"\n }\n ]\n }\n ]\n }\n ]\n}\n```\n\nNotice that all of the previous items were discarded and were replaced with items provided in the request.\nIt's also not possible to override properties in nested arrays. So whenever you are changing the array\nvalue you need to provide full object.\n\n## Example of order update\n\n<details>\n <summary>Order that is being updated</summary>\n\n```\n{\n \"data\": {\n \"id\": 94188292,\n \"external_id\": null,\n \"store_id\": 11229252,\n \"shipping\": \"STANDARD\",\n \"status\": \"draft\",\n \"created_at\": \"2023-10-18T12:35:07Z\",\n \"updated_at\": \"2023-10-18T12:35:07Z\",\n \"recipient\": {\n \"name\": \"John Smith\",\n \"company\": \"John Smith Inc\",\n \"address1\": \"19749 Dearborn St\",\n \"address2\": \"string\",\n \"city\": \"Chatsworth\",\n \"state_code\": \"CA\",\n \"state_name\": \"California\",\n \"country_code\": \"US\",\n \"country_name\": \"United States\",\n \"zip\": \"91311\",\n \"phone\": \"string\",\n \"email\": \"[email protected]\",\n \"tax_number\": \"123.456.789-10\"\n },\n \"costs\": {\n \"calculation_status\": \"calculating\",\n \"currency\": null,\n \"subtotal\": null,\n \"discount\": null,\n \"shipping\": null,\n \"digitization\": null,\n \"additional_fee\": null,\n \"fulfillment_fee\": null,\n \"retail_delivery_fee\": null,\n \"tax\": null,\n \"vat\": null,\n \"total\": null\n },\n \"retail_costs\": {\n \"calculation_status\": \"calculating\",\n \"currency\": \"USD\",\n \"subtotal\": null,\n \"discount\": \"0.00\",\n \"shipping\": \"0.00\",\n \"tax\": \"0.00\",\n \"vat\": \"0.00\",\n \"total\": null\n },\n \"order_items\": [\n {\n \"id\": 66655730,\n \"external_id\": \"some_external_id\",\n \"type\": \"order_item\",\n \"source\": \"catalog\",\n \"catalog_variant_id\": 4012,\n \"quantity\": 1,\n \"name\": \"my_custom_name\",\n \"price\": \"10.50\",\n \"retail_price\": null,\n \"currency\": \"EUR\",\n \"retail_currency\": \"USD\",\n \"_links\": {\n \"self\": {\n \"href\": \"https://api.printful.test/v2/orders/94188292/order-items/66655730\"\n }\n }\n }\n ],\n \"customization\": null,\n \"_links\": {\n \"self\": {\n \"href\": \"https://api.printful.test/v2/orders/94188292\"\n },\n \"order_confirmation\": {\n \"href\": \"https://api.printful.test/v2/orders/94188292/confirmation\"\n },\n \"order_items\": {\n \"href\": \"https://api.printful.test/v2/orders/94188292/order-items\"\n },\n \"shipments\": {\n \"href\": \"https://api.printful.test/v2/orders/94188292/shipments\"\n }\n }\n },\n \"extra\": [],\n}\n```\n\n</details>\n\n### Changing specified fields in recipient object\n\nEndpoint `PATCH https://api.printful.com/v2/orders/{order_id}`\n<details>\n <summary>Request body</summary>\n\n```\n{\n \"recipient\": {\n \"address1\": \"new address\",\n \"name\": \"new name\"\n }\n}\n```\n\n</details>\n\nEndpoint `GET https://api.printful.com/v2/orders/{order_id}`\n<details>\n <summary>Response body</summary>\n\n```\n{\n \"data\": {\n \"id\": 94188292,\n \"external_id\": null,\n \"store_id\": 11229252,\n \"shipping\": \"STANDARD\",\n \"status\": \"draft\",\n \"created_at\": \"2023-10-18T12:35:07Z\",\n \"updated_at\": \"2023-10-18T12:35:07Z\",\n \"recipient\": {\n \"name\": \"new name\", <--------Changed field\n \"company\": \"John Smith Inc\",\n \"address1\": \"new address\", <--------Changed field\n \"address2\": \"string\",\n \"city\": \"Chatsworth\",\n \"state_code\": \"CA\",\n \"state_name\": \"California\",\n \"country_code\": \"US\",\n \"country_name\": \"United States\",\n \"zip\": \"91311\",\n \"phone\": \"string\",\n \"email\": \"[email protected]\",\n \"tax_number\": \"123.456.789-10\"\n },\n \"costs\": {\n \"calculation_status\": \"calculating\",\n \"currency\": null,\n \"subtotal\": null,\n \"discount\": null,\n \"shipping\": null,\n \"digitization\": null,\n \"additional_fee\": null,\n \"fulfillment_fee\": null,\n \"retail_delivery_fee\": null,\n \"tax\": null,\n \"vat\": null,\n \"total\": null\n },\n \"retail_costs\": {\n \"calculation_status\": \"calculating\",\n \"currency\": \"USD\",\n \"subtotal\": null,\n \"discount\": \"0.00\",\n \"shipping\": \"0.00\",\n \"tax\": \"0.00\",\n \"vat\": \"0.00\",\n \"total\": null\n },\n \"order_items\": [\n {\n \"id\": 66655730,\n \"external_id\": \"some_external_id\",\n \"type\": \"order_item\",\n \"source\": \"catalog\",\n \"catalog_variant_id\": 4012,\n \"quantity\": 1,\n \"name\": \"my_custom_name\",\n \"price\": \"10.50\",\n \"retail_price\": null,\n \"currency\": \"EUR\",\n \"retail_currency\": \"USD\",\n \"_links\": {\n \"self\": {\n \"href\": \"https://api.printful.test/v2/orders/94188292/order-items/66655730\"\n }\n }\n }\n ],\n \"customization\": null,\n \"_links\": {\n \"self\": {\n \"href\": \"https://api.printful.test/v2/orders/94188292\"\n },\n \"order_confirmation\": {\n \"href\": \"https://api.printful.test/v2/orders/94188292/confirmation\"\n },\n \"order_items\": {\n \"href\": \"https://api.printful.test/v2/orders/94188292/order-items\"\n },\n \"shipments\": {\n \"href\": \"https://api.printful.test/v2/orders/94188292/shipments\"\n }\n }\n },\n \"extra\": [],\n}\n```\n\n</details>\n\n### Changing `external_id` property\n\nEndpoint `PATCH https://api.printful.com/v2/orders/{order_id}`\n<details>\n <summary>Request body</summary>\n\n```\n{\n \"external_id\": \"1234_abc\"\n}\n```\n\n</details>\n\nEndpoint `GET https://api.printful.com/v2/orders/{order_id}`\n<details>\n <summary>Response body</summary>\n\n```\n{\n \"data\": {\n \"id\": 94188292,\n \"external_id\": \"1234_abc\", <--------Changed field\n \"store_id\": 11229252,\n \"shipping\": \"STANDARD\",\n \"status\": \"draft\",\n \"created_at\": \"2023-10-18T12:35:07Z\",\n \"updated_at\": \"2023-10-18T12:35:07Z\",\n \"recipient\": {\n \"name\": \"John Smith\",\n \"company\": \"John Smith Inc\",\n \"address1\": \"19749 Dearborn St\",\n \"address2\": \"string\",\n \"city\": \"Chatsworth\",\n \"state_code\": \"CA\",\n \"state_name\": \"California\",\n \"country_code\": \"US\",\n \"country_name\": \"United States\",\n \"zip\": \"91311\",\n \"phone\": \"string\",\n \"email\": \"[email protected]\",\n \"tax_number\": \"123.456.789-10\"\n },\n \"costs\": {\n \"calculation_status\": \"calculating\",\n \"currency\": null,\n \"subtotal\": null,\n \"discount\": null,\n \"shipping\": null,\n \"digitization\": null,\n \"additional_fee\": null,\n \"fulfillment_fee\": null,\n \"retail_delivery_fee\": null,\n \"tax\": null,\n \"vat\": null,\n \"total\": null\n },\n \"retail_costs\": {\n \"calculation_status\": \"calculating\",\n \"currency\": \"USD\",\n \"subtotal\": null,\n \"discount\": \"0.00\",\n \"shipping\": \"0.00\",\n \"tax\": \"0.00\",\n \"vat\": \"0.00\",\n \"total\": null\n },\n \"order_items\": [\n {\n \"id\": 66655730,\n \"external_id\": \"some_external_id\",\n \"type\": \"order_item\",\n \"source\": \"catalog\",\n \"catalog_variant_id\": 4012,\n \"quantity\": 1,\n \"name\": \"my_custom_name\",\n \"price\": \"10.50\",\n \"retail_price\": null,\n \"currency\": \"EUR\",\n \"retail_currency\": \"USD\",\n \"_links\": {\n \"self\": {\n \"href\": \"https://api.printful.test/v2/orders/94188292/order-items/66655730\"\n }\n }\n }\n ],\n \"customization\": null,\n \"_links\": {\n \"self\": {\n \"href\": \"https://api.printful.test/v2/orders/94188292\"\n },\n \"order_confirmation\": {\n \"href\": \"https://api.printful.test/v2/orders/94188292/confirmation\"\n },\n \"order_items\": {\n \"href\": \"https://api.printful.test/v2/orders/94188292/order-items\"\n },\n \"shipments\": {\n \"href\": \"https://api.printful.test/v2/orders/94188292/shipments\"\n }\n }\n },\n \"extra\": [],\n}\n```\n\n</details>\n\n### Replacing ordered item with another one\n\nEndpoint `PATCH https://api.printful.com/v2/orders/{order_id}`\n<details>\n <summary>Request body</summary>\n\n```\n{\n \"items\": [\n {\n \"source\": \"catalog\",\n \"catalog_variant_id\": 4011,\n \"quantity\": 1,\n \"placements\": [\n {\n \"placement\": \"front\",\n \"technique\": \"dtg\",\n \"layers\": [\n {\n \"type\": \"file\",\n \"url\": \"https://www.printful.com/static/images/layout/printful-logo.png\",\n }\n ]\n }\n ]\n }\n ]\n}\n```\n\n</details>\n\nEndpoint `GET https://api.printful.com/v2/orders/{order_id}`\n<details>\n <summary>Response body</summary>\n\n```\n{\n \"data\": {\n \"id\": 94188292,\n \"external_id\": null,\n \"store_id\": 11229252,\n \"shipping\": \"STANDARD\",\n \"status\": \"draft\",\n \"created_at\": \"2023-10-18T12:35:07Z\",\n \"updated_at\": \"2023-10-18T12:35:07Z\",\n \"recipient\": {\n \"name\": \"John Smith\",\n \"company\": \"John Smith Inc\",\n \"address1\": \"19749 Dearborn St\",\n \"address2\": \"string\",\n \"city\": \"Chatsworth\",\n \"state_code\": \"CA\",\n \"state_name\": \"California\",\n \"country_code\": \"US\",\n \"country_name\": \"United States\",\n \"zip\": \"91311\",\n \"phone\": \"string\",\n \"email\": \"[email protected]\",\n \"tax_number\": \"123.456.789-10\"\n },\n \"costs\": {\n \"calculation_status\": \"calculating\",\n \"currency\": null,\n \"subtotal\": null,\n \"discount\": null,\n \"shipping\": null,\n \"digitization\": null,\n \"additional_fee\": null,\n \"fulfillment_fee\": null,\n \"retail_delivery_fee\": null,\n \"tax\": null,\n \"vat\": null,\n \"total\": null\n },\n \"retail_costs\": {\n \"calculation_status\": \"calculating\",\n \"currency\": \"USD\",\n \"subtotal\": null,\n \"discount\": \"0.00\",\n \"shipping\": \"0.00\",\n \"tax\": \"0.00\",\n \"vat\": \"0.00\",\n \"total\": null\n },\n \"order_items\": [ <--------Changed field\n {\n \"id\": 66655731,\n \"external_id\": null,\n \"type\": \"order_item\",\n \"source\": \"catalog\",\n \"catalog_variant_id\": 4011,\n \"quantity\": 1,\n \"name\": null,\n \"price\": \"10.50\",\n \"retail_price\": null,\n \"currency\": \"EUR\",\n \"retail_currency\": \"USD\",\n \"_links\": {\n \"self\": {\n \"href\": \"https://api.printful.test/v2/orders/94188292/order-items/66655730\"\n }\n }\n }\n ],\n \"customization\": null,\n \"_links\": {\n \"self\": {\n \"href\": \"https://api.printful.test/v2/orders/94188292\"\n },\n \"order_confirmation\": {\n \"href\": \"https://api.printful.test/v2/orders/94188292/confirmation\"\n },\n \"order_items\": {\n \"href\": \"https://api.printful.test/v2/orders/94188292/order-items\"\n },\n \"shipments\": {\n \"href\": \"https://api.printful.test/v2/orders/94188292/shipments\"\n }\n }\n },\n \"extra\": [],\n}\n```\n\n</details>\n\n# Utilising options\n\nOptions are the special properties which are used to customise the products. Depending on the product and the technique different options might be available.\nYou can check the available options for a product in [Retrieve a single catalog product](#tag/Catalog-v2/operation/getProductById). Currently, there are 3 types of options each referencing a different ascpect of the design:\n* `product_options` - options which affect the entire product e.g. if the product should contain inside pocket or not.\n* `placement_options` - options which are affecting the specific placement\n* `layer_options` - options which are affecting the specific layer e.g. thread colors\n\n### Custom border color option\n\nStickers can have a different border color which can be set by using the `thread_colors_outline` option.\nThis option is available in `product_options` for stickers. To showcase the usage we will use the order flow\nwhich will create order with a sticker that will have a red border color:\n\nEndpoint `POST https://api.printful.com/v2/orders`\n<details>\n <summary>Request body</summary>\n\n```\n{\n \"recipient\": {\n \"name\": \"John Smith\",\n \"company\": \"John Smith Inc\",\n \"address1\": \"19749 Dearborn St\",\n \"address2\": \"string\",\n \"city\": \"Chatsworth\",\n \"state_code\": \"CA\",\n \"state_name\": \"California\",\n \"country_code\": \"US\",\n \"country_name\": \"United States\",\n \"zip\": \"91311\"\n },\n \"items\": [\n {\n \"quantity\": 1,\n \"variant_id\": 10163,\n \"source\": \"catalog\",\n \"placements\": [\n {\n \"placement\": \"default\",\n \"technique\": \"digital\",\n \"layers\": [\n {\n \"type\": \"file\",\n \"url\": \"https://www.printful.com/static/images/layout/printful-logo.png\",\n \"position\": {\n \"width\": 3,\n \"height\": 3,\n \"top\": 0,\n \"left\": 0\n }\n }\n ]\n }\n ],\n \"product_options\": [\n {\n \"name\": \"custom_border_color\",\n \"value\": \"#FFFF00\"\n }\n ]\n }\n ]\n}\n```\n\n</details>\n\n# Creating Orders for Knitwear Products \n\nKnitwear products can be configured with some unique options that affect the color of the final knitted product.\n\nThese options are `trim_color`, `color_reduction_mode`, `base_color`, they only apply to\nknitwear and function differently to other similar options. \n\nNote that `yarn_colors` can be applied on each layer of a product.\n\n\nEndpoint `POST https://api.printful.com/v2/orders`\n<details>\n <summary>Request body</summary>\n\n```\n{\n \"recipient\": {\n \"name\": \"John Smith\",\n \"company\": \"John Smith Inc\",\n \"address1\": \"19749 Dearborn St\",\n \"city\": \"Chatsworth\",\n \"state_code\": \"CA\",\n \"country_code\": \"US\",\n \"country_name\": \"United States\",\n \"zip\": \"91311\"\n },\n \"order_items\": [\n {\n \"source\": \"catalog\",\n \"quantity\": 1,\n \"catalog_variant_id\": 19634,\n \"placements\": [\n {\n \"placement\": \"sleeve_right\",\n \"technique\": \"knitting\",\n \"layers\": [\n {\n \"type\": \"file\",\n \"url\": \"https://picsum.photos/200\",\n \"layer_options\": [\n {\n \"name\": \"yarn_colors\",\n \"value\": [\n \"#090909\",\n \"#48542e\"\n ]\n }\n ]\n }\n ]\n }\n ],\n \"product_options\": [\n {\n \"name\": \"trim_color\",\n \"value\": \"#dcd3cc\"\n },\n {\n \"name\": \"color_reduction_mode\",\n \"value\": \"pixelated\"\n },\n {\n \"name\": \"base_color\",\n \"value\": \"#dda032\"\n }\n ]\n }\n ]\n}\n```\n\n</details>\n# My Product API examples\n\nLet's start by creating an unpublished My Product through the API.\nTo do that you need to make the below request to create a My Product:\n\nEndpoint `POST https://api.printful.com/v2/products`\n<details>\n <summary>Request body</summary>\n\n```\n{\n \"placements\": [\n {\n \"placement\": \"front\",\n \"technique\": \"dtg\",\n \"layers\": [\n {\n \"type\": \"file\",\n \"url\": \"https://www.printful.com/static/images/layout/printful-logo.png\",\n }\n ]\n }\n ],\n \"source\": \"catalog\",\n \"catalog_product_id\": 71,\n \"name\": \"My custom Printful T-Shirt\"\n}\n```\n\n</details>\n\nAnd in the response you will receive:\n\n<details>\n <summary>Response body</summary>\n\n```\n{\n \"data\": {\n \"product_options\": [],\n \"placements\": [\n {\n \"placement\": \"front\",\n \"technique\": \"dtg\",\n \"layers\": [\n {\n \"type\": \"file\",\n \"url\": \"https://www.printful.com/static/images/layout/printful-logo.png\",\n \"layer_options\": []\n }\n ],\n \"placement_options\": [],\n \"status\": \"ok\",\n \"status_explanation\": \"\"\n }\n ],\n \"id\": 1000,\n \"external_id\": \"12312414\",\n \"source\": \"catalog\",\n \"catalog_product_id\": 71,\n \"name\": \"Red T-Shirt\",\n \"thumbnail_url\": \"https://your-domain.com/path/to/image.png\",\n \"published_to_stores\": [\n {\n \"store_id\": 123,\n \"sync_product_id\": 12345678,\n \"sync_product_external_id\": \"abc-1234\"\n }\n ],\n \"statuses\": {\n \"statuses\": [\n \"All in stock\"\n ]\n },\n \"available_catalog_variant_ids\": [\n 4011\n ],\n \"_links\": {\n \"self\": {\n \"href\": \"https://api.printful.com/v2/products/1000\"\n },\n \"variants\": {\n \"href\": \"https://api.printful.com/v2/products/1000/variants\"\n }\n }\n }\n}\n```\n\n</details>\n\nBelow are the most common use cases for My Products.\n\n## Creating order from My Product\n\nTo order the product using v2 order flow you need to provide:\n- `product_id` - which is the ID of your already prepared product\n- `catalog_variant_id` - which is a specific variant from the prepared product\n- `source` - needs to be `product` for this use case\n\nEndpoint `POST https://api.printful.com/v2/orders`\n<details>\n <summary>Request body</summary>\n\n```\n{\n \"recipient\": {\n \"name\": \"John Smith\",\n \"company\": \"John Smith Inc\",\n \"address1\": \"19749 Dearborn St\",\n \"address2\": \"string\",\n \"city\": \"Chatsworth\",\n \"state_code\": \"CA\",\n \"state_name\": \"California\",\n \"country_code\": \"US\",\n \"country_name\": \"United States\",\n \"zip\": \"91311\"\n },\n \"items\": [\n {\n \"quantity\": 1,\n \"variant_id\": 4011,\n \"product_id\": 1000,\n \"source\": \"product\",\n \"placements\": [\n {\n \"placement\": \"front\",\n \"technique\": \"dtg\",\n \"layers\": [\n {\n \"type\": \"file\",\n \"url\": \"https://www.printful.com/static/images/layout/printful-logo.png\"\n }\n ]\n }\n ]\n }\n ]\n}\n```\n\n</details>\n\n## Generating mockups from My Products\n\nTo generate mockups using custom product you need to provide:\n- `product_id` - which is the ID of your already prepared product,\n- `variant_id` - which is a specific variant from the prepared product,\n- `source` - needs to be `product` for this use case.\n\nEndpoint `POST https://api.printful.com/v2/mockup-tasks`\n<details>\n <summary>Request body</summary>\n\n```\n{\n \"format\": \"jpg\",\n \"products\": [\n {\n \"source\": \"product\",\n \"mockup_style_ids\": [\n 123\n ],\n \"product_id\": 1000,\n \"variant_ids\": [11, 12],\n \"placements\": [\n {\n \"placement\": \"front\",\n \"technique\": \"dtg\",\n \"layers\": [\n {\n \"type\": \"file\",\n \"url\": \"https://www.printful.com/static/images/layout/printful-logo.png\"\n }\n ]\n }\n ]\n }\n ]\n}\n```\n\n</details>\n\nIn the response \n\n## Updating My Product\n\n[Updating product](/docs/#operation/updateMyProduct) lets you change basic product\ndata such as name or design. There will be some small differences to keep in mind based on, whether the product is `\"published\"` or `\"unpublished\"`\n\n### Unpublished product\n\nUnpublished products can be only linked to a Printful catalog product. That means that certain properties will\nalways have the same value:\n- `source` - catalog,\n- `catalog_product_id` - an ID of the Printful catalog product.\n\nPlease keep in mind that if you change the catalog product that is linked to a product,\nyou will be required to also specify the `placements` property, since the new catalog product\nmight not be compatible with the current design.\n\nEndpoint `PATCH https://api.printful.com/v2/products/{product_id}`\n<details>\n <summary>Request body</summary>\n\n```\n{\n \"placements\": [\n {\n \"placement\": \"back\",\n \"technique\": \"dtg\",\n \"layers\": [\n {\n \"type\": \"file\",\n \"url\": \"https://www.printful.com/static/images/layout/printful-logo.png\",\n }\n ]\n }\n ],\n \"external_id\": \"1234-abcd\",\n \"source\": \"catalog\",\n \"catalog_product_id\": 71,\n \"name\": \"My custom Printful T-Shirt v2\"\n}\n```\n\n</details>\n\n### Published product\n\nUpdating the entire published product at once is only possible if it's been synced to a Printful catalog product.\nIn the case of a published product you can specify two distinct `source` properties:\n- warehouse - used for custom products stored in Printful warehouse,\n- catalog - used for Printful catalog products.\n\n## Updating My product variants\n\nIn the case, of an unpublished product, you won't be able to have separate designs\nfor each variant. In those cases, only one main design applies to each variant.\n\nTo sync a variant you need to link to a proper warehouse variant or the Printful catalog variant\n\nEndpoint `PATCH https://api.printful.com/v2/variants/{variant_id}`\n<details>\n <summary>Request body</summary>\n\n```\n{\n \"source\": \"catalog\",\n \"catalog_variant_id\": 4011,\n \"placements\": [\n {\n \"placement\": \"front\",\n \"technique\": \"dtg\",\n \"layers\": [\n {\n \"type\": \"file\",\n \"url\": \"https://www.printful.com/static/images/layout/printful-logo.png\"\n }\n ]\n }\n ],\n \"external_id\": \"12312414\",\n \"retail_price\": \"5.50\",\n \"retail_price_currency\": \"USD\"\n}\n```\n\n</details>\n\nIf you managed to update all the variants inside a product the entire product\nshould now have the status `All in stock`. \n"
}
],
"paths": {
"/v2/oauth-scopes": {
"get": {
"summary": "Retrieve OAuth scopes",
"description": "This endpoint will retrieve all OAuth scopes associated with the used token",
"operationId": "getOAuthScopes",
"security": [
{
"OAuth": []
}
],
"tags": ["OAuth Scopes v2"],
"responses": {
"200": {
"$ref": "#/components/responses/GetOAuthScopes"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"5XX": {
"$ref": "#/components/responses/ServerError"
}
}
}
},
"/v2/catalog-products": {
"get": {
"summary": "Retrieve a list of catalog products",
"description": "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.\nFor a visual representation of the design data, please see the following diagram:\n[<img src=\"images/catalog/design_data_diagram.png#center\" width=\"700\"/>](images/catalog/design_data_diagram.png)\n",
"operationId": "getProducts",
"security": [
{
"OAuth": []
}
],
"tags": ["Catalog v2"],
"parameters": [
{
"$ref": "#/components/parameters/ProductCategoryIds"
},
{
"$ref": "#/components/parameters/ColorsFilter"
},
{
"$ref": "#/components/parameters/Limit"
},
{
"$ref": "#/components/parameters/NewFilter"
},
{
"$ref": "#/components/parameters/Offset"
},
{
"$ref": "#/components/parameters/PlacementsFilter"
},
{
"$ref": "#/components/parameters/SellingRegion"
},
{
"$ref": "#/components/parameters/SortDirection"
},
{
"$ref": "#/components/parameters/SortType"
},
{
"$ref": "#/components/parameters/TechniquesFilter"
},
{
"$ref": "#/components/parameters/Locale"
}
],
"responses": {
"200": {
"$ref": "#/components/responses/GetProducts"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"5XX": {
"$ref": "#/components/responses/ServerError"
}
}
}
},
"/v2/catalog-products/{id}": {
"get": {
"summary": "Retrieve a single catalog product",
"description": "Returns information about a single specified catalog product. [See catalog product](#tag/Catalog-v2/What-is-a-catalog-product)\n",
"operationId": "getProductById",
"security": [
{
"OAuth": []
}
],
"tags": ["Catalog v2"],
"parameters": [
{
"$ref": "#/components/parameters/ProductId"
},
{
"$ref": "#/components/parameters/SellingRegion"
},
{
"$ref": "#/components/parameters/Locale"
}
],
"responses": {
"200": {
"$ref": "#/components/responses/GetProductById"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"5XX": {
"$ref": "#/components/responses/ServerError"
}
}
}
},
"/v2/catalog-variants/{id}": {
"get": {
"summary": "Retrieve information about specific catalog variant",
"description": "Returns information about single specified catalog variant. [See catalog variant](#tag/Catalog-v2/What-is-a-catalog-variant)\n",
"operationId": "getVariantById",
"security": [
{
"OAuth": []
}
],
"tags": ["Catalog v2"],
"parameters": [
{
"$ref": "#/components/parameters/VariantId"
},
{
"$ref": "#/components/parameters/Locale"
}
],
"responses": {
"200": {
"$ref": "#/components/responses/GetVariantById"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"5XX": {
"$ref": "#/components/responses/ServerError"
}
}
}
},
"/v2/catalog-products/{id}/catalog-variants": {
"get": {
"summary": "Retrieve information about catalog product variants",
"description": "Returns information about all catalog variants associated with the specified\ncatalog product. [See catalog variant](#tag/Catalog-v2/What-is-a-catalog-variant)\n",
"operationId": "getProductVariantsById",
"security": [
{
"OAuth": []
}
],
"tags": ["Catalog v2"],
"parameters": [
{
"$ref": "#/components/parameters/ProductId"
},
{
"$ref": "#/components/parameters/Locale"
}
],
"responses": {
"200": {
"$ref": "#/components/responses/GetProductVariantsById"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"5XX": {
"$ref": "#/components/responses/ServerError"
}
}
}
},
"/v2/catalog-categories": {
"get": {
"tags": ["Catalog v2"],
"summary": "Retrieve a list of catalog categories",
"description": "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.\nCategories can be used to filter the product list by specific tags [See categories_ids](#operation/getProducts)\n",
"operationId": "getCategories",
"security": [
{
"OAuth": []
}
],
"responses": {
"200": {
"$ref": "#/components/responses/GetCategories"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"5XX": {
"$ref": "#/components/responses/ServerError"
}
}
}
},
"/v2/catalog-categories/{id}": {
"get": {
"summary": "Retrieve information about specific category",
"description": "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.\nCategories can be used to filter the product list by specific tags [See categories_ids](#operation/getProducts)\n",
"operationId": "getCategoryById",
"security": [
{
"OAuth": []
}
],
"tags": ["Catalog v2"],
"parameters": [
{
"$ref": "#/components/parameters/CategoryId"
}
],
"responses": {
"200": {
"$ref": "#/components/responses/GetCategoryById"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"5XX": {
"$ref": "#/components/responses/ServerError"
}
}
}
},
"/v2/catalog-products/{id}/catalog-categories": {
"get": {
"summary": "Retrieve a list of catalog product categories",
"description": "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.\n",
"operationId": "getCategoriesByProductId",
"security": [
{
"OAuth": []
}
],
"tags": ["Catalog v2"],
"parameters": [
{
"$ref": "#/components/parameters/ProductId"
},
{
"$ref": "#/components/parameters/SellingRegion"
}
],
"responses": {
"200": {
"$ref": "#/components/responses/GetCategoriesByProductId"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"5XX": {
"$ref": "#/components/responses/ServerError"
}
}
}
},
"/v2/catalog-products/{id}/sizes": {
"get": {
"summary": "Retrieve size guide for a catalog product",
"description": "Returns information about the size guide for a specific product.",
"operationId": "getProductSizeGuideById",
"security": [
{
"OAuth": []
}
],
"tags": ["Catalog v2"],
"parameters": [
{
"$ref": "#/components/parameters/ProductId"
},
{
"$ref": "#/components/parameters/MeasurementUnit"
},
{
"$ref": "#/components/parameters/Locale"
}
],
"responses": {
"200": {
"$ref": "#/components/responses/GetProductSizeGuideById"
},
"404": {
"$ref": "#/components/responses/NotFound"
},
"5XX": {
"$ref": "#/components/responses/ServerError"
}
}
}
},
"/v2/catalog-products/{id}/prices": {
"get": {
"summary": "Retrieve catalog product prices",
"description": "\nCalculates 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.\n\nFor more information on product pricing please refer to the information provided at https://www.printful.com/pricing\n<div class=\"alert alert-info\" style=\"word-wrap: break-word; padding: 16px; border-radius: 0; cursor: default; color: #31708f; background-color: #d9edf7; border-color: #bce8f1;\">\n <p>\n 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.\n </p>\n <p>\n There is a minor difference in the handling of prices for placements between V1 and V2.\n In V1 the price of the first placement is always null, this is because there\n is always a placement included in the price of each product. In V2 the price of placements\n is always displayed even if it is included in the price of the product because any\n placement can be included.\n </p>\n</div>\n",
"operationId": "getProductPricesById",
"security": [
{
"OAuth": []
}
],
"tags": ["Catalog v2"],
"parameters": [
{
"$ref": "#/components/parameters/ProductId"
},
{
"$ref": "#/components/parameters/SellingRegionPrice"
},
{
"$ref": "#/components/parameters/Currency"
},
{
"$ref": "#/components/parameters/Locale"
}
],
"responses": {
"200": {
"$ref": "#/components/responses/GetProductPricesById"
},
"404": {
"$ref": "#/components/responses/NotFound"
},
"5XX": {
"$ref": "#/components/responses/ServerError"
}
}
}
},
"/v2/catalog-variants/{id}/prices": {
"get": {
"summary": "Retrieve pricing information for the catalog variant",
"description": "Return pricing information from a single variant and the parent product",
"operationId": "getVariantPricesById",
"security": [
{
"OAuth": []
}
],
"tags": ["Catalog v2"],
"parameters": [
{
"$ref": "#/components/parameters/VariantId"
},
{
"$ref": "#/components/parameters/SellingRegionPrice"
},
{
"$ref": "#/components/parameters/Currency"
},
{
"$ref": "#/components/parameters/Locale"
}
],
"responses": {
"200": {
"$ref": "#/components/responses/GetVariantPricesById"
},
"404": {
"$ref": "#/components/responses/NotFound"
},
"5XX": {
"$ref": "#/components/responses/ServerError"
}
}
}
},
"/v2/catalog-products/{id}/images": {
"get": {
"summary": "Retrieve blank images for a catalog product",
"description": "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.\n",
"operationId": "getProductImagesById",
"security": [
{
"OAuth": []
}
],
"tags": ["Catalog v2"],
"parameters": [
{
"$ref": "#/components/parameters/ProductId"
},
{
"$ref": "#/components/parameters/MockupStyleIds"
},
{
"$ref": "#/components/parameters/VariantColor"
},
{
"$ref": "#/components/parameters/PlacementFilter"
},
{
"$ref": "#/components/parameters/Locale"
}
],
"responses": {
"200": {
"$ref": "#/components/responses/GetProductImagesById"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"5XX": {
"$ref": "#/components/responses/ServerError"
}
}
}
},
"/v2/catalog-variants/{id}/images": {
"get": {
"summary": "Retrieve blank images for a catalog variant",
"description": "Returns images for a specified Variant.",
"operationId": "getVariantImagesById",
"security": [
{
"OAuth": []
}
],
"tags": ["Catalog v2"],
"parameters": [
{
"$ref": "#/components/parameters/VariantId"
},
{
"$ref": "#/components/parameters/MockupStyleIds"
},
{
"$ref": "#/components/parameters/PlacementFilter"
},
{
"$ref": "#/components/parameters/Locale"
}
],
"responses": {
"200": {
"$ref": "#/components/responses/GetVariantImagesById"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"5XX": {
"$ref": "#/components/responses/ServerError"
}
}
}
},
"/v2/catalog-products/{id}/mockup-styles": {
"get": {
"summary": "Retrieve catalog product mockup styles",
"description": "Returns information about available mockup styles for specified catalog product.\n",
"operationId": "retrieveMockupStylesByProductId",
"security": [
{
"OAuth": []
}
],
"tags": ["Catalog v2"],
"parameters": [
{
"$ref": "#/components/parameters/ProductId"
},
{
"$ref": "#/components/parameters/MockupPlacementsFilter"
},
{
"$ref": "#/components/parameters/SellingRegion"
},
{
"$ref": "#/components/parameters/Offset-2"
},
{
"$ref": "#/components/parameters/Limit-2"
},
{
"$ref": "#/components/parameters/Locale"
}
],
"responses": {
"200": {
"$ref": "#/components/responses/GetCatalogProductMockupsStyles"
},
"401": {
"$ref": "#/components/responses/Unauthorized-2"
},
"404": {
"$ref": "#/components/responses/NotFound-2"
},
"5XX": {
"$ref": "#/components/responses/ServerError"
}
}
}
},
"/v2/catalog-products/{id}/mockup-templates": {
"get": {
"summary": "Retrieve catalog product mockup templates",
"description": "Returns positional data for specified catalog product mockups. The data from this endpoint could be used\nto generate your own mockups without the need to use Printful's mockup generator.\n\n",
"operationId": "getMockupTemplatesByProductId",
"security": [
{
"OAuth": []
}
],
"tags": ["Catalog v2"],
"parameters": [
{
"$ref": "#/components/parameters/ProductId"
},
{
"$ref": "#/components/parameters/PlacementsFilter"
},
{
"$ref": "#/components/parameters/SellingRegion"
},
{
"$ref": "#/components/parameters/Limit"
},
{
"$ref": "#/components/parameters/Offset"
},
{
"$ref": "#/components/parameters/Locale"
}
],
"responses": {
"200": {
"$ref": "#/components/responses/GetCatalogProductMockupsTemplates"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"5XX": {
"$ref": "#/components/responses/ServerError"
}
}
}
},
"/v2/catalog-products/{id}/availability": {
"get": {
"summary": "Retrieve catalog product stock availability",
"description": "Provides information about the catalog product stock status. Stock availability is grouped by variants → techniques → selling regions.\n",
"operationId": "getProductStockAvailabilityById",
"security": [
{
"OAuth": []
}
],
"tags": ["Catalog v2"],
"parameters": [
{
"$ref": "#/components/parameters/ProductId"
},
{
"$ref": "#/components/parameters/TechniquesFilter"
},
{
"$ref": "#/components/parameters/SellingRegionAll"
},
{
"$ref": "#/components/parameters/Limit"
},
{
"$ref": "#/components/parameters/Offset"
},
{
"$ref": "#/components/parameters/Locale"
}
],
"responses": {
"200": {
"$ref": "#/components/responses/GetProductStockAvailabilityById"
},
"400": {
"$ref": "#/components/responses/BadRequest"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"403": {
"$ref": "#/components/responses/Forbidden"
},
"404": {
"$ref": "#/components/responses/NotFound"
},
"5XX": {
"$ref": "#/components/responses/ServerError"
}
}
}
},
"/v2/catalog-variants/{id}/availability": {
"get": {
"summary": "Retrieve catalog variant stock availability",
"description": "Provides information about the catalog variant stock status. Stock availability is grouped by variants → techniques → selling regions.\n",
"operationId": "getVariantStockAvailabilityById",
"security": [
{
"OAuth": []
}
],
"tags": ["Catalog v2"],
"parameters": [
{
"$ref": "#/components/parameters/VariantId"
},
{
"$ref": "#/components/parameters/TechniquesFilter"
},
{
"$ref": "#/components/parameters/SellingRegion"
},
{
"$ref": "#/components/parameters/Locale"
}
],
"responses": {
"200": {
"$ref": "#/components/responses/GetVariantStockAvailabilityById"
},
"400": {
"$ref": "#/components/responses/BadRequest"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"403": {
"$ref": "#/components/responses/Forbidden"
},
"404": {
"$ref": "#/components/responses/NotFound"
},
"5XX": {
"$ref": "#/components/responses/ServerError"
}
}
}
},
"/v2/orders": {
"get": {
"summary": "Retrieve a list of orders",
"description": "Retrieve a list of orders from a specific store. The order list will be paginated with twenty items per page by default.",
"operationId": "getOrders",
"security": [
{
"OAuth": ["orders/read"]
}
],
"tags": ["Orders v2"],
"parameters": [
{
"$ref": "#/components/parameters/Limit"
},
{
"$ref": "#/components/parameters/Offset"
},
{
"$ref": "#/components/parameters/StoreId"
}
],
"responses": {
"200": {
"$ref": "#/components/responses/GetOrders"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"5XX": {
"$ref": "#/components/responses/ServerError"
}
}
},
"post": {
"summary": "Create a new order",
"description": "This endpoint allows the creation of a new order in which the default status will be `draft`.",
"operationId": "createOrder",
"security": [
{
"OAuth": ["orders"]
}
],
"tags": ["Orders v2"],
"parameters": [
{
"$ref": "#/components/parameters/StoreId"
}
],
"requestBody": {
"$ref": "#/components/requestBodies/OrderInput"
},
"responses": {
"200": {
"$ref": "#/components/responses/GetOrderById"
},
"400": {
"$ref": "#/components/responses/BadRequest"
},
"5XX": {
"$ref": "#/components/responses/ServerError"
}
}
}
},
"/v2/orders/{order_id}": {
"get": {
"summary": "Retrieve a single order",
"description": "Retrieve a single order from the specified store. The result object will contain links to the same resource, order items, and shipments.",
"operationId": "getOrder",
"security": [
{
"OAuth": ["orders/read"]
}
],
"tags": ["Orders v2"],
"parameters": [
{
"$ref": "#/components/parameters/OrderId"
},
{
"$ref": "#/components/parameters/StoreId"
}
],
"responses": {
"200": {
"$ref": "#/components/responses/GetOrderById"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"404": {
"$ref": "#/components/responses/NotFound"
},
"5XX": {
"$ref": "#/components/responses/ServerError"
}
}
},
"delete": {
"summary": "Delete an order",
"description": "<div class=\"alert alert-danger\">\n <strong>Warning:</strong> The DELETE HTTP method in version 2 of order in the \n API will delete the order if the order can be deleted. This is distinct from \n version 1 where the DELETE method will actually cancel the order rather than \n delete it. Please, keep this in mind if you are migrating to version 2 from \n version 1\n</div>\n\nDelete the order if it can be deleted. An order can be deleted if it's status is\n`draft`, `failed` or `cancelled`. The order must also have not been charged yet\nand there must be no payments pending.\n",
"operationId": "deleteOrder",
"security": [
{
"OAuth": ["orders"]
}
],
"tags": ["Orders v2"],
"parameters": [
{
"$ref": "#/components/parameters/StoreId"
},
{
"$ref": "#/components/parameters/OrderId"
}
],
"responses": {
"204": {
"$ref": "#/components/responses/NoContent"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"404": {
"$ref": "#/components/responses/NotFound"
},
"409": {
"$ref": "#/components/responses/Conflict"
},
"5XX": {
"$ref": "#/components/responses/ServerError"
}
}
},
"patch": {
"summary": "Update an order",
"description": "Make a partial update of an order.",
"operationId": "updateOrder",
"security": [
{
"OAuth": ["orders"]
}
],
"tags": ["Orders v2"],
"parameters": [
{
"$ref": "#/components/parameters/StoreId"
},
{
"$ref": "#/components/parameters/OrderId"
}
],
"requestBody": {
"$ref": "#/components/requestBodies/OrderPatchInput"
},
"responses": {
"200": {
"$ref": "#/components/responses/GetOrderById"
},
"400": {
"$ref": "#/components/responses/BadRequest"
},
"5XX": {
"$ref": "#/components/responses/ServerError"
}
}
}
},
"/v2/orders/{order_id}/confirmation": {
"post": {
"summary": "Confirm an order",
"description": "This endpoint allows customers to confirm the order and start the fulfillment in the production facility.",
"operationId": "confirmOrder",
"security": [
{
"OAuth": ["orders"]
}
],
"tags": ["Orders v2"],
"parameters": [
{
"$ref": "#/components/parameters/StoreId"
},
{
"$ref": "#/components/parameters/OrderId"
}
],
"responses": {
"200": {
"$ref": "#/components/responses/ConfirmOrderById"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"5XX": {
"$ref": "#/components/responses/ServerError"
}
}
}
},
"/v2/orders/{order_id}/order-items": {
"get": {
"summary": "Retrieve a list of order items",
"description": "This endpoint retrieves the list of items that belong to the order.",
"operationId": "getItemsByOrderId",
"security": [
{
"OAuth": ["orders/read"]
}
],
"tags": ["Orders v2"],
"parameters": [
{
"$ref": "#/components/parameters/OrderId"
},
{
"$ref": "#/components/parameters/Type"
},
{
"$ref": "#/components/parameters/Limit"
},
{
"$ref": "#/components/parameters/Offset"
},
{
"$ref": "#/components/parameters/StoreId"
}
],
"responses": {
"200": {
"$ref": "#/components/responses/GetOrderItemsById"
},
"400": {
"$ref": "#/components/responses/BadRequest"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"403": {
"$ref": "#/components/responses/Forbidden"
},
"404": {
"$ref": "#/components/responses/NotFound"
},
"5XX": {
"$ref": "#/components/responses/ServerError"
}
}
},
"post": {
"summary": "Create a new order item",
"description": "This endpoint allows the creation of a new item that will be added to an existing order.",
"operationId": "createItemByOrderId",
"security": [
{
"OAuth": ["orders"]
}
],
"tags": ["Orders v2"],
"parameters": [
{
"$ref": "#/components/parameters/OrderId"
},
{
"$ref": "#/components/parameters/StoreId"
}
],
"requestBody": {
"$ref": "#/components/requestBodies/ItemInput"