# Arrangementer

<https://kuvert.dk/no/dokumentation/api/arrangementer>

Fire åpne kall gir deres egen nettside de samme kveldene som butikken viser: navn, tider, plakat, line-up, priser, serier og bordpakker. De krever ingen API-nøkkel.

Kallene ligger under https://api.kuvert.dk/v1/merchants/{slug}, der {slug} er butikkens adresse, f.eks. demo-natklubben i shop.kuvert.dk/demo-natklubben. De er åpne som butikken selv: ingen nøkkel, ingen konto og bare det en gjest også kan se. En kveld som fortsatt er et utkast, kommer aldri med.

> **Viktig:** Kall dem fra serveren deres, f.eks. fra en WordPress-plugin eller et byggesteg, og ikke fra nettleserens JavaScript på deres egen side. API-et tillater bare Kuverts egne domener i nettleseren, så en fetch fra et annet domene blir stoppet av nettleseren.

> **Merk:** Lagre gjerne svaret i et minutt eller to, men ikke i timevis. Priser og plasser endrer seg mens det selges, så la billettknappen gå til butikken, der tallene alltid er riktige.

## Kallene

| Kall | Gir |
| --- | --- |
| `GET /v1/merchants/{slug}` | Butikken og kveldene som er til salgs, i `events`, den tidligste først. Med `?include=canceled` kommer avlyste kvelder med, og med `?include=closed` kvelder der nettsalget er stengt, men kvelden ikke er over. Begge kan stå sammen: `?include=canceled,closed`. |
| `GET /v1/merchants/{slug}/events/{event}` | Én kveld med alle priser, hva som er igjen, og om den kan kjøpes akkurat nå. {event} er kveldens slug eller id. |
| `GET /v1/merchants/{slug}/series` | De faste seriene, hver med kveldene i serien som er til salgs. |
| `GET /v1/merchants/{slug}/table-nights` | De kommende kveldene med bordpakker, og om hver pakke kan bookes akkurat nå. |
| `GET /v1/merchants/{slug}/events/{event}/plan` | Klubbens kart for én kveld med bordpakker: rommene og hvert bord, ledig eller solgt. Det står ingenting om hvem som har kjøpt. |

## Kveldene

Butikkens eget kall har kveldene med i `events`. Hver kveld har navn, tider, sted og plakat og feltene et program bygges av. Her er et utdrag av svaret med én kveld:

```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": []
    }
  ]
}
```

| Felt | Betyr |
| --- | --- |
| `id, slug` | Kveldens id og den lesbare adressen. Kveldens side i butikken er shop.kuvert.dk/{slug}/event/{slug}, med id-en hvis kvelden ikke har en slug. |
| `startsAt, endsAt` | Når kvelden begynner og slutter. `endsAt` er `null` hvis kvelden ikke sier det. |
| `salesCloseAt` | Når nettsalget stenger. |
| `bannerUrl, bannerWidth, bannerHeight` | Plakaten og størrelsen i piksler, så siden kan holde av plassen før den er hentet. Vis den hel: den er laget for å ses uten beskjæring. |
| `status, cancelNote` | `published` eller `canceled`, og meldingen dere skrev da kvelden ble avlyst. |
| `series, seriesDate` | Serien bak kvelden med navn, ukedager (0 er søndag), regelen og en ferdig setning å vise, f.eks. «Hver fredag og lørdag», og hvilken av seriens dager det er. `null` på en kveld dere har opprettet selv. |
| `subtitle, genres, dressCode` | Undertittelen, sjangrene og antrekkskoden, slik dere skrev dem. |
| `lineup` | Navnene i rekkefølge, hvert med `name`, `role` og `time`. `time` har dato med, så et sett etter midnatt havner på riktig dag. |
| `doorsAt, lastEntryAt` | Når dørene åpner, og når siste gjest slippes inn. |
| `ticketsUrl` | Hvor billettene selges når noen andre selger dem, f.eks. arrangøren. Har kvelden egne priser i Kuvert, selges de her, og feltet brukes ikke. |

> **Merk:** Alle tidspunkter er i UTC. 21:00Z er klokken 23.00 i dansk sommertid og klokken 22.00 om vinteren, så regn om til Europe/Copenhagen før dere viser dem.

## Én kveld

Kveldens eget kall gir alt: beskrivelsen, aldersgrensen og alle priser i `tiers`. `onSale` sier om det kan kjøpes akkurat nå, og `refusalCode` hvorfor ikke, f.eks. `soldOut` eller `closed`. `waitlistOpen` er `true` når gjesten kan skrive seg på ventelisten.

```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": []
}
```

| Felt | Betyr |
| --- | --- |
| `priceOre` | Prisen i øre: 10000 er 100 DKK. |
| `availability` | `on_sale`, `not_yet` (åpner senere), `closed` eller `sold_out`. |
| `remaining, scarcity` | Hvor mange som er igjen til den prisen, og hva butikken viser om det: tallet (`count`), «få igjen» (`few`) eller ingenting (`null`). Vis det `scarcity` sier, og ikke tallet. `remaining` er `null` når prisen ikke har sitt eget antall. |
| `salesOpenAt, salesCloseAt, opensAfterTierId` | Prisens eget tidsrom, og prisen den venter på skal bli utsolgt når billettene selges i trinn. |
| `tablePackage, picksTable, tableSeats, tablesFree` | En bordpakke: om gjesten velger bordet på kartet, det minste og største bordet, og hvor mange bord som er ledige. |
| `includedItems, creditPromisedOre` | Det som følger med en pakke, og barkreditten hvis det finnes en. |
| `ageLimit` | Aldersgrensen i døren, eller `null`. |

## Serier

Holder dere den samme kvelden hver uke, gir seriene dere den som én rad: «Hver fredag og lørdag», og kveldene i serien som er til salgs. En serie der alle kveldene fortsatt er utkast, er ikke med.

```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"
        }
      ]
    }
  ]
}
```

## Bordpakker

Selger dere bord til kveldene, gir dette kallet de kommende kveldene med bordpakkene, så siden kan sette «Book bord» ved hver kveld uten å hente hver kvelds side. `bookable` sier om pakken kan bookes akkurat nå.

```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
        }
      ]
    }
  ]
}
```

## Hold programmet oppdatert

Må siden deres vite det med en gang når en kveld endrer seg, kan den abonnere på webhooks i stedet for å spørre hvert minutt: event.published når en kveld legges ut for salg, event.updated når noe offentlig endrer seg (med navnene på feltene i `changedFields`), event.canceled og event.unpublished. Hver leveranse har hele kvelden i samme form som listen over, med `eventId` i stedet for `id`. Et webhook-endepunkt opprettes under Innstillinger → Webhooks eller med en API-nøkkel.

## Et eksempel

Det minste som virker: hent kveldene på serveren deres, og bygg en lenke til hver kvelds side i butikken.

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

- [Webhooks og signaturer](https://kuvert.dk/no/dokumentation/api/webhooks)
- [Billetter: programmet på deres egen nettside](https://kuvert.dk/no/dokumentation/billetter#hjemmeside)
- [Innebygging: en kjøpsknapp ved hver kveld](https://kuvert.dk/no/dokumentation/indlejring)

## Delte kvelder

En kveld kan deles av flere bedrifter, f.eks. en arrangør som selger billettene, og klubben som selger bordene. Kvelden tilhører verten, men den står i programmet hos dem alle og kan hentes under hver av deres slugs, med samme id og samme slug. Den telles én gang i hver bedrifts liste.

| Felt | Betyr |
| --- | --- |
| `host` | Bedriften kvelden tilhører, med `slug` og `name`. Kveldens riktige adresse er shop.kuvert.dk/{host.slug}/event/{slug}, også når dere henter den under deres egen slug. |
| `cohosts` | De andre bedriftene som selger på kvelden, i den rekkefølgen de ble med. En tom liste på en kveld som ikke er delt. |
| `tiers[].seller` | Hvem som selger prisen, og som gjesten betaler. Bruk den til å vise deres egne priser for seg eller til å skrive hvem som selger hva. |
| `lineup[].merchantSlug` | Den opptredendes egen butikk på Kuvert, når verten har koblet navnet til den. |

GET /v1/merchants/{slug}/appearances gir kveldene andre bedrifter har booket dere til, enten som medvert eller i line-upen, i samme form som listen over pluss `seller` (bedriften hvis side selger kvelden) og `appearance` (`cohost` eller `lineup`). Da kan en artists side vise klubbkveldene artisten spiller på, uten at noen må skrive dem inn igjen. En kveld dere selv er medvert på, står også på deres egen liste over, så vis bare den ene, eller filtrer på `appearance`.

Webhooks for en delt kveld (event.*) går til alle bedriftene på kvelden. order.paid og ticket.issued går bare til den som solgte, og har `seller`, `host` og `cohosts` med, så systemet deres kan skille deres eget salg fra partnerens.

- [Del en kveld med en annen bedrift](https://kuvert.dk/no/dokumentation/del-en-aften)
