{ "components": { "securitySchemes": { "BearerAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "JWT", "description": "JWT access token obtained from /auth/login or /auth/register" }, "ApiKeyAuth": { "type": "apiKey", "in": "header", "name": "X-API-Key", "description": "API key token for agent/programmatic access with scoped permissions" } }, "schemas": { "Error": { "type": "object", "required": ["error", "code"], "properties": { "error": { "type": "string", "description": "Human-readable error message" }, "code": { "type": "string", "description": "Machine-readable error code", "enum": ["VALIDATION_ERROR", "AUTH_REQUIRED", "AUTH_INVALID", "FORBIDDEN", "NOT_FOUND", "CONFLICT", "RATE_LIMITED", "INTERNAL"] }, "details": { "description": "Additional error context" } } }, "OkResponse": { "type": "object", "required": ["ok"], "properties": { "ok": { "type": "boolean", "example": true } } }, "PageInfo": { "type": "object", "required": ["limit", "next_cursor"], "properties": { "limit": { "type": "integer", "example": 50 }, "next_cursor": { "type": "string", "nullable": true, "description": "Opaque cursor for next page, null if no more results" } } }, "User": { "type": "object", "required": ["id", "email", "timezone", "created_at", "updated_at"], "properties": { "id": { "type": "string", "format": "uuid" }, "email": { "type": "string", "format": "email" }, "timezone": { "type": "string", "example": "America/New_York", "description": "IANA timezone name" }, "created_at": { "type": "string", "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" } } }, "Calendar": { "type": "object", "required": ["id", "name", "color", "is_public", "created_at", "updated_at"], "properties": { "id": { "type": "string", "format": "uuid" }, "name": { "type": "string", "minLength": 1, "maxLength": 80 }, "color": { "type": "string", "pattern": "^#[0-9A-Fa-f]{6}$", "example": "#22C55E" }, "is_public": { "type": "boolean" }, "ical_url": { "type": "string", "format": "uri", "description": "iCal feed URL. Present for both public and private calendars. Public calendars use a shorter token; private calendars use a 64-character SHA256 hex token for additional security." }, "role": { "type": "string", "enum": ["owner", "editor", "viewer"], "description": "Current user's role on this calendar" }, "created_at": { "type": "string", "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" } } }, "Reminder": { "type": "object", "required": ["id", "minutes_before"], "properties": { "id": { "type": "string", "format": "uuid" }, "minutes_before": { "type": "integer", "minimum": 0, "maximum": 10080 } } }, "Attendee": { "type": "object", "required": ["id", "status"], "properties": { "id": { "type": "string", "format": "uuid" }, "user_id": { "type": "string", "format": "uuid", "nullable": true }, "email": { "type": "string", "format": "email", "nullable": true }, "status": { "type": "string", "enum": ["pending", "accepted", "declined", "tentative"] } } }, "Attachment": { "type": "object", "required": ["id", "file_url"], "properties": { "id": { "type": "string", "format": "uuid" }, "file_url": { "type": "string", "format": "uri" } } }, "Event": { "type": "object", "required": ["id", "calendar_id", "title", "start_time", "end_time", "timezone", "all_day", "created_by", "updated_by", "created_at", "updated_at"], "properties": { "id": { "type": "string", "format": "uuid" }, "calendar_id": { "type": "string", "format": "uuid" }, "title": { "type": "string", "minLength": 1, "maxLength": 140 }, "description": { "type": "string", "nullable": true }, "location": { "type": "string", "nullable": true }, "start_time": { "type": "string", "format": "date-time", "description": "UTC start time in RFC3339" }, "end_time": { "type": "string", "format": "date-time", "description": "UTC end time in RFC3339" }, "timezone": { "type": "string", "example": "America/Asuncion", "description": "Original IANA timezone" }, "all_day": { "type": "boolean" }, "recurrence_rule": { "type": "string", "nullable": true, "description": "RFC5545 RRULE string", "example": "FREQ=WEEKLY;BYDAY=MO,WE,FR" }, "is_occurrence": { "type": "boolean", "description": "True if this is an expanded recurrence occurrence" }, "occurrence_start_time": { "type": "string", "format": "date-time", "nullable": true }, "occurrence_end_time": { "type": "string", "format": "date-time", "nullable": true }, "created_by": { "type": "string", "format": "uuid" }, "updated_by": { "type": "string", "format": "uuid" }, "created_at": { "type": "string", "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" }, "reminders": { "type": "array", "items": { "$ref": "#/components/schemas/Reminder" } }, "attendees": { "type": "array", "items": { "$ref": "#/components/schemas/Attendee" } }, "tags": { "type": "array", "items": { "type": "string" } }, "attachments": { "type": "array", "items": { "$ref": "#/components/schemas/Attachment" } } } }, "Contact": { "type": "object", "required": ["id", "created_at", "updated_at"], "properties": { "id": { "type": "string", "format": "uuid" }, "first_name": { "type": "string", "nullable": true }, "last_name": { "type": "string", "nullable": true }, "email": { "type": "string", "format": "email", "nullable": true }, "phone": { "type": "string", "nullable": true }, "company": { "type": "string", "nullable": true }, "notes": { "type": "string", "nullable": true }, "created_at": { "type": "string", "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" } } }, "APIKeyResponse": { "type": "object", "required": ["id", "name", "created_at"], "properties": { "id": { "type": "string", "format": "uuid" }, "name": { "type": "string" }, "created_at": { "type": "string", "format": "date-time" }, "revoked_at": { "type": "string", "format": "date-time", "nullable": true }, "token": { "type": "string", "description": "Raw token, only returned once on creation" } } }, "CalendarMember": { "type": "object", "required": ["user_id", "email", "role"], "properties": { "user_id": { "type": "string", "format": "uuid" }, "email": { "type": "string", "format": "email" }, "role": { "type": "string", "enum": ["owner", "editor", "viewer"] } } }, "CalendarSubscription": { "type": "object", "required": ["id", "calendar_id", "source_url", "created_at"], "properties": { "id": { "type": "string", "format": "uuid" }, "calendar_id": { "type": "string", "format": "uuid" }, "source_url": { "type": "string", "format": "uri", "description": "iCal feed URL" }, "last_synced_at": { "type": "string", "format": "date-time", "nullable": true }, "sync_interval_minutes": { "type": "integer", "nullable": true }, "created_at": { "type": "string", "format": "date-time" } } }, "BusyBlock": { "type": "object", "required": ["start", "end", "event_id"], "properties": { "start": { "type": "string", "format": "date-time" }, "end": { "type": "string", "format": "date-time" }, "event_id": { "type": "string", "format": "uuid" } } }, "WorkingHourSlot": { "type": "object", "required": ["start", "end"], "properties": { "start": { "type": "string", "example": "09:00", "pattern": "^\\d{2}:\\d{2}$" }, "end": { "type": "string", "example": "17:00", "pattern": "^\\d{2}:\\d{2}$" } } }, "TimeSlot": { "type": "object", "required": ["start", "end"], "properties": { "start": { "type": "string", "format": "date-time" }, "end": { "type": "string", "format": "date-time" } } } } } }