Magento (Adobe Commerce) is the second catalog shape you will meet building a marketplace on existing vendors, and it behaves nothing like the first. Its public GraphQL API is genuinely good — you can read products, attributes and stock over a single typed endpoint, often with no token — but Magento models product data through internal option IDs and configurable-product attribute sets, and if you ingest those naively your storefront will announce that a product is made "by 2822". This is the seam we read Magento through, the specific bug that number represents, and the fallbacks that fill what GraphQL leaves thin.
Public GraphQL as the ingestion seam
Magento ships a GraphQL endpoint intended for headless storefronts, which makes it a natural read seam for a marketplace. A single query can return a product's name, price, media, stock status and its attributes, and configurable products expose their variants with the option combinations that distinguish them. Because it is typed, you request exactly the fields you need and get a predictable shape back, which is a relief after screen-scraping.
Two things to plan for from the start. First, GraphQL is a read seam only — orders route back to the vendor through a separate hand-off, exactly as they do for a WooCommerce vendor. Second, GraphQL hands you Magento's internal representation of the data, and Magento's internal representation is where the adventures begin.
Two operational notes save pain later. GraphQL lets you request deep, nested queries, but a marketplace ingest should page through the catalog in modest batches and stay a polite client — a query that asks for the entire store in one shot is how you get throttled or time out mid-sync. And because the endpoint is public and unauthenticated for catalog data, treat it as read-only truth about the storefront, not a private admin channel: everything you need is what a shopper could already see.
The option-ID problem (brands that are numbers)
Magento stores many attribute values — brand, colour, material, and so on — as option IDs: integers that point at a label in a separate lookup, rather than the label itself. Ask for the brand and a naive query can return 2822. The label "meant" by 2822 lives elsewhere, in the attribute's option metadata, and if you do not resolve it you publish the pointer instead of the value.
A Magento vendor's feed exported its manufacturer field as exactly this kind of internal option ID, so freshly ingested products proudly announced they were made "by 2822". The language model downstream did not save us — it dutifully wrote fluent product copy about a brand named 2822. The permanent fix was deterministic, upstream of any AI: reject numeric brand values outright, and resolve option IDs to their labels at ingest by reading the attribute's option metadata. An LLM will not rescue you from garbage input; it will eloquently amplify it.
The general rule this bug teaches: any attribute whose value comes back as a bare integer is probably an unresolved option ID, and should be resolved or rejected before it reaches a shopper. The same discipline catches the same class of defect on variants, where the axis that distinguishes two variations can also arrive as an opaque numeric index. Treat numeric-where-a-word-belongs as a red flag everywhere in the pipeline — it is one of the seven defects catalogued in product data quality.
Reading stock signals you can trust
Stock is the field a marketplace most needs to be right and the one Magento is most inconsistent about exposing. Depending on configuration you may get a clean in-stock boolean, a quantity, or — for a first-party integration that has not enabled the relevant fields — very little. The failure mode to avoid is defaulting missing stock to "in stock", which sells products the vendor cannot ship, or to "out of stock", which hides a live catalog.
Pick a safe default deliberately, and reach for a second source when GraphQL is thin: the product page's own structured data often carries an availability value even when the API field is unset. In practice, treat stock as the field most worth a second opinion — a product that shows in stock but ships nothing generates a refund, a support ticket and a dent in trust all at once — so it is worth crossing the API signal against the product page and defaulting conservatively when the two disagree. Which brings us to the most useful fallback Magento gives you.
Mapping attribute sets to your schema
Magento groups attributes into attribute sets — a "supplement" set has different fields from a "clothing" set — and different vendors define their sets differently. Your marketplace has its own schema, so ingestion is a mapping problem: this vendor's "net_weight" and that vendor's "size" both feed your canonical weight field; a vendor's free-text "flavour" attribute feeds your controlled flavour list after normalisation.
Do the mapping explicitly and defensively. An unmapped attribute set means products land with half their fields empty; a mis-mapped one means a clothing size lands in a weight field. A practical safeguard: log the misses. When a vendor introduces an attribute set you have not mapped, you want the product to land with a flagged "unmapped attributes" note for review, not to silently drop half its fields — so the unmapped set becomes a small, visible onboarding task instead of a data gap that surfaces as a shopper complaint weeks later. This is the same shopper-first mapping problem you solve for categories, and it feeds the same downstream taxonomy — worth reading alongside designing a product taxonomy.
When product-page JSON-LD fills the gaps
When GraphQL is thin, the vendor's own product pages usually carry Product structured data (schema.org JSON-LD), because they emit it for Google. That markup frequently includes the exact fields the API left unset — a resolved brand name instead of an option ID, an availability value, a price, a GTIN. Reading it as a fallback is a cheap way to recover data without asking the vendor to change their store.
Treat it as a fallback, not the primary source — structured data can be stale or incomplete — but as fallbacks go it is high quality, because the vendor maintains it for their own search visibility. Between resolved option IDs, safe stock defaults, explicit attribute mapping and JSON-LD backfill, a Magento catalog becomes as clean a marketplace citizen as any other, without the vendor lifting a finger.
Key takeaways
- Public GraphQL is a strong read seam — typed, often token-free, and it exposes variants — but it hands you Magento's internal representation.
- Resolve option IDs to labels or reject them; a bare integer where a brand belongs is an unresolved pointer, and an LLM will happily write copy about it.
- Choose a safe default for missing stock deliberately, and never let "no signal" silently become "in stock".
- Map attribute sets to your canonical schema explicitly; unmapped sets leave products half-empty, mis-mapped ones put a size in a weight field.
- Use product-page JSON-LD as a high-quality fallback for the fields GraphQL leaves thin — the vendor already maintains it for search.
Frequently asked questions
How do you ingest a Magento store into a marketplace?
Why does a Magento product show a number instead of a brand name?
How reliable is Magento stock data over GraphQL?
Can product-page structured data help ingest a Magento catalog?
Magento catalogs, cleaned and merchandised.
We ingest Magento and WooCommerce vendors into one managed marketplace, resolving the option-ID and attribute-set messes so shoppers never see them.
Request early access See the live marketplace →