Skip to main content

Embedding checkout at scale

Put a "Buy Tickets" button for every event on your own website without hand-generating a snippet per event. This is the approach for integrations that cover dozens, hundreds, or thousands of events — you read your events from the API and emit one button each.

tip

For a single event, generate the snippet from your Viewcy dashboard under Marketing → Embed Checkout — no code required. This page is for generating buttons in bulk from the API.

How the embed works

The embed is two parts:

  1. The loader script — included once per page:

    <script src="https://YOUR_EMBED_HOST/embed/checkout.js" async></script>

    Copy the exact <script> from your dashboard (Marketing → Embed Checkout) so the host matches your account.

  2. One <div> per event you want a button for:

    <div data-viewcy-checkout data-event="EVENT_SLUG" data-occurrence="OCCURRENCE_ID"></div>

    The loader turns each <div> into a button that opens checkout in a popup (with a full-window redirect fallback on mobile) and reports the result back to your page.

So embedding all your events is: drop the loader once, then loop your events and emit one <div> each. No per-event snippet generation needed.

The button label is resolved automatically — the loader reads each event's configured purchase-button text at runtime, so the button always matches your event settings and never goes stale. To override it for a specific placement, add data-label="…" to that <div>.

The only two per-event values

Snippet attributeAPI fieldWhat it is
data-eventthe event's slugthe event identifier checkout resolves
data-occurrencethe occurrence's idthe specific date/time being sold
warning

Use the event's slug for data-eventnot its id. An event's id is a v4 UUID, while slug is the identifier the checkout path matches. The occurrence's eventId is also the v4 UUID, so don't reach for it here. The occurrence's id is the right value for data-occurrence and is used directly.

Step 1 — List your events

Page through GET /events and expand occurrences so each event returns its sellable dates in one call. All requests use your Bearer token:

GET /2025_06/events?expand=occurrences&perPage=100&page=1
Authorization: Bearer YOUR_API_TOKEN

Response (trimmed):

{
"data": [
{
"id": "0f9d…",
"slug": "8a1c…",
"name": "Summer Festival",
"occurrences": {
"data": [
{ "id": "b720…", "startsAt": "2026-07-01T18:00:00Z" },
{ "id": "c931…", "startsAt": "2026-07-02T18:00:00Z" }
]
}
}
],
"page": 1,
"totalPages": 12,
"perPage": 100,
"totalCount": 1180
}

Step 2 — Generate one <div> per occurrence

const TOKEN = process.env.VIEWCY_API_TOKEN
const BASE = 'https://api.viewcy.com/2025_06'

async function buildEmbed() {
const divs = []
let page = 1
let totalPages = 1

do {
const res = await fetch(`${BASE}/events?expand=occurrences&perPage=100&page=${page}`, {
headers: { Authorization: `Bearer ${TOKEN}` },
})
const body = await res.json()
totalPages = body.totalPages

for (const event of body.data) {
for (const occurrence of event.occurrences?.data ?? []) {
// data-event = event.slug; data-occurrence = occurrence.id
divs.push(
`<div data-viewcy-checkout data-event="${event.slug}" data-occurrence="${occurrence.id}"></div>`
)
}
}
page++
} while (page <= totalPages)

return divs.join('\n')
}

Render the result once on your page, with the loader script included a single time:

<script src="https://YOUR_EMBED_HOST/embed/checkout.js" async></script>

<!-- one per occurrence, generated from the API -->
<div data-viewcy-checkout data-event="8a1c…" data-occurrence="b720…"></div>
<div data-viewcy-checkout data-event="8a1c…" data-occurrence="c931…"></div>
<!-- … -->

Because you regenerate from the API, button labels, new events, and new dates stay in sync automatically — there is nothing per-event to maintain by hand.

Step 3 — Register the sites that host the buttons

Checkout only returns buyers to an allowlisted origin. Add every site that hosts the buttons under Marketing → Embed Checkout → Register your website in your dashboard. Completion messages and redirect returns are silently dropped for unregistered origins.

Notes

  • Free tickets complete in the popup without payment; paid tickets run the normal payment flow inside the popup.
  • Buyer-facing PII stays inside the secure Viewcy checkout window — your page only receives the final completed/failed result.

See also