Public endpoints

The visitor-facing endpoints of a live profile: the page, its share image, the Save contact vCard, the QR code, Discord presence snapshot and stream, the analytics beacon, fonts, and music.

A live profile exposes a small set of public endpoints to visitors and their browsers. None of them take an API key, and they only answer for a page that is live: published, on an address, in good standing, and not expired. Contact-form endpoints are documented separately on Contact forms.

You need a profile's ID for most of these. It is the last part of the profile's workspace URL in the dashboard, and it appears in the page's share-image URL.

The profile page

GEThttps://yourname.hep.gg/Public
The server-rendered public profile page.

The page is chosen by the address it is requested on, not by a path or query parameter.

  • Returns 200 with Content-Type: text/html; charset=utf-8, a weak ETag, and Cache-Control: public, max-age=0, must-revalidate. Send the ETag back in If-None-Match and an unchanged page answers 304 Not Modified with no body, so repeat visits are fast and an edit is visible immediately.
  • The head carries a canonical link, Open Graph and Twitter card tags (a 1200x630 share image with a versioned URL), a theme-color, structured data describing you as a person, and <meta name="referrer" content="strict-origin-when-cross-origin">, so the sites you link to see your profile as the source of the visit.
  • The page counts its own views and clicks with the analytics beacon once it is shown on screen; simply fetching the HTML is not a view.
  • Add ?src=<tag> to attribute a visit to a source in analytics. The page removes it from the address bar after loading.

When the address belongs to a profile that is not live, the request gets a short notice page instead (with Cache-Control: no-store):

StatusWhen
404The profile is private or paused
402The profile's slot has expired
403The profile is suspended

Every other path on the address belongs to your uploads, so https://yourname.hep.gg/<id> keeps serving the file or short link with that ID.

Share image

GEThttps://api.hep.gg/v1/profiles/:profileID/og.pngPublic
The 1200x630 social card for a profile.

A designed card with your photo, name, tagline, address, and first few links in your theme's style. The page's og:image points here with a ?v= version that changes whenever the page changes, so social networks fetch a fresh card after an edit.

Path parameters
profileID
stringrequired
The profile's ID.
Query parameters
v
stringoptional
Any version value. With v, the image is cached for a year (immutable); without it, for 5 minutes.
  • Returns 200 with Content-Type: image/png.
  • Returns 404 when the profile is not live, 429 (with Retry-After) past 60 requests a minute from one address, and 500 if the card could not be drawn.
curl
curl -o card.png https://api.hep.gg/v1/profiles/PROFILE_ID/og.png

Save contact (vCard)

GEThttps://api.hep.gg/v1/profiles/:profileID/contact.vcfPublic
Download the profile's contact card.

The file behind the Save contact button: a vCard 3.0 contact with the name, organization, title, phone numbers, emails, website, postal address, and note from the profile's Contact card section, plus your photo when the card includes it. Phones open it straight into their contacts app.

  • Returns 200 with Content-Type: text/vcard; charset=utf-8 and Content-Disposition: attachment, plus an ETag (If-None-Match answers 304).
  • Returns 404 when the profile is not live, has no Contact card section, or the card's Save contact button is turned off.
curl
curl -o contact.vcf https://api.hep.gg/v1/profiles/PROFILE_ID/contact.vcf

QR code

GEThttps://api.hep.gg/v1/profiles/:profileID/qr.svgPublic
An SVG QR code for the profile's address.

A QR code that opens the profile's address with ?src=qr, so scans show up as their own source in analytics. SVG scales to any print size.

Query parameters
fg
stringoptional
Foreground color as a 3 or 6 digit hex value, with or without # (URL-encode the #). Defaults to black.
bg
stringoptional
Background color, same format. Defaults to white.

If the two colors do not contrast enough to scan reliably, the code is drawn black on white instead.

  • Returns 200 with Content-Type: image/svg+xml and a one-day cache.
  • Returns 404 when the profile is not live or has no address.
curl
curl -o qr.svg "https://api.hep.gg/v1/profiles/PROFILE_ID/qr.svg?fg=111111&bg=ffffff"

Live Discord presence (snapshot)

GEThttps://api.hep.gg/v1/profiles/presence/:userIDPublic
One-shot Discord presence snapshot for a profile owner.

The owner's current Discord status and activity, as shown on the page's presence card. Presence is only shared for an owner with Hep.gg Prime who has presence turned on and at least one live profile; for anyone else presence is null.

Path parameters
userID
stringrequired
The profile owner's Hep.gg user ID.

Returns 200 with the standard envelope; data.presence is a presence snapshot or null.

200 response
{
  "ok": true,
  "data": {
    "presence": {
      "status": "online",
      "activity": {
        "name": "Spotify",
        "type": 2,
        "details": "Song Title",
        "state": "Artist Name",
        "startedAt": 1716900000000,
        "endsAt": 1716900210000,
        "largeImage": "https://i.scdn.co/image/...",
        "largeText": "Album Name"
      },
      "updatedAt": "2026-05-29T12:00:00.000Z"
    }
  }
}

Presence snapshot

PresenceSnapshot fields
status
stringoptional
One of online, idle, dnd, offline.
activity
objectoptional
Present only when the owner has an active Discord activity. See below.
updatedAt
stringoptional
ISO 8601 timestamp of when the snapshot was written to cache.
activity fields
name
stringoptional
Activity name, e.g. Spotify, Visual Studio Code.
type
numberoptional
Discord activity type: 0 Playing, 1 Streaming, 2 Listening, 3 Watching, 4 Custom (text is in state), 5 Competing.
details
stringoptional
Optional first detail line.
state
stringoptional
Optional second detail line. For custom status, holds the status text.
startedAt
numberoptional
Optional Unix epoch in milliseconds for when the activity started. Useful for an elapsed-time ticker.
endsAt
numberoptional
Optional Unix epoch in milliseconds for when the activity ends. Present for playback with a known finish time (e.g. Spotify).
largeImage
stringoptional
Optional large image asset reference. For Spotify this is the album art URL.
largeText
stringoptional
Optional large image hover text. For Spotify this is the album name.

Live Discord presence (stream)

GEThttps://api.hep.gg/v1/profiles/presence/:userID/streamPublic
Server-Sent Events stream of presence updates.

A Server-Sent Events stream that keeps a presence card live without polling. The page opens it only when it has a presence section, closes it while the tab is hidden, and reconnects with a short randomized delay if the connection drops.

  • Returns 200 with Content-Type: text/event-stream and Cache-Control: no-store.
  • The stream starts with retry: 15000 (the reconnect hint), then an initial presence event, then one event per change and a : ping comment every 30 seconds.
  • When presence is not shared for that user (see the snapshot rules above), the stream sends a : no presence comment and closes.
  • Each presence event's data: line is a presence snapshot.
event stream
retry: 15000
 
event: presence
data: {"status":"online","activity":{"name":"Spotify","type":2},"updatedAt":"2026-05-29T12:00:00.000Z"}
 
: ping
 
event: presence
data: {"status":"idle","updatedAt":"2026-05-29T12:01:30.000Z"}
curl
curl -N https://api.hep.gg/v1/profiles/presence/USER_ID/stream

Analytics beacon

POSThttps://api.hep.gg/v1/profiles/:profileID/ePublic
Record a view or a click on a profile.

How a profile page reports its views and clicks. The page sends one view when it is first shown on screen and one click each time a tracked element is activated, using navigator.sendBeacon so navigation is never delayed. The body is plain text, which keeps it a simple cross-origin request with no preflight.

Path parameters
profileID
stringrequired
The profile's ID.

Send Content-Type: text/plain and one of these bodies (at most 4 KB):

BodyRecords
v|<source>|<referrer>A view. <source> is the ?src= tag (letters, digits, _ and -, up to 32 characters) or empty; <referrer> is document.referrer or empty.
c|<element>|<url>A click. <element> is the clicked element's data-t value from the page; <url> is where it leads, or empty.
examples
v|qr|https://www.instagram.com/
c|l:links:item_3|https://example.com/shop
  • Always returns 204 with an empty body, whether or not the event was counted, so it is safe to fire and forget.
  • Events are only counted for a live profile, from the profile's own page (requests sent from another site are ignored), and within a per-visitor rate limit. Prefetches and prerenders are ignored.
curl
curl -X POST https://api.hep.gg/v1/profiles/PROFILE_ID/e \
  -H "Content-Type: text/plain" \
  --data 'v|newsletter|'

Fonts

GEThttps://api.hep.gg/v1/profiles/fonts/:filePublic
A self-hosted web font file used by profile themes.

The WOFF2 files behind the theme fonts. A page's stylesheet references exactly the files it needs. File names include a content hash, so each file never changes and is cached for a year.

  • Returns 200 with Content-Type: font/woff2, Cache-Control: public, max-age=31536000, immutable, and Access-Control-Allow-Origin: *, so the fonts load on any address.
  • Returns 404 for a file that is not in the catalog.

Music

GEThttps://api.hep.gg/v1/profiles/:profileID/music/:isrcPublic
Audio stream for a track in a profile's music section.

The audio behind a profile's music player. The track is streamed using the owner's Hep.gg Music access; no key is ever exposed to the visitor.

Path parameters
profileID
stringrequired
The profile's ID.
isrc
stringrequired
The track's ISRC: 12 letters and digits.
  • GET and HEAD are supported. The audio's content-type, content-length, and track metadata headers (x-track-title, x-track-artist, x-track-album, x-track-duration, x-track-artwork) are passed through.
  • Returns 400 for an invalid ISRC, 404 when the profile is not live or the owner's music access is off, and 502 if the track could not be fetched.
GEThttps://api.hep.gg/v1/profiles/:profileID/music/:isrc/artPublic
Cover art for a track in a profile's music section.

The track's cover art, resized for the player. Pass w for a width in pixels (default 512); the image is served as WebP to browsers that accept it and cached for a week.

curl
curl -o track.mp3 https://api.hep.gg/v1/profiles/PROFILE_ID/music/USRC17607839