Go to App
workflow

User Workflow

The full operator path: ingest, normalize, transform, publish, and keep inventory in sync.

Ingestion

Three vectors feed the same catalog. Use whichever matches how the product showed up:

  1. **URL scraper** — POST /api/import/url or POST /api/scrape with { "urls": [...], "persist": true }. Best when the storefront exposes JSON-LD.
  2. **Document importer** — CSV, JSON, or PDF via POST /api/import/document (10MB cap, MIME checks). Google Drive public links are accepted after host checks.
  3. **Browser extension** — POST /api/extension/ingest with header x-toksync-api-key. Use this when you are already on the supplier page and do not want to copy the URL.

Preview before persist when you are learning a new domain. Persist writes products + variants; it does not publish to marketplaces by itself.

AI normalization

After extract, eListSync maps titles, descriptions, currencies, and Size×Color (or similar) matrices into the canonical product + variant schema. Specs such as GTIN, MPN, and weight land in ai_generated_metadata when present.

Normalization is **once per product**, not once per channel. That is the time saving the ROI calculator models (~0.5 minutes per product vs minutes × channels for copy-paste).

If a marketplace needs a different title length or attribute set, the transformer trims or maps fields. You can still edit the canonical record in the catalog; the next publish uses the new values.

Channel transformation

transformForChannel builds the payload the destination API expects:

  • Shopify — GraphQL productCreate / variant options
  • Amazon — SP-API listings items JSON for the marketplace id
  • eBay — Inventory API item + offer
  • WooCommerce — REST product + variations
  • Medusa / custom REST — Admin POST /admin/products with options and minor-unit prices
  • TikTok Shop / Walmart — channel-shaped product and inventory bodies

Transformers do not call the source URL. If an attribute is missing, it was missing at ingest or not stored on the variant — fix the catalog, do not patch the transformer per SKU in production.

API publishing

POST /api/products/publish with productIds and destinationAccountIds enqueues one job family per destination bulkhead.

You can publish the same canonical product to several destinations in one action. Listings are tracked separately so a Shopify success and an Amazon rejection can coexist.

Aliases: /api/v1/* maps to the same handlers behind a production gateway.

Inventory sync

After a sale:

  1. The marketplace sends a webhook (or a poll worker notices the order)
  2. Idempotency key drops duplicates
  3. Lua lock decrements canonical (and linked channel) stock
  4. Sibling channels receive an inventory update so they stop selling a ghost SKU

Seconds, not overnight batch files. If a channel is in an open circuit, we do not silently apply a stale quantity.

When something fails

  • **Mapper error** — payload missing a required channel field; fix variants or metadata, republish
  • **HTTP 401/403** — re-auth the destination; tokens expire
  • **HTTP 429** — backoff on that queue; other channels unaffected
  • **Timeout / 5xx** — retries then DLQ; Admin can replay

Open the product's sync log. That row is the source of truth for operators.