Let your fans create the hype and see your reach explode.

Every vote, reaction and achievement is a share card for link previews and a story for Instagram, from a single API.

HypeCard flywheel: fan engages, card created, fan shares, friends see, friends engage, repeat

From API call to
viral share card

Every template produces OG link previews and Instagram-ready story cards, wherever fans share.

// Fan submits their top-3 Premier League prediction
const { shareUrl } = await hypecard.shares.create({
  templateId: "prem-prediction",
  payload: {
    first: "Arsenal", // 1st
    second: "Man City", // 2nd
    third: "Aston Villa", // 3rd
    season: "2025–26",
    fan: "@jamie_gooner"
  },
  destinationUrl: "https://myapp.com/predict"
})

// → shareUrl auto-renders on WhatsApp, iMessage etc.
As it appears on WhatsApp
J
Jamie G. · just now
🔒 My Prem 2025–26 prediction is locked in – hypecard.io/r/ax7kp
Premier League 2025–26 · My Prediction
workspace_premium Arsenal
workspace_premium Man City
workspace_premium Aston Villa
@jamie_gooner
hypecard.io · Prem Prediction
// Viewer casts their Love Island vote
const { shareUrl } = await hypecard.shares.create({
  templateId: "reality-vote",
  payload: {
    show: "Love Island UK",
    couple: "Mia & Callum",
    voteLabel: "My winners",
    fan: "@sophie_li_fan"
  },
  destinationUrl: "https://loveisland.com/vote"
})

// Shared link drives viewers back to vote
As it appears on iMessage
S
Sophie · now
Mia and Callum to WIN!! 🙌❤️‍🔥 hypecard.io/r/li99z
Love Island UK · Series 11 Final
favorite
Mia & Callum
My winners
hypecard.io · Reality Vote
// Fan reacts to a key match moment
const { shareUrl } = await hypecard.shares.create({
  templateId: "moment-reaction",
  payload: {
    event: "Arsenal 3–1 Man City",
    moment: "Saka. 90+4. What a goal.",
    reaction: "Absolutely scenes",
    intensity: 98, // 0–100 hype score
    fan: "@arsenalmad_tom"
  },
  destinationUrl: "https://myapp.com/moments"
})

// Fans share the moment. You get the traffic.
As it appears on Telegram
T
Tom A. · 2m
SAKAAAAAA ⚽🔥 absolutely scenes!! hypecard.io/r/sk90x
Arsenal 3–1 Man City · PL 2025–26
local_fire_department
Saka. 90+4.
What a goal.
Hype score
98
hypecard.io · Moment Reaction
// Fan's score card, rendered as an Instagram Story
const { shareUrl } = await hypecard.shares.create({
  templateId: "score-card",
  format: "story", // 1080x1920
  payload: {
    playerName: "Alice",
    score: "4,200",
    event: "League Finals"
  },
  destinationUrl: "https://myapp.com/results"
})

// Same template, purpose-built 9:16 story format
As it appears on Instagram Stories
A
alice_fan
2h
League Finals
Goals this season
4,200
Alice
hypecard.io
keyboard_arrow_up
See results

Fan-driven hype. Operator-driven data.
One platform.

Fan-driven

A fan does something.
A card is born.

Fan votes, predicts, or unlocks an achievement. Your backend fires one API call. HypeCard renders a personalised card and returns a short link the fan can share immediately.

POST /v1/shares Handlebars templates REST API MCP
Data-driven

Live data changes.
Card updates silently.

Register your org once. HypeCard polls Opta or SportMonks, detects lineup confirmations and kick-off events, then renders and caches cards automatically. The URL never changes.

GET /{org}/lineup/{id}.jpg Opta SportMonks Auto-cache

Cards that know the score
before you ask.

Connect to Opta (Stats Perform) or SportMonks once. HypeCard watches for lineup confirmations arriving ~75 minutes before kick-off, then renders and caches the card. Serve the same URL at any point - pre-match, post-confirmation, post-match - and always get the current state.

Stable endpoint - bookmark it, embed it, share it
GET /{orgSlug}/lineup/{fixtureId}.jpg   # bitmap image, always current
GET /{orgSlug}/lineup/{fixtureId}.html   # live interactive card (PostMessage)
GET /{orgSlug}/result/{fixtureId}.jpg   # final score + goal scorers
GET /{orgSlug}/lineup/{fixtureId}.jpg?refresh=1   # bust server cache + re-render
1
Pre-match — lineup TBA
Awaiting lineup
RM
vs
FCB
El Clasico · LaLiga
Sat 22 Mar · 15:00
Lineup TBA
Refreshes every 60s
Cache-Control: max-age=60
/{org}/lineup/{id}.jpg hypecard.io
2
75 min before kickoff
3
Full time — result card
Full Time
Real Madrid vs Barcelona
3-1
Vini Jr 23'
Bellingham 58'
Rodrygo 87'
Same URL · always current state
/{org}/result/{id}.jpg hypecard.io
sports_soccer
Formation rendering
Starting XI plotted to correct pitch positions from Opta formationPosition or SportMonks type_id.
person
Roster sync + headshots
Player photos loaded from Studio via RosterCache. Short-name overrides per org. 1-hour in-memory TTL.
schedule
Smart cache lifecycle
max-age=60 pre-confirmation, jumps to 300s on lineup lock. Same URL, CloudFront handles it.
database
Dual data source
Per-org config selects opta or sportmonks. Override per-request with ?source=.
html
Bitmap or interactive
Static .jpg/.png or a live HTML card using the hypecard-ddc-v1 PostMessage protocol.
palette
Per-org branding
Team colours, crest URL, and player short-name overrides applied at render time. Zero config per card.

7 live card types  ·  2 coming soon

sports_soccer
Lineup
calendar_today
Match Preview
scoreboard
Match Result
bar_chart
Match Stats
trending_up
Form Guide
compare_arrows
H2H Stats
military_tech
Top Scorers
lock format_list_numbered
League Table
lock account_circle
Player Profile
How it works

Create shareable moments
in four steps.

No image generation infrastructure. No CDN to configure. No crawler handling to figure out.

Step 01

Design your template

Write HTML with {{variableName}} placeholders. Inline your styles. We render at 1200×630 (OG) or 1080×1920 (Story) using Satori, a high-performance engine that supports gradients, custom fonts, and layered layouts. Set format: "story" for Instagram-ready 9:16 cards.

<!-- score-card.html -->
<div class="card">
  <h1 class="score">
    {{score}}
  </h1>
  <p>{{playerName}}</p>
</div>
Step 02

Create a share

One API call with your fan's data. We fill the template, render it asynchronously, and hand you back a short link. Poll once – it's usually ready in under a second.

POST /v1/shares

{
  "templateId": "score-card",
  "format": "story", // or "og" (default)
  "payload": {
    "score": 14
  }
}

← { shareUrl, status: "ready" }
Step 03

Share it anywhere

Post the link on Twitter, WhatsApp, LinkedIn, anywhere. Social crawlers automatically fetch the OG image and render a rich preview card. No extra setup.

# Crawler sees:
og:image → 1200×630 PNG
og:title → "Alice scored 14"

# Rich preview on:
Twitter · LinkedIn · WhatsApp
iMessage · Telegram · Slack

# Story format (9:16):
Instagram · TikTok · Snapchat · WhatsApp Status
Step 04

Fan clicks, lands in your app

When a fan taps the link, they're redirected straight back to your platform. Attribution parameters are automatically appended so you know exactly which share drove each visit.

# Human redirect:
myapp.com/fan/42
  ?utm_source=hypecard
  &hc_share_id=x8k2m

# Full attribution loop closed

Try it now.

Pick a template, fill in the variables, get a live share link.

info Playground limits apply. Organisations are limited in generation credits per hour and per day. This demo environment allows only a small number of requests per minute, enough to try it out, not for production use. Sign up for a full API key to remove restrictions.
Format:
Request
curl -X POST $API/v1/shares \
  -H "Content-Type: application/json" \
  -H "x-organisation-id: demo-org" \
  -H "x-api-key: <YOUR_KEY>" \
  -d '{'
  }'
Card renders here
under 1 second
POST
/v1/templates
Create a template
Returns a templateId used for all subsequent operations. Templates are versioned, you never edit HTML in place, you add a new version.
Body
namestringrequired
spaceIdstringoptional
cURL
curl -X POST $API/v1/templates \
  -H "x-organisation-id: $ORG" \
  -H "x-api-key: $KEY" \
  -d '{"name": "Score Card"}'

← { "id": "uuid", "name": "Score Card" }
POST
/v1/templates/:id/versions
Add a template version
Each call creates a new version (v1, v2, …). Canvas is 1200×630 (OG) or 1080×1920 (Story). Use {{variable}} tokens. Inline all CSS for fast renders (50–150ms with Satori).
Body
htmlstringrequired
variablesarrayoptional
stylesstringoptional
format"og" | "story"optional (default: "og")
previewTypeimage | video | bothoptional
cURL
curl -X POST $API/v1/templates/$ID/versions \
  -H "x-organisation-id: $ORG" \
  -H "x-api-key: $KEY" \
  -d '{'
    "html": $(jq -Rs . < template.html),
    "variables": [
      { "name": "playerName", "required": true }
    ]
  }'

← { "id": "uuid", "version": 1 }
GET
/v1/templates
List templates
Returns your org's templates plus all system templates (organisationId: "_system"). System templates are always visible to every org.
cURL
curl $API/v1/templates \
  -H "x-organisation-id: $ORG" \
  -H "x-api-key: $KEY"

← { "items": [ { "id": "...", "name": "Score Card" } ] }
POST
/v1/shares
Create a share
Rendering is async, returns status: "pending" immediately. Poll GET /v1/shares/:id until status === "ready". The format field selects which template format to render: og (1200×630) or story (1080×1920). Defaults to og.
Body
templateIdstringrequired
payloadobjectrequired
destinationUrlstringrequired
format"og" | "story"optional (default: "og")
attributionDataobjectoptional
expirySecondsnumberoptional
cURL
curl -X POST $API/v1/shares \
  -H "x-organisation-id: $ORG" \
  -H "x-api-key: $KEY" \
  -d '{'
    "templateId": "$TEMPLATE_ID",
    "payload": { "playerName": "Alice", "score": "42" },
    "destinationUrl": "https://myapp.com/fan/42"
  }'

← { "shareId": "...", "status": "pending", "shareUrl": "..." }
GET
/v1/shares/:id
Poll share status
Poll every 2s until status === "ready". Inline-CSS templates: 3–5s. Google Fonts: up to ~30s. Once ready, shareUrl and renderArtifactId are populated.
Status values
pendingqueued
renderingin progress
readycomplete
failedall retries exhausted
cURL
curl $API/v1/shares/$SHARE_ID \
  -H "x-organisation-id: $ORG" \
  -H "x-api-key: $KEY"

← {
  "status": "ready",
  "shareUrl": "https://…/s/ax7kp"
}
DELETE
/v1/shares/:id
Delete a share
Permanently removes the share, its render artifact, and stored media. The shareUrl returns 404 immediately after deletion.
cURL
curl -X DELETE $API/v1/shares/$SHARE_ID \
  -H "x-organisation-id: $ORG" \
  -H "x-api-key: $KEY"

← 204 No Content

Wire it up to your AI agent
in 30 seconds.

HypeCard exposes a full MCP (Model Context Protocol) endpoint. Point any Claude or OpenAI-compatible agent at /mcp and it can browse templates, generate custom HTML, create shares, and return preview URLs – no human in the loop.

Natural language prompt
"Create a share card for Alice who scored 42 goals this season and ranked 3rd globally."
MCP endpoint
https://your-api.hypecard.io/mcp

Tools available:
  get_docs
  list_templates
  add_template_version
  create_share
  get_share_status
Tool calls
list_templates → score-card, leaderboard-rank…
create_share → templateId: "leaderboard-rank", format: "story"
get_share_status → status: "ready"
Result
Leaderboard Rank
#3
Alice · 42 goals
hypecard.io/r/a3z9q
→ https://hypecard.io/r/a3z9q
Read the MCP docs →