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
https://yourname.hep.gg/PublicThe page is chosen by the address it is requested on, not by a path or query parameter.
- Returns
200withContent-Type: text/html; charset=utf-8, a weakETag, andCache-Control: public, max-age=0, must-revalidate. Send theETagback inIf-None-Matchand an unchanged page answers304 Not Modifiedwith 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):
| Status | When |
|---|---|
404 | The profile is private or paused |
402 | The profile's slot has expired |
403 | The 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
https://api.hep.gg/v1/profiles/:profileID/og.pngPublicA 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.
profileIDvv, the image is cached for a year (immutable); without it, for 5 minutes.- Returns
200withContent-Type: image/png. - Returns
404when the profile is not live,429(withRetry-After) past 60 requests a minute from one address, and500if the card could not be drawn.
Save contact (vCard)
https://api.hep.gg/v1/profiles/:profileID/contact.vcfPublicThe 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
200withContent-Type: text/vcard; charset=utf-8andContent-Disposition: attachment, plus anETag(If-None-Matchanswers304). - Returns
404when the profile is not live, has no Contact card section, or the card's Save contact button is turned off.
curl -o contact.vcf https://api.hep.gg/v1/profiles/PROFILE_ID/contact.vcfQR code
https://api.hep.gg/v1/profiles/:profileID/qr.svgPublicA 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.
fg# (URL-encode the #). Defaults to black.bgIf the two colors do not contrast enough to scan reliably, the code is drawn black on white instead.
- Returns
200withContent-Type: image/svg+xmland a one-day cache. - Returns
404when the profile is not live or has no address.
curl -o qr.svg "https://api.hep.gg/v1/profiles/PROFILE_ID/qr.svg?fg=111111&bg=ffffff"Live Discord presence (snapshot)
https://api.hep.gg/v1/profiles/presence/:userIDPublicThe 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.
userIDReturns 200 with the standard envelope; data.presence is a presence snapshot or null.
{
"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
statusonline, idle, dnd, offline.activityupdatedAtnameSpotify, Visual Studio Code.type0 Playing, 1 Streaming, 2 Listening, 3 Watching, 4 Custom (text is in state), 5 Competing.detailsstatestartedAtendsAtlargeImagelargeTextLive Discord presence (stream)
https://api.hep.gg/v1/profiles/presence/:userID/streamPublicA 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
200withContent-Type: text/event-streamandCache-Control: no-store. - The stream starts with
retry: 15000(the reconnect hint), then an initialpresenceevent, then one event per change and a: pingcomment every 30 seconds. - When presence is not shared for that user (see the snapshot rules above), the stream sends a
: no presencecomment and closes. - Each
presenceevent'sdata:line is a presence snapshot.
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"}Analytics beacon
https://api.hep.gg/v1/profiles/:profileID/ePublicHow 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.
profileIDSend Content-Type: text/plain and one of these bodies (at most 4 KB):
| Body | Records |
|---|---|
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. |
v|qr|https://www.instagram.com/
c|l:links:item_3|https://example.com/shop- Always returns
204with 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.
Fonts
https://api.hep.gg/v1/profiles/fonts/:filePublicThe 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
200withContent-Type: font/woff2,Cache-Control: public, max-age=31536000, immutable, andAccess-Control-Allow-Origin: *, so the fonts load on any address. - Returns
404for a file that is not in the catalog.
Music
https://api.hep.gg/v1/profiles/:profileID/music/:isrcPublicThe 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.
profileIDisrcGETandHEADare supported. The audio'scontent-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
400for an invalid ISRC,404when the profile is not live or the owner's music access is off, and502if the track could not be fetched.
https://api.hep.gg/v1/profiles/:profileID/music/:isrc/artPublicThe 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.