Die Aufrufe liegen unter https://api.kuvert.dk/v1/merchants/{slug}, wobei {slug} die Adresse des Shops ist, z. B. demo-natklubben in shop.kuvert.dk/demo-natklubben. Sie sind öffentlich wie der Shop selbst: kein Schlüssel, kein Konto und nur das, was auch ein Gast sehen kann. Ein Abend, der noch ein Entwurf ist, ist nie dabei.
| Aufruf | Liefert |
|---|---|
GET /v1/merchants/{slug} | Der Shop und die Abende im Verkauf, in events, der früheste zuerst. Mit ?include=canceled kommen abgesagte Abende dazu, mit ?include=closed Abende, deren Online-Verkauf geschlossen, die aber noch nicht vorbei sind. Beides geht zusammen: ?include=canceled,closed. |
GET /v1/merchants/{slug}/events/{event} | Ein Abend mit allen Preisen, was noch übrig ist und ob er gerade gekauft werden kann. {event} ist der Slug oder die ID des Abends. |
GET /v1/merchants/{slug}/series | Die festen Serien, jede mit den Abenden der Serie, die im Verkauf sind. |
GET /v1/merchants/{slug}/table-nights | Die kommenden Abende mit Tischpaketen und ob jedes Paket gerade gebucht werden kann. |
GET /v1/merchants/{slug}/events/{event}/plan | Der Plan des Clubs für einen Abend mit Tischpaketen: die Räume und jeder Tisch, frei oder verkauft. Wer gekauft hat, steht nicht darauf. |
Der Aufruf des Shops selbst enthält die Abende in events. Jeder Abend hat Name, Zeiten, Ort und Plakat und die Felder, aus denen ein Programm gebaut wird. Hier ein Auszug der Antwort mit einem Abend:
{
"events": [
{
"id": "evt_65694ef606f6483083d368ec040601e2",
"slug": "klubnat-2026-10-17",
"name": "Klubnat",
"startsAt": "2026-10-17T21:00:00.000Z",
"endsAt": "2026-10-18T03:00:00.000Z",
"venue": "Natklubben, Vejle",
"bannerUrl": null,
"bannerWidth": null,
"bannerHeight": null,
"salesCloseAt": "2026-10-18T00:00:00.000Z",
"status": "published",
"cancelNote": null,
"series": {
"id": "ser_216c1567afbb42368340cb9b11146a90",
"name": "Klubnat",
"weekdays": [
5,
6
],
"isRecurring": true,
"recurrence": {
"kind": "weekly",
"weekdays": [
5,
6
]
},
"description": "Hver fredag og lørdag"
},
"seriesDate": "2026-10-17",
"subtitle": "Husets DJs på to gulve",
"lineup": [
{
"name": "Kasper Ø",
"role": "warm-up",
"time": "2026-10-17T21:00:00.000Z"
},
{
"name": "Selma Rask",
"role": "resident",
"time": "2026-10-17T23:00:00.000Z"
}
],
"genres": [
"House",
"Hiphop",
"Top 40"
],
"doorsAt": "2026-10-17T21:00:00.000Z",
"lastEntryAt": "2026-10-18T01:00:00.000Z",
"dressCode": "Ingen sportstøj",
"ticketsUrl": null,
"host": {
"slug": "demo-natklubben",
"name": "Natklubben"
},
"cohosts": []
}
]
}| Feld | Bedeutet |
|---|---|
id, slug | Die ID des Abends und seine lesbare Adresse. Die Seite des Abends im Shop ist shop.kuvert.dk/{slug}/event/{slug}, mit der ID, wenn der Abend keinen Slug hat. |
startsAt, endsAt | Wann der Abend beginnt und endet. endsAt ist null, wenn der Abend es nicht angibt. |
salesCloseAt | Wann der Online-Verkauf schließt. |
bannerUrl, bannerWidth, bannerHeight | Das Plakat und seine Größe in Pixeln, damit die Seite den Platz dafür freihalten kann, bevor es geladen ist. Zeigen Sie es ganz: Es ist gestaltet, um unbeschnitten gesehen zu werden. |
status, cancelNote | published oder canceled und die Nachricht, die Sie bei der Absage geschrieben haben. |
series, seriesDate | Die Serie hinter dem Abend mit Name, Wochentagen (0 ist Sonntag), der Regel und einem fertigen Satz zum Anzeigen, z. B. «Hver fredag og lørdag», und welcher Tag der Serie es ist. null bei einem Abend, den Sie selbst angelegt haben. |
subtitle, genres, dressCode | Untertitel, Genres und Dresscode, so wie Sie sie geschrieben haben. |
lineup | Die Namen in Reihenfolge, jeweils mit name, role und time. time enthält das Datum, sodass ein Set nach Mitternacht auf dem richtigen Tag steht. |
doorsAt, lastEntryAt | Wann die Türen öffnen und wann der letzte Gast eingelassen wird. |
ticketsUrl | Wo die Tickets verkauft werden, wenn jemand anderes sie verkauft, z. B. der Veranstalter. Hat der Abend eigene Preise in Kuvert, werden sie hier verkauft, und das Feld wird nicht verwendet. |
Der Aufruf des Abends selbst liefert alles: die Beschreibung, die Altersgrenze und alle Preise in tiers. onSale sagt, ob gerade gekauft werden kann, und refusalCode, warum nicht, z. B. soldOut oder closed. waitlistOpen ist true, wenn sich der Gast auf die Warteliste setzen kann.
{
"id": "evt_65694ef606f6483083d368ec040601e2",
"slug": "klubnat-2026-10-17",
"name": "Klubnat",
"startsAt": "2026-10-17T21:00:00.000Z",
"endsAt": "2026-10-18T03:00:00.000Z",
"venue": "Natklubben, Vejle",
"bannerUrl": null,
"bannerWidth": null,
"bannerHeight": null,
"description": "Gratis før midnat på gæstelisten, entré ved døren derefter. Borde med flasker hele natten.",
"ageLimit": 18,
"tiers": [
{
"id": "etr_e5e5766ded1e456599d7e8925f68bff9",
"name": "Entré",
"description": "Spring billetkøen over. Gælder hele natten.",
"priceOre": 10000,
"availability": "on_sale",
"remaining": null,
"scarcity": null,
"salesOpenAt": null,
"salesCloseAt": null,
"seatsPerTicket": 1,
"seatsChosenByGuest": false,
"creditPromisedOre": null,
"tablePackage": false,
"includedItems": [],
"minSeats": 1,
"arriveBy": null,
"seller": {
"slug": "demo-natklubben",
"name": "Natklubben"
}
},
{
"id": "etr_773b122865f0469e81c06781c4befa63",
"name": "Flaske",
"description": null,
"priceOre": 240000,
"availability": "on_sale",
"remaining": 10,
"scarcity": null,
"salesOpenAt": null,
"salesCloseAt": null,
"seatsPerTicket": 10,
"seatsChosenByGuest": true,
"creditPromisedOre": null,
"tablePackage": true,
"picksTable": true,
"tableSeats": {
"min": 4,
"max": 10
},
"tablesFree": 10,
"includedItems": [
"1 × Absolut Vodka 70 cl",
"6 × Red Bull",
"Entré for hele bordet"
],
"minSeats": 1,
"arriveBy": "2026-10-17T22:30:00.000Z",
"seller": {
"slug": "demo-natklubben",
"name": "Natklubben"
}
}
],
"minQuantity": 1,
"salesCloseAt": "2026-10-18T00:00:00.000Z",
"pickups": [],
"remaining": 350,
"onSale": true,
"refusal": null,
"refusalCode": null,
"refusalCount": null,
"waitlistOpen": false,
"questions": [],
"status": "published",
"cancelNote": null,
"series": {
"id": "ser_216c1567afbb42368340cb9b11146a90",
"name": "Klubnat",
"weekdays": [
5,
6
],
"isRecurring": true,
"recurrence": {
"kind": "weekly",
"weekdays": [
5,
6
]
},
"description": "Hver fredag og lørdag"
},
"seriesDate": "2026-10-17",
"subtitle": "Husets DJs på to gulve",
"lineup": [
{
"name": "Kasper Ø",
"role": "warm-up",
"time": "2026-10-17T21:00:00.000Z"
},
{
"name": "Selma Rask",
"role": "resident",
"time": "2026-10-17T23:00:00.000Z"
}
],
"genres": [
"House",
"Hiphop",
"Top 40"
],
"doorsAt": "2026-10-17T21:00:00.000Z",
"lastEntryAt": "2026-10-18T01:00:00.000Z",
"dressCode": "Ingen sportstøj",
"ticketsUrl": null,
"host": {
"slug": "demo-natklubben",
"name": "Natklubben"
},
"cohosts": []
}| Feld | Bedeutet |
|---|---|
priceOre | Der Preis in Øre: 10000 sind 100 DKK. |
availability | on_sale, not_yet (öffnet später), closed oder sold_out. |
remaining, scarcity | Wie viele zu diesem Preis noch übrig sind und was der Shop davon zeigt: die Zahl (count), «nur noch wenige» (few) oder nichts (null). Zeigen Sie, was scarcity sagt, und nicht die Zahl. remaining ist null, wenn der Preis kein eigenes Kontingent hat. |
salesOpenAt, salesCloseAt, opensAfterTierId | Das eigene Verkaufsfenster des Preises und der Preis, dessen Ausverkauf er abwartet, wenn Tickets in Stufen verkauft werden. |
tablePackage, picksTable, tableSeats, tablesFree | Ein Tischpaket: ob der Gast den Tisch auf dem Plan wählt, der kleinste und größte Tisch und wie viele Tische frei sind. |
includedItems, creditPromisedOre | Was zu einem Paket gehört, und das Guthaben für die Bar, falls es eines gibt. |
ageLimit | Die Altersgrenze an der Tür oder null. |
Veranstalten Sie jede Woche denselben Abend, liefern die Serien ihn als eine Zeile: «Hver fredag og lørdag» und die Abende der Serie, die im Verkauf sind. Eine Serie, deren Abende alle noch Entwürfe sind, ist nicht dabei.
{
"series": [
{
"id": "ser_216c1567afbb42368340cb9b11146a90",
"name": "Klubnat",
"weekdays": [
5,
6
],
"isRecurring": true,
"recurrence": {
"kind": "weekly",
"weekdays": [
5,
6
]
},
"description": "Hver fredag og lørdag",
"nights": [
{
"id": "evt_65694ef606f6483083d368ec040601e2",
"slug": "klubnat-2026-10-17",
"name": "Klubnat",
"startsAt": "2026-10-17T21:00:00.000Z",
"seriesDate": "2026-10-17"
},
{
"id": "evt_0ba0fd9fb19c42cd80f4ebc11879b462",
"slug": "klubnat-2026-10-23",
"name": "Klubnat",
"startsAt": "2026-10-23T21:00:00.000Z",
"seriesDate": "2026-10-23"
}
]
}
]
}Verkaufen Sie Tische für Ihre Abende, liefert dieser Aufruf die kommenden Abende mit ihren Tischpaketen, sodass die Seite neben jeden Abend «Book bord» setzen kann, ohne die Seite jedes Abends abzurufen. bookable sagt, ob das Paket gerade gebucht werden kann.
{
"nights": [
{
"id": "evt_65694ef606f6483083d368ec040601e2",
"slug": "klubnat-2026-10-17",
"name": "Klubnat",
"startsAt": "2026-10-17T21:00:00.000Z",
"endsAt": "2026-10-18T03:00:00.000Z",
"venue": "Natklubben, Vejle",
"bannerUrl": null,
"bannerWidth": null,
"bannerHeight": null,
"ageLimit": 18,
"onSale": true,
"packages": [
{
"id": "etr_773b122865f0469e81c06781c4befa63",
"name": "Flaske",
"description": null,
"priceOre": 240000,
"availability": "on_sale",
"remaining": 10,
"scarcity": null,
"salesOpenAt": null,
"salesCloseAt": null,
"seatsPerTicket": 10,
"seatsChosenByGuest": true,
"creditPromisedOre": null,
"tablePackage": true,
"picksTable": true,
"tableSeats": {
"min": 4,
"max": 10
},
"tablesFree": 10,
"includedItems": [
"1 × Absolut Vodka 70 cl",
"6 × Red Bull",
"Entré for hele bordet"
],
"minSeats": 1,
"arriveBy": "2026-10-17T22:30:00.000Z",
"seller": {
"slug": "demo-natklubben",
"name": "Natklubben"
},
"bookable": true
}
]
}
]
}Muss Ihre Seite sofort wissen, wenn sich ein Abend ändert, kann sie Webhooks abonnieren, statt jede Minute nachzufragen: event.published, wenn ein Abend in den Verkauf geht, event.updated, wenn sich etwas Öffentliches ändert (mit den Namen der Felder in changedFields), event.canceled und event.unpublished. Jede Lieferung enthält den ganzen Abend in derselben Form wie die Liste oben, mit eventId statt id. Ein Webhook-Endpunkt wird unter Einstellungen → Webhooks oder mit einem API-Schlüssel angelegt.
Das Kleinste, das funktioniert: Rufen Sie die Abende auf Ihrem Server ab, und bauen Sie zu jedem Abend einen Link auf seine Seite im Shop.
const res = await fetch('https://api.kuvert.dk/v1/merchants/demo-natklubben')
const { events } = await res.json()
for (const night of events) {
const link = `https://shop.kuvert.dk/demo-natklubben/event/${night.slug ?? night.id}`
console.log(night.name, night.startsAt, night.status, link)
}- Webhooks und Signaturen
- Tickets: das Programm auf Ihrer eigenen Website
- Einbettung: ein Kauf-Button neben jedem Abend
Ein Abend kann von mehreren Unternehmen geteilt werden, z. B. von einem Veranstalter, der die Tickets verkauft, und dem Club, der die Tische verkauft. Der Abend gehört dem Gastgeber, steht aber im Programm aller und lässt sich unter jedem ihrer Slugs abrufen, mit derselben ID und demselben Slug. In der Liste jedes Unternehmens wird er einmal gezählt.
| Feld | Bedeutet |
|---|---|
host | Das Unternehmen, dem der Abend gehört, mit slug und name. Die richtige Adresse des Abends ist shop.kuvert.dk/{host.slug}/event/{slug}, auch wenn Sie ihn unter Ihrem eigenen Slug abrufen. |
cohosts | Die anderen Unternehmen, die an dem Abend verkaufen, in der Reihenfolge, in der sie dazukamen. Eine leere Liste bei einem Abend, der nicht geteilt ist. |
tiers[].seller | Wer den Preis verkauft und wen der Gast bezahlt. Nutzen Sie es, um Ihre eigenen Preise für sich zu zeigen oder anzugeben, wer was verkauft. |
lineup[].merchantSlug | Der eigene Shop des Auftretenden bei Kuvert, wenn der Gastgeber den Namen damit verknüpft hat. |
GET /v1/merchants/{slug}/appearances liefert die Abende, für die andere Unternehmen Sie gebucht haben, entweder als Mitveranstalter oder im Line-up, in derselben Form wie die Liste oben plus seller (das Unternehmen, dessen Seite den Abend verkauft) und appearance (cohost oder lineup). So kann die Website eines Künstlers die Clubabende zeigen, an denen er spielt, ohne dass jemand sie noch einmal eintippen muss. Ein Abend, bei dem Sie selbst Mitveranstalter sind, steht auch auf Ihrer eigenen Liste oben. Zeigen Sie also nur einen davon, oder filtern Sie nach appearance.
Webhooks für einen geteilten Abend (event.*) gehen an alle Unternehmen des Abends. order.paid und ticket.issued gehen nur an das verkaufende Unternehmen und enthalten seller, host und cohosts, damit Ihr System Ihre eigenen Verkäufe von denen des Partners unterscheiden kann.
War diese Seite hilfreich?