openapi: '3.0.3' info: title: Todo REST API version: '1.0.0' description: A RESTful API for managing todo items servers: - url: /api/v1 description: Base API path components: schemas: Todo: type: object properties: id: type: string format: uuid readOnly: true title: type: string minLength: 1 maxLength: 200 description: type: string maxLength: 2000 completed: type: boolean default: false dueDate: type: string format: date-time userId: type: string createdAt: type: string format: date-time readOnly: true updatedAt: type: string format: date-time readOnly: true required: - id - title - completed - userId - createdAt - updatedAt TodoCreate: type: object properties: title: type: string minLength: 1 maxLength: 200 description: type: string maxLength: 2000 dueDate: type: string format: date-time userId: type: string required: - title - userId TodoUpdate: type: object properties: title: type: string minLength: 1 maxLength: 200 description: type: string maxLength: 2000 completed: type: boolean dueDate: type: string format: date-time minProperties: 1 TodoList: type: object properties: data: type: array items: $ref: '#/components/schemas/Todo' metadata: type: object properties: total: type: integer minimum: 0 limit: type: integer minimum: 1 offset: type: integer minimum: 0 required: - total - limit - offset required: - data - metadata TodoResponse: type: object properties: data: $ref: '#/components/schemas/Todo' required: - data Error: type: object properties: error: type: object properties: code: type: string enum: - VALIDATION_ERROR - UNAUTHORIZED - FORBIDDEN - NOT_FOUND - RATE_LIMIT_EXCEEDED - INTERNAL_ERROR message: type: string details: type: array items: type: object properties: field: type: string message: type: string required: - field - message required: - code - message parameters: TodoId: name: todoId in: path required: true schema: type: string format: uuid UserId: name: userId in: query required: true schema: type: string Status: name: status in: query schema: type: string enum: [active, completed] Limit: name: limit in: query schema: type: integer minimum: 1 maximum: 100 default: 50 Offset: name: offset in: query schema: type: integer minimum: 0 default: 0 SortBy: name: sortBy in: query schema: type: string enum: [createdAt, dueDate] default: createdAt SortOrder: name: sortOrder in: query schema: type: string enum: [asc, desc] default: desc securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: JWT security: - bearerAuth: [] paths: /todos: get: summary: List todos parameters: - $ref: '#/components/parameters/UserId' - $ref: '#/components/parameters/Status' - $ref: '#/components/parameters/Limit' - $ref: '#/components/parameters/Offset' - $ref: '#/components/parameters/SortBy' - $ref: '#/components/parameters/SortOrder' responses: '200': description: Successfully retrieved todos headers: ETag: schema: type: string Last-Modified: schema: type: string X-Request-ID: schema: type: string X-RateLimit-Limit: schema: type: integer X-RateLimit-Remaining: schema: type: integer X-RateLimit-Reset: schema: type: integer content: application/json: schema: $ref: '#/components/schemas/TodoList' '400': description: Invalid parameters content: application/json: schema: $ref: '#/components/schemas/Error' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/Error' '429': description: Too many requests headers: Retry-After: schema: type: integer content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/Error' post: summary: Create a new todo requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TodoCreate' responses: '201': description: Todo created successfully headers: Location: schema: type: string format: uri ETag: schema: type: string X-Request-ID: schema: type: string content: application/json: schema: $ref: '#/components/schemas/TodoResponse' '400': description: Invalid input content: application/json: schema: $ref: '#/components/schemas/Error' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/Error' /todos/{todoId}: parameters: - $ref: '#/components/parameters/TodoId' get: summary: Get a specific todo responses: '200': description: Successfully retrieved todo headers: ETag: schema: type: string Last-Modified: schema: type: string X-Request-ID: schema: type: string content: application/json: schema: $ref: '#/components/schemas/TodoResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Todo not found content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/Error' patch: summary: Update a todo requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TodoUpdate' responses: '200': description: Todo updated successfully headers: ETag: schema: type: string X-Request-ID: schema: type: string content: application/json: schema: $ref: '#/components/schemas/TodoResponse' '400': description: Invalid input content: application/json: schema: $ref: '#/components/schemas/Error' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Todo not found content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/Error' delete: summary: Delete a todo responses: '204': description: Todo deleted successfully headers: X-Request-ID: schema: type: string '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Todo not found content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/Error'