{"openapi":"3.1.0","info":{"title":"TCGM integrations-API","version":"v1","description":"Offentlig API-reference. Bearer-nøgler administreres under /konto/virk/<orgslug>/api."},"servers":[{"url":"https://www.tcgm.dk"}],"paths":{"/api/v1/store/events":{"get":{"operationId":"public_butiksaktiviteter_liste","tags":["Butiksaktiviteter"],"summary":"Hent butiksaktiviteter","description":"Henter butikkens aktiviteter og godkendelsesstatus. Ændrer ingen data.\n\nAdgang: TCGM Bearer-nøgle. Organisation og ressource skal være godkendte, aktive og have aktuelt ejerskab hos nøglens organisation. Nøglen skal have det relevante scope og adgang til ressourcen.\n\nSorteret efter id. Send after=nextCursor for næste side. Listen indeholder også kladder og aktiviteter, der afventer godkendelse; standarden udelader aktiviteter, hvor sletning er startet.","parameters":[{"name":"organization","in":"query","required":true,"description":"Organisationens id fra /api/v1/access.","schema":{"type":"string","minLength":1,"maxLength":200,"description":"Trimmes før validering."},"example":"org_example"},{"name":"store","in":"query","required":true,"description":"Butikkens id fra /api/v1/access.","schema":{"type":"string","minLength":1,"maxLength":200,"description":"Trimmes før validering."},"example":"store_example"},{"name":"state","in":"query","required":false,"description":"Aktive, slettede eller alle aktiviteter.","schema":{"type":"string","enum":["active","deleted","all"],"default":"active"}},{"name":"limit","in":"query","required":false,"description":"Antal aktiviteter pr. side.","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"after","in":"query","required":false,"description":"Brug nextCursor fra forrige svar uændret.","schema":{"type":"string","minLength":1,"maxLength":200,"description":"Trimmes før validering."}}],"security":[{"bearerAuth":[]}],"x-required-scope":"store:events:read","responses":{"200":{"description":"En side aktiviteter; nextCursor er null på sidste side.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"events":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"storeId":{"type":"string"},"slug":{"type":"string"},"title":{"type":"string"},"description":{"type":["string","null"]},"category":{"type":"string","enum":["PLAY","TOURNAMENT","PRERELEASE","RELEASE","LEARN_TO_PLAY","TRADE_DAY","COMMUNITY","STORE_EVENT"]},"tcgBrandId":{"type":["string","null"]},"url":{"type":["string","null"]},"startsAt":{"type":"string","format":"date-time","description":"UTC-tidspunkt i ISO 8601-format."},"endsAt":{"type":"string","format":"date-time","description":"UTC-tidspunkt i ISO 8601-format."},"timezone":{"type":"string"},"repeat":{"type":"string","enum":["once","weekly","even","odd","monthly-date","monthly-weekday"]},"status":{"type":"string","enum":["DRAFT","PENDING","APPROVED"]},"approvedAt":{"type":["string","null"],"format":"date-time","description":"UTC-tidspunkt i ISO 8601-format."},"createdAt":{"type":"string","format":"date-time","description":"UTC-tidspunkt i ISO 8601-format."},"updatedAt":{"type":"string","format":"date-time","description":"UTC-tidspunkt i ISO 8601-format."},"deletedAt":{"type":["string","null"],"format":"date-time","description":"Tidspunktet, hvor sletning blev startet. null, når aktiviteten ikke er under sletning."}},"required":["id","storeId","slug","title","description","category","tcgBrandId","url","startsAt","endsAt","timezone","repeat","status","approvedAt","createdAt","updatedAt","deletedAt"]}},"nextCursor":{"type":["string","null"]}},"required":["events","nextCursor"]},"example":{"events":[{"id":"store_ev_example","storeId":"store_example","slug":"kortspil-i-butikken","title":"Kortspil i butikken","description":null,"category":"STORE_EVENT","tcgBrandId":null,"url":null,"startsAt":"2026-12-04T17:00:00.000Z","endsAt":"2026-12-04T20:00:00.000Z","timezone":"Europe/Copenhagen","repeat":"once","status":"PENDING","approvedAt":null,"createdAt":"2026-11-13T12:00:00.000Z","updatedAt":"2026-11-13T12:00:00.000Z","deletedAt":null}],"nextCursor":null}}}},"400":{"description":"Ugyldigt input: invalid_request.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"invalid_request"}}}},"401":{"description":"Manglende eller ugyldig Bearer-nøgle: invalid_credential.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}},"WWW-Authenticate":{"description":"Bearer","schema":{"type":"string","const":"Bearer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"invalid_credential"}}}},"403":{"description":"Adgang nægtet: nøgle, scope, ejerskab eller godkendelse er ikke længere gyldig.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"access_denied"}}}},"404":{"description":"Aktiviteten findes ikke i den valgte butik: event_not_found.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"event_not_found"}}}},"405":{"description":"HTTP-metoden understøttes ikke. Svaret genereres af Next.js."},"503":{"description":"Lager eller behandling er utilgængelig. Ingen interne fejl eller skemadetaljer udleveres i produktion.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"service_unavailable"}}}}},"x-codeSamples":[{"lang":"Shell","source":"curl --request GET 'https://www.tcgm.dk/api/v1/store/events?organization=org_example&store=store_example' \\\n  --header 'Authorization: Bearer <api-nøgle>'"}]},"post":{"operationId":"public_butiksaktiviteter_opret","tags":["Butiksaktiviteter"],"summary":"Opret en butiksaktivitet","description":"Opretter en butiksaktivitet og indsender den til godkendelse. Kræver en offentlig butik.\n\nAdgang: TCGM Bearer-nøgle. Organisation og ressource skal være godkendte, aktive og have aktuelt ejerskab hos nøglens organisation. Nøglen skal have det relevante scope og adgang til ressourcen. Butikken skal være offentlig.\n\nJSON-body må højst fylde 256 KiB. Ukendte bodyfelter afvises. Identiske genforsøg med samme Idempotency-Key returnerer det oprindelige resultat; ændret indhold giver 409. Genbrug nøglen ved usikkert udfald.\n\nAdgang og ejerskab kontrolleres også ved genforsøg og før beskyttet baggrundsarbejde. En senere fejl fortryder ikke automatisk allerede gennemførte ændringer.\n\nGentagelse gemmes efter de eksisterende aktivitetsregler. Ingen workflow eller polling er nødvendig. Der registreres intet forbrug.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"1–200 synlige ASCII-tegn uden mellemrum. Genbrug ved genforsøg; ny nøgle til en ny handling.","schema":{"type":"string","minLength":1,"maxLength":200,"pattern":"^[\\x21-\\x7e]+$"},"example":"example-operation-1"}],"security":[{"bearerAuth":[]}],"x-required-scope":"store:events:create","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"organization":{"type":"string","minLength":1,"maxLength":200,"description":"Trimmes før validering."},"store":{"type":"string","minLength":1,"maxLength":200,"description":"Trimmes før validering."},"data":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200,"description":"Skal give en gyldig slug; opret og tcgm er reserverede."},"description":{"type":"string","maxLength":10000,"default":"","description":"Valgfri tekst. Tom streng betyder ingen beskrivelse; normaliseres ved lagring."},"category":{"type":"string","enum":["PLAY","TOURNAMENT","PRERELEASE","RELEASE","LEARN_TO_PLAY","TRADE_DAY","COMMUNITY","STORE_EVENT"]},"tcgBrandId":{"type":"string","maxLength":200,"default":"","description":"Et eksisterende, ikke slettet spil kræves undtagen ved STORE_EVENT, som ikke gemmer et spil."},"url":{"type":"string","maxLength":2000,"default":"","description":"Gyldig HTTPS-adresse eller tom streng."},"startsAt":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}$","description":"Lokal dato og tid som YYYY-MM-DDTHH:mm i den angivne timezone. Ugyldige lokale tidspunkter afvises."},"endsAt":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}$","description":"Lokal dato og tid som YYYY-MM-DDTHH:mm i den angivne timezone. Ugyldige lokale tidspunkter afvises. Skal ligge efter startsAt."},"timezone":{"type":"string","const":"Europe/Copenhagen","default":"Europe/Copenhagen","description":"Dansk tidszone. Kun Europe/Copenhagen understøttes."},"repeat":{"type":"string","enum":["once","weekly","even","odd","monthly-date","monthly-weekday"],"default":"once","description":"once: én dato. weekly: hver uge. even/odd: lige/ulige ISO-uger. monthly-date: samme dato hver måned. monthly-weekday: samme ugedagsplacering, fx første fredag. startsAt forankrer gentagelsen; måneder uden datoen eller ugedagsplaceringen springes over. Tidspunktet bevares i Europe/Copenhagen, også ved sommertid."}},"required":["title","category","startsAt","endsAt"],"additionalProperties":false}},"required":["organization","store","data"],"additionalProperties":false},"example":{"organization":"org_example","store":"store_example","data":{"title":"Kortspil i butikken","category":"STORE_EVENT","startsAt":"2026-12-04T18:00","endsAt":"2026-12-04T21:00","timezone":"Europe/Copenhagen"}}}}},"responses":{"201":{"description":"Oprettet og indsendt til godkendelse.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string","enum":["PENDING","APPROVED"]}},"required":["id","slug","status"]},"example":{"id":"store_ev_example","slug":"kortspil-i-butikken","status":"PENDING"}}}},"400":{"description":"Ugyldigt input: invalid_request.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"invalid_request"}}}},"401":{"description":"Manglende eller ugyldig Bearer-nøgle: invalid_credential.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}},"WWW-Authenticate":{"description":"Bearer","schema":{"type":"string","const":"Bearer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"invalid_credential"}}}},"403":{"description":"Adgang nægtet: nøgle, scope, ejerskab eller godkendelse er ikke længere gyldig.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"access_denied"}}}},"404":{"description":"Ressourcen findes ikke eller er ikke tilgængelig.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"order_not_found"}}}},"405":{"description":"HTTP-metoden understøttes ikke. Svaret genereres af Next.js."},"409":{"description":"Konflikt: fx idempotency_conflict, external_id_conflict eller order_closed. Samme nøgle med andet valideret indhold afvises.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"idempotency_conflict"}}}},"413":{"description":"JSON-body overstiger 256 KiB.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"request_too_large"}}}},"415":{"description":"Content-Type skal være application/json.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"json_required"}}}},"503":{"description":"Lager eller behandling er utilgængelig. Ingen interne fejl eller skemadetaljer udleveres i produktion.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"service_unavailable"}}}}},"x-codeSamples":[{"lang":"Shell","source":"curl --request POST 'https://www.tcgm.dk/api/v1/store/events' \\\n  --header 'Authorization: Bearer <api-nøgle>' \\\n  --header 'Content-Type: application/json' \\\n  --header 'Idempotency-Key: example-operation-1' \\\n  --data '{\n  \"organization\": \"org_example\",\n  \"store\": \"store_example\",\n  \"data\": {\n    \"title\": \"Kortspil i butikken\",\n    \"category\": \"STORE_EVENT\",\n    \"startsAt\": \"2026-12-04T18:00\",\n    \"endsAt\": \"2026-12-04T21:00\",\n    \"timezone\": \"Europe/Copenhagen\"\n  }\n}'"}]}},"/api/v1/store/events/{eventid}":{"get":{"operationId":"public_butiksaktiviteter_hent","tags":["Butiksaktiviteter"],"summary":"Hent en butiksaktivitet","description":"Henter aktivitetens indhold, godkendelsesstatus og eventuelle slettetidspunkt.\n\nAdgang: TCGM Bearer-nøgle. Organisation og ressource skal være godkendte, aktive og have aktuelt ejerskab hos nøglens organisation. Nøglen skal have det relevante scope og adgang til ressourcen.\n\ndeletedAt er null for aktive aktiviteter. Læsning ændrer ingen data.","parameters":[{"name":"eventid","in":"path","required":true,"description":"Butiksaktivitetens TCGM-id (store_ev_…) fra oprettelse eller aktivitetslisten. Ikke et api_ev_-behandlings-id eller butikkens id.","schema":{"type":"string","minLength":1,"maxLength":200,"description":"Trimmes før validering."},"example":"store_ev_example"},{"name":"organization","in":"query","required":true,"description":"Organisationens id fra /api/v1/access.","schema":{"type":"string","minLength":1,"maxLength":200,"description":"Trimmes før validering."},"example":"org_example"},{"name":"store","in":"query","required":true,"description":"Butikkens id fra /api/v1/access.","schema":{"type":"string","minLength":1,"maxLength":200,"description":"Trimmes før validering."},"example":"store_example"}],"security":[{"bearerAuth":[]}],"x-required-scope":"store:events:read","responses":{"200":{"description":"Aktiviteten, også hvis sletning er startet.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"event":{"type":"object","properties":{"id":{"type":"string"},"storeId":{"type":"string"},"slug":{"type":"string"},"title":{"type":"string"},"description":{"type":["string","null"]},"category":{"type":"string","enum":["PLAY","TOURNAMENT","PRERELEASE","RELEASE","LEARN_TO_PLAY","TRADE_DAY","COMMUNITY","STORE_EVENT"]},"tcgBrandId":{"type":["string","null"]},"url":{"type":["string","null"]},"startsAt":{"type":"string","format":"date-time","description":"UTC-tidspunkt i ISO 8601-format."},"endsAt":{"type":"string","format":"date-time","description":"UTC-tidspunkt i ISO 8601-format."},"timezone":{"type":"string"},"repeat":{"type":"string","enum":["once","weekly","even","odd","monthly-date","monthly-weekday"]},"status":{"type":"string","enum":["DRAFT","PENDING","APPROVED"]},"approvedAt":{"type":["string","null"],"format":"date-time","description":"UTC-tidspunkt i ISO 8601-format."},"createdAt":{"type":"string","format":"date-time","description":"UTC-tidspunkt i ISO 8601-format."},"updatedAt":{"type":"string","format":"date-time","description":"UTC-tidspunkt i ISO 8601-format."},"deletedAt":{"type":["string","null"],"format":"date-time","description":"Tidspunktet, hvor sletning blev startet. null, når aktiviteten ikke er under sletning."}},"required":["id","storeId","slug","title","description","category","tcgBrandId","url","startsAt","endsAt","timezone","repeat","status","approvedAt","createdAt","updatedAt","deletedAt"]}},"required":["event"]},"example":{"event":{"id":"store_ev_example","storeId":"store_example","slug":"kortspil-i-butikken","title":"Kortspil i butikken","description":null,"category":"STORE_EVENT","tcgBrandId":null,"url":null,"startsAt":"2026-12-04T17:00:00.000Z","endsAt":"2026-12-04T20:00:00.000Z","timezone":"Europe/Copenhagen","repeat":"once","status":"PENDING","approvedAt":null,"createdAt":"2026-11-13T12:00:00.000Z","updatedAt":"2026-11-13T12:00:00.000Z","deletedAt":null}}}}},"400":{"description":"Ugyldigt input: invalid_request.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"invalid_request"}}}},"401":{"description":"Manglende eller ugyldig Bearer-nøgle: invalid_credential.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}},"WWW-Authenticate":{"description":"Bearer","schema":{"type":"string","const":"Bearer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"invalid_credential"}}}},"403":{"description":"Adgang nægtet: nøgle, scope, ejerskab eller godkendelse er ikke længere gyldig.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"access_denied"}}}},"404":{"description":"Aktiviteten findes ikke i den valgte butik: event_not_found.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"event_not_found"}}}},"405":{"description":"HTTP-metoden understøttes ikke. Svaret genereres af Next.js."},"503":{"description":"Lager eller behandling er utilgængelig. Ingen interne fejl eller skemadetaljer udleveres i produktion.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"service_unavailable"}}}}},"x-codeSamples":[{"lang":"Shell","source":"curl --request GET 'https://www.tcgm.dk/api/v1/store/events/store_ev_example?organization=org_example&store=store_example' \\\n  --header 'Authorization: Bearer <api-nøgle>'"}]},"post":{"operationId":"public_butiksaktiviteter_opdater","tags":["Butiksaktiviteter"],"summary":"Opdatér en butiksaktivitet","description":"Opdaterer aktiviteten og annullerer en eventuel sletning. Ændrede aktiviteter og aktiviteter, hvor sletningen annulleres, indsendes til godkendelse igen.\n\nAdgang: TCGM Bearer-nøgle. Organisation og ressource skal være godkendte, aktive og have aktuelt ejerskab hos nøglens organisation. Nøglen skal have det relevante scope og adgang til ressourcen. Butikken skal være offentlig.\n\nJSON-body må højst fylde 256 KiB. Ukendte bodyfelter afvises. Identiske genforsøg med samme Idempotency-Key returnerer det oprindelige resultat; ændret indhold giver 409. Genbrug nøglen ved usikkert udfald.\n\nAdgang og ejerskab kontrolleres også ved genforsøg og før beskyttet baggrundsarbejde. En senere fejl fortryder ikke automatisk allerede gennemførte ændringer.\n\nEfter start kan startsAt ikke ændres (409 event_started), så en historisk aktivitet ikke kan flyttes til fremtiden for at omgå slettereglen. Udeladt repeat bevarer gentagelsen; repeat: once fjerner den. Udeladte felter bevares. data: {} annullerer en påbegyndt sletning; på en aktiv aktivitet er det en no-op. Slug og ejerskab bevares. Der registreres intet forbrug.\n\nÆndringer og annullering af sletning giver PENDING, eller APPROVED med organisationens eksisterende automatiske godkendelse. Tidligere manuel godkendelse ryddes. En uændret aktiv aktivitet beholder sin status.\n\nInputtider er lokale; svartider er UTC. Ændring af timezone alene bevarer start- og sluttidspunktets faktiske tidspunkt. Ugyldigt spil eller tidsinterval giver 400. Status, godkendelse, slug og ejerskab kan ikke sættes af klienten.\n\nGenforsøg returnerer den oprindelige kvittering og annullerer ikke en senere sletning. Brug en ny idempotensnøgle til en ny opdatering, der skal annullere sletningen.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"1–200 synlige ASCII-tegn uden mellemrum. Genbrug ved genforsøg; ny nøgle til en ny handling.","schema":{"type":"string","minLength":1,"maxLength":200,"pattern":"^[\\x21-\\x7e]+$"},"example":"example-operation-1"},{"name":"eventid","in":"path","required":true,"description":"Butiksaktivitetens TCGM-id (store_ev_…) fra oprettelse eller aktivitetslisten. Ikke et api_ev_-behandlings-id eller butikkens id.","schema":{"type":"string","minLength":1,"maxLength":200,"description":"Trimmes før validering."},"example":"store_ev_example"}],"security":[{"bearerAuth":[]}],"x-required-scope":"store:events:update","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"organization":{"type":"string","minLength":1,"maxLength":200,"description":"Trimmes før validering."},"store":{"type":"string","minLength":1,"maxLength":200,"description":"Butikkens id fra /api/v1/access."},"data":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200,"description":"Aktivitetens titel. Den eksisterende slug bevares."},"description":{"type":"string","maxLength":10000,"description":"Valgfri tekst. Tom streng betyder ingen beskrivelse; normaliseres ved lagring."},"category":{"type":"string","enum":["PLAY","TOURNAMENT","PRERELEASE","RELEASE","LEARN_TO_PLAY","TRADE_DAY","COMMUNITY","STORE_EVENT"]},"tcgBrandId":{"type":"string","maxLength":200,"description":"Et eksisterende, ikke slettet spil kræves undtagen ved STORE_EVENT, som ikke gemmer et spil."},"url":{"type":"string","maxLength":2000,"description":"Gyldig HTTPS-adresse eller tom streng."},"startsAt":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}$","description":"Lokal dato og tid som YYYY-MM-DDTHH:mm i den angivne timezone. Ugyldige lokale tidspunkter afvises."},"endsAt":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}$","description":"Lokal dato og tid som YYYY-MM-DDTHH:mm i den angivne timezone. Ugyldige lokale tidspunkter afvises. Skal ligge efter startsAt."},"timezone":{"type":"string","const":"Europe/Copenhagen","description":"Dansk tidszone. Kun Europe/Copenhagen understøttes."},"repeat":{"type":"string","enum":["once","weekly","even","odd","monthly-date","monthly-weekday"],"description":"once: én dato. weekly: hver uge. even/odd: lige/ulige ISO-uger. monthly-date: samme dato hver måned. monthly-weekday: samme ugedagsplacering, fx første fredag. startsAt forankrer gentagelsen; måneder uden datoen eller ugedagsplaceringen springes over. Tidspunktet bevares i Europe/Copenhagen, også ved sommertid."}},"required":[],"additionalProperties":false}},"required":["organization","store","data"],"additionalProperties":false},"example":{"organization":"org_example","store":"store_example","data":{"title":"Ny titel"}}}}},"responses":{"200":{"description":"Aktiviteten efter kaldet; changed angiver en ændring eller annulleret sletning.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"event":{"type":"object","properties":{"id":{"type":"string"},"storeId":{"type":"string"},"slug":{"type":"string"},"title":{"type":"string"},"description":{"type":["string","null"]},"category":{"type":"string","enum":["PLAY","TOURNAMENT","PRERELEASE","RELEASE","LEARN_TO_PLAY","TRADE_DAY","COMMUNITY","STORE_EVENT"]},"tcgBrandId":{"type":["string","null"]},"url":{"type":["string","null"]},"startsAt":{"type":"string","format":"date-time","description":"UTC-tidspunkt i ISO 8601-format."},"endsAt":{"type":"string","format":"date-time","description":"UTC-tidspunkt i ISO 8601-format."},"timezone":{"type":"string"},"repeat":{"type":"string","enum":["once","weekly","even","odd","monthly-date","monthly-weekday"]},"status":{"type":"string","enum":["DRAFT","PENDING","APPROVED"]},"approvedAt":{"type":["string","null"],"format":"date-time","description":"UTC-tidspunkt i ISO 8601-format."},"createdAt":{"type":"string","format":"date-time","description":"UTC-tidspunkt i ISO 8601-format."},"updatedAt":{"type":"string","format":"date-time","description":"UTC-tidspunkt i ISO 8601-format."},"deletedAt":{"type":["string","null"],"format":"date-time","description":"Tidspunktet, hvor sletning blev startet. null, når aktiviteten ikke er under sletning."}},"required":["id","storeId","slug","title","description","category","tcgBrandId","url","startsAt","endsAt","timezone","repeat","status","approvedAt","createdAt","updatedAt","deletedAt"]},"changed":{"type":"boolean"}},"required":["event","changed"]},"example":{"event":{"id":"store_ev_example","storeId":"store_example","slug":"kortspil-i-butikken","title":"Ny titel","description":null,"category":"STORE_EVENT","tcgBrandId":null,"url":null,"startsAt":"2026-12-04T17:00:00.000Z","endsAt":"2026-12-04T20:00:00.000Z","timezone":"Europe/Copenhagen","repeat":"once","status":"PENDING","approvedAt":null,"createdAt":"2026-11-13T12:00:00.000Z","updatedAt":"2026-11-13T12:00:00.000Z","deletedAt":null},"changed":true}}}},"400":{"description":"Ugyldigt input: invalid_request.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"invalid_request"}}}},"401":{"description":"Manglende eller ugyldig Bearer-nøgle: invalid_credential.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}},"WWW-Authenticate":{"description":"Bearer","schema":{"type":"string","const":"Bearer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"invalid_credential"}}}},"403":{"description":"Adgang nægtet: nøgle, scope, ejerskab eller godkendelse er ikke længere gyldig.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"access_denied"}}}},"404":{"description":"Aktiviteten findes ikke i den valgte butik: event_not_found.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"event_not_found"}}}},"405":{"description":"HTTP-metoden understøttes ikke. Svaret genereres af Next.js."},"409":{"description":"Konflikt: idempotency_conflict ved genbrugt nøgle med andet indhold; event_started ved sletning efter start eller ændring af et allerede startet starttidspunkt.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"idempotency_conflict"}}}},"413":{"description":"JSON-body overstiger 256 KiB.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"request_too_large"}}}},"415":{"description":"Content-Type skal være application/json.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"json_required"}}}},"503":{"description":"Lager eller behandling er utilgængelig. Ingen interne fejl eller skemadetaljer udleveres i produktion.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"service_unavailable"}}}}},"x-codeSamples":[{"lang":"Shell","source":"curl --request POST 'https://www.tcgm.dk/api/v1/store/events/store_ev_example' \\\n  --header 'Authorization: Bearer <api-nøgle>' \\\n  --header 'Content-Type: application/json' \\\n  --header 'Idempotency-Key: example-operation-1' \\\n  --data '{\n  \"organization\": \"org_example\",\n  \"store\": \"store_example\",\n  \"data\": {\n    \"title\": \"Ny titel\"\n  }\n}'"}]},"delete":{"operationId":"public_butiksaktiviteter_slet","tags":["Butiksaktiviteter"],"summary":"Start sletning af en butiksaktivitet","description":"Starter sletning af en aktivitet, som endnu ikke er startet. Igangværende og afsluttede aktiviteter kan ikke slettes.\n\nAdgang: TCGM Bearer-nøgle. Organisation og ressource skal være godkendte, aktive og have aktuelt ejerskab hos nøglens organisation. Nøglen skal have det relevante scope og adgang til ressourcen.\n\nJSON-body må højst fylde 256 KiB. Ukendte bodyfelter afvises. Identiske genforsøg med samme Idempotency-Key returnerer det oprindelige resultat; ændret indhold giver 409. Genbrug nøglen ved usikkert udfald.\n\nAdgang og ejerskab kontrolleres også ved genforsøg og før beskyttet baggrundsarbejde. En senere fejl fortryder ikke automatisk allerede gennemførte ændringer.\n\nAktiviteten skjules, når sletningen starter. En senere POST-opdatering på samme adresse annullerer sletningen; data: {} er nok. Brug en ny idempotensnøgle. Aktiviteten indsendes til godkendelse igen.\n\nStarttidspunktet skal være senere end serverens aktuelle tidspunkt; ellers returneres 409 med error: event_started. Det gælder også gentagende aktiviteter fra deres første start. data kan udelades eller være {}. Der registreres intet forbrug.\n\nEt identisk genforsøg henter kvitteringen for den oprindelige handling. Det starter ikke sletning igen, hvis den senere er annulleret.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"1–200 synlige ASCII-tegn uden mellemrum. Genbrug ved genforsøg; ny nøgle til en ny handling.","schema":{"type":"string","minLength":1,"maxLength":200,"pattern":"^[\\x21-\\x7e]+$"},"example":"example-operation-1"},{"name":"eventid","in":"path","required":true,"description":"Butiksaktivitetens TCGM-id (store_ev_…) fra oprettelse eller aktivitetslisten. Ikke et api_ev_-behandlings-id eller butikkens id.","schema":{"type":"string","minLength":1,"maxLength":200,"description":"Trimmes før validering."},"example":"store_ev_example"}],"security":[{"bearerAuth":[]}],"x-required-scope":"store:events:delete","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"organization":{"type":"string","minLength":1,"maxLength":200,"description":"Trimmes før validering."},"store":{"type":"string","minLength":1,"maxLength":200,"description":"Butikkens id fra /api/v1/access."},"data":{"type":"object","properties":{},"required":[],"additionalProperties":false}},"required":["organization","store"],"additionalProperties":false},"example":{"organization":"org_example","store":"store_example"}}}},"responses":{"200":{"description":"Sletning startet, eller allerede startet med changed=false.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"event":{"type":"object","properties":{"id":{"type":"string"},"storeId":{"type":"string"},"slug":{"type":"string"},"title":{"type":"string"},"description":{"type":["string","null"]},"category":{"type":"string","enum":["PLAY","TOURNAMENT","PRERELEASE","RELEASE","LEARN_TO_PLAY","TRADE_DAY","COMMUNITY","STORE_EVENT"]},"tcgBrandId":{"type":["string","null"]},"url":{"type":["string","null"]},"startsAt":{"type":"string","format":"date-time","description":"UTC-tidspunkt i ISO 8601-format."},"endsAt":{"type":"string","format":"date-time","description":"UTC-tidspunkt i ISO 8601-format."},"timezone":{"type":"string"},"repeat":{"type":"string","enum":["once","weekly","even","odd","monthly-date","monthly-weekday"]},"status":{"type":"string","enum":["DRAFT","PENDING","APPROVED"]},"approvedAt":{"type":["string","null"],"format":"date-time","description":"UTC-tidspunkt i ISO 8601-format."},"createdAt":{"type":"string","format":"date-time","description":"UTC-tidspunkt i ISO 8601-format."},"updatedAt":{"type":"string","format":"date-time","description":"UTC-tidspunkt i ISO 8601-format."},"deletedAt":{"type":["string","null"],"format":"date-time","description":"Tidspunktet, hvor sletning blev startet. null, når aktiviteten ikke er under sletning."}},"required":["id","storeId","slug","title","description","category","tcgBrandId","url","startsAt","endsAt","timezone","repeat","status","approvedAt","createdAt","updatedAt","deletedAt"]},"changed":{"type":"boolean"}},"required":["event","changed"]},"example":{"event":{"id":"store_ev_example","storeId":"store_example","slug":"kortspil-i-butikken","title":"Kortspil i butikken","description":null,"category":"STORE_EVENT","tcgBrandId":null,"url":null,"startsAt":"2026-12-04T17:00:00.000Z","endsAt":"2026-12-04T20:00:00.000Z","timezone":"Europe/Copenhagen","repeat":"once","status":"PENDING","approvedAt":null,"createdAt":"2026-11-13T12:00:00.000Z","updatedAt":"2026-11-13T12:01:00.000Z","deletedAt":"2026-11-13T12:01:00.000Z"},"changed":true}}}},"400":{"description":"Ugyldigt input: invalid_request.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"invalid_request"}}}},"401":{"description":"Manglende eller ugyldig Bearer-nøgle: invalid_credential.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}},"WWW-Authenticate":{"description":"Bearer","schema":{"type":"string","const":"Bearer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"invalid_credential"}}}},"403":{"description":"Adgang nægtet: nøgle, scope, ejerskab eller godkendelse er ikke længere gyldig.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"access_denied"}}}},"404":{"description":"Aktiviteten findes ikke i den valgte butik: event_not_found.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"event_not_found"}}}},"405":{"description":"HTTP-metoden understøttes ikke. Svaret genereres af Next.js."},"409":{"description":"Aktiviteten er startet: event_started. Genbrug af en nøgle med andet indhold giver idempotency_conflict.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"event_started"}}}},"413":{"description":"JSON-body overstiger 256 KiB.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"request_too_large"}}}},"415":{"description":"Content-Type skal være application/json.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"json_required"}}}},"503":{"description":"Lager eller behandling er utilgængelig. Ingen interne fejl eller skemadetaljer udleveres i produktion.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"service_unavailable"}}}}},"x-codeSamples":[{"lang":"Shell","source":"curl --request DELETE 'https://www.tcgm.dk/api/v1/store/events/store_ev_example' \\\n  --header 'Authorization: Bearer <api-nøgle>' \\\n  --header 'Content-Type: application/json' \\\n  --header 'Idempotency-Key: example-operation-1' \\\n  --data '{\n  \"organization\": \"org_example\",\n  \"store\": \"store_example\"\n}'"}]}},"/api/v1/access":{"get":{"operationId":"public_adgang","tags":["Adgang"],"summary":"Find organisation og ressourcer","description":"Henter nøglens organisation, scopes og ressourcer. Ændrer ingen data.\n\nAdgang: Gyldig TCGM Bearer-nøgle fra en godkendt organisation.\n\nListen kan være tom. all omfatter nuværende og fremtidige godkendte ressourcer inden for nøglens organisation; selected omfatter kun valgte ressourcer. TCGM-administrationsorganisationen udleveres ikke.\n\nQuery-parametre kan ikke vælge en anden organisation eller udvide adgangen.","parameters":[],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Nøglens aktuelle adgang.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"organization":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"}},"required":["id","slug","name"]},"scopes":{"type":"array","items":{"type":"string","enum":["store:events:create","store:events:read","store:events:update","store:events:delete","webshop:orders:read","webshop:orders:create","webshop:orders:update","webshop:orders:queue","webshop:orders:complete","webshop:events:read"]}},"resourceAccess":{"type":"string","enum":["all","selected"]},"resources":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"type":{"type":"string","enum":["store","webshop","event"]},"scopes":{"type":"array","items":{"type":"string","enum":["store:events:create","store:events:read","store:events:update","store:events:delete","webshop:orders:read","webshop:orders:create","webshop:orders:update","webshop:orders:queue","webshop:orders:complete","webshop:events:read"]}}},"required":["id","slug","name","type","scopes"]}}},"required":["organization","scopes","resourceAccess","resources"]},"example":{"organization":{"id":"org_example","slug":"eksempel","name":"Eksempelbutikken"},"scopes":["store:events:create"],"resourceAccess":"selected","resources":[{"id":"store_example","slug":"eksempelbutik","name":"Eksempelbutikken","type":"store","scopes":["store:events:create"]}]}}}},"401":{"description":"Manglende eller ugyldig Bearer-nøgle: invalid_credential.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}},"WWW-Authenticate":{"description":"Bearer","schema":{"type":"string","const":"Bearer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"invalid_credential"}}}},"403":{"description":"Adgang nægtet: nøgle, scope, ejerskab eller godkendelse er ikke længere gyldig.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"access_denied"}}}},"405":{"description":"HTTP-metoden understøttes ikke. Svaret genereres af Next.js."},"503":{"description":"Lager eller behandling er utilgængelig. Ingen interne fejl eller skemadetaljer udleveres i produktion.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"service_unavailable"}}}}},"x-codeSamples":[{"lang":"Shell","source":"curl --request GET 'https://www.tcgm.dk/api/v1/access' \\\n  --header 'Authorization: Bearer <api-nøgle>'"}]}},"/api/v1/tcg":{"get":{"operationId":"public_adgang_tcg","tags":["Adgang"],"summary":"Find TCG-brands og forbindelser","description":"Henter alle aktive TCG-brands med de butikker og netbutikker, som er forbundet og tilgængelige for nøglen. Ændrer ingen data.\n\nAdgang: Gyldig TCGM Bearer-nøgle fra en godkendt organisation.\n\nressources indeholder kun aktuelle, godkendte ressourcer fra nøglens organisation, inden for nøglens valgte ressourcer og scopes. Private ressourcer kan indgå, når nøglen har adgang. Andre organisationers forbindelser udleveres ikke.\n\nSlettede brands udelades. Brands uden tilgængelige forbindelser har tomme stores- og webshops-lister. Der kræves ingen mål-ID'er eller særskilt scope; query-parametre udvider ikke adgangen. Listen er sorteret efter brandnavn og id.","parameters":[],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Alle aktive brands, også når nøglens ressourcer ikke har forbindelser til dem.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"ressources":{"type":"object","properties":{"stores":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"}},"required":["id","slug","name"]}},"webshops":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"}},"required":["id","slug","name"]}}},"required":["stores","webshops"]}},"required":["id","slug","name","ressources"]}},"example":[{"id":"tcg_example","name":"Eksempelspillet","slug":"eksempelspillet","ressources":{"stores":[{"id":"store_example","name":"Eksempelbutikken","slug":"eksempelbutikken"}],"webshops":[{"id":"wshop_example","name":"Eksempelnetbutikken","slug":"eksempelnetbutikken"}]}},{"id":"tcg_other_example","name":"Et andet eksempelspil","slug":"andet-eksempelspil","ressources":{"stores":[],"webshops":[]}}]}}},"401":{"description":"Manglende eller ugyldig Bearer-nøgle: invalid_credential.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}},"WWW-Authenticate":{"description":"Bearer","schema":{"type":"string","const":"Bearer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"invalid_credential"}}}},"403":{"description":"Adgang nægtet: nøgle, scope, ejerskab eller godkendelse er ikke længere gyldig.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"access_denied"}}}},"405":{"description":"HTTP-metoden understøttes ikke. Svaret genereres af Next.js."},"503":{"description":"Lager eller behandling er utilgængelig. Ingen interne fejl eller skemadetaljer udleveres i produktion.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"service_unavailable"}}}}},"x-codeSamples":[{"lang":"Shell","source":"curl --request GET 'https://www.tcgm.dk/api/v1/tcg' \\\n  --header 'Authorization: Bearer <api-nøgle>'"}]}},"/api/v1/webshop/orders":{"get":{"operationId":"public_ordrer_liste","tags":["Ordrer"],"summary":"Hent ordrer","description":"Henter netbutikkens ordrer. Ændrer ingen data og registrerer ikke forbrug.\n\nAdgang: TCGM Bearer-nøgle. Organisation og ressource skal være godkendte, aktive og have aktuelt ejerskab hos nøglens organisation. Nøglen skal have det relevante scope og adgang til ressourcen.\n\nLæsninger registrerer ikke visningsforbrug. Fuldstændige kundenavne og e-mailhashes udleveres ikke.","parameters":[{"name":"organization","in":"query","required":true,"description":"Organisationens ID fra /api/v1/access.","schema":{"type":"string","minLength":1,"maxLength":200,"description":"Trimmes før validering."},"example":"org_example"},{"name":"webshop","in":"query","required":true,"description":"Netbutikkens ID fra /api/v1/access.","schema":{"type":"string","minLength":1,"maxLength":200,"description":"Trimmes før validering."},"example":"wshop_example"},{"name":"state","in":"query","required":false,"description":"Åbne, afsluttede eller alle ordrer.","schema":{"type":"string","enum":["open","closed","all"],"default":"open"}},{"name":"limit","in":"query","required":false,"description":"Heltal 1–100, standard 25.","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"after","in":"query","required":false,"description":"Brug nextCursor fra det forrige svar uændret.","schema":{"type":"string","maxLength":200}}],"security":[{"bearerAuth":[]}],"x-required-scope":"webshop:orders:read","responses":{"200":{"description":"Ordreside. nextCursor er null, når der ikke er en næste side.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"orders":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"externalId":{"type":"string"},"providerOrderId":{"type":"string"},"orderNumber":{"type":["string","null"]},"displayName":{"type":"string","description":"Visningssikkert navn. Fuldt kundenavn og e-mailhash returneres ikke."},"creatorTag":{"type":["string","null"]},"syncedBy":{"type":["string","null"]},"createdAt":{"type":"string"},"receivedAt":{"type":"string"},"updatedAt":{"type":"string"},"completedAt":{"type":["string","null"]},"queue":{"type":"object","properties":{"hidden":{"type":"boolean"},"position":{"type":["number","null"]},"preparing":{"type":"boolean"}},"required":["hidden","position","preparing"]},"lines":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"externalId":{"type":"string"},"productId":{"type":"string"},"variantId":{"type":["string","null"]},"itemName":{"type":"string"},"quantity":{"type":"number"}},"required":["id","externalId","productId","variantId","itemName","quantity"]}}},"required":["id","externalId","providerOrderId","orderNumber","displayName","creatorTag","syncedBy","createdAt","receivedAt","updatedAt","completedAt","queue","lines"]}},"nextCursor":{"type":["string","null"]}},"required":["orders","nextCursor"]},"example":{"orders":[{"id":"wshop_o_example","externalId":"order-example","providerOrderId":"api:order-example","orderNumber":null,"displayName":"Mads E.","creatorTag":"api","syncedBy":"api","createdAt":"2026-11-13T12:00:00.000Z","receivedAt":"2026-11-13T12:00:00.000Z","updatedAt":"2026-11-13T12:00:00.000Z","completedAt":null,"queue":{"hidden":true,"position":null,"preparing":true},"lines":[{"externalId":"line-example","productId":"product-example","itemName":"Boosterpakke","quantity":2,"id":"wshop_ol_example","variantId":null}]}],"nextCursor":null}}}},"400":{"description":"Ugyldigt input: invalid_request.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"invalid_request"}}}},"401":{"description":"Manglende eller ugyldig Bearer-nøgle: invalid_credential.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}},"WWW-Authenticate":{"description":"Bearer","schema":{"type":"string","const":"Bearer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"invalid_credential"}}}},"403":{"description":"Adgang nægtet: nøgle, scope, ejerskab eller godkendelse er ikke længere gyldig.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"access_denied"}}}},"404":{"description":"Ressourcen findes ikke eller er ikke tilgængelig.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"order_not_found"}}}},"405":{"description":"HTTP-metoden understøttes ikke. Svaret genereres af Next.js."},"503":{"description":"Lager eller behandling er utilgængelig. Ingen interne fejl eller skemadetaljer udleveres i produktion.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"service_unavailable"}}}}},"x-codeSamples":[{"lang":"Shell","source":"curl --request GET 'https://www.tcgm.dk/api/v1/webshop/orders?organization=org_example&webshop=wshop_example' \\\n  --header 'Authorization: Bearer <api-nøgle>'"}]},"post":{"operationId":"public_ordrer_opret","tags":["Ordrer"],"summary":"Opret en ordre","description":"Opretter en ordre og starter forberedelse til køen. Registrerer 4 øre ekskl. moms.\n\nAdgang: TCGM Bearer-nøgle. Organisation og ressource skal være godkendte, aktive og have aktuelt ejerskab hos nøglens organisation. Nøglen skal have det relevante scope og adgang til ressourcen.\n\nJSON-body må højst fylde 256 KiB. Ukendte bodyfelter afvises. Identiske genforsøg med samme Idempotency-Key returnerer det oprindelige resultat; ændret indhold giver 409. Genbrug nøglen ved usikkert udfald.\n\nAdgang og ejerskab kontrolleres også ved genforsøg og før beskyttet baggrundsarbejde. En senere fejl fortryder ikke automatisk allerede gennemførte ændringer.\n\nqueue.preparing er først true. Forberedelse kan vise en ikke-draft ordre; draft forbliver skjult. Et eksplicit køvalg annullerer automatisk visning. Hent ordren for dens nyeste tilstand og brug eventId til behandlingsstatus.\n\nannounceTwitch er false som standard. true anmoder om annoncering under de gældende samtykke- og adgangskrav; det garanterer ikke levering.\n\nEksisterende externalId giver konflikt. Oprettelse registrerer 4 øre; indledende forberedelse og visning er inkluderet. Eventuel annoncering registrerer 4 øre. Alle beløb er ekskl. moms og følger ordrens låste pris og loft.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"1–200 synlige ASCII-tegn uden mellemrum. Genbrug ved genforsøg; ny nøgle til en ny handling.","schema":{"type":"string","minLength":1,"maxLength":200,"pattern":"^[\\x21-\\x7e]+$"},"example":"example-operation-1"}],"security":[{"bearerAuth":[]}],"x-required-scope":"webshop:orders:create","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"organization":{"type":"string","minLength":1,"maxLength":200,"description":"Trimmes før validering."},"webshop":{"type":"string","minLength":1,"maxLength":200,"description":"Trimmes før validering."},"data":{"type":"object","properties":{"displayName":{"type":"string","minLength":1,"maxLength":500,"description":"Trimmes før validering."},"customerName":{"type":"string","minLength":1,"maxLength":500,"description":"Trimmes før validering."},"orderNumber":{"type":["string","null"],"minLength":1,"maxLength":200,"description":"Trimmes før validering."},"lines":{"type":"array","items":{"type":"object","properties":{"externalId":{"type":"string","minLength":1,"maxLength":200,"description":"Trimmes før validering."},"productId":{"type":"string","minLength":1,"maxLength":200,"description":"Trimmes før validering."},"variantId":{"type":["string","null"],"minLength":1,"maxLength":200,"description":"Trimmes før validering.","default":null},"itemName":{"type":"string","minLength":1,"maxLength":500,"description":"Trimmes før validering."},"quantity":{"type":"number","minimum":0,"maximum":90071992547409.9,"multipleOf":0.01,"description":"Endeligt tal med højst to decimaler."}},"required":["externalId","productId","itemName","quantity"],"additionalProperties":false},"maxItems":250,"description":"externalId skal være unik blandt linjerne. Tom liste accepteres."},"externalId":{"type":"string","minLength":1,"maxLength":200,"description":"Trimmes før validering."},"draft":{"type":"boolean","default":false},"announceTwitch":{"type":"boolean","default":false},"customerEmail":{"type":"string","format":"email","maxLength":320,"description":"Trimmes. Bruges til Twitch-match; rå e-mail gemmes ikke i ordre eller workflow."},"shopifyOrderId":{"type":"string","pattern":"^\\d+$","description":"Præcist Shopify-ordre-ID, hvis ordren skal forbindes med senere Shopify-leverancer."}},"required":["externalId","displayName","lines"],"additionalProperties":false}},"required":["organization","webshop","data"],"additionalProperties":false},"example":{"organization":"org_example","webshop":"wshop_example","data":{"externalId":"order-example","displayName":"Mads Eksempel","lines":[{"externalId":"line-example","productId":"product-example","itemName":"Boosterpakke","quantity":2}]}}}}},"responses":{"201":{"description":"Ordreobjektet direkte, med eventId; ikke pakket ind i order.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"externalId":{"type":"string"},"providerOrderId":{"type":"string"},"orderNumber":{"type":["string","null"]},"displayName":{"type":"string","description":"Visningssikkert navn. Fuldt kundenavn og e-mailhash returneres ikke."},"creatorTag":{"type":["string","null"]},"syncedBy":{"type":["string","null"]},"createdAt":{"type":"string"},"receivedAt":{"type":"string"},"updatedAt":{"type":"string"},"completedAt":{"type":["string","null"]},"queue":{"type":"object","properties":{"hidden":{"type":"boolean"},"position":{"type":["number","null"]},"preparing":{"type":"boolean"}},"required":["hidden","position","preparing"]},"lines":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"externalId":{"type":"string"},"productId":{"type":"string"},"variantId":{"type":["string","null"]},"itemName":{"type":"string"},"quantity":{"type":"number"}},"required":["id","externalId","productId","variantId","itemName","quantity"]}},"eventId":{"type":"string"}},"required":["id","externalId","providerOrderId","orderNumber","displayName","creatorTag","syncedBy","createdAt","receivedAt","updatedAt","completedAt","queue","lines","eventId"]},"example":{"id":"wshop_o_example","externalId":"order-example","providerOrderId":"api:order-example","orderNumber":null,"displayName":"Mads E.","creatorTag":"api","syncedBy":"api","createdAt":"2026-11-13T12:00:00.000Z","receivedAt":"2026-11-13T12:00:00.000Z","updatedAt":"2026-11-13T12:00:00.000Z","completedAt":null,"queue":{"hidden":true,"position":null,"preparing":true},"lines":[{"externalId":"line-example","productId":"product-example","itemName":"Boosterpakke","quantity":2,"id":"wshop_ol_example","variantId":null}],"eventId":"api_ev_example"}}}},"400":{"description":"Ugyldigt input: invalid_request.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"invalid_request"}}}},"401":{"description":"Manglende eller ugyldig Bearer-nøgle: invalid_credential.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}},"WWW-Authenticate":{"description":"Bearer","schema":{"type":"string","const":"Bearer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"invalid_credential"}}}},"403":{"description":"Adgang nægtet: nøgle, scope, ejerskab eller godkendelse er ikke længere gyldig.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"access_denied"}}}},"404":{"description":"Ressourcen findes ikke eller er ikke tilgængelig.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"order_not_found"}}}},"405":{"description":"HTTP-metoden understøttes ikke. Svaret genereres af Next.js."},"409":{"description":"Konflikt: fx idempotency_conflict, external_id_conflict eller order_closed. Samme nøgle med andet valideret indhold afvises.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"idempotency_conflict"}}}},"413":{"description":"JSON-body overstiger 256 KiB.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"request_too_large"}}}},"415":{"description":"Content-Type skal være application/json.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"json_required"}}}},"503":{"description":"Lager eller behandling er utilgængelig. Ingen interne fejl eller skemadetaljer udleveres i produktion.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"service_unavailable"}}}}},"x-codeSamples":[{"lang":"Shell","source":"curl --request POST 'https://www.tcgm.dk/api/v1/webshop/orders' \\\n  --header 'Authorization: Bearer <api-nøgle>' \\\n  --header 'Content-Type: application/json' \\\n  --header 'Idempotency-Key: example-operation-1' \\\n  --data '{\n  \"organization\": \"org_example\",\n  \"webshop\": \"wshop_example\",\n  \"data\": {\n    \"externalId\": \"order-example\",\n    \"displayName\": \"Mads Eksempel\",\n    \"lines\": [\n      {\n        \"externalId\": \"line-example\",\n        \"productId\": \"product-example\",\n        \"itemName\": \"Boosterpakke\",\n        \"quantity\": 2\n      }\n    ]\n  }\n}'"}]}},"/api/v1/webshop/orders/{orderid}":{"get":{"operationId":"public_ordrer_hent","tags":["Ordrer"],"summary":"Hent en ordre","description":"Henter ordrens indhold og køstatus. Ændrer ingen data og registrerer ikke forbrug.\n\nAdgang: TCGM Bearer-nøgle. Organisation og ressource skal være godkendte, aktive og have aktuelt ejerskab hos nøglens organisation. Nøglen skal have det relevante scope og adgang til ressourcen.\n\nqueue.position er null for skjulte eller afsluttede ordrer. queue.preparing beskriver fortsat forberedelse.","parameters":[{"name":"orderid","in":"path","required":true,"description":"TCGM-ordrens id fra oprettelsessvaret eller et ordreopslag (wshop_o_…). Brug ikke externalId, providerOrderId eller orderNumber.","schema":{"type":"string"},"example":"wshop_o_example"},{"name":"organization","in":"query","required":true,"description":"Organisationens ID fra /api/v1/access.","schema":{"type":"string","minLength":1,"maxLength":200,"description":"Trimmes før validering."},"example":"org_example"},{"name":"webshop","in":"query","required":true,"description":"Netbutikkens ID fra /api/v1/access.","schema":{"type":"string","minLength":1,"maxLength":200,"description":"Trimmes før validering."},"example":"wshop_example"}],"security":[{"bearerAuth":[]}],"x-required-scope":"webshop:orders:read","responses":{"200":{"description":"Den aktuelle ordre.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"order":{"type":"object","properties":{"id":{"type":"string"},"externalId":{"type":"string"},"providerOrderId":{"type":"string"},"orderNumber":{"type":["string","null"]},"displayName":{"type":"string","description":"Visningssikkert navn. Fuldt kundenavn og e-mailhash returneres ikke."},"creatorTag":{"type":["string","null"]},"syncedBy":{"type":["string","null"]},"createdAt":{"type":"string"},"receivedAt":{"type":"string"},"updatedAt":{"type":"string"},"completedAt":{"type":["string","null"]},"queue":{"type":"object","properties":{"hidden":{"type":"boolean"},"position":{"type":["number","null"]},"preparing":{"type":"boolean"}},"required":["hidden","position","preparing"]},"lines":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"externalId":{"type":"string"},"productId":{"type":"string"},"variantId":{"type":["string","null"]},"itemName":{"type":"string"},"quantity":{"type":"number"}},"required":["id","externalId","productId","variantId","itemName","quantity"]}}},"required":["id","externalId","providerOrderId","orderNumber","displayName","creatorTag","syncedBy","createdAt","receivedAt","updatedAt","completedAt","queue","lines"]}},"required":["order"]},"example":{"order":{"id":"wshop_o_example","externalId":"order-example","providerOrderId":"api:order-example","orderNumber":null,"displayName":"Mads E.","creatorTag":"api","syncedBy":"api","createdAt":"2026-11-13T12:00:00.000Z","receivedAt":"2026-11-13T12:00:00.000Z","updatedAt":"2026-11-13T12:00:00.000Z","completedAt":null,"queue":{"hidden":true,"position":null,"preparing":true},"lines":[{"externalId":"line-example","productId":"product-example","itemName":"Boosterpakke","quantity":2,"id":"wshop_ol_example","variantId":null}]}}}}},"400":{"description":"Ugyldigt input: invalid_request.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"invalid_request"}}}},"401":{"description":"Manglende eller ugyldig Bearer-nøgle: invalid_credential.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}},"WWW-Authenticate":{"description":"Bearer","schema":{"type":"string","const":"Bearer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"invalid_credential"}}}},"403":{"description":"Adgang nægtet: nøgle, scope, ejerskab eller godkendelse er ikke længere gyldig.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"access_denied"}}}},"404":{"description":"Ressourcen findes ikke eller er ikke tilgængelig.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"order_not_found"}}}},"405":{"description":"HTTP-metoden understøttes ikke. Svaret genereres af Next.js."},"503":{"description":"Lager eller behandling er utilgængelig. Ingen interne fejl eller skemadetaljer udleveres i produktion.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"service_unavailable"}}}}},"x-codeSamples":[{"lang":"Shell","source":"curl --request GET 'https://www.tcgm.dk/api/v1/webshop/orders/wshop_o_example?organization=org_example&webshop=wshop_example' \\\n  --header 'Authorization: Bearer <api-nøgle>'"}]},"post":{"operationId":"public_ordrer_opdater","tags":["Ordrer"],"summary":"Opdatér en ordre","description":"Starter en opdatering af ordrens indhold. En indholdsændring registrerer 2 øre ekskl. moms.\n\nAdgang: TCGM Bearer-nøgle. Organisation og ressource skal være godkendte, aktive og have aktuelt ejerskab hos nøglens organisation. Nøglen skal have det relevante scope og adgang til ressourcen.\n\nJSON-body må højst fylde 256 KiB. Ukendte bodyfelter afvises. Identiske genforsøg med samme Idempotency-Key returnerer det oprindelige resultat; ændret indhold giver 409. Genbrug nøglen ved usikkert udfald.\n\nAdgang og ejerskab kontrolleres også ved genforsøg og før beskyttet baggrundsarbejde. En senere fejl fortryder ikke automatisk allerede gennemførte ændringer.\n\nUdeladte felter bevares; orderNumber: null rydder nummeret. lines erstatter linjesættet og bevarer ID'er og skjult-status for eksisterende eksterne linjereferencer.\n\nAfsluttede ordrer kan ikke ændres. Indholdsændringer registrerer 2 øre under ordrens låste pris og loft. Opdateringen kan følge eksisterende aktive Shopify-indstillinger for annoncering; den skriver ikke tilbage til Shopify.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"1–200 synlige ASCII-tegn uden mellemrum. Genbrug ved genforsøg; ny nøgle til en ny handling.","schema":{"type":"string","minLength":1,"maxLength":200,"pattern":"^[\\x21-\\x7e]+$"},"example":"example-operation-1"},{"name":"orderid","in":"path","required":true,"description":"TCGM-ordrens id fra oprettelsessvaret eller et ordreopslag (wshop_o_…). Brug ikke externalId, providerOrderId eller orderNumber.","schema":{"type":"string"},"example":"wshop_o_example"}],"security":[{"bearerAuth":[]}],"x-required-scope":"webshop:orders:update","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"organization":{"type":"string","minLength":1,"maxLength":200,"description":"Trimmes før validering."},"webshop":{"type":"string","minLength":1,"maxLength":200,"description":"Trimmes før validering."},"data":{"type":"object","properties":{"displayName":{"type":"string","minLength":1,"maxLength":500,"description":"Trimmes før validering."},"customerName":{"type":"string","minLength":1,"maxLength":500,"description":"Trimmes før validering."},"orderNumber":{"type":["string","null"],"minLength":1,"maxLength":200,"description":"Trimmes før validering."},"lines":{"type":"array","items":{"type":"object","properties":{"externalId":{"type":"string","minLength":1,"maxLength":200,"description":"Trimmes før validering."},"productId":{"type":"string","minLength":1,"maxLength":200,"description":"Trimmes før validering."},"variantId":{"type":["string","null"],"minLength":1,"maxLength":200,"description":"Trimmes før validering.","default":null},"itemName":{"type":"string","minLength":1,"maxLength":500,"description":"Trimmes før validering."},"quantity":{"type":"number","minimum":0,"maximum":90071992547409.9,"multipleOf":0.01,"description":"Endeligt tal med højst to decimaler."}},"required":["externalId","productId","itemName","quantity"],"additionalProperties":false},"maxItems":250,"description":"externalId skal være unik blandt linjerne. Tom liste accepteres."}},"required":[],"additionalProperties":false,"minProperties":1}},"required":["organization","webshop","data"],"additionalProperties":false},"example":{"organization":"org_example","webshop":"wshop_example","data":{"displayName":"Mads Eksempel"}}}}},"responses":{"202":{"description":"Accepteret; følg eventId for resultatet.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"eventId":{"type":"string"}},"required":["eventId"]},"example":{"eventId":"api_ev_example"}}}},"400":{"description":"Ugyldigt input: invalid_request.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"invalid_request"}}}},"401":{"description":"Manglende eller ugyldig Bearer-nøgle: invalid_credential.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}},"WWW-Authenticate":{"description":"Bearer","schema":{"type":"string","const":"Bearer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"invalid_credential"}}}},"403":{"description":"Adgang nægtet: nøgle, scope, ejerskab eller godkendelse er ikke længere gyldig.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"access_denied"}}}},"404":{"description":"Ressourcen findes ikke eller er ikke tilgængelig.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"order_not_found"}}}},"405":{"description":"HTTP-metoden understøttes ikke. Svaret genereres af Next.js."},"409":{"description":"Konflikt: fx idempotency_conflict, external_id_conflict eller order_closed. Samme nøgle med andet valideret indhold afvises.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"idempotency_conflict"}}}},"413":{"description":"JSON-body overstiger 256 KiB.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"request_too_large"}}}},"415":{"description":"Content-Type skal være application/json.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"json_required"}}}},"503":{"description":"Lager eller behandling er utilgængelig. Ingen interne fejl eller skemadetaljer udleveres i produktion.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"service_unavailable"}}}}},"x-codeSamples":[{"lang":"Shell","source":"curl --request POST 'https://www.tcgm.dk/api/v1/webshop/orders/wshop_o_example' \\\n  --header 'Authorization: Bearer <api-nøgle>' \\\n  --header 'Content-Type: application/json' \\\n  --header 'Idempotency-Key: example-operation-1' \\\n  --data '{\n  \"organization\": \"org_example\",\n  \"webshop\": \"wshop_example\",\n  \"data\": {\n    \"displayName\": \"Mads Eksempel\"\n  }\n}'"}]},"delete":{"operationId":"public_ordrer_afslut","tags":["Ordrer"],"summary":"Afslut en ordre","description":"Afslutter ordren og registrerer slutforbrug op til ordrens prisloft. Ordren slettes ikke.\n\nAdgang: TCGM Bearer-nøgle. Organisation og ressource skal være godkendte, aktive og have aktuelt ejerskab hos nøglens organisation. Nøglen skal have det relevante scope og adgang til ressourcen.\n\nJSON-body må højst fylde 256 KiB. Ukendte bodyfelter afvises. Identiske genforsøg med samme Idempotency-Key returnerer det oprindelige resultat; ændret indhold giver 409. Genbrug nøglen ved usikkert udfald.\n\nAdgang og ejerskab kontrolleres også ved genforsøg og før beskyttet baggrundsarbejde. En senere fejl fortryder ikke automatisk allerede gennemførte ændringer.\n\ndata kan udelades eller være {}. Send ikke orderId i body. Allerede afsluttet ordre er en gratis no-op.\n\nAfslutning anvender den eksisterende slutafregning op til ordrens prisloft på 25 øre ekskl. moms; allerede låste priser bevares. API'et tilbyder ikke genåbning.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"1–200 synlige ASCII-tegn uden mellemrum. Genbrug ved genforsøg; ny nøgle til en ny handling.","schema":{"type":"string","minLength":1,"maxLength":200,"pattern":"^[\\x21-\\x7e]+$"},"example":"example-operation-1"},{"name":"orderid","in":"path","required":true,"description":"TCGM-ordrens id fra oprettelsessvaret eller et ordreopslag (wshop_o_…). Brug ikke externalId, providerOrderId eller orderNumber.","schema":{"type":"string"},"example":"wshop_o_example"}],"security":[{"bearerAuth":[]}],"x-required-scope":"webshop:orders:complete","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"organization":{"type":"string","minLength":1,"maxLength":200,"description":"Trimmes før validering."},"webshop":{"type":"string","minLength":1,"maxLength":200,"description":"Trimmes før validering."},"data":{"type":"object","properties":{},"required":[],"additionalProperties":false,"default":{}}},"required":["organization","webshop"],"additionalProperties":false},"example":{"organization":"org_example","webshop":"wshop_example"}}}},"responses":{"200":{"description":"Afsluttet eller allerede afsluttet.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","const":"succeeded"},"orderId":{"type":"string"},"changed":{"type":"boolean"},"action":{"type":"string","enum":["create","update","queue-state","complete"]},"announceTwitch":{"type":"boolean"},"order":{"type":"object","properties":{"id":{"type":"string"},"externalId":{"type":"string"},"providerOrderId":{"type":"string"},"orderNumber":{"type":["string","null"]},"displayName":{"type":"string","description":"Visningssikkert navn. Fuldt kundenavn og e-mailhash returneres ikke."},"creatorTag":{"type":["string","null"]},"syncedBy":{"type":["string","null"]},"createdAt":{"type":"string"},"receivedAt":{"type":"string"},"updatedAt":{"type":"string"},"completedAt":{"type":["string","null"]},"queue":{"type":"object","properties":{"hidden":{"type":"boolean"},"position":{"type":["number","null"]},"preparing":{"type":"boolean"}},"required":["hidden","position","preparing"]},"lines":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"externalId":{"type":"string"},"productId":{"type":"string"},"variantId":{"type":["string","null"]},"itemName":{"type":"string"},"quantity":{"type":"number"}},"required":["id","externalId","productId","variantId","itemName","quantity"]}}},"required":["id","externalId","providerOrderId","orderNumber","displayName","creatorTag","syncedBy","createdAt","receivedAt","updatedAt","completedAt","queue","lines"]}},"required":["status","orderId","changed"]},"example":{"status":"succeeded","action":"complete","orderId":"wshop_o_example","changed":true}}}},"400":{"description":"Ugyldigt input: invalid_request.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"invalid_request"}}}},"401":{"description":"Manglende eller ugyldig Bearer-nøgle: invalid_credential.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}},"WWW-Authenticate":{"description":"Bearer","schema":{"type":"string","const":"Bearer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"invalid_credential"}}}},"403":{"description":"Adgang nægtet: nøgle, scope, ejerskab eller godkendelse er ikke længere gyldig. Direkte handlinger kan også returnere status=failed og en forretningsfejl.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},{"type":"object","properties":{"status":{"type":"string","const":"failed"},"error":{"type":"string","enum":["access_revoked","order_not_found","order_closed","external_id_conflict","queue_unavailable","queue_position_limit"]}},"required":["status","error"]}]},"example":{"error":"access_denied"}}}},"404":{"description":"Ressourcen findes ikke eller er ikke tilgængelig. Direkte handlinger kan også returnere status=failed og en forretningsfejl.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},{"type":"object","properties":{"status":{"type":"string","const":"failed"},"error":{"type":"string","enum":["access_revoked","order_not_found","order_closed","external_id_conflict","queue_unavailable","queue_position_limit"]}},"required":["status","error"]}]},"example":{"error":"order_not_found"}}}},"405":{"description":"HTTP-metoden understøttes ikke. Svaret genereres af Next.js."},"409":{"description":"Konflikt: fx idempotency_conflict, external_id_conflict eller order_closed. Samme nøgle med andet valideret indhold afvises. Direkte handlinger kan også returnere status=failed og en forretningsfejl.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},{"type":"object","properties":{"status":{"type":"string","const":"failed"},"error":{"type":"string","enum":["access_revoked","order_not_found","order_closed","external_id_conflict","queue_unavailable","queue_position_limit"]}},"required":["status","error"]}]},"example":{"error":"idempotency_conflict"}}}},"413":{"description":"JSON-body overstiger 256 KiB.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"request_too_large"}}}},"415":{"description":"Content-Type skal være application/json.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"json_required"}}}},"503":{"description":"Lager eller behandling er utilgængelig. Ingen interne fejl eller skemadetaljer udleveres i produktion.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"service_unavailable"}}}}},"x-codeSamples":[{"lang":"Shell","source":"curl --request DELETE 'https://www.tcgm.dk/api/v1/webshop/orders/wshop_o_example' \\\n  --header 'Authorization: Bearer <api-nøgle>' \\\n  --header 'Content-Type: application/json' \\\n  --header 'Idempotency-Key: example-operation-1' \\\n  --data '{\n  \"organization\": \"org_example\",\n  \"webshop\": \"wshop_example\"\n}'"}]}},"/api/v1/webshop/events/{eventid}":{"get":{"operationId":"public_behandling_status","tags":["Behandling"],"summary":"Hent behandlingsstatus","description":"Henter status for en ordreoprettelse eller opdatering. Ændrer ingen data.\n\nAdgang: TCGM Bearer-nøgle. Organisation og ressource skal være godkendte, aktive og have aktuelt ejerskab hos nøglens organisation. Nøglen skal have det relevante scope og adgang til ressourcen.\n\npending afventer behandling; running behandles; completed er gennemført; failed er fejlet eller annulleret. Stop polling ved completed/failed og brug et passende interval samt backoff ved fejl.\n\nUtilgængelig workflowhistorik giver 503 frem for en gættet status. Hent selve ordren for aktuel køtilstand. completed er ikke garanti for en leveret Twitch-besked.","parameters":[{"name":"eventid","in":"path","required":true,"description":"Det eventId, som ordreoprettelse eller -opdatering returnerer (api_ev_…).","schema":{"type":"string"},"example":"api_ev_example"},{"name":"organization","in":"query","required":true,"description":"Organisationens ID fra /api/v1/access.","schema":{"type":"string","minLength":1,"maxLength":200,"description":"Trimmes før validering."},"example":"org_example"},{"name":"webshop","in":"query","required":true,"description":"Netbutikkens ID fra /api/v1/access.","schema":{"type":"string","minLength":1,"maxLength":200,"description":"Trimmes før validering."},"example":"wshop_example"}],"security":[{"bearerAuth":[]}],"x-required-scope":"webshop:events:read","responses":{"200":{"description":"Kun behandlingsstatus, uden workflow-ID'er eller interne fejl.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["pending","running","completed","failed"]}},"required":["status"]},"example":{"status":"running"}}}},"400":{"description":"Ugyldigt input: invalid_request.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"invalid_request"}}}},"401":{"description":"Manglende eller ugyldig Bearer-nøgle: invalid_credential.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}},"WWW-Authenticate":{"description":"Bearer","schema":{"type":"string","const":"Bearer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"invalid_credential"}}}},"403":{"description":"Adgang nægtet: nøgle, scope, ejerskab eller godkendelse er ikke længere gyldig.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"access_denied"}}}},"404":{"description":"Ressourcen findes ikke eller er ikke tilgængelig.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"order_not_found"}}}},"405":{"description":"HTTP-metoden understøttes ikke. Svaret genereres af Next.js."},"503":{"description":"Lager eller behandling er utilgængelig. Ingen interne fejl eller skemadetaljer udleveres i produktion.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"service_unavailable"}}}}},"x-codeSamples":[{"lang":"Shell","source":"curl --request GET 'https://www.tcgm.dk/api/v1/webshop/events/api_ev_example?organization=org_example&webshop=wshop_example' \\\n  --header 'Authorization: Bearer <api-nøgle>'"}]}},"/api/v1/webshop/orders/queue-state":{"put":{"operationId":"public_ordrer_ko","tags":["Kø"],"summary":"Ændr synlighed og køplacering","description":"Ændrer synlighed og placering i køen. En ændring registrerer 2 øre ekskl. moms. Kræver Rip & Ship-adgang.\n\nAdgang: TCGM Bearer-nøgle. Organisation og ressource skal være godkendte, aktive og have aktuelt ejerskab hos nøglens organisation. Nøglen skal have det relevante scope og adgang til ressourcen. Kræver desuden aktuel Rip & Ship-adgang.\n\nJSON-body må højst fylde 256 KiB. Ukendte bodyfelter afvises. Identiske genforsøg med samme Idempotency-Key returnerer det oprindelige resultat; ændret indhold giver 409. Genbrug nøglen ved usikkert udfald.\n\nAdgang og ejerskab kontrolleres også ved genforsøg og før beskyttet baggrundsarbejde. En senere fejl fortryder ikke automatisk allerede gennemførte ændringer.\n\ncurrent bevarer placering; first og last placerer før eller efter andre synlige åbne ordrer. Skjulte ordrer kan også få en placering til senere visning. receivedAt ændres ikke.\n\nEt eksplicit valg annullerer automatisk forberedelse/visning, også hvis ordren allerede er skjult. Matchende tilstand er gratis; samlet ændring af synlighed og placering tæller som én handling til 2 øre ekskl. moms under prisloftet. Ingen annoncering udløses.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"1–200 synlige ASCII-tegn uden mellemrum. Genbrug ved genforsøg; ny nøgle til en ny handling.","schema":{"type":"string","minLength":1,"maxLength":200,"pattern":"^[\\x21-\\x7e]+$"},"example":"example-operation-1"}],"security":[{"bearerAuth":[]}],"x-required-scope":"webshop:orders:queue","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"organization":{"type":"string","minLength":1,"maxLength":200,"description":"Trimmes før validering."},"webshop":{"type":"string","minLength":1,"maxLength":200,"description":"Trimmes før validering."},"data":{"type":"object","properties":{"orderId":{"type":"string","minLength":1,"maxLength":200,"description":"Trimmes før validering."},"visibility":{"type":"string","enum":["show","hide"]},"position":{"type":"string","enum":["current","first","last"]}},"required":["orderId","visibility","position"],"additionalProperties":false}},"required":["organization","webshop","data"],"additionalProperties":false},"example":{"organization":"org_example","webshop":"wshop_example","data":{"orderId":"wshop_o_example","visibility":"show","position":"last"}}}}},"responses":{"200":{"description":"Køtilstand opdateret eller allerede som ønsket.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","const":"succeeded"},"orderId":{"type":"string"},"changed":{"type":"boolean"},"action":{"type":"string","enum":["create","update","queue-state","complete"]},"announceTwitch":{"type":"boolean"},"order":{"type":"object","properties":{"id":{"type":"string"},"externalId":{"type":"string"},"providerOrderId":{"type":"string"},"orderNumber":{"type":["string","null"]},"displayName":{"type":"string","description":"Visningssikkert navn. Fuldt kundenavn og e-mailhash returneres ikke."},"creatorTag":{"type":["string","null"]},"syncedBy":{"type":["string","null"]},"createdAt":{"type":"string"},"receivedAt":{"type":"string"},"updatedAt":{"type":"string"},"completedAt":{"type":["string","null"]},"queue":{"type":"object","properties":{"hidden":{"type":"boolean"},"position":{"type":["number","null"]},"preparing":{"type":"boolean"}},"required":["hidden","position","preparing"]},"lines":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"externalId":{"type":"string"},"productId":{"type":"string"},"variantId":{"type":["string","null"]},"itemName":{"type":"string"},"quantity":{"type":"number"}},"required":["id","externalId","productId","variantId","itemName","quantity"]}}},"required":["id","externalId","providerOrderId","orderNumber","displayName","creatorTag","syncedBy","createdAt","receivedAt","updatedAt","completedAt","queue","lines"]}},"required":["status","orderId","changed"]},"example":{"status":"succeeded","action":"queue-state","orderId":"wshop_o_example","changed":true}}}},"400":{"description":"Ugyldigt input: invalid_request.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"invalid_request"}}}},"401":{"description":"Manglende eller ugyldig Bearer-nøgle: invalid_credential.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}},"WWW-Authenticate":{"description":"Bearer","schema":{"type":"string","const":"Bearer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"invalid_credential"}}}},"403":{"description":"Adgang nægtet: nøgle, scope, ejerskab eller godkendelse er ikke længere gyldig. Direkte handlinger kan også returnere status=failed og en forretningsfejl.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},{"type":"object","properties":{"status":{"type":"string","const":"failed"},"error":{"type":"string","enum":["access_revoked","order_not_found","order_closed","external_id_conflict","queue_unavailable","queue_position_limit"]}},"required":["status","error"]}]},"example":{"error":"access_denied"}}}},"404":{"description":"Ressourcen findes ikke eller er ikke tilgængelig. Direkte handlinger kan også returnere status=failed og en forretningsfejl.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},{"type":"object","properties":{"status":{"type":"string","const":"failed"},"error":{"type":"string","enum":["access_revoked","order_not_found","order_closed","external_id_conflict","queue_unavailable","queue_position_limit"]}},"required":["status","error"]}]},"example":{"error":"order_not_found"}}}},"405":{"description":"HTTP-metoden understøttes ikke. Svaret genereres af Next.js."},"409":{"description":"Konflikt: fx idempotency_conflict, external_id_conflict eller order_closed. Samme nøgle med andet valideret indhold afvises. Direkte handlinger kan også returnere status=failed og en forretningsfejl.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},{"type":"object","properties":{"status":{"type":"string","const":"failed"},"error":{"type":"string","enum":["access_revoked","order_not_found","order_closed","external_id_conflict","queue_unavailable","queue_position_limit"]}},"required":["status","error"]}]},"example":{"error":"idempotency_conflict"}}}},"413":{"description":"JSON-body overstiger 256 KiB.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"request_too_large"}}}},"415":{"description":"Content-Type skal være application/json.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"json_required"}}}},"503":{"description":"Lager eller behandling er utilgængelig. Ingen interne fejl eller skemadetaljer udleveres i produktion.","headers":{"Cache-Control":{"description":"no-store","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"example":{"error":"service_unavailable"}}}}},"x-codeSamples":[{"lang":"Shell","source":"curl --request PUT 'https://www.tcgm.dk/api/v1/webshop/orders/queue-state' \\\n  --header 'Authorization: Bearer <api-nøgle>' \\\n  --header 'Content-Type: application/json' \\\n  --header 'Idempotency-Key: example-operation-1' \\\n  --data '{\n  \"organization\": \"org_example\",\n  \"webshop\": \"wshop_example\",\n  \"data\": {\n    \"orderId\": \"wshop_o_example\",\n    \"visibility\": \"show\",\n    \"position\": \"last\"\n  }\n}'"}]}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}}}}