Skip to main content
GET

Get Product Feed

Returns the entire public catalog as a ACP Product Feed in JSONL — one JSON object per line, no wrapping array.
Requires catalog: read. This is the format agent platforms ingest to index your events. It is a whole-catalog snapshot, not a paginated endpoint.

Query Parameters

string
Set to json to get a wrapped JSON object with build counters instead of JSONL. Useful for inspecting a feed before shipping it; JSONL is what an uploader consumes.

Response

200 with Content-Type: application/x-ndjson; charset=utf-8. Each line is one product row:
string
Stable across refreshes — an agent’s dedupe key. The event id.
string
Event name, truncated to 150 characters.
string
Truncated to 5,000 characters. Falls back to a factual line derived from the event when the organizer left it blank.
string
The canonical, buyable event page.
string
The organizer’s name. A real name, never a placeholder.
string
Also the organizer. Gomry is the marketplace, not the seller.
string
Cover image. Required — see skipped rows below.
string
in_stock, out_of_stock, pre_order, backorder, or unknown.
string
"79.99 USD" — major units, one space, uppercase ISO 4217.
Always true.
boolean
Currently false on every row. See below.
boolean
Always true. A ticket is delivered, not shipped — this keeps rows out of shipping-cost and delivery-estimate surfaces.
string
Events > Music, Events > Virtual, or Events.
array
Uppercase ISO 3166-1 alpha-2. Where the ticket can actually be bought.
boolean
Always false.

Length caps

Truncation prefers a word boundary, but only when one falls in the last 15% of the limit — otherwise the text is cut at the limit exactly, so a long unbroken string does not lose a large tail to a distant space. An event is always truncated, never dropped, for being too long.

Availability mapping

The feed’s vocabulary is narrower than the catalog’s:
not_yet_open maps to out_of_stock, not pre_order. Pre-order means “buy now, delivered later”; a sales window that has not opened cannot be bought at all, and saying otherwise sends a buyer to a checkout that refuses them.

About is_eligible_checkout

Every row currently reports false. This flag is a claim about the merchant’s checkout integration, not about one event’s sales window. The spec is explicit that it does not itself complete checkout onboarding and requires a separately enabled integration. Gomry’s ACP checkout endpoints are live and conformant, but no agent platform currently consumes them for public purchases — so asserting true would claim an integration that is not in place. It flips in the same change that turns a real integration on. Never per-event.

Why the feed has no date or venue

It has no field for either. The ACP feed format was written for retail, and there is no date, venue, or location field anywhere in the spec. product_category is therefore the only place the nature of the item survives, which is why it is always populated. Date, venue, and coordinates are available on the catalog endpoints.

Rows that are skipped

An event is omitted rather than published with invented data. A row is skipped when it has no quotable price, no organizer name, or no cover image.
A missing cover image is the most common reason a live event does not appear in the feed. It will be listable on /catalog/events and absent here, with no error. If you expect an event in the feed and it is missing, check its cover image first.

Errors

No feed has been built yet. Retry shortly — do not treat this as an empty catalog. Sent with Retry-After.
A feed exists but is too old to stand behind, which means recent rebuilds have been failing. We withhold it rather than serve prices nobody has checked since. Sent with Retry-After.
The stored feed could not be read.
Anything we cannot vouch for returns 503 rather than a short feed. A 200 carrying fewer rows than the catalog holds would be read as “these are all your events”, and the platform would de-index everything missing. Treat a non-2xx as “keep yesterday’s feed”, never as “the catalog shrank”.
One case is not covered by that guarantee: if an individual event’s detail lookup fails, the feed falls back to the list row for that event, which may then be skipped for want of a price. The response is still a 200 and the event is counted in skipped rather than count.So a 200 is not proof the feed is complete. Compare count against the previous run with ?format=json, and treat a sudden drop as a signal to investigate rather than as a catalog that shrank.

Freshness and caching

The feed is built on a schedule and served from the prepared copy, so the request returns quickly however large the catalog is — it is not rebuilt while you wait. Last-Modified tells you when the copy you received was built, and ?format=json carries the same timestamp as meta.built_at, so you can tell whether anything moved since your last pull. Responses are Cache-Control: public, s-maxage=900, stale-while-revalidate=3600. The feed is identical for every caller, so one cached copy serves all of them. The spec’s own refresh cadence is daily; fetching more often than the rebuild interval returns the same copy.