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.

Event lineup

GET/v1/events/{slug}/lineup

The published lineup for an event — every set, with its stage, start and end time.

Slots arrive as one flat slots array rather than pre-grouped, so you can group by day, by stage, or by both, depending on how your page is laid out. A back-to-back set carries its full roster in artists, with the lead act repeated in artist; an unannounced slot has artist: null and a placeholderLabel to render instead. A setNote ("DJ set", "Live") says how a set is played: show it beside the name when it is there.

startTime and endTime are ISO instants, not wall-clock strings — format them in the event's timezone (from event detail) for display. An overnight set crosses midnight in those timestamps but keeps its day on the festival day it belongs to, so group by day, not by the date inside the timestamp.

This reads the organiser's published snapshot, never their working draft. A lineup being rearranged in the console will not appear here until it is published, which is what makes it safe to render straight onto a public page.

On the web surface the response also carries schemaOrg: a ready-made MusicEvent JSON-LD block you can drop into a <script type="application/ld+json"> tag for rich search results.

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/lineup?surface=web'

Path parameters

slugstringrequired
The event's URL slug. Globally unique. It can change if the organiser renames the event, but an old slug keeps reaching the same event, so a stored one never breaks. 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": {
    "eventId": "6f1c8e2a-4b3d-4c9e-9f21-8a7d5e0b1c34",
    "eventSlug": "summer-fest",
    "surface": "web",
    "slots": [
      {
        "id": "3e5a7c9b-0d2f-4e6a-9b8c-1d3f5a7e9c02",
        "stage": "Main Stage",
        "day": "2026-07-17",
        "startTime": "2026-07-17T20:30:00+00:00",
        "endTime": "2026-07-17T22:00:00+00:00",
        "durationMinutes": 90,
        "billingTier": "headliner",
        "isPlaceholder": false,
        "placeholderLabel": null,
        "placeholderDescription": null,
        "setNote": null,
        "featured": true,
        "createdAtIso": "2026-04-02T11:20:00.000Z",
        "artist": {
          "id": "9c7e5a3b-1f0d-4b2e-8a6c-4d2f0b8e6a13",
          "name": "Nala Vex",
          "imageUrl": "https://cdn.grofomo.com/summer-fest/artists/nala-vex.jpg",
          "genres": [
            "House",
            "Breaks"
          ],
          "hometown": "Manchester",
          "region": "England",
          "country": "GB",
          "locationLabel": "Manchester, England, United Kingdom"
        },
        "artists": [
          {
            "id": "9c7e5a3b-1f0d-4b2e-8a6c-4d2f0b8e6a13",
            "name": "Nala Vex",
            "imageUrl": "https://cdn.grofomo.com/summer-fest/artists/nala-vex.jpg",
            "genres": [
              "House",
              "Breaks"
            ],
            "hometown": "Manchester",
            "region": "England",
            "country": "GB",
            "locationLabel": "Manchester, England, United Kingdom"
          }
        ]
      },
      {
        "id": "47a9e1c3-5b8d-4f20-9c6e-3a1b7d5f9e02",
        "stage": "The Orchard",
        "day": "2026-07-18",
        "startTime": "2026-07-18T22:00:00+00:00",
        "endTime": "2026-07-19T00:00:00+00:00",
        "durationMinutes": 120,
        "billingTier": "special guest",
        "isPlaceholder": false,
        "placeholderLabel": null,
        "placeholderDescription": null,
        "setNote": "DJ set",
        "featured": false,
        "createdAtIso": "2026-04-02T11:22:00.000Z",
        "artist": {
          "id": "d1f3b5a7-9c2e-4d80-8b6f-5a3c1e7d9b04",
          "name": "Sonny Delrey",
          "imageUrl": "https://cdn.grofomo.com/summer-fest/artists/sonny-delrey.jpg",
          "genres": [
            "Disco",
            "Italo"
          ],
          "hometown": "Bristol",
          "region": "England",
          "country": "GB",
          "locationLabel": "Bristol, England, United Kingdom"
        },
        "artists": [
          {
            "id": "d1f3b5a7-9c2e-4d80-8b6f-5a3c1e7d9b04",
            "name": "Sonny Delrey",
            "imageUrl": "https://cdn.grofomo.com/summer-fest/artists/sonny-delrey.jpg",
            "genres": [
              "Disco",
              "Italo"
            ],
            "hometown": "Bristol",
            "region": "England",
            "country": "GB",
            "locationLabel": "Bristol, England, United Kingdom"
          },
          {
            "id": "5b8d2f4a-6c0e-4a13-9d7b-8f2a6c4e0d15",
            "name": "Kiruna",
            "imageUrl": null,
            "genres": [
              "Ambient"
            ],
            "hometown": "Gothenburg",
            "region": null,
            "country": "SE",
            "locationLabel": "Gothenburg, Sweden"
          }
        ]
      },
      {
        "id": "a3c5e7d9-2b4f-4061-8e9a-7c5d3b1f9a26",
        "stage": "Main Stage",
        "day": "2026-07-19",
        "startTime": "2026-07-19T21:00:00+00:00",
        "endTime": "2026-07-19T22:30:00+00:00",
        "durationMinutes": 90,
        "billingTier": "headliner",
        "isPlaceholder": true,
        "placeholderLabel": "Sunday headliner",
        "placeholderDescription": "Announced 1 June.",
        "setNote": null,
        "featured": true,
        "createdAtIso": "2026-04-02T11:25:00.000Z",
        "artist": null,
        "artists": []
      }
    ],
    "schemaOrg": {
      "@context": "https://schema.org",
      "@type": "MusicEvent",
      "name": "Summer Fest",
      "startDate": "2026-07-17T12:00:00+01:00",
      "endDate": "2026-07-19T23:59:00+01:00",
      "location": {
        "@type": "Place",
        "name": "Ashton Court",
        "address": "Ashton Court Estate, Bristol BS41 9JN, United Kingdom"
      },
      "performer": [
        {
          "@type": "MusicGroup",
          "name": "Nala Vex"
        },
        {
          "@type": "MusicGroup",
          "name": "Sonny Delrey"
        }
      ],
      "dateModified": "2026-06-01T09:15:00.000Z"
    },
    "lastUpdatedAt": "2026-06-01T09:15:00.000Z"
  }
}
eventIduuid
eventSlugstring
surface"app" | "web"
Echo of the surface this response was built for.
slotsobject[]
Every published set, as one flat list. Group by `day` or `stage` yourself, depending on how your page is laid out.
slots[].iduuid
Stable id for this set. Use it as a render key.
slots[].stagestring | null
Stage name. Null before a stage is assigned.
slots[].daystring | null
Festival day this set belongs to, as `YYYY-MM-DD`. An after-midnight set is attributed to the day it started, so a 01:00 slot sits under the previous date.
slots[].startTimestring | null
When the set starts, as an ISO 8601 instant (e.g. `2026-07-17T20:30:00+00:00`). Convert to the event `timezone` (from event detail) for display — do not render it raw.
slots[].endTimestring | null
When the set ends, as an ISO 8601 instant. Same conversion rule as `startTime`.
slots[].durationMinutesnumber | null
Set length in minutes.
slots[].billingTierstring | null
Organiser's billing label, e.g. "headliner". Free text; do not switch on it.
slots[].isPlaceholderboolean
True for an unannounced set. Render `placeholderLabel` instead of an artist name.
slots[].placeholderLabelstring | null
What to show in place of a name, e.g. "Sunday headliner".
slots[].placeholderDescriptionstring | null
Longer copy for a placeholder, e.g. when it will be announced.
slots[].setNotestring | null
A short note on how this set is played, e.g. "DJ set" or "Live", at most 80 characters. Show it beside the act; null when there is none.
slots[].featuredboolean
The organiser has flagged this set as a highlight.
slots[].createdAtIsostring | null
When the slot was first created.
slots[].artistobject | null
The lead artist, and the first entry of `artists`. Null on a placeholder slot.
slots[].artist.iduuid
Pass this to the artist-detail endpoint for the full profile.
slots[].artist.namestring
Billed name, as the organiser wants it displayed.
slots[].artist.imageUrlstring | null
Press shot. Null when the artist has none.
slots[].artist.genresstring[]
Free-text genre tags. May be empty.
slots[].artist.hometownstring | null
City.
slots[].artist.regionstring | null
State or province.
slots[].artist.countrystring | null
Raw ISO 3166-1 alpha-2 code, e.g. "GB".
slots[].artist.locationLabelstring | null
Pre-formatted location for display, e.g. "Bristol, England, United Kingdom". Render this rather than joining the parts yourself.
slots[].artistsobject[]
Every artist on the slot, in billing order. A back-to-back set has two or more; a normal set has exactly one; a placeholder has none.
slots[].artists[].iduuid
Pass this to the artist-detail endpoint for the full profile.
slots[].artists[].namestring
Billed name, as the organiser wants it displayed.
slots[].artists[].imageUrlstring | null
Press shot. Null when the artist has none.
slots[].artists[].genresstring[]
Free-text genre tags. May be empty.
slots[].artists[].hometownstring | null
City.
slots[].artists[].regionstring | null
State or province.
slots[].artists[].countrystring | null
Raw ISO 3166-1 alpha-2 code, e.g. "GB".
slots[].artists[].locationLabelstring | null
Pre-formatted location for display, e.g. "Bristol, England, United Kingdom". Render this rather than joining the parts yourself.
schemaOrgobject | null
A ready-made schema.org `MusicEvent` block. Serialise it into a `<script type="application/ld+json">` tag. Null on the app surface.
lastUpdatedAtstring | null
Latest edit across the event and every set here. Good for a "last updated" line.
Generated from EventLineupResponse

Structured data

The response carries a ready-made MusicEvent JSON-LD block in schemaOrg. Emitted on the web surface — paste straight into a JSON-LD script tag. Drop it into a <script type="application/ld+json"> tag and search engines can read your lineup without you modelling any of it yourself.

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.
  • Cached for 60 seconds at the edge, so a publish can take up to a minute to appear.