Dashboard: You can register a feed URL for scheduled sync from your Tybrite dashboard, or push products directly via the API and SDK. Find your signing secret under Integrations → API Keys.
When it applies
Ingestion is the path for a catalog that lives somewhere else and is mirrored into Galactic Core:- A merchant runs their inventory in an ERP/PIM and wants it reflected in their Tybrite store.
- You’re migrating a catalog from another platform.
- A nightly export from a back-office system should keep the storefront in sync.
Batch size
A request carries at most 12 products. A larger batch is rejected with400 and nothing is
written, rather than applying part of the batch and leaving the rest to fail item by item.
For a large catalog, send a sequence of batches, or configure a scheduled sync,
which fetches and imports a whole catalog on a timer and has no such limit.
Selling on a marketplace
Nothing changes. A merchant whose store is part of a marketplace pushes their catalog exactly as any other merchant does, with their own store’s secret key, and their products appear on the marketplace storefront alongside everyone else’s once the store is approved. The marketplace listing is a read over the same catalog — approved stores, aggregated — so there is no separate marketplace feed, no marketplace ingestion endpoint, and nothing extra to configure. An operator key is refused with403 — ingestion is store-scoped, because a catalog belongs to the
merchant who owns it rather than to the marketplace that lists it.
Quick start
Ingestion is a write, so initialize the SDK with a secret key and sign each request. Below, one standalone product and one multi-variant product (its rows share aproduct_group):
The SDK signs the request for you when it’s configured with your secret key. If you call the endpoint directly (curl, another language, a serverless handler), you must add the signing headers yourself — see Signing a request.
How matching by SKU works
Every row carries asku — your unique stock-keeping unit. That SKU is the identity Galactic Core matches on, scoped to your store:
- SKU already exists → the product, its variant, and its stock are updated in place.
- SKU is new → a product (and variant) is created.
strategy: 'create_only'. Matching SKUs are then skipped (counted in rows_skipped) rather than updated:
upsert_by_sku (update existing, create new).
Variants
Rows that share the same non-emptyproduct_group become variants of a single product — each row still needs its own unique sku. A row with no product_group is a standalone, single-variant product. The first row in a group supplies the product-level fields (name, description, category); each row contributes its own variant_name, price, and stock.
Formats
Declare the format with theContent-Type header or the ?format= query parameter. All three normalize to the same result. The SDK sends JSON; the XML and CSV shapes below are for when you push the raw body yourself.
Product Name maps to name).
Product fields
Your own columns
A column that is not in the table above is matched against the custom fields defined on products for your store, by the field’s label — the name shown in the dashboard, which is what you would have called the column. A match records the value on the product; anything else is ignored, so a feed carrying extra columns behaves exactly as it did before.Fabric and Country of origin land on the product if fields with those labels exist. Values are
written after the product itself, and on an update they are refreshed along with everything else, so a
feed stays the source of truth for them.
The field has to exist before a feed can fill it. Fields are created in the dashboard under
Settings → Custom Fields, not by a feed — a new column does not define a new field.
Response shape
Rows are validated and applied independently — one bad row never fails the whole batch. The response always carries asummary of counts and an errors array describing every rejected row:
status is success when nothing failed, or partial when some rows failed but others imported. If every row fails validation, the request returns 422 and nothing is written.
Summary fields
Per-row errors
Each entry inerrors pinpoints exactly what to fix:
Signing a request
The SDK signs for you when initialized with a secret key. If you push the raw body yourself, add three headers. The signature is a base64 HMAC-SHA256 of`${timestamp}.${rawBody}` using your store’s signing secret (the same scheme as orders and payments) — sign the exact bytes you send.
Test without a key
Two public, no-key endpoints validate a feed format ahead of any integration work. Both are rate-limited to 60 requests/hour per IP. A valid sample feed to model your own on (?format=json|xml|csv):
product_group expresses variants.
A validation run that writes nothing. It returns the same summary and errors a real import would, plus a normalized_preview showing how Galactic Core interpreted each row:
Scheduled sync
Instead of pushing, you can have Galactic Core pull a feed for you. Register a feed URL in your dashboard, choose a cadence, and Galactic Core fetches and syncs the catalog on that schedule — matching by SKU exactly like the push API. After each scheduled run, afeed.sync.completed webhook fires with the run’s summary, so your systems can react to the result without polling. Subscribe to it the same way as any other event:
Publish your own catalog (outbound feed)
Ingestion works both ways: a store can also expose its own catalog as a public feed for other systems to pull from — another store’s scheduled sync, a partner, a marketplace, or your own tooling. It is enabled in the dashboard under Integrations → Catalog Sync → Publish my catalog, which produces a public URL in two formats, readable with no API key:{store} is your store id or short store code.
On a store belonging to an operated platform, the host is that platform’s own. The dashboard shows
the URL to copy, and where the store belongs to an agency it reads
https://api.theirplatform.com/v1/feeds/…
rather than the address above — a feed URL is pasted into Google Merchant Center or a partner’s system,
where it outlives the screen it came from. The path, the formats and the token all behave identically.
See Running your own platform.products.json.
A token added in the dashboard and appended as ?token=… keeps a feed semi-private.

