Skip to content

Events

Four public calls give your own website the same nights the shop shows: name, times, poster, line-up, prices, series and table packages. They need no API key.

The calls live under https://api.kuvert.dk/v1/merchants/{slug}, where {slug} is the shop’s address, e.g. demo-natklubben in shop.kuvert.dk/demo-natklubben. They are public like the shop itself: no key, no account, and only what a guest can see too. A night that is still a draft is never included.

The calls

CallReturns
GET /v1/merchants/{slug}The shop and the nights on sale, in events, earliest first. With ?include=canceled cancelled nights are included, and with ?include=closed nights whose online sale has closed but which are not over. Both can be combined: ?include=canceled,closed.
GET /v1/merchants/{slug}/events/{event}One night with every price, what is left, and whether it can be bought right now. {event} is the night’s slug or id.
GET /v1/merchants/{slug}/seriesThe regular series, each with the nights of the series that are on sale.
GET /v1/merchants/{slug}/table-nightsThe coming nights with table packages, and whether each package can be booked right now.
GET /v1/merchants/{slug}/events/{event}/planThe club’s map for one night with table packages: the rooms and every table, free or sold. It says nothing about who bought.

The nights

The shop’s own call carries the nights in events. Each night has a name, times, venue and poster, and the fields a programme is built from. Here is an excerpt of the answer with one night:

JSON
{
  "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": []
    }
  ]
}
FieldMeans
id, slugThe night’s id and its readable address. The night’s page in the shop is shop.kuvert.dk/{slug}/event/{slug}, with the id if the night has no slug.
startsAt, endsAtWhen the night starts and ends. endsAt is null if the night does not say.
salesCloseAtWhen the online sale closes.
bannerUrl, bannerWidth, bannerHeightThe poster and its size in pixels, so the page can hold its space before it has loaded. Show it whole: it is drawn to be seen uncropped.
status, cancelNotepublished or canceled, and the message you wrote when the night was cancelled.
series, seriesDateThe series behind the night with name, weekdays (0 is Sunday), the rule and a ready sentence to show, e.g. «Hver fredag og lørdag», and which of the series’ days it is. null on a night you created yourselves.
subtitle, genres, dressCodeThe subtitle, the genres and the dress code, as you wrote them.
lineupThe names in running order, each with name, role and time. time includes the date, so a set after midnight lands on the right day.
doorsAt, lastEntryAtWhen the doors open, and when the last guest is let in.
ticketsUrlWhere the tickets are sold when someone else sells them, e.g. the promoter. If the night has its own prices in Kuvert, they are sold here and the field is not used.

One night

The night’s own call gives you everything: the description, the age limit and every price in tiers. onSale says whether it can be bought right now, and refusalCode why not, e.g. soldOut or closed. waitlistOpen is true when the guest can join the waiting list.

JSON
{
  "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": []
}
FieldMeans
priceOreThe price in øre: 10000 is DKK 100.
availabilityon_sale, not_yet (opens later), closed or sold_out.
remaining, scarcityHow many are left at that price, and what the shop shows about it: the number (count), «few left» (few) or nothing (null). Show what scarcity says, not the number. remaining is null when the price has no count of its own.
salesOpenAt, salesCloseAt, opensAfterTierIdThe price’s own sales window, and the price it waits to sell out when tickets are sold in tiers.
tablePackage, picksTable, tableSeats, tablesFreeA table package: whether the guest picks the table on the map, the smallest and largest table, and how many tables are free.
includedItems, creditPromisedOreWhat comes with a package, and the bar credit if there is one.
ageLimitThe age limit at the door, or null.

Series

If you hold the same night every week, the series give it to you as one row: «Hver fredag og lørdag», and the nights of the series that are on sale. A series whose nights are all still drafts is not included.

JSON
{
  "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"
        }
      ]
    }
  ]
}

Table packages

If you sell tables for your nights, this call gives the coming nights with their table packages, so the page can put «Book bord» beside each night without fetching every night’s page. bookable says whether the package can be booked right now.

JSON
{
  "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
        }
      ]
    }
  ]
}

Keep the programme up to date

If your site needs to know the moment a night changes, it can subscribe to webhooks instead of asking every minute: event.published when a night goes on sale, event.updated when something public changes (with the names of the fields in changedFields), event.canceled and event.unpublished. Each delivery carries the whole night in the same form as the list above, with eventId instead of id. A webhook endpoint is created under Settings → Webhooks or with an API key.

An example

The smallest thing that works: fetch the nights on your server, and build a link to each night’s page in the shop.

JavaScript
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)
}

Shared nights

A night can be shared by several businesses, e.g. a promoter who sells the tickets and the club that sells the tables. The night belongs to the host, but it is in the programme of all of them and can be fetched under each of their slugs, with the same id and the same slug. It is counted once in each business’s list.

FieldMeans
hostThe business the night belongs to, with slug and name. The night’s real address is shop.kuvert.dk/{host.slug}/event/{slug}, also when you fetch it under your own slug.
cohostsThe other businesses selling on the night, in the order they joined. An empty list on a night that is not shared.
tiers[].sellerWho sells the price, and who the guest pays. Use it to show your own prices on their own or to say who sells what.
lineup[].merchantSlugThe performer’s own shop on Kuvert, when the host has linked the name to it.

GET /v1/merchants/{slug}/appearances gives the nights other businesses have booked you for, either as co-host or in the line-up, in the same form as the list above plus seller (the business whose page sells the night) and appearance (cohost or lineup). An artist’s site can then show the club nights the artist plays without anybody typing them in again. A night you co-host yourself is also on your own list above, so show only one of them, or filter on appearance.

Webhooks for a shared night (event.*) go to every business on the night. order.paid and ticket.issued go only to the one that sold, and carry seller, host and cohosts, so your system can tell your own sales from your partner’s.

Was this page helpful?