{ "paths": { "/availability/aggregate": { "get": { "tags": ["Availability"], "summary": "Get aggregate availability (public)", "description": "Returns merged busy time blocks across multiple calendars by their public tokens. No authentication required.", "operationId": "getAvailabilityAggregate", "parameters": [ { "name": "tokens", "in": "query", "required": true, "schema": { "type": "string", "description": "Comma-separated calendar tokens from ical_url" }, "description": "Calendar tokens" }, { "name": "start", "in": "query", "required": true, "schema": { "type": "string", "format": "date-time" }, "description": "Range start (RFC3339)" }, { "name": "end", "in": "query", "required": true, "schema": { "type": "string", "format": "date-time" }, "description": "Range end (RFC3339)" } ], "responses": { "200": { "description": "Aggregate busy blocks", "content": { "application/json": { "schema": { "type": "object", "required": ["range_start", "range_end", "busy"], "properties": { "range_start": { "type": "string", "format": "date-time" }, "range_end": { "type": "string", "format": "date-time" }, "busy": { "type": "array", "items": { "$ref": "#/components/schemas/BusyBlock" } } } } } } }, "400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "security": [] } }, "/availability/{token}": { "get": { "tags": ["Availability"], "summary": "Get availability by token (public)", "description": "Returns busy time blocks for a calendar by its public token. No authentication required.", "operationId": "getAvailabilityByToken", "parameters": [ { "name": "token", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Calendar token from ical_url" }, { "name": "start", "in": "query", "required": true, "schema": { "type": "string", "format": "date-time" }, "description": "Range start (RFC3339)" }, { "name": "end", "in": "query", "required": true, "schema": { "type": "string", "format": "date-time" }, "description": "Range end (RFC3339)" } ], "responses": { "200": { "description": "Busy blocks for the calendar", "content": { "application/json": { "schema": { "type": "object", "required": ["calendar_id", "range_start", "range_end", "busy"], "properties": { "calendar_id": { "type": "string", "format": "uuid" }, "range_start": { "type": "string", "format": "date-time" }, "range_end": { "type": "string", "format": "date-time" }, "busy": { "type": "array", "items": { "$ref": "#/components/schemas/BusyBlock" } } } } } } }, "400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "404": { "description": "Calendar not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }, "security": [] } }, "/availability": { "get": { "tags": ["Availability"], "summary": "Get calendar availability", "description": "Returns busy time blocks for a calendar within a given range. Includes expanded recurring event occurrences. User must have at least viewer role on the calendar. Requires `availability:read` scope.", "operationId": "getAvailability", "parameters": [ { "name": "calendar_id", "in": "query", "required": true, "schema": { "type": "string", "format": "uuid" }, "description": "Calendar to query" }, { "name": "start", "in": "query", "required": true, "schema": { "type": "string", "format": "date-time" }, "description": "Range start (RFC3339)" }, { "name": "end", "in": "query", "required": true, "schema": { "type": "string", "format": "date-time" }, "description": "Range end (RFC3339)" } ], "responses": { "200": { "description": "Availability with busy blocks", "content": { "application/json": { "schema": { "type": "object", "required": ["calendar_id", "range_start", "range_end", "busy"], "properties": { "calendar_id": { "type": "string", "format": "uuid" }, "range_start": { "type": "string", "format": "date-time" }, "range_end": { "type": "string", "format": "date-time" }, "busy": { "type": "array", "items": { "$ref": "#/components/schemas/BusyBlock" } } } } } } }, "400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }, "403": { "description": "Insufficient scope or permission", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } } } } } }