Origo Help
Product feeds
Give another system a current, filtered view of Product data in JSON or CSV.
Last reviewed:
What Product feeds are
A Product feed is a read-only list of current Product records. Use it when a shop, search service, integration, spreadsheet, or agent must regularly read catalogue data without creating an Export Job. A feed does not save a file or change Products. Each request creates a fresh response from the filters in its URL or tool input.
Use a feed for repeat reads from a stable address. Use an Export Job when a person needs a stored result and job history. Use activation when Origo must publish through a configured destination connection.
Open and authenticate a feed
- Sign in to your Origo tenant.
- In the left navigation, find Tools.
- Select Feeds.
- Choose common filters, then copy or open the generated Product feed URL.
- Add other parameters from this guide when the URL builder does not show them.
Admins, editors, and viewers can read Product feeds. A signed-in browser can use its
current session. An external system must send an Origo API key in the request header:
Authorization: Bearer {api-key}. Do not put the API key in the URL.
An admin or editor can create a personal API key under Access Management → API Keys. A personal key inherits its owner's current role. Only an admin can create an organisation key. An admin can give that key a fixed Viewer role for an external feed consumer. The key must remain active.
GET /feeds/:channel when the
channel is part of the address. Use GET /api/feeds/products when filters
are query parameters. Both routes need authentication.
Choose JSON, CSV, selected rows, or image URLs
Set format=json for structured data. Set format=csv for a
table that a spreadsheet or import tool can read. The
/api/feeds/products route defaults to CSV. The
/feeds/:channel route defaults to JSON. State the format in saved URLs so
the result is clear.
Omit projection, fields, attributes, and
attributeCodes for rich rows. Omitting fields and attributes preserves
the existing rich feed shape. Rich rows contain the Product fields, translated values,
Product attributes, associations, and other feed data. Rich JSON includes
images and files. Therefore, an exact rich Product read with
format=json&productId={product-id} includes its selected images. Rich
CSV does not include images or files. It stores complex metadata and associations as
JSON text inside CSV cells.
Add projection=sparse when you only need an ID, Product number, and
translated name. Sparse rows skip attributes, associations, images, files, and rich
variant checks. projection=sparse rejects fields and attributes. Do not
use projection=full. Omit the parameter for rich rows.
Use comma-separated fields and attributes for an exact
compact row. There are six core fields: id, brands,
name, productNumber, status, and
type. Choose up to six fields and up to 50 Product attribute codes, in
the order you want returned. attributes=slug selects the existing Product
EAV attribute and returns it as attribute:slug; it does not add a Product
slug field. Selected Product EAV attributes must be active, coded, Product-applicable,
non-link/multiLink, and channel-compatible: global, or
scoped to the selected Channel; without a Channel, global only. Selected rows contain
no unrequested fields, served-locale companions, metadata, associations, images, or
files.
Prefer repeated attributeCodes parameters for exact codes:
attributeCodes=finish%2Ccolour&attributeCodes=slug selects
finish,colour and slug, in that order. URL-encode each value
once; literal commas, percent signs, plus signs, quotes, Unicode, and meaningful
whitespace are preserved. Empty, whitespace-only, duplicate, unknown, or more than 50
codes are rejected. Legacy attributes=a,b still splits on commas and
trims each token. Do not combine attributes and attributeCodes. Both selectors are
rejected with sparse or images projection. MCP accepts attributeCodes as a native
string array, for example ["finish,colour", "slug"].
When selected, brands is an ordered array of { id, name }
objects from active direct Brand assignments. Each name uses the feed locale, then the
configured base locale when needed, with no served-locale companion. CSV serializes
that array as JSON text.
Use projection=images only for an exact Product image feed.
projection=images requires format=json, a nonblank productId, and
isActive=true
because returned public media URLs must be servable. It rejects CSV, brandId, fields,
and attributes. Its normal JSON envelope's
data is an ordered list of original image URLs—never Product rows,
documents, image records, or metadata. Page 1 returns every URL for the one Product;
an absent Product or a later page returns data: [],
total: 0, and hasMore: false.
Filter the Product rows
All supplied row filters apply together. A Product must match each
supplied brandId, productId, Channel, status,
isActive, and textFilter value. The
locale value controls the returned language instead of selecting rows.
brandId and productId together are valid for normal full or
sparse feeds and use AND filtering. Image projection is the exception: it requires the
exact Product ID alone and rejects brandId.
-
brandId={brand-id}matches one Brand ID. Brand filtering uses active, direct Product-Brand assignments only. A Brand inherited from a parent Product does not match. Deleted Brands and deleted assignments do not match. -
productId={product-id}matches one immutable Product ID exactly. It does not match a Product number or part of an ID. -
channelId={channel-id}returns Products linked to that Channel. On the canonical route, put the Channel ID or code in/feeds/{channel}instead. -
locale={locale}selects an enabled content locale, such asen-USornl-NL. It does not exclude a Product when Origo must use locale fallback. Without it, Origo uses the Channel's first locale, or the catalogue base locale when no Channel is selected. -
status={status}acceptsdraft,prepared,reviewed,notReady, orready. An unsupported value does not apply a status filter. -
isActive=truereturns active Products. This is also the default.isActive=falsereturns inactive Products. Use an explicit empty value,isActive=, to include both active states. -
textFilter={text}finds a partial match in the base Product name, Product number, or Product type. It does not search a translated name returned for the selected locale. The text filter is not an exact Product lookup.
Deleted Products never appear. Filters also apply before paging. For example, a Product with the requested Brand but a different status does not appear.
Read all pages
page is one-based. Omit it for page 1, or use a positive whole number.
Each page contains at most 1,000 rows in stable base Product name and ID order.
Translated names can appear out of alphabetic order in the returned locale.
JSON includes page and hasMore. While
hasMore is true, request the next page. CSV puts the same
values in the X-Feed-Page and X-Feed-Has-More response
headers. Do not use the current row count as the continuation rule. A full page can
still be the last page.
page value.
Copy a URL example
Replace each value in braces. Use the tenant origin where you sign in, without a
trailing slash. Percent-encode each query value before you add it. For example, use
red%20%26%20blue for red & blue. The
Tools → Feeds builder does this automatically.
Active Products as sparse JSON
{tenant-origin}/api/feeds/products?format=json&projection=sparse
Recommended Brand selected feed
{tenant-origin}/api/feeds/products?format=json&brandId={brand-id}&fields=id,brands,name&attributeCodes=slug
One Product's image URLs
{tenant-origin}/api/feeds/products?format=json&projection=images&productId={product-id}&isActive=true
Ready Products that contain text
{tenant-origin}/api/feeds/products?format=csv&status=ready&textFilter={search-text}&page=1
Both active and inactive Products
{tenant-origin}/api/feeds/products?format=json&isActive=&page=1
Canonical Channel route
{tenant-origin}/feeds/{channel-id-or-code}?format=json&projection=sparse&locale=en-US&page=1
Recognise sparse output
Sparse JSON uses the normal feed envelope. total is the number of rows on
this page, not the total across all pages. productNumber can be null.
{
"data": [
{
"id": "{product-id}",
"productNumber": "CHAIR-001",
"name": "Lounge chair"
}
],
"total": 1,
"locale": "en-US",
"page": 1,
"hasMore": false
}
A deprecated locale alias can add a warnings list. Use the
canonicalLocale in that warning before the stated sunset date.
Sparse CSV always has exactly these three columns:
id,productNumber,name
{product-id},CHAIR-001,Lounge chair
Resolve errors and empty results
Feed validation and domain errors include a short code and a readable
error message. Authentication responses differ. An unauthenticated feed
request returns {"error":"Unauthorized"} without a code. A
browser request for the canonical route can redirect to sign-in. A suspended browser
session receives 403. The compatibility route returns JSON with
ACCOUNT_BANNED. The canonical route returns plain text
Forbidden. A personal API key whose owner is suspended is rejected with
401. An organisation key does not depend on its creator's current account
status. It remains usable while the key itself is active. Correct the request or
access before retrying.
401: sign in, or send a valid Bearer API key.-
VALIDATION_ERROR: usejsonorcsv; use onlyprojection=sparseorprojection=images; do not send blank, duplicate, unknown, or over-limit field/attribute selectors; and follow the image projection requirements. INVALID_PAGE: use page 1 or a larger positive whole number.INVALID_LOCALE: use an enabled locale available to the Channel.-
LOCALE_ALIAS_EXPIRED: replace the old locale with the returned canonical locale. -
VARIANT_SETUP_INVALID: a rich feed found an invalid ready variant family. Correct that setup, or use sparse rows when rich data is not needed. -
NOT_FOUND: the Channel in/feeds/{channel}does not exist or was deleted.
No matching products is not an error. JSON returns an empty
data list with total: 0 and hasMore: false. CSV
returns its header row and X-Feed-Has-More: false. An unknown Brand or
Product ID gives an empty result. The compatibility route also gives an empty result
for an unknown channelId; the canonical Channel route gives
NOT_FOUND instead.
Use the MCP equivalent
An authenticated MCP client can call read_product_feed. Use the same
named inputs: format, projection, brandId,
productId, fields, attributes,
channelId, locale, status,
isActive, textFilter, and page. The tool
defaults to JSON and active Products.
{
"projection": "sparse",
"brandId": "{brand-id}",
"channelId": "{channel-id}",
"locale": "en-US",
"page": 1
}
For JSON, the tool returns the same feed envelope as HTTP. For CSV, its first content
item is the CSV body. Its second content item contains page and
hasMore. Request the next page while hasMore is true.
MCP uses the same fields, attributes, and projection=images rules, limits, validation, and output shapes.