Resources
Artwork & API limits
File specifications, card limits and request allowances for this deployment.
Artwork and request limits
These values reflect this deployment's configuration.
| Field / limit | Description |
|---|---|
| Cart size | 1000 items maximum AND 1000 total card copies. |
| JSON body | 512,000 bytes maximum, including chunked requests. |
| Image URLs | At most 2048 UTF-16 code units. HTTPS only, without credentials, fragments or ports other than 443. Must resolve to public IPv4 addresses; private/local addresses and IPv6-only hosts are not accepted. |
| File formats | Single-frame PNG or JPEG that can be fully decoded. The file extension alone is not sufficient. |
| Image size | At most 20 MiB (20,971,520 bytes) per file and 40,000,000 pixels (width × height). |
| Recommended dimensions | 744 pixels wide × 1040 pixels high. Smaller readable images are accepted with image_low_resolution warnings; customers can acknowledge the warning and order. |
| Redirects | At most 3 per download, with HTTPS/public-address checks on every hop. |
| Download timeout | 15 seconds total per URL attempt, including DNS, TLS, redirects and body reads. This is not the total queue-processing time for the cart. |
| API-key rate limit | 60 requests per API key per minute, shared by upload-grant POSTs, cart POSTs, order GETs and ALL /v1/prepaid endpoints: quote creation, quote GET polling, reserve, release, prepaid orders, and balance/ledger reads. Retries also count. There is no separate prepaid allowance. Only authenticated cart-status GETs are exempt. On HTTP 429, wait for Retry-After (currently 60 seconds), then retry mutations with the same body and idempotency key where required. |
| Widget quotas | 60 new sessions per partner/hour; 2,000 upload grants per session; 10,000 upload grants per partner/rolling 24 hours. Defaults: 60 / 2,000 / 10,000; operator environment overrides are reflected here. These are separate from the API-key limit. Front/back uploads count separately, copies reuse uploaded artwork, and identical request_id retries reuse their grant. Widget cart GETs do not consume session/upload quotas. |
| Printing-credit polling | Poll GET /v1/prepaid/quotes/{id} through your server every five seconds or slower. One quote polled every five seconds uses 12 requests/minute; budget across all concurrent quotes and your other API requests. Quote polling and balance reads count toward the shared API-key limit. |
Keep source URLs reachable without authentication until validation finishes. Progress counts unique URLs, not copies. Each URL is checked once per cart in a normal run; an interrupted worker can retry. Files are stored privately at cart-specific paths and never reused across carts.
Server integration example
// YOUR server: authenticate the customer and load their selected order.
const API_BASE = "https://partner.tcgplaytest.com";
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.revisionId
},
body: JSON.stringify({
external_ref: customerOrder.id,
return_url: new URL("/order-complete", process.env.STORE_ORIGIN).href,
items: [{ image_url: frontUrl, back_image_url: backUrl, quantity: 3 }]
})
});
const cart = await response.json();
if (!response.ok) throw new Error(cart.error.message);
// Save cart.id against this customer's order. Relay the cart JSON to your UI.
// On a network error, retry these SAME instructions with the SAME Idempotency-Key.
// YOUR server: check cart ownership before proxying a browser's status request.
const statusResponse = await fetch(API_BASE + "/v1/carts/" + ownedCartId, {
headers: { Authorization: "Bearer " + process.env.TCGP_API_KEY },
cache: "no-store"
});
const status = await statusResponse.json();
if (!statusResponse.ok) throw new Error(status.error.message);
// Relay JSON to your UI. Poll every 3–5 seconds while validating.
// When open: live -> TCGPlaytest.checkout(status); test -> open status.checkout_url as a full page.
// Stop on failed/expired/blocked/cancelled/converted; show the relevant outcome.