{
  "auth": {
    "bearer": [
      {
        "key": "token",
        "type": "string",
        "value": "{{apiKey}}"
      }
    ],
    "type": "bearer"
  },
  "info": {
    "_postman_id": "6b1f3f2e-4f7a-4f2b-9a51-0c9d2b6e2a97",
    "description": "Sell POD Mfg products from your own store, site or ERP. Generated from docs/partner-api/openapi.yaml; do not edit by hand. Set `apiKey` to a test key (podmfg_test_…). Docs: https://podmf.com/docs/partner-api",
    "name": "POD Mfg Partner API (v1)",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "item": [
    {
      "item": [
        {
          "name": "Who this key is (a connection test)",
          "request": {
            "description": "Your brand, the key's mode and scopes, and whether a card is on file.",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "method": "GET",
            "url": {
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "me"
              ],
              "raw": "{{baseUrl}}/me"
            }
          }
        }
      ],
      "name": "Account"
    },
    {
      "item": [
        {
          "name": "List published products",
          "request": {
            "description": "Your published products, newest first, each with its variants. Needs `products:read`.\nUnknown query parameters are refused (`400 parameter_unknown`).\n",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "method": "GET",
            "url": {
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "products"
              ],
              "query": [
                {
                  "description": "Page size, 1 to 100.",
                  "disabled": true,
                  "key": "limit",
                  "value": ""
                },
                {
                  "description": "The `next_cursor` of the previous page (the last id you got).",
                  "disabled": true,
                  "key": "starting_after",
                  "value": ""
                },
                {
                  "description": "Only products changed at or after this time (ISO 8601).",
                  "disabled": true,
                  "key": "updated_since",
                  "value": ""
                },
                {
                  "description": "Only `published` is available.",
                  "disabled": true,
                  "key": "status",
                  "value": ""
                }
              ],
              "raw": "{{baseUrl}}/products"
            }
          }
        },
        {
          "name": "One published product",
          "request": {
            "description": "The product with its variants, mockup images and prices. Needs `products:read`.",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "method": "GET",
            "url": {
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "products",
                ":id"
              ],
              "raw": "{{baseUrl}}/products/:id",
              "variable": [
                {
                  "description": "",
                  "key": "id",
                  "value": ""
                }
              ]
            }
          }
        },
        {
          "name": "One variant",
          "request": {
            "description": "A variant of a published product. Needs `products:read`.",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "method": "GET",
            "url": {
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "variants",
                ":id"
              ],
              "raw": "{{baseUrl}}/variants/:id",
              "variable": [
                {
                  "description": "",
                  "key": "id",
                  "value": ""
                }
              ]
            }
          }
        },
        {
          "name": "Set your own SKU for a variant",
          "request": {
            "body": {
              "mode": "raw",
              "options": {
                "raw": {
                  "language": "json"
                }
              },
              "raw": "{\n  \"external_sku\": \"TEAM-TEE-NAVY-M\"\n}"
            },
            "description": "The only change allowed on products in v1. `external_sku` is unique among your variants\n(`409 external_sku_taken`); `null` clears it. Orders may name a variant by its\n`id`, our `sku` or your `external_sku`. Needs `orders:write`.\n",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "method": "PATCH",
            "url": {
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "variants",
                ":id"
              ],
              "raw": "{{baseUrl}}/variants/:id",
              "variable": [
                {
                  "description": "",
                  "key": "id",
                  "value": ""
                }
              ]
            }
          }
        }
      ],
      "name": "Products"
    },
    {
      "item": [
        {
          "name": "List orders",
          "request": {
            "description": "Your orders in the key's mode (a test key sees test orders only), newest first. Needs `orders:read`.",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "method": "GET",
            "url": {
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "orders"
              ],
              "query": [
                {
                  "description": "Page size, 1 to 100.",
                  "disabled": true,
                  "key": "limit",
                  "value": ""
                },
                {
                  "description": "The `next_cursor` of the previous page (the last id you got).",
                  "disabled": true,
                  "key": "starting_after",
                  "value": ""
                },
                {
                  "description": "",
                  "disabled": true,
                  "key": "status",
                  "value": ""
                },
                {
                  "description": "",
                  "disabled": true,
                  "key": "external_order_id",
                  "value": ""
                },
                {
                  "description": "Only orders created at or after this time (ISO 8601).",
                  "disabled": true,
                  "key": "created_since",
                  "value": ""
                }
              ],
              "raw": "{{baseUrl}}/orders"
            }
          }
        },
        {
          "name": "Create an order",
          "request": {
            "body": {
              "mode": "raw",
              "options": {
                "raw": {
                  "language": "json"
                }
              },
              "raw": "{\n  \"external_order_id\": \"1042\",\n  \"external_order_url\": \"https://merchant-admin.example.com/orders/1042\",\n  \"line_items\": [\n    {\n      \"external_line_id\": \"li_1\",\n      \"quantity\": 2,\n      \"retail_price\": 2800,\n      \"variant_id\": \"var_31xaQ8dZr0mJxWb7fKp2sT\"\n    }\n  ],\n  \"metadata\": {\n    \"anything\": \"merchant wants echoed back\"\n  },\n  \"packing_slip\": {\n    \"message\": \"Thanks for supporting the team!\",\n    \"show_prices\": false\n  },\n  \"ship_to\": {\n    \"address1\": \"123 Main St\",\n    \"address2\": \"Apt 4\",\n    \"city\": \"Irvine\",\n    \"company\": null,\n    \"country\": \"US\",\n    \"email\": \"jane@example.com\",\n    \"name\": \"Jane Smith\",\n    \"phone\": \"+19495551234\",\n    \"postal_code\": \"92618\",\n    \"state\": \"CA\"\n  },\n  \"shipping_method\": \"standard\"\n}"
            },
            "description": "Needs `orders:write`. Each line names exactly one of `variant_id`, `sku` (ours) or\n`external_sku` (yours); unknown fields are refused. Answers `201` with the order, its\n`status` and the `charge` result: a live order is charged now (`charge.status`\n`succeeded` → `status: paid`; `failed` → `status: payment_failed`, retried\nautomatically; `pending` → Stripe is still working on it). A held order\n(`on_hold`) isn't charged until we release it.\n",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "method": "POST",
            "url": {
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "orders"
              ],
              "raw": "{{baseUrl}}/orders"
            }
          }
        },
        {
          "name": "Price an order without making it",
          "request": {
            "body": {
              "mode": "raw",
              "options": {
                "raw": {
                  "language": "json"
                }
              },
              "raw": "{\n  \"line_items\": [\n    {\n      \"quantity\": 12,\n      \"sku\": \"PMG-ST350-NAV-M-8F2KA19C0D\"\n    }\n  ],\n  \"ship_to\": {\n    \"address1\": \"123 Main St\",\n    \"city\": \"Irvine\",\n    \"country\": \"US\",\n    \"name\": \"Jane Smith\",\n    \"postal_code\": \"92618\",\n    \"state\": \"CA\"\n  },\n  \"shipping_method\": \"standard\"\n}"
            },
            "description": "The same body as `POST /orders` (`external_order_id` optional). Answers the wholesale\ntotal, shipping and tax, and whether the order would be held. Nothing is stored or\ncharged. Needs `orders:write` or `orders:read`.\n",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "method": "POST",
            "url": {
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "orders",
                "estimate"
              ],
              "raw": "{{baseUrl}}/orders/estimate"
            }
          }
        },
        {
          "name": "One order",
          "request": {
            "description": "Status, the price snapshot, charges, refunds and shipments. Needs `orders:read`.",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "method": "GET",
            "url": {
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "orders",
                ":id"
              ],
              "raw": "{{baseUrl}}/orders/:id",
              "variable": [
                {
                  "description": "",
                  "key": "id",
                  "value": ""
                }
              ]
            }
          }
        },
        {
          "name": "Cancel an order before production",
          "request": {
            "body": {
              "mode": "raw",
              "options": {
                "raw": {
                  "language": "json"
                }
              },
              "raw": "{}"
            },
            "description": "Allowed until the order is `in_production`; a paid order is refunded in full. Cancelling\na cancelled order answers it again. After production starts: `409 order_not_cancellable`\n(contact us). Needs `orders:write`.\n",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "method": "POST",
            "url": {
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "orders",
                ":id",
                "cancel"
              ],
              "raw": "{{baseUrl}}/orders/:id/cancel",
              "variable": [
                {
                  "description": "",
                  "key": "id",
                  "value": ""
                }
              ]
            }
          }
        },
        {
          "name": "Charge a failed order again",
          "request": {
            "description": "For a live order that is `payment_failed`, or `on_hold` with `payment_failed_final`\n(e.g. after you saved a new card). Answers the paid order, or `402 payment_failed` when\nthe card is declined again. Test orders: a simulated failure\n(`POST /orders/{id}/simulate/payment_failed`) retries into simulated success\n(`order.paid`); any other test order is `409 test_mode`. Needs `orders:write`.\n",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "method": "POST",
            "url": {
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "orders",
                ":id",
                "retry_payment"
              ],
              "raw": "{{baseUrl}}/orders/:id/retry_payment",
              "variable": [
                {
                  "description": "",
                  "key": "id",
                  "value": ""
                }
              ]
            }
          }
        }
      ],
      "name": "Orders"
    },
    {
      "item": [
        {
          "name": "List events",
          "request": {
            "description": "The events of the key's mode, newest first, exactly as they were (or would have been)\nsent: to poll, or to backfill after your endpoint was down. Kept 30 days. Needs\n`orders:read`.\n",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "method": "GET",
            "url": {
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "events"
              ],
              "query": [
                {
                  "description": "Page size, 1 to 100.",
                  "disabled": true,
                  "key": "limit",
                  "value": ""
                },
                {
                  "description": "The `next_cursor` of the previous page (the last id you got).",
                  "disabled": true,
                  "key": "starting_after",
                  "value": ""
                },
                {
                  "description": "",
                  "disabled": true,
                  "key": "type",
                  "value": ""
                },
                {
                  "description": "Only events created at or after this time (ISO 8601).",
                  "disabled": true,
                  "key": "since",
                  "value": ""
                }
              ],
              "raw": "{{baseUrl}}/events"
            }
          }
        },
        {
          "name": "One event",
          "request": {
            "description": "The envelope exactly as sent. Needs `orders:read`.",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "method": "GET",
            "url": {
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "events",
                ":id"
              ],
              "raw": "{{baseUrl}}/events/:id",
              "variable": [
                {
                  "description": "",
                  "key": "id",
                  "value": ""
                }
              ]
            }
          }
        },
        {
          "name": "Send an event again",
          "request": {
            "body": {
              "mode": "raw",
              "options": {
                "raw": {
                  "language": "json"
                }
              },
              "raw": "{}"
            },
            "description": "To one endpoint (`webhook_endpoint_id`) or to every active endpoint of the key's mode that\nwants the event's type. Each delivery starts the retry schedule again; it goes out within\nseconds. `409 no_webhook_endpoint` when no active endpoint wants it. Needs `orders:write`.\n",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "method": "POST",
            "url": {
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "events",
                ":id",
                "resend"
              ],
              "raw": "{{baseUrl}}/events/:id/resend",
              "variable": [
                {
                  "description": "",
                  "key": "id",
                  "value": ""
                }
              ]
            }
          }
        },
        {
          "name": "List webhook endpoints",
          "request": {
            "description": "Your endpoints in the key's mode, newest first. Never the secrets. Needs `orders:write`.",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "method": "GET",
            "url": {
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "webhook_endpoints"
              ],
              "query": [
                {
                  "description": "Page size, 1 to 100.",
                  "disabled": true,
                  "key": "limit",
                  "value": ""
                },
                {
                  "description": "The `next_cursor` of the previous page (the last id you got).",
                  "disabled": true,
                  "key": "starting_after",
                  "value": ""
                }
              ],
              "raw": "{{baseUrl}}/webhook_endpoints"
            }
          }
        },
        {
          "name": "Add a webhook endpoint",
          "request": {
            "body": {
              "mode": "raw",
              "options": {
                "raw": {
                  "language": "json"
                }
              },
              "raw": "{\n  \"description\": \"Order system\",\n  \"enabled_events\": [\n    \"order.shipped\",\n    \"order.payment_failed\",\n    \"order.cancelled\"\n  ],\n  \"url\": \"https://merchant.example.com/podmfg/webhooks\"\n}"
            },
            "description": "In the key's mode (a test key makes a test endpoint). Live endpoints must be https; the\nhost must be a public address. Answers the endpoint with its signing `secret`, the only\ntime it is shown (a replay with the same Idempotency-Key answers `secret: null`). At most\n16 endpoints per mode. Needs `orders:write`.\n",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "method": "POST",
            "url": {
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "webhook_endpoints"
              ],
              "raw": "{{baseUrl}}/webhook_endpoints"
            }
          }
        },
        {
          "name": "One webhook endpoint",
          "request": {
            "description": "Needs `orders:write`.",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "method": "GET",
            "url": {
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "webhook_endpoints",
                ":id"
              ],
              "raw": "{{baseUrl}}/webhook_endpoints/:id",
              "variable": [
                {
                  "description": "",
                  "key": "id",
                  "value": ""
                }
              ]
            }
          }
        },
        {
          "name": "Change a webhook endpoint",
          "request": {
            "body": {
              "mode": "raw",
              "options": {
                "raw": {
                  "language": "json"
                }
              },
              "raw": "{\n  \"enabled_events\": [\n    \"*\"\n  ]\n}"
            },
            "description": "Any of `url`, `enabled_events`, `description` (null clears it), `status` (`active` /\n`disabled`). Turning an endpoint back on forgets its failures and resumes deliveries that\nwere waiting. Needs `orders:write`.\n",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "method": "PATCH",
            "url": {
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "webhook_endpoints",
                ":id"
              ],
              "raw": "{{baseUrl}}/webhook_endpoints/:id",
              "variable": [
                {
                  "description": "",
                  "key": "id",
                  "value": ""
                }
              ]
            }
          }
        },
        {
          "name": "Delete a webhook endpoint",
          "request": {
            "description": "Nothing more is sent to it; deliveries still waiting end as failed. Needs `orders:write`.",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "method": "DELETE",
            "url": {
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "webhook_endpoints",
                ":id"
              ],
              "raw": "{{baseUrl}}/webhook_endpoints/:id",
              "variable": [
                {
                  "description": "",
                  "key": "id",
                  "value": ""
                }
              ]
            }
          }
        },
        {
          "name": "Rotate an endpoint's signing secret",
          "request": {
            "description": "A new secret, shown once in this answer; deliveries are signed with it from now on (the old\none stops at once; update your handler first, or accept both while you switch). Needs\n`orders:write`.\n",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "method": "POST",
            "url": {
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "webhook_endpoints",
                ":id",
                "rotate_secret"
              ],
              "raw": "{{baseUrl}}/webhook_endpoints/:id/rotate_secret",
              "variable": [
                {
                  "description": "",
                  "key": "id",
                  "value": ""
                }
              ]
            }
          }
        }
      ],
      "name": "Webhooks"
    },
    {
      "item": [
        {
          "name": "Test mode: POD Mfg cancels a test order",
          "request": {
            "description": "Cancels the order as POD Mfg staff would (`reason: cancelled_by_pod_mfg`) and sends\n`order.cancelled`, so you can test an order you did not cancel yourself. Allowed before\nproduction, like `POST /orders/{id}/cancel`.\n**Test keys and test orders only** (a live key: `403 test_mode_only`; a live order's id\nis not found with a test key). No body. Needs `orders:write`. Wrong state:\n`409 order_state`.\n",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "method": "POST",
            "url": {
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "orders",
                ":id",
                "simulate",
                "cancel"
              ],
              "raw": "{{baseUrl}}/orders/:id/simulate/cancel",
              "variable": [
                {
                  "description": "",
                  "key": "id",
                  "value": ""
                }
              ]
            }
          }
        },
        {
          "name": "Test mode: fail a test order's payment",
          "request": {
            "description": "The simulated payment fails: the order becomes `payment_failed` (`status_reason:\ncard_declined`, `charge.status: failed`) and `order.payment_failed` is sent. Then\n`POST /orders/{id}/retry_payment` simulates success (`order.paid`), or cancel it. No card\nis involved. Needs the order `paid`.\n**Test keys and test orders only** (a live key: `403 test_mode_only`; a live order's id\nis not found with a test key). No body. Needs `orders:write`. Wrong state:\n`409 order_state`.\n",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "method": "POST",
            "url": {
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "orders",
                ":id",
                "simulate",
                "payment_failed"
              ],
              "raw": "{{baseUrl}}/orders/:id/simulate/payment_failed",
              "variable": [
                {
                  "description": "",
                  "key": "id",
                  "value": ""
                }
              ]
            }
          }
        },
        {
          "name": "Test mode: mark a test order shipped",
          "request": {
            "description": "Makes one simulated parcel for the whole order (carrier USPS, service Ground Advantage, a\nfake tracking number `TEST` + 16 digits) and moves the order to `shipped`. An\n`order.shipped` webhook goes to your **test** endpoints through the same pipeline (signing,\nretries, delivery log) as a real shipment. Nothing is made or shipped. Needs the order\n`paid`.\n**Test keys and test orders only** (a live key: `403 test_mode_only`; a live order's id\nis not found with a test key). No body. Needs `orders:write`. Wrong state:\n`409 order_state`.\n",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "method": "POST",
            "url": {
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "orders",
                ":id",
                "simulate",
                "ship"
              ],
              "raw": "{{baseUrl}}/orders/:id/simulate/ship",
              "variable": [
                {
                  "description": "",
                  "key": "id",
                  "value": ""
                }
              ]
            }
          }
        }
      ],
      "name": "Sandbox"
    }
  ],
  "variable": [
    {
      "key": "baseUrl",
      "value": "https://app.podmf.com/api/v1"
    },
    {
      "key": "apiKey",
      "value": "podmfg_test_REPLACE_ME"
    }
  ]
}
