{
  "openapi": "3.1.0",
  "info": {
    "title": "vaschego för AI-agenter",
    "version": "1.1.0",
    "description": "REST-fasad över vaschegos MCP-verktyg. Utan token nås demoorganisationerna (ange `org`). Med `Authorization: Bearer <token>` (utfärdad av en organisation under Integrationer) nås den organisationen; `org` utelämnas då. Lediga pass bär `bookUrl` — en direktlänk som öppnar bokningen på resurssidan; föredra den framför att boka åt någon.",
    "contact": { "email": "hej@vaschego.se" }
  },
  "servers": [{ "url": "https://www.vaschego.se/api/mcp/rest" }],
  "components": {
    "securitySchemes": { "orgToken": { "type": "http", "scheme": "bearer", "description": "Organisationens MCP-token (booking- eller admin-scope). Utelämna för demoläge." } },
    "schemas": {
      "Organization": { "type": "object", "properties": { "slug": { "type": "string" }, "name": { "type": "string" }, "accountType": { "type": "string" }, "url": { "type": "string" } } },
      "Resource": { "type": "object", "properties": { "resource_id": { "type": "string" }, "resource_slug": { "type": "string" }, "name": { "type": "string" }, "status": { "type": "string" }, "booking_model": { "type": "string" }, "building_label": { "type": "string", "nullable": true } } },
      "Block": { "type": "object", "properties": { "blockId": { "type": "string" }, "label": { "type": "string" }, "start": { "type": "string" }, "end": { "type": "string" }, "free": { "type": "boolean" }, "bookedBy": { "type": "string" }, "bookUrl": { "type": "string", "description": "Direktlänk som öppnar bokningen på resurssidan (bara när free=true)." } } },
      "BookingRequest": { "type": "object", "required": ["resource", "date", "blockId", "bookedBy"], "properties": { "org": { "type": "string", "description": "Demo-organisationens slug (bara utan token)" }, "resource": { "type": "string", "description": "Resursens slug eller id" }, "date": { "type": "string", "format": "date" }, "blockId": { "type": "string" }, "bookedBy": { "type": "string", "description": "Vem bokningen gäller (namn eller lägenhet)" } } }
    }
  },
  "security": [{}, { "orgToken": [] }],
  "paths": {
    "/organizations": { "get": { "operationId": "listOrganizations", "summary": "Demoorganisationerna (bara utan token)", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "organizations": { "type": "array", "items": { "$ref": "#/components/schemas/Organization" } } } } } } } } } },
    "/resources": { "get": { "operationId": "listResources", "summary": "Resurser med status just nu", "parameters": [{ "name": "org", "in": "query", "schema": { "type": "string" }, "description": "Demo-slug (bara utan token)" }], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "resources": { "type": "array", "items": { "$ref": "#/components/schemas/Resource" } } } } } } } } } },
    "/availability": { "get": { "operationId": "getAvailability", "summary": "Lediga och upptagna pass för ett datum, med bookUrl per ledigt pass", "parameters": [{ "name": "org", "in": "query", "schema": { "type": "string" } }, { "name": "resource", "in": "query", "required": true, "schema": { "type": "string" } }, { "name": "date", "in": "query", "required": true, "schema": { "type": "string", "format": "date" } }], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "resource": { "type": "string" }, "date": { "type": "string" }, "blocks": { "type": "array", "items": { "$ref": "#/components/schemas/Block" } } } } } } }, "400": { "description": "Okänd resurs eller ogiltigt datum" } } } },
    "/bookings": {
      "post": { "operationId": "bookSlot", "summary": "Boka ett pass (misslyckas om upptaget)", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BookingRequest" } } } }, "responses": { "201": { "description": "Bokat" }, "400": { "description": "Upptaget, okänd resurs eller ogiltiga fält" } } },
      "delete": { "operationId": "cancelBooking", "summary": "Avboka ett pass som bokats under samma identitet", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BookingRequest" } } } }, "responses": { "200": { "description": "Avbokat" }, "400": { "description": "Ingen bokning för identiteten" } } }
    }
  }
}
