TCG WHOLESALE HQ · DEVELOPER GUIDE
Connect your website to our wholesale catalogue
For approved customers and their developers. Use our prices, current stock and hosted product images in your own store.
1. Generate your key
Sign in with the customer account you used to request access. After our team approves your API request, select Generate API key. Copy it once into your server's secret settings. Each customer has one active key. Rotation immediately stops the old key; revocation stops access until you generate another.
Keep the key on your server. Never paste it into Shopify Liquid, a browser script, a public repository, a URL, an email or chat. A normal browser-facing CSV URL is not an authenticated integration.
2. Choose how your site connects
| Platform | Setup |
|---|---|
| Shopify | Have your developer use a private server-side app or a compatible importer that supports Bearer authentication, pagination and scheduled updates. Map our stable SKU to your store's product/variant ID. Store this API key in the integration's secret settings, never your theme. We do not need your Shopify admin password. |
| WordPress / WooCommerce | Use a server-side plugin or scheduled job. Store the key in a protected server setting and use WordPress HTTP requests with an Authorization header. Use real server scheduling for reliable 15-minute updates. Map our SKU to your WooCommerce product/variation ID. |
| Custom website | Fetch JSON from your backend, save it in your database, and display that local catalogue to visitors. Keep API credentials and raw request logs private. |
No one-click Shopify or WooCommerce plugin is included. Your developer must implement the mapping and update rules below, or configure an importer with those capabilities. Start with a draft product or test store before enabling bulk updates.
3. Fetch JSON or CSV
Endpoint: https://tcg-wholesale-wise.fly.dev/api/v1/catalogue
Method: GET
Header: Authorization: Bearer YOUR_API_KEY
JSON: ?currency=AUD&limit=100
CSV: ?currency=AUD&format=csv&limit=100
Supported currencies: ?format=currencies
Available fiat currencies depend on our current exchange-rate feed. Unsupported currencies return an error; there is no silent fallback. Catalogue prices exclude our 5% commission fee. Please incorporate this fee into your pricing, alongside your own retail margin. Exchange rates may differ from your bank's rate; shipping, duties and taxes are separate.
Prices are decimal strings with an explicit currency. Preserve decimal precision in your database. Keep the selected currency consistent across a full export and its incremental updates. Changing currency requires a fresh full export.
4. Finish every page before saving
For JSON, follow next_cursor with ?cursor=VALUE&limit=100 until it is empty. Treat tokens as opaque and URL-encode them. Save the checkpoint from the final page only after all data commits successfully. For CSV, use the response headers X-Next-Cursor and X-Checkpoint; keep format=csv on each request.
Schedule one sync every 15 minutes. After the initial full export, request ?since=CHECKPOINT, then follow any next cursors. Do not combine since and cursor. A changed exchange rate can return all current products again; upsert them normally. Pagination tokens last 24 hours and checkpoints last 30 days. Restart a full export if your token expires.
Default page size is 100; maximum is 500. The limit is 60 requests per minute per customer. Honour Retry-After on HTTP 429 and spread large jobs over time. Your site should serve visitors from your own cached database, not call our API on every page view.
5. Map products and updates safely
| Field | How to use it |
|---|---|
| sku | Stable catalogue variant identifier. Use it as your integration key and map it to your own product/variant ID. Do not match by title. |
| title / option | Product name and variant description. Review before initially publishing. |
| price / currency | Catalogue price excluding our 5% commission fee. Incorporate this fee and your own retail margin into your selling price. |
| stock / available | Recent available inventory. Stock is not reserved. Hide or disable purchases when unavailable; confirm availability before ordering. |
| image | Use the supplied hosted image URL. It may be blank. Keep a neutral placeholder in that case; do not invent a replacement URL. |
| deleted | When true, hide/remove the integration record by SKU. A removal has no price or stock fields; do not require them. Only change products owned by this integration. |
| revision / updated_at | Change information. Apply repeated records idempotently and save the final checkpoint atomically. |
Keep the last good catalogue when a request fails or a page is missing. Do not set everything to zero because of a timeout. A full export replaces only your integration's snapshot. Stock-only updates should not overwrite your descriptions or retail margins.
This is a read-only catalogue API. It does not create orders, accept payment, reserve inventory or automatically fulfil orders placed on your website.
Server-side JavaScript example
This example downloads a complete batch. Your developer must add the database transaction and scheduler described in its comments.
// Run on your server with Node.js 22+. Store the key in secret settings.
const endpoint = 'https://tcg-wholesale-wise.fly.dev/api/v1/catalogue';
const key = process.env.TCG_WHOLESALE_API_KEY;
if (!key) throw new Error('Configure TCG_WHOLESALE_API_KEY');
const currency = 'AUD'; // e.g. USD, EUR, GBP, JPY
// Set savedCheckpoint only after the previous complete sync committed.
const savedCheckpoint = null;
let params = new URLSearchParams({ currency, limit: '100' });
if (savedCheckpoint) params.set('since', savedCheckpoint);
const changes = [];
let checkpoint;
do {
const response = await fetch(endpoint + '?' + params, {
headers: { Authorization: 'Bearer ' + key },
signal: AbortSignal.timeout(20000)
});
if (!response.ok) {
// Keep the last good catalogue. Retry 429 using Retry-After; retry 503 later.
throw new Error('Catalogue returned HTTP ' + response.status);
}
const page = await response.json();
if (page.currency !== currency) throw new Error('Unexpected currency');
changes.push(...page.data);
checkpoint = page.checkpoint;
params = page.next_cursor
? new URLSearchParams({cursor: page.next_cursor, limit: '100'})
: null;
} while (params);
if (!checkpoint) throw new Error('Incomplete export');
// In one local database transaction:
// - If savedCheckpoint is null, replace YOUR integration's catalogue snapshot.
// - Otherwise, upsert each change by sku; remove/hide records with deleted:true.
// - Save checkpoint and currency only after all records commit successfully.
// Keep other products in your store untouched. Never log the key or headers.
console.log('Ready to commit', changes.length, 'catalogue records');Troubleshooting
| HTTP status | Action |
|---|---|
| 400 | Check parameters, currency and token validity. Restart a full export for an expired token or changed currency. |
| 401 | Check the Bearer header. Generate a key, or replace your server secret if you rotated/revoked it. |
| 403 | Account approval or wholesale eligibility is missing. Contact our team. |
| 429 | Wait for the Retry-After interval before retrying. |
| 503 | Catalogue, rates or verification are temporarily unavailable. Keep your last good data and retry later. |
Contact info@tcgwholesalehq.com with your website platform, timestamp and HTTP status. Never send API keys, authorization headers or customer passwords.