HotGlue Data API

A read-only view of one studio's public catalog: classes and their schedules, free trials, registration seasons, membership tiers and prices, bookable appointment services, and locations. It returns what the studio already shows the public on its HotGlue pages, nothing more: no customers, no rosters, no payments, no drafts.

Use it to put live schedules and prices on a website, to feed a partner system such as a studio directory, or to send families to the right HotGlue page with one click (every record carries ready-made links).

  • Base URL: https://go.hotglue.app/api/v1
  • Auth: X-API-Key header, one key per studio
  • Format: JSON, UTF-8. Money is integer cents. Dates are YYYY-MM-DD.
  • Reference: every endpoint and schema, or the raw OpenAPI document

1. Get a key

The studio owner creates keys in HotGlue under Settings → API Keys (owners only). Pick a name, a type and the scopes the key needs:

TypePrefixUse it for
Secrethg_sk_Servers and partner software. Shown once; never put it in a web page or a mobile app.
Publishablehg_pk_JavaScript on a public web page. Anyone can read it, so it only ever reads public data.

Both types read the same data. The difference is where the key is allowed to live. More in Keys and scopes.

2. Check the key

curl https://go.hotglue.app/api/v1/me -H "X-API-Key: hg_sk_…"
{ "data": { "studio": { "id": "…", "name": "Sunrise Dance", "slug": "sunrise-dance" },
            "key": { "type": "secret", "prefix": "hg_sk_3f9a1c2e", "scopes": ["classes:read", "memberships:read"] } } }

/me needs no scope and tells you which studio you are looking at and which endpoints the key unlocks.

3. Make a request

curl https://go.hotglue.app/api/v1/classes?limit=2 \
  -H "X-API-Key: hg_sk_…"
const res = await fetch('https://go.hotglue.app/api/v1/classes?limit=2', {
  headers: { 'X-API-Key': process.env.HOTGLUE_API_KEY },
})
const { data, pagination } = await res.json()

A list response:

{
  "data": [
    {
      "id": "6f1c…",
      "name": "Ballet II",
      "schedule_description": "Mon & Wed, 4:30 PM",
      "price_cents": 8500,
      "price_display": "$85.00/month",
      "capacity": { "max": 12, "enrolled": 9, "spots_remaining": 3 },
      "links": { "checkout": "https://go.hotglue.app/store/sunrise-dance/checkout?type=class&classId=6f1c…&qty=1", "…": "…" }
    }
  ],
  "pagination": { "total": 41, "limit": 2, "offset": 0, "has_more": true }
}

There is no studio id to pass: the key identifies the studio. A key only ever sees its own studio, and asking for another studio's id returns 404.

4. What's there

EndpointReturns
GET /meThe studio and scopes behind your key
GET /classesActive classes with schedule, price, capacity and category
GET /classes/{id}/instancesA class's dated sessions, for calendars, one-time classes and drop-in booking
GET /categoriesClass categories in display order
GET /trial-classesTrial offers (free or cheap first classes) with their sign-up links
GET /registrationsRegistration seasons (enrollment windows)
GET /registrations/{id}One season with its catalog of classes and memberships
GET /membership-typesMembership tiers with active prices
GET /appointment-servicesBookable services such as private lessons
GET /locationsLocations with address, contact and hours

Every list takes limit and offset. Details on each in the reference.

5. The rules in one place

  • Responses are never cached between callers. Expect Cache-Control: private, no-store. Cache on your side if you need to.
  • 300 requests per minute per IP address, then 429. See Pagination, errors and limits.
  • A known parameter with a bad value is a 400, never a silent default. Unknown parameters are ignored.
  • Read-only. Anything other than GET is a 405, so a key can't be used to tamper with a studio.
  • Money is always integer cents in a *_cents field, with a ready-to-print price_display next to it.
  • Blank is null, never "".
  • "Active" means the studio hasn't archived it, not that it's current: pass ends_after=<today> to /classes to hide finished classes.