Hva skjer i Midtre Gauldal?

For utviklere

Det åpne API-et til denne kalenderen, hvordan du bygger den inn på ditt nettsted, og nøklene som identifiserer applikasjonen din.

API

Det åpne GraphQL-API-et til Hva skjer i Midtre Gauldal?. Les oversikten først hvis du ikke har gjort det; den fullstendige typelisten finner du på referansesiden og i schema.graphql.

Endepunkt

POST https://hvaskjerimidtregauldal.no/graphQL
Content-Type: application/json

{"query": "...", "variables": {...}, "operationName": "..."}
  • variables og operationName er valgfrie. Svar er JSON: {"data": ..., "errors": [...], "extensions": {...}}.
  • GET godtas for spørringer (?query=...&variables=..., URL-kodet), men bare med headeren Apollo-Require-Preflight: true. Uten den svarer tjeneren 400 med en CSRF-melding. Bruk helst POST.
  • CORS er åpent: en nettside på hvilket som helst opphav kan kalle endepunktet direkte. Egne headere utløser en preflight, som besvares.
  • Sandboxen er det samme endepunktet åpnet i en nettleser (en forespørsel som godtar HTML): skjemaet, autofullføring og en kjørbar spørring. Introspeksjon er på.
  • Det er ingen versjonering i URL-en. Endringer kunngjøres i endringsloggen og, for kallere med nøkkel, på e-post før de lander.

Headere

Header / parameter Hvem sender den Betydning
X-Api-Key: hsk_… du Applikasjonens nøkkel. Identitet, ikke sikkerhet: se Nøkler.
?key=hsk_… du, når headere er utenfor rekkevidde Samme nøkkel som parameter i spørrestrengen, for plattformer som ikke kan sette headere.
X-Page-Url: https://… innbygginger i nettleser Full URL til siden innbyggingen står på. Nettlesere sender bare opphavet som Referer på tvers av opphav, så uten denne er en widget på example.no/kultur/program umulig å skille fra enhver annen side på example.no.
X-Client-Id: name/version våre egne klienter Reservert for kalenderens egen front-end, tjenerrenderingen, widgeten og skjermappene. Ikke send den: trafikken din ville blitt ført under vår.

En nøkkel som er ukjent eller trukket tilbake får ikke forespørselen til å feile: den behandles som anonym, og svaret bærer en extensions.notice som sier det.

events-spørringen

query Upcoming($page: Int, $pageSize: Int, $filter: Filter) {
  events(page: $page, pageSize: $pageSize, filter: $filter) {
    totalCount
    hasMore
    pageInfo { currentPage pageSize totalPages }
    data {
      id
      event_slug
      eventLink
      title_nb
      title_en
      startDate
      endDate
      startTime
      duration
      categories
      mode
      venue { id name slug address location { latitude longitude } }
      organizers { id name slug website }
      images { urlSmall urlLarge alt }
      repetitions { startDate endDate startTime venue { name } }
    }
  }
}

Paginering

events(filter, page, pageSize). page starter på 0; pageSize er 10 som standard. Les totalene fra EventConnection, ikke fra lengden på data:

  • totalCount — arrangementer som matcher filteret, på tvers av alle sider;
  • hasMore — om page + 1 har noe;
  • pageInfo — currentPage, pageSize, totalPages.

page < 0 eller pageSize <= 0 gir feilen BAD_USER_INPUT. Forbindelsen bærer også fasetter over hele det filtrerte settet (ikke bare siden): venues, organizers og categories, hver en liste av { …, hits }.

Filter

Alle felt er valgfrie. Kombiner fritt; hver betingelse må holde.

Felt Betydning
fromDate Arrangementer som fortsatt pågår på dette tidspunktet eller senere: ikke avsluttet ennå, eller (for arrangementer publisert uten sluttid, der endDate == startDate) startet for mindre enn tre timer siden. Standard er nå.
untilDate Arrangementer som starter før dette tidspunktet.
fromStartDate Arrangementer som starter på dette tidspunktet eller senere. Bruk denne heller enn fromDate når pågående arrangementer ikke skal vises.
categories Kategori-id-er (se Identifikatorer); hvilken som helst av dem. Tom betyr alle.
notCategories Utelukk disse kategori-id-ene.
venues, venueSlug Sted-slugs (Venue.slug), hvilken som helst av dem / én av dem.
organizers, organizerSlug Arrangør-slugs (Organizer.slug).
searchTerm Fritekst, matchet uavhengig av store/små bokstaver og aksenter mot titler, beskrivelser, stikkord, stedsnavn, arrangørnavn og kategorietiketter; når ingenting matcher bokstavelig, matches titler og beskrivelser omtrentlig (én eller to skrivefeil).
tag Ett stikkord fra Event.tags.
mode online eller offline.
superEvent Id-en til et beholderarrangement (en festival, et marked): programmet dets.
onlyFeatured Bare arrangementer arrangøren har fremhevet.
onlyFeaturedSpecialEvent Bare arrangementer fremhevet i lisensens spesialarrangement, der det er satt opp.
cancelledNotIncluded, soldOutNotIncluded Fjern avlyste / utsolgte arrangementer.
hoursRange HH:mm-HH:mm, f.eks. 16:00-22:00: arrangementer som starter innenfor det vinduet.
groupRepetitionsByDay Utvid hver fremtidig dag i et arrangement med flere datoer til sin egen node (med den dagens startDate), så en liste kan vise én rad per dag. Datoer samme dag blir i den nodens repetitions.
municipality, postalCodes Filtrer på stedets adresse.
sortBy Utgått: resultatene er alltid kronologiske.

Datoargumenter tar YYYY-MM-DD HH:mm:ss etterfulgt av en forskyvning (+02:00, +0200, +02 eller Z), for eksempel "2026-09-01 00:00:00+02:00". En dato som ikke kan tolkes gir feilen Query Arguments invalid med extensions.invalidArgs som navngir argumentet.

{
  events(
    filter: {
      searchTerm: "konsert"
      fromDate: "2026-09-01 00:00:00+02:00"
      untilDate: "2026-12-31 23:59:59+01:00"
    }
    page: 0
    pageSize: 20
  ) {
    totalCount
    data { id title_nb startDate venue { name } }
  }
}

Andre spørringer

Spørring Returnerer
eventByID(eventID: String!) Ett arrangement etter id.
eventBySlug(eventSlug: String!) Ett arrangement etter event_slug (siste segment i eventLink).
eventsBySlugs(eventsSlugs: [String]!) Flere arrangementer etter slug.
eventByTitle(title: String!, lan: String!) Ett arrangement etter eksakt tittel; lan er nb eller en.
allUpcomingSuperEvents Beholderarrangementer (festivaler, markeder) som ikke er avsluttet.
allUpcomingEventsInArea(minLatitude, maxLatitude, minLongitude, maxLongitude) Kommende arrangementer med sted innenfor boksen.
categories Denne lisensens kategorier med id-er, etiketter, slugs og underkategorier.
venues, organizers Katalogen over steder og arrangører, med id-er og slugs.

Det finnes ingen mutasjoner. Arrangementer publiseres av mennesker gjennom kalenderens egne skjemaer og av kalenderens egne importører.

Datoer

To fakta. Hvert av dem har gitt feil program på noens nettsted.

1. startDate og endDate bærer UTC-forskyvningen som gjelder på arrangementets dato. Norge er +01:00 om vinteren og +02:00 om sommeren, og verdien sier hvilken:

2026-02-14 19:00:00+01:00    en februarkonsert kl. 19:00 Oslo-tid
2026-07-14 19:00:00+02:00    en julikonsert kl. 19:00 Oslo-tid

Begge er kl. 19:00 på veggklokka. Begge er gyldige tidspunkt. Det de ikke er, er «ISO med +00»: en parser satt opp med fast forskyvning, eller en formatering som skriver i tjenerens egen sone, viser 18:00 eller 20:00 for én av dem, og feilen snur ved hver overgang til og fra sommertid. Et reiselivsnettsted viste hvert klokkeslett feil i ukevis på denne måten.

  • Formatet er YYYY-MM-DD HH:mm:ss±HH:mm med et mellomrom mellom dato og tid. En streng RFC 3339-parser vil ha en T: bytt ut mellomrommet, så tolkes den overalt.
  • For visning: konverter tidspunktet til Europe/Oslo (aldri til leserens eller tjenerens sone).
  • Eller dropp regnestykket: startTime (HH:mm) er den norske starten på veggklokka nøyaktig slik arrangøren skrev den, og duration er i minutter. Det finnes ikke noe endTime-felt; utled det fra endDate i Europe/Oslo eller fra startTime + duration.
  • publishingDate og ticketsFromDate følger samme regel. created_at og updated_at er bokføring og gjør ikke nødvendigvis det.

2. startDate er neste kommende forekomst; repetitions lister bare fremtidige. Et arrangement med flere datoer er ett arrangement med én id. Når den første datoen har passert, løfter API-et den neste datoen som fortsatt gjelder inn i startDate, endDate, startTime, duration, venue, ticketsURL, eventCancelled og eventSoldOut, og repetitions holder datoene etter den. Passerte datoer returneres ikke, så samme id svarer med en annen startDate neste uke. Ikke nøkle dine egne poster på id + startDate med mindre du vil ha én post per forekomst; i så fall gir groupRepetitionsByDay deg dagsnodene direkte.

Identifikatorer

3. Filtrer og vis etter id. Navn og slugs er presentasjon.

  • Event.id er identiteten til et arrangement hele dets levetid. event_slug er URL-segmentet (eventLink er hele URL-en); title_nb / title_en redigeres av mennesker.
  • Event.categories er en liste over kategori-id-er. Hent etikettene fra categories ved hver kjøring — ikke én gang ved installasjon, og aldri skrevet for hånd. Id-er er forskjellige mellom lisenser (samme etikett er CONCERT på én kalender og noe annet på en annen), og en lisens kan bytte ut hele taksonomien sin: en pensjonert id forsvinner fra categories, arrangementene som bar den migreres, og id-en gjenbrukes aldri til noe annet. Å filtrere på en id som ikke lenger finnes i categories returnerer ingenting, uten feilmelding. Endringsloggen registrerer hver slik endring.
  • Venue og Organizer har en id og en slug. events-filteret tar sluggen (venues, organizers); les den fra venues / organizers heller enn å utlede den fra et navn.
  • categories returnerer visible per kategori; skjulte er fortsatt gyldige id-er på arrangementer.

Kategoriene til Hva skjer i Midtre Gauldal?

Slik de fulgte med dette bygget. categories-spørringen er sannheten ved kjøring.

id name_nb name_en slug_nb slug_en
CHURCH Kirke Church kirke church
CULTURE Kultur & historie Culture & history kultur-historie culture-history
FAMILY Barn & familie Children & family barn-familie children-family
FOOD Mat & marked Food & market mat-marked food-market
LECTURE Kurs & foredrag Courses & talks kurs-foredrag courses-talks
MOVIES Kino Cinema kino cinema
MUSIC Konsert & musikk Concerts & music konsert-musikk concerts-music
OTHER Annet Other annet other
SENIOR Senior Senior senior senior
SOCIAL Sosialt & samfunn Social & community sosialt-samfunn social-community
SPORT Idrett & friluft Sports & outdoors idrett-friluft sports-outdoors
THEATER Teater & scene Theatre & stage teater-scene theatre-stage

Billettyper

Price.type er en billettype-id. De innebygde på denne kalenderen:

id name_nb name_en
ASSISTANT Ledsager Assistant
CHILD Barn Child
FAMILY Familie Family
MEMBERS Medlemmer Members
REGULAR Vanlig Regular
REDUCED Redusert Reduced
SENIOR Honnør Senior
STUDENT Student Student

En arrangør kan også definere egne billettyper for sine arrangementer; de id-ene står ikke her, og Price.name_nb / Price.name_en bærer etiketten når arrangøren ga en.

Pris og kapasitet

4. Ingenting som kommer fra et skjema er garantert numerisk.

  • Price.price er typet Int, og tjeneren avrunder det arrangøren lagret — men den lagrede verdien kan være 1.595 (skrevet med norsk tusenskilletegn), 150,- eller tom. Når den ikke kan leses som tall er feltet null. Del aldri på det, anta aldri øre.
  • ticketsInformation sier hvilken av free, noTicketsInfo eller ticketsInfo som gjelder; prices er bare meningsfull for ticketsInfo. ticketsURL er der billetter selges når de selges et annet sted.
  • duration, minimumAge, maximumAge, cancellationPeriod, views kan være null.
  • Kapasitetsfeltene (registrationEnabled, availableTickets, activeTickets, maxBookingDate, maxBookingTime, paymentMethod) finnes for kalendere der besøkende melder seg på gjennom kalenderen selv. På en kalender uten påmelding er de null eller false; ikke les availableTickets: null som «utsolgt». eventSoldOut er arrangørens eksplisitte flagg.
  • En Repetition kan bære sine egne prices; når den er null, gjelder arrangementets prices.

Bilder

Event.images er en liste; det første bildet er forsidebildet. urlSmall og urlLarge er samme bilde i to størrelser.

Et kort beskjærer som regel bildet til en boks med sin egen form, og en beskjæring rundt midten kutter hodene av et gruppebilde. focusX og focusY sier hvor menneskene er, som andeler av bildet: 0, 0 er øverste venstre hjørne, 1, 1 nederste høyre. Legg det punktet i bildet på samme punkt i boksen din, så blir det i bildet uansett hvilken form boksen har. I CSS er det én deklarasjon:

img { object-fit: cover; object-position: 51% 31%; }   /* focusX: 0.51, focusY: 0.31 */
{
  events(pageSize: 3) {
    data { title_nb images { urlLarge alt focusX focusY width height } }
  }
}
  • Begge er null når det ikke ble funnet noe ansikt i bildet, og den første halvtimen eller så av et nytt bildes liv, før det er analysert. Behold din egen standardbeskjæring da.
  • width og height er pikselstørrelsen til bildet på urlLarge, og null til det er analysert.

Feil

Svarkroppen er alltid JSON.

Situasjon HTTP Kropp
Kroppen er ikke gyldig JSON 400 {"errors":[{"message":"Malformed JSON body"}]}
GET uten Apollo-Require-Preflight 400 errors[0].extensions.code = "BAD_REQUEST", meldingen nevner CSRF
Spørringen validerer ikke (ukjent felt eller argument, feil type) 400 errors[0].extensions.code = "GRAPHQL_VALIDATION_FAILED"; meldingen navngir feltet
Ugyldig argumentverdi (negativ side, dato som ikke kan tolkes) 200 data: null, errors[0].extensions.code = "BAD_USER_INPUT" eller extensions.invalidArgs
Feil i en resolver 200 data med null for feltet som feilet og en oppføring i errors

En errors-liste kan følge med delvise data; sjekk etter den i hvert svar, ikke bare ved statuser som ikke er 200.

extensions.notice er ikke en feil. Det er en streng på vellykkede svar til forespørsler uten gyldig nøkkel, som peker til denne portalen. En klient som ignorerer extensions påvirkes ikke; en som leser den kan logge den én gang og gå videre.

Rate limits og kvote

Ingen i dag, med eller uten nøkkel. Når en kvote kommer, beholder applikasjoner med nøkkel sitt eget budsjett, og anonym trafikk som først ses etter den datoen kan få en lavere. Ikke ennå — dette avsnittet endres først, og endringsloggen sier fra.

Cache det du kan: en liste som endrer seg noen ganger om dagen trenger ikke hentes hvert sekund.

Kontakt

Spørsmål, et felt du trenger, et endringsvarsel du ikke fikk: post@hvaskjerimidtregauldal.no. Si hvilken kalender og, hvis du har en, hvilken nøkkel.

Markdown-versjon