PTG API Documentation

Print-on-Demand Production System API - Version 2

Table of Contents

Introduction

The PTG API is a RESTful API for managing print-on-demand orders. It provides endpoints for creating orders, checking order status, and administrative functions.

Base URL: https://api.picthegift.com

All API requests should use HTTPS. The API returns JSON responses.

Breaking Changes in Version 2

Version 2 of the PTG API introduces several breaking changes from Version 1 (Legacy). If you are migrating from Version 1, please review the following changes:

1. Authentication

Version 2 uses JWT (JSON Web Token) authentication via the Authorization: Bearer header. This replaces the OAuth 2 Basic authentication method used in Version 1.

JWT tokens are obtained from the Pic The Gift customer portal. See the Authentication section for details.

2. Field Name Changes

Several field names have changed in Version 2:

Version 1 (Legacy) endpoints continue to support the old field names for backward compatibility.

3. Content-Type Requirements

Version 2 requires application/json for all request bodies. The application/x-www-form-urlencoded content type is no longer supported.

Migration Note: If you are currently using Version 1, you can continue using it without changes. Version 2 is available for new integrations and provides improved field naming consistency and future flexibility. Both versions are fully supported.

Authentication

Most API endpoints require JWT (JSON Web Token) authentication. Authentication tokens are available in the Pic The Gift customer portal, which is a separate application.

How to get your API token:
  1. Log in to the Pic The Gift customer portal
  2. Navigate to your account settings or API section
  3. Generate or copy your API token

Using Authentication

Include your JWT token in the Authorization header of your requests:

Authorization: Bearer YOUR_JWT_TOKEN_HERE
Important: Keep your JWT token secure. Do not share it or commit it to version control. If your token is compromised, regenerate it immediately in the customer portal.

Order Endpoints

POST /api/orders Requires Authentication

Create a new order. This endpoint validates the order data, checks item availability, validates artwork URLs, and creates the order.

Request Body Fields

The request body should be a JSON object. Below is a complete reference of all available fields:

Order-Level Fields

Field Required Description Allowable Values
customer_order_id Yes Customer's unique order identifier Any string, must be unique per customer
shipto_name Yes Recipient's full name Any string
shipto_address_1 Yes Primary shipping address line Any string
shipto_address_2 No Secondary shipping address line (apartment, suite, etc.) Any string
shipto_city Yes Shipping city Any string
shipto_state Yes Shipping state or province Any string
shipto_zip Yes Shipping ZIP or postal code Any string
shipto_country Yes Shipping country code 2 letter ISO country code (e.g., "US", "CA")
shipto_phone No Recipient's phone number Any string
ship_method Yes Shipping method Any string (see Preferred Shipping Methods table below)
custom_pack_slip Yes Custom pack slip URL Valid URL pointing to an image (JPG or PNG) or PDF that is 4x6 inches dimensions
ship_acct_num No 3rd party shipping account number Any string
tracking_callback No URL to receive tracking number updates Valid HTTPS URL
external_customer_id No Customer account identifier for your records Any string
handling No Expedited production handling "URG" or "RUSH" (surcharge applies)
returnto_name No Return address name Any string
returnto_address1 No Return address line 1 Any string
returnto_address2 No Return address line 2 Any string
returnto_city No Return address city Any string
returnto_state No Return address state Any string
returnto_country No Return address country 2 letter ISO country code
returnto_postal_code No Return address postal code Any string
returnto_company No Return address company name Any string
returnto_phone No Return address phone number Any string
items Yes Array of order items (at least one required) Array of item objects

Item-Level Fields

Field Required Description Allowable Values
ptg_item_code Yes Pic The Gift's item code Valid product code from Pic The Gift's catalog
customer_item_code No Customer's item code for reference, can be returned with tracking number updates Any string
line_num No Line number will be returned with tracking number updates Any string
qty Yes Quantity of items Integer greater than 0
artwork_url_1 through artwork_url_6 Conditional** Artwork file to be printed on the item. artwork_url_1 is "front side", artwork_url_2 is "back side" typically. Valid HTTPS URL returning image
personalization_text_1 through personalization_text_15 No Personalization text fields (1-15). These are very helpful for visual quality control and tracking. Any string

** artwork_url_1 to 6 is required depending on the product's requirement. example: double sided product requires both artwork_url_1 and artwork_url_2

Shipping Methods

Rate Shop GUI Name Code
Y 1 Day 1_day
Y 2 Day 2_day
Y 3 Day 3_day
Y Economy economy
Y International Economy int_economy
Y International Priority int_priority
N FedEx 2 Day fedex_2_day
N FedEx Ground fedex_ground
N FedEx International Economy fedex_int_economy
N FedEx Standard Overnight fedex_std_overnight
N UPS 2 Day ups_2_day
N UPS 3 Day ups_3_day
N UPS Ground ups_ground
N UPS Next Day ups_next_day
N USPS First Class usps_first_class
N USPS Ground Advantage usps_ground_advantage
N USPS Priority usps_priority

Validation

The API validates:

  • JWT token validity and expiration
  • Required fields (order ID, shipping address, items)
  • Item codes exist in the product catalog
  • Item stock status (rejects out-of-stock items)
  • Artwork URL count matches product requirements
  • Artwork URLs are accessible and return image content

Rate Limit Headers

Response includes rate limit information:

  • X-RateLimit-Limit - Maximum requests per window
  • X-RateLimit-Remaining - Remaining requests
  • X-RateLimit-Reset - Unix timestamp when limit resets

Order-Level Fields

Field Required Description Allowable Values
order_nbr Yes Unique order identifier Any string
shipto_name Yes Recipient's full name Any string
shipto_address_1 Yes Primary shipping address line Any string
shipto_address_2 Yes Secondary shipping address line (apartment, suite, etc.) Any string
shipto_city Yes Shipping city Any string
shipto_state Yes Shipping state or province Any string
shipto_zip Yes Shipping ZIP or postal code Any string
shipto_country Yes Shipping country code ISO country code (e.g., "US", "CA")
shipto_phone Yes Recipient's phone number Any string
ship_method Yes Shipping method Any string (see Preferred Shipping Methods table below)
tracking_callback Yes URL to receive tracking number updates Valid HTTPS URL
items Yes Array of order items (at least one required) Array of item objects
external_customer_id No Customer account identifier for your records Any string
notes No Order notes Any string
gift_message No Gift message to include with order Any string
handling No Expedited production handling "URG" or "RUSH" (surcharge applies)
returnto_name No Return address name Any string
returnto_address1 No Return address line 1 Any string
returnto_address2 No Return address line 2 Any string
returnto_city No Return address city Any string
returnto_state No Return address state Any string
returnto_country No Return address country Any string
returnto_postal_code No Return address postal code Any string
returnto_company No Return address company name Any string
returnto_phone No Return address phone number Any string

Item-Level Fields

Field Required Description Allowable Values
ptg_part_number Yes Product part number Valid product code from catalog
artwork_url_1 Yes Artwork file for side 1 (front side of product) Valid HTTPS URL returning image
item_qty Yes Quantity of items Integer greater than 0
artwork_url_2 No Artwork file for side 2 (back side of product) Valid HTTPS URL returning image
artwork_url_3 No Artwork file for side 3 Valid HTTPS URL returning image
artwork_url_4 No Artwork file for side 4 Valid HTTPS URL returning image
artwork_url_5 No Artwork file for side 5 Valid HTTPS URL returning image
artwork_url_6 No Artwork file for side 6 Valid HTTPS URL returning image
name No Item name for reference only Any string
line_num No Line number will be returned with tracking number updates Any string
item_name_packslip No Item name for pack slip Any string
personalization_text_1 through personalization_text_15 No Personalization text fields (1-15). These are very helpful for visual quality control and tracking. Any string

Shipping Methods

Rate Shop GUI Name Code
Y 1 Day 1_day
Y 2 Day 2_day
Y 3 Day 3_day
Y Economy economy
Y International Economy int_economy
Y International Priority int_priority
N FedEx 2 Day fedex_2_day
N FedEx Ground fedex_ground
N FedEx International Economy fedex_int_economy
N FedEx Standard Overnight fedex_std_overnight
N UPS 2 Day ups_2_day
N UPS 3 Day ups_3_day
N UPS Ground ups_ground
N UPS Next Day ups_next_day
N USPS First Class usps_first_class
N USPS Ground Advantage usps_ground_advantage
N USPS Priority usps_priority

Validation

The API validates:

  • JWT token validity and expiration
  • Required fields (order ID, shipping address, items)
  • Item codes exist in the product catalog
  • Item stock status (rejects out-of-stock items)
  • Artwork URL count matches product requirements
  • Artwork URLs are accessible and return image content

Rate Limit Headers

Response includes rate limit information:

  • X-RateLimit-Limit - Maximum requests per window
  • X-RateLimit-Remaining - Remaining requests
  • X-RateLimit-Reset - Unix timestamp when limit resets

Example Request

{ "customer_order_id": "ORDER123", "shipto_name": "John Doe", "shipto_address_1": "123 Main St", "shipto_city": "New York", "shipto_state": "NY", "shipto_zip": "10001", "shipto_country": "US", "ship_method": "2_day", "custom_pack_slip": "https://example.com/packslip.pdf", "items": [ { "ptg_item_code": "TSHIRT-001", "qty": 1, "artwork_url_1": "https://example.com/artwork.jpg" } ] }

Success Response 201 Created

{ "status": "success", "customer_order_id": "ORDER123", "ptg_payload_id": 3894513, "messages": ["Order ORDER123 was created successfully!"], "payload_received": { ... } }

Error Response 400 Bad Request

{ "status": "error", "customer_order_id": "ORDER123", "ptg_payload_id": 3894513, "messages": [ "<TSHIRT-001> is out of stock", "<https://example.com/artwork.jpg> is not valid" ], "payload_received": { ... } }
POST /api/orders/tracking-number Requires Authentication

Get tracking number for an order using the customer's order identifier.

Request Body:

{ "customer_order_id": "ORDER123" }

Success Response:

{ "status": "ok", "customer_order_id": "ORDER123", "ptg_payload_id": 5145411, "tracking_number": "61290983132311826002365", "carrier": "fedex", "carrier_service": "fedex_smartpost_parcel_select", "ship_date": "2018-07-08" }

Error Response:

{ "status": "failed", "messages": ["Order not found."] }

Note: Tracking number may be null if the order has not been shipped yet.

Request Body:

{ "order_nbr": "0FA667S-45" }

Success Response:

{ "status": "ok", "order_nbr": "0FA667S-45", "order_id": "5145411", "tracking_number": "61290983132311826002365", "carrier": "fedex", "carrier_service": "fedex_smartpost_parcel_select", "ship_date": "2018-07-08" }

Error Response:

{ "status": "failed", "messages": ["Order not found."] }

Note: Tracking number may be null if the order has not been shipped yet.

POST /api/orders/modify-order Requires Authentication

Modify an existing order. At least one optional parameter must be provided.

Request Body:

{ "customer_order_id": "ORDER123", "shipto_name": "Jane Doe", "shipto_address_1": "456 Oak Ave", "shipto_address_2": "Apt 4B", "shipto_city": "Los Angeles", "shipto_state": "CA", "shipto_zip": "90001", "shipto_country": "US", "shipto_phone": "555-5678", "ship_method": "express" }

Required: customer_order_id - the customer's order identifier

Optional Parameters: shipto_name, shipto_address_1, shipto_address_2, shipto_city, shipto_state, shipto_zip, shipto_country, shipto_phone, ship_method

Success Response:

{ "status": "success", "message": "Successfully modified!" }

Error Response:

{ "status": "failed", "messages": "Can't find order id." }
{ "status": "failed", "messages": "No Changes Made!" }
{ "status": "failed", "messages": "Order Number {YourOrderNbr} is Cancelled or Closed, all fields and lines for this document will be skipped" }

Request Body:

{ "order_nbr": "0FA667S-45", "shipto_name": "Jane Doe", "shipto_address_1": "456 Oak Ave", "shipto_address_2": "Apt 4B", "shipto_city": "Los Angeles", "shipto_state": "CA", "shipto_zip": "90001", "shipto_country": "US", "shipto_phone": "555-5678", "ship_method": "express", "gift_message": "Happy Birthday!" }

Required: order_nbr - the customer's order identifier

Optional Parameters: shipto_name, shipto_address_1, shipto_address_2, shipto_city, shipto_state, shipto_zip, shipto_country, shipto_phone, ship_method, gift_message

Success Response:

{ "status": "success", "message": "Successfully modified!" }

Error Response:

{ "status": "failed", "messages": "Can't find order id." }
{ "status": "failed", "messages": "No Changes Made!" }
{ "status": "failed", "messages": "Order Number {YourOrderNbr} is Cancelled or Closed, all fields and lines for this document will be skipped" }
POST /api/orders/cancel-order Requires Authentication

Cancel an existing order. Cancellation is only allowed until the order is in the production queue.

Request Body:

{ "customer_order_id": "ORDER123" }

Required: customer_order_id - the customer's order identifier

Success Response:

{ "status": "success", "message": "Successfully Cancelled! It may take up to 5 minutes to complete." }

Error Response:

{ "status": "failed", "messages": "Can't find order id." }
{ "status": "failed", "messages": "Order Number {YourOrderNbr} is Cancelled or Closed, all fields and lines for this document will be skipped" }

Request Body:

{ "order_nbr": "0FA667S-45" }

Required: order_nbr - the customer's order identifier

Success Response:

{ "status": "success", "message": "Successfully Cancelled! It may take up to 5 minutes to complete." }

Error Response:

{ "status": "failed", "messages": "Can't find order id." }
{ "status": "failed", "messages": "Order Number {YourOrderNbr} is Cancelled or Closed, all fields and lines for this document will be skipped" }
GET /api/products/list Requires Authentication

Get a list of all available products with their item codes and status.

Success Response:

[ { "ptg_item_code": "TB1416S-RD", "product_status": "in_stock", "required_artwork_urls": 1 }, { "ptg_item_code": "TB1416S-BL", "product_status": "in_stock", "required_artwork_urls": 1 }, { "ptg_item_code": "TB1416S-PK", "product_status": "in_stock", "required_artwork_urls": 1 } ]

Response Fields:

  • ptg_item_code - Product item code
  • product_status - Product stock status: "in_stock", "discontinued", "low", or "out_of_stock"
  • required_artwork_urls - Number of artwork URLs required for this product (0-6)
GET /api/products/:item_code Requires Authentication

Get a single product by its item code.

URL Parameters:

  • item_code - The product item code (e.g., "TB1416S-RD")

Success Response:

{ "ptg_item_code": "TB1416S-RD", "product_status": "in_stock", "required_artwork_urls": 1 }

Error Response:

{ "status": "error", "message": "Product not found" }

Response Fields:

  • ptg_item_code - Product item code
  • product_status - Product stock status: "in_stock", "discontinued", "low", or "out_of_stock"
  • required_artwork_urls - Number of artwork URLs required for this product (0-6)

Rate Limiting

The API implements rate limiting to prevent abuse and ensure fair usage.

API Endpoints

Rate Limit Exceeded

When rate limit is exceeded, the API returns:

HTTP/1.1 429 Too Many Requests X-RateLimit-Limit: 100 X-RateLimit-Remaining: 0 X-RateLimit-Reset: 1704567890 { "status": "error", "message": "Rate limit exceeded. Please try again later." }

HTTP Status Codes

Code Meaning Description
200 OK Request successful
201 Created Order created successfully
400 Bad Request Validation errors in request
401 Unauthorized Invalid or missing JWT token
403 Forbidden Access denied
429 Too Many Requests Rate limit exceeded
500 Internal Server Error Server error
503 Service Unavailable Service temporarily unavailable

Support

For API support, please contact [email protected].

Last Updated: January 2026