Grofomo API
Browse the docs

Examples use a fictional festival, summer-fest. Sign in at events.grofomo.com and they switch to your own events.

Merch catalogue

GET/v1/events/{slug}/merch

The event's merch catalogue: each product with its colours, sizes, print zones and price.

Products carry the plain garment image plus the event logo to overlay, so you can render a preview without anyone shipping you mock-ups.

Send ?surface=webOmit it and the request is treated as coming from the mobile app, which is gated on a different visibility setting — so a perfectly live event can return 404 not_found for no visible reason.

Request

curl -sS \
  -H 'X-Grofomo-Key: pk_live_YOUR_PUBLISHABLE_KEY' \
  'https://api.grofomo.com/v1/events/summer-fest/merch?surface=web'

Path parameters

slugstringrequired
The event's URL slug. Globally unique, and fixed once the event is created. Example: `summer-fest`.

Query parameters

surface'web'required
Must be `web` for a website. Omit it and you get the mobile-app surface, which is gated on a different visibility setting — so a perfectly live event can return 404. Example: `web`.

Response

200 OK
{
  "apiVersion": 1,
  "data": {
    "eventSlug": "summer-fest",
    "logoUrl": "https://cdn.grofomo.com/summer-fest/brand/logo.svg",
    "deliveryPennies": 495,
    "items": [
      {
        "value": "8e0d2f4a-6c8b-4f17-9e2a-3b5d7f9c1e71",
        "name": "Summer Fest 2026 Tee",
        "garmentType": "Heavyweight cotton t-shirt",
        "description": "Organic cotton, boxy fit, printed in Bristol.",
        "pricePennies": 2500,
        "currency": "GBP",
        "sizes": [
          "S",
          "M",
          "L",
          "XL",
          "XXL"
        ],
        "colours": [
          {
            "label": "Bone",
            "hex": "#FAFAF7",
            "frontImageUrl": "https://cdn.grofomo.com/summer-fest/merch/tee-bone-front.png",
            "backImageUrl": "https://cdn.grofomo.com/summer-fest/merch/tee-bone-back.png",
            "logoColor": "black",
            "outOfStock": false
          },
          {
            "label": "Carbon",
            "hex": "#080808",
            "frontImageUrl": "https://cdn.grofomo.com/summer-fest/merch/tee-carbon-front.png",
            "backImageUrl": "https://cdn.grofomo.com/summer-fest/merch/tee-carbon-back.png",
            "logoColor": "white",
            "outOfStock": true
          }
        ],
        "printZones": [
          {
            "side": "front",
            "x": 0.5,
            "y": 0.34,
            "scale": 0.32,
            "recolor": true,
            "logoColor": "auto",
            "clip": true
          },
          {
            "side": "back",
            "x": 0.5,
            "y": 0.28,
            "scale": 0.55,
            "recolor": true,
            "logoColor": "auto",
            "clip": true
          }
        ]
      }
    ]
  }
}
eventSlugstring
logoUrlstring | null
The logo to overlay on each print zone — so you can render previews without any mock-ups.
deliveryPenniesnumber
Flat delivery fee in minor units, for shipped orders. 0 means free, or collection only.
itemsobject[]
items[].valuestring
Product id. Matches the option value on a `merch_items` form field.
items[].namestring
items[].garmentTypestring
What the garment is, e.g. "Heavyweight cotton t-shirt".
items[].descriptionstring | null
items[].pricePenniesnumber
Unit price in minor units, so 2500 is £25.00.
items[].currencystring
ISO 4217 code, e.g. "GBP".
items[].sizesstring[]
Available sizes, in display order.
items[].coloursobject[]
Colourways. Each carries the PLAIN garment image; overlay the event logo yourself.
items[].colours[].labelstring
Colourway name, e.g. "Bone".
items[].colours[].hexstring | null
Swatch colour, for a colour picker.
items[].colours[].frontImageUrlstring | null
Plain garment front, with no logo applied.
items[].colours[].backImageUrlstring | null
Plain garment back, with no logo applied.
items[].colours[].logoColorstring | nullmay be absent
How to treat the logo on this colourway: `auto`, `brand`, `white` or `black`.
items[].colours[].outOfStockbooleanmay be absent
Show the colourway, but do not let anyone buy it.
items[].printZonesobject[]
Where to place the logo on each side. All coordinates are 0–1 fractions, so a preview scales freely.
items[].printZones[].side"front" | "back"
items[].printZones[].xnumber
Centre of the logo, as a 0–1 fraction of the garment image width.
items[].printZones[].ynumber
Centre of the logo, as a 0–1 fraction of the garment image height.
items[].printZones[].scalenumber
Logo width, as a 0–1 fraction of the garment image width.
items[].printZones[].recolorbooleanmay be absent
items[].printZones[].logoUrlstring | nullmay be absent
A logo specific to this placement. Absent means use the event logo.
items[].printZones[].logoColorstring | nullmay be absent
`auto`, `brand`, `white` or `black`.
items[].printZones[].clipbooleanmay be absent
Mask the logo to the garment silhouette, so a wide placement does not bleed off the edge.
items[].outlineobject[]may be absent
Traced garment silhouette (0–1 points) driving the `clip` mask. Absent means use a default tee shape.
items[].outline[].xnumber
items[].outline[].ynumber
Generated from PublicEventMerchResponse

Errors

unauthorizedHTTP 401
No key was sent and the organiser requires one — or the key is invalid, revoked, belongs to another organisation, or is scoped to a different event.
origin_not_allowedHTTP 403
Your site's domain is not on the organiser's allowed list. Browser calls only: a server sends no Origin header and is unaffected.
not_foundHTTP 404
No event with that slug is published on this surface. Check the slug, and check you sent `?surface=web`.

Notes

  • Rate limited to roughly 60 requests per minute per caller. Guidance, not a contract — see caching and rate limits.
  • Cache-Control: no-store
  • Never cached, so stock and price changes are immediate.