Partner REST API v1
Authenticate from your server with a tcgp_test_ or tcgp_live_ bearer key. The base URL is the deployed partner platform origin. Never expose API keys in browser code.
| Endpoint | Purpose |
|---|---|
| POST /v1/carts | Create a certified cart and checkout link |
| GET /v1/carts/{id} | Cart status, expiry, order ID, and saved affiliate code |
| GET /v1/orders/{id} | Production and shipment status, without customer or payment details |
Submit an order
When a customer places an order, provide HTTPS PNG/JPEG front and back URLs, their SHA-256 hashes, positive integer quantities, and all three certifications shown below. A shared back can be submitted using top-level back_image_url and back_sha256. Only standard stock is available. Optional external_ref is returned in status responses. After payment confirmation, customers return to your registered website. To choose a specific page, supply return_url on that same HTTPS origin. Your server must still confirm payment through order webhooks or the order API.
Artwork is downloaded after payment. Keep URLs available until processing finishes, and ensure files match the submitted hashes. Invalid or unavailable files hold production. Test mode validates instructions without downloading artwork, charging, printing, or shipping.
const response = await fetch(API_BASE + "/v1/carts", {
method: "POST",
headers: {
Authorization: "Bearer " + process.env.TCGP_API_KEY,
"Content-Type": "application/json",
"Idempotency-Key": customerOrder.id,
},
body: JSON.stringify({
external_ref: customerOrder.id,
return_url: new URL("/order-complete", process.env.STORE_ORIGIN).href,
card_stock: "standard",
items: [{ image_url: frontUrl, sha256: frontSha256,
back_image_url: backUrl, back_sha256: backSha256, quantity: 3 }],
certification: {
client_supplied: true,
reproduction_authorized: true,
manufacturing_only: true,
terms_version: "2026-10-02"
}
})
});
const cart = await response.json();
if (!response.ok) throw new Error(cart.error.message);
// Send only this URL to the customer's browser.
return { checkout_url: cart.checkout_url };Optional affiliate code
If your sign-in email has an approved TCGPlaytest affiliate code, select Yes under Your affiliate link in the partner dashboard. Create a key to save the choice, or choose Save without rotating a key if you already have one.
This account setting applies to new carts created through any of your API keys or your widget. The API key itself does not contain the code. Do not add an affiliate_code field to your cart request; it is selected by the server. The cart response includes affiliate_code, or null when none is saved.
Checkout prefills the saved code and checks eligibility after the customer enters their email. Customers can remove or replace it. Existing TCGPlaytest discount and reward rules apply, including self-referral restrictions; a saved code does not guarantee a discount.
To test a changed setting, create a new cart with a new idempotency key and use a different customer email from the affiliate owner. Existing carts keep their original code. Selecting No and saving turns off automatic application for future carts.
Checkout widget
Add a “Print with TCGPlaytest” button to your store. Customers choose their cards on your website, then continue to TCGPlaytest to pay for printing and delivery.
- Accept the manufacturing terms and generate a server-side API key in your dashboard.
- Create
POST /api/tcgplaytest/carton your own website. Authenticate the customer and verify the request origin/CSRF protection. Load their selected order from your server, verify rights acceptance, and submit the manufacturing instructions using the API example above. Use a stable order revision ID as the idempotency key so retries do not create duplicate carts. - Return JSON
{"checkout_url":"https://www.tcgplaytest.com/partner-checkout/TOKEN"}from that endpoint for live checkout. Use the exact URL returned by the API. Never return the API key to the browser. - Copy the widget script from your dashboard into your website. Set
data-cart-endpointif your server route has a different path. The widget sends a same-origin POST with an empty JSON object and your customer's cookies; your server must load the correct customer's cart.
On click, the widget calls your server to create a cart and redirects the customer to TCGPlaytest checkout. Your account must have active API access.
For a custom button, set data-auto-button="false" on the script and call await TCGPlaytest.open({ createCart: yourCheckoutFunction }) on click. That function should call your own server, including any CSRF token your shop requires, and return the same JSON response. Handle a rejected promise by showing an error to the customer.
Use signed order webhooks to confirm payment and fulfillment; opening checkout is not proof of payment. Test keys open a non-chargeable preview. Live keys open the main TCGPlaytest checkout. If you use a Content Security Policy, allow the partner platform in script-src and your own server in connect-src.
If your site uses the previous upload popup, replace it with the current dashboard snippet and add the server endpoint above.
Retries and limits
Idempotency-Key is required. Reusing it with identical instructions returns the original cart; changed instructions return 409. Use a unique key for each order revision. Keys remain reserved for the lifetime of the cart record. Default limits are 1,000 cards per cart, 60 requests per key per minute, seven-day cart expiry, 20 MiB per image, and 40 megapixels. Confirm current limits and minimum artwork dimensions with TCGPlaytest before integration.
Errors are JSON: {"error":{"code":"invalid_request","message":"…","item_index":0}}. Statuses include 400 validation, 401 invalid key, 403 blocked content, 404 not found, 409 conflict, 413 oversized request, 429 rate limit (Retry-After: 60), and 503 unavailable. Download/preflight errors occur after payment and prevent production.
Order webhooks
Configure test and live webhook URLs in your dashboard. Events include order.paid, order.in_production, order.shipped, order.cancelled, and cart.expired. Deduplicate by event ID.
Verify TCGP-Signature as t=unix_seconds,v1=hex_hmac. Calculate HMAC-SHA256 of the exact timestamp + "." + rawBody using your signing secret, compare in constant time, and reject timestamps more than five minutes old. Respond with 2xx. Failed deliveries retry with exponential delays up to 12 attempts; contact TCGPlaytest to resend events after retries are exhausted.