diff --git a/docs/get-task-status.mdx b/docs/get-task-status.mdx new file mode 100644 index 0000000..2ff9273 --- /dev/null +++ b/docs/get-task-status.mdx @@ -0,0 +1,3 @@ +--- +openapi: post /get-task-status +--- \ No newline at end of file diff --git a/docs/get-upload-url.mdx b/docs/get-upload-url.mdx new file mode 100644 index 0000000..ff3c365 --- /dev/null +++ b/docs/get-upload-url.mdx @@ -0,0 +1,3 @@ +--- +openapi: post /get-upload-url +--- \ No newline at end of file diff --git a/docs/get-upscayl-history.mdx b/docs/get-upscayl-history.mdx new file mode 100644 index 0000000..b872d91 --- /dev/null +++ b/docs/get-upscayl-history.mdx @@ -0,0 +1,3 @@ +--- +openapi: post /get-upscayl-history +--- \ No newline at end of file diff --git a/docs/history/get-image-processing-history.mdx b/docs/history/get-image-processing-history.mdx new file mode 100644 index 0000000..b872d91 --- /dev/null +++ b/docs/history/get-image-processing-history.mdx @@ -0,0 +1,3 @@ +--- +openapi: post /get-upscayl-history +--- \ No newline at end of file diff --git a/docs/openapi.yaml b/docs/openapi.yaml index 34945b8..9c878e1 100644 --- a/docs/openapi.yaml +++ b/docs/openapi.yaml @@ -1,354 +1,528 @@ ---- openapi: 3.0.0 info: - title: Upscayl Cloud API Documentation + title: Upscayl Cloud API + description: | + API for Upscayl Cloud - An AI-powered image upscaling service. + Use this API to upscale images, check processing status, and manage uploads. version: 1.0.0 + contact: + name: Upscayl Support + url: https://upscayl.github.io +servers: + - url: https://api.upscayl.com/v1 + description: Production server + +security: + - ApiKeyAuth: [] +components: + responses: + BadRequest: + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + example: + error: BAD_REQUEST + message: "Invalid request parameters provided" + + NotFound: + description: Requested resource not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + example: + error: NOT_FOUND + message: "Requested resource could not be found" + Unauthorized: + description: Authentication failed or API key missing + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + example: + error: UNAUTHORIZED + message: "Invalid or missing API key" + + TooManyRequests: + description: Rate limit exceeded + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + example: + error: RATE_LIMIT_EXCEEDED + message: "Too many requests. Try again in 1 hour" + InternalError: + description: Internal server error occurred + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + example: + error: INTERNAL_SERVER_ERROR + message: "An unexpected error occurred" + securitySchemes: + ApiKeyAuth: + type: apiKey + in: header + name: X-API-Key + schemas: + TaskStatus: + type: object + required: + - status + - data + properties: + status: + type: string + enum: [success] + data: + type: object + properties: + batchMode: + type: boolean + description: Whether task is in batch mode + enhanceFace: + type: boolean + description: Whether face enhancement is enabled + error: + type: string + description: Error message if task failed + files: + type: array + items: + $ref: '#/components/schemas/ProcessedFile' + model: + type: string + description: AI model used for processing + progress: + type: string + description: Processing progress percentage + scale: + type: string + description: Upscale factor applied + status: + type: string + enum: [pending, processing, completed, failed] + saveImageAs: + type: string + enum: [png, jpg, webp] + compression: + type: number + minimum: 0 + maximum: 100 + creditsDeducted: + type: boolean + deductedCredits: + type: number + UploadedFile: + type: object + required: + - fileName + - fileType + - fileSize + properties: + fileName: + type: string + description: Unique file identifier + fileType: + type: string + description: MIME type of file + enum: [image/jpeg, image/png, image/webp] + fileSize: + type: integer + description: File size in bytes + minimum: 1 + maximum: 104857600 + originalFileName: + type: string + description: Original uploaded filename + createdAt: + type: integer + format: int64 + description: Upload timestamp (Unix ms) + expiresAt: + type: integer + format: int64 + description: Expiration timestamp (Unix ms) + ProcessingTask: + type: object + properties: + batchMode: + type: boolean + description: Whether task was processed in batch mode + enhanceFace: + type: boolean + description: Whether face enhancement was applied + error: + type: string + description: Error message if processing failed + files: + type: array + items: + $ref: '#/components/schemas/ProcessedFile' + model: + type: string + description: AI model used for processing + progress: + type: string + description: Processing progress percentage + scale: + type: string + description: Upscale factor applied + status: + type: string + enum: [pending, processing, completed, failed] + saveImageAs: + type: string + enum: [png, jpg, webp] + compression: + type: number + minimum: 0 + maximum: 100 + creditsDeducted: + type: boolean + + ProcessedFile: + type: object + properties: + fileName: + type: string + fileType: + type: string + path: + type: string + createdAt: + type: integer + format: int64 + expiresAt: + type: integer + format: int64 + originalFileName: + type: string + fileSize: + type: integer + downloadLink: + type: string + format: uri + thumbnailLink: + type: string + format: uri + finalFileSize: + type: integer + processedFileName: + type: string + dimensions: + type: object + properties: + width: + type: integer + minimum: 1 + height: + type: integer + minimum: 1 + Error: + type: object + properties: + error: + type: string + message: + type: string +tags: + - name: Upload + description: File upload operations + - name: Tasks + description: Image processing task operations + - name: History + description: Historical data operations + + paths: /get-upload-url: post: + tags: + - Upload + summary: Generate Pre-signed Upload URL + description: | + Generates a pre-signed URL for secure direct file upload to cloud storage. + The URL expires after a specified duration for security. + + **Note**: File size is limited to 100MB per upload. operationId: getUploadUrl - summary: Get upload URL + security: + - ApiKeyAuth: [] + x-rateLimit: + requests: 100 + period: 1 hour requestBody: + required: true content: application/json: schema: type: object + required: + - originalFileName + - fileType + - fileSize properties: originalFileName: type: string - description: The original file name - example: file.jpeg + description: Original name of the file to be uploaded + example: vacation-photo.jpeg + minLength: 1 + maxLength: 255 fileType: type: string - description: The file type + description: MIME type of the file example: image/jpeg + enum: + - image/jpeg + - image/png + - image/webp fileSize: - type: number - description: The file size in bytes - example: 123456 + type: integer + description: File size in bytes (max 100MB) + example: 1048576 + minimum: 1 + maximum: 104857600 responses: "200": - description: Successful operation + description: Pre-signed URL generated successfully content: application/json: schema: type: object + required: + - status + - data properties: status: type: string - example: success + enum: [success] data: type: object + required: + - uploadURL + - fileName + - expiresAt properties: uploadURL: type: string - example: http://example.com/upload + format: uri + description: Pre-signed URL for upload + example: https://storage.upscayl.com/upload/abc123 fileName: type: string - example: example.jpg + description: Generated unique filename + example: f7d9a2b4-vacation-photo.jpeg fileType: type: string + description: MIME type of file example: image/jpeg fileSize: - type: number - example: 12345 + type: integer + description: File size in bytes + example: 1048576 originalFileName: type: string - example: original.jpg + description: Original filename + example: vacation-photo.jpeg createdAt: - type: number + type: integer + format: int64 + description: URL creation timestamp (Unix ms) example: 1633024800000 expiresAt: - type: number - example: 1654560800000 + type: integer + format: int64 + description: URL expiration timestamp (Unix ms) + example: 1633028400000 "400": - description: Bad request + description: Invalid request parameters content: application/json: schema: - type: object - properties: - error: - type: string - message: - type: string + $ref: '#/components/schemas/Error' examples: InvalidFileType: value: - error: InvalidFileType - message: "Bad Request: Invalid File Type" - MissingUserID: + error: INVALID_FILE_TYPE + message: "Unsupported file type. Allowed: JPEG, PNG, WEBP" + FileSizeTooLarge: value: - error: MissingUserID - message: "Bad Request: Missing User ID" - MissingOriginalFileName: + error: FILE_SIZE_EXCEEDED + message: "File size exceeds maximum limit of 100MB" + MissingFields: value: - error: MissingOriginalFileName - message: "Bad Request: Missing Original File Name" + error: MISSING_REQUIRED_FIELDS + message: "Required fields missing: originalFileName" + "401": + $ref: '#/components/responses/Unauthorized' + "429": + $ref: '#/components/responses/TooManyRequests' "500": - description: Internal server error - content: - text/plain: - schema: - type: string - example: Internal Server Error + $ref: '#/components/responses/InternalError' /get-upscayl-history: post: + tags: + - History + summary: Get Image Processing History + description: | + Retrieves paginated history of image processing tasks. + Results can be filtered by status and time range. operationId: getUpscaylHistory - summary: Get Upscayl History + security: + - ApiKeyAuth: [] + x-rateLimit: + requests: 100 + period: 1 hour requestBody: + required: true content: application/json: schema: type: object properties: timestampOffset: - type: number - description: The timestamp offset + type: integer + format: int64 + description: Unix timestamp (ms) to start fetching records from example: 1633024800000 batch: type: boolean - description: The batch mode status + description: Filter by batch processing status example: true failed: type: boolean - description: The failed status + description: Filter by failed status example: false limit: - type: number - description: The limit for the number of records to retrieve + type: integer + minimum: 1 + maximum: 100 + default: 20 + description: Number of records to return per page example: 10 processed: type: string - description: The processed status + enum: [pending, processing, completed, failed] + description: Filter by processing status example: processing responses: "200": - description: Successful operation + description: Successfully retrieved history content: application/json: schema: type: object + required: + - status + - data + - pagination properties: status: type: string - example: "success" + enum: [success] + pagination: + type: object + properties: + total: + type: integer + description: Total number of records + hasMore: + type: boolean + description: Whether more records exist + nextOffset: + type: integer + format: int64 + description: Timestamp offset for next page data: type: array items: - type: object - properties: - batchMode: - type: boolean - enhanceFace: - type: boolean - error: - type: string - files: - type: array - items: - type: object - properties: - fileName: - type: string - fileType: - type: string - path: - type: string - createdAt: - type: number - expiresAt: - type: number - originalFileName: - type: string - fileSize: - type: number - downloadLink: - type: string - thumbnailLink: - type: string - finalFileSize: - type: number - processedFileName: - type: string - dimensions: - type: object - properties: - width: - type: number - height: - type: number - model: - type: string - progress: - type: string - scale: - type: string - status: - type: string - saveImageAs: - type: string - enum: ["png", "jpg", "webp"] - compression: - type: number - creditsDeducted: - type: boolean + $ref: '#/components/schemas/ProcessingTask' "400": - description: Bad request - content: - text/plain: - schema: - type: string - example: "Bad Request: Missing User ID" - "204": - description: No content - content: - text/plain: - schema: - type: string - example: "No data found" + $ref: '#/components/responses/BadRequest' + "401": + $ref: '#/components/responses/Unauthorized' + "404": + $ref: '#/components/responses/NotFound' + "429": + $ref: '#/components/responses/TooManyRequests' "500": - description: Internal server error - content: - text/plain: - schema: - type: string - example: "Error getting data" + $ref: '#/components/responses/InternalError' /get-task-status: post: + tags: + - Tasks + summary: Check Task Status + description: | + Get current status and progress of an upscaling task. + Returns detailed information about the task including processed files and progress. operationId: getTaskStatus - summary: Get Task Status + security: + - ApiKeyAuth: [] + x-rateLimit: + requests: 100 + period: 1 hour requestBody: + required: true content: application/json: schema: type: object + required: + - taskId properties: - data: - type: object - properties: - taskId: - type: string - description: The task ID - example: 30a89e69-c702-4247-9905-f0a53dfa45ab + taskId: + type: string + format: uuid + description: Task ID returned by start-task endpoint. See [Start Image Upscaling Task](#operation/startTask). + example: 30a89e69-c702-4247-9905-f0a53dfa45ab responses: "200": - description: Successful operation + description: Task status retrieved successfully content: application/json: schema: - type: object - properties: - status: - type: string - example: "success" - data: - type: object - properties: - batchMode: - type: boolean - description: Indicates if batch mode is enabled - enhanceFace: - type: boolean - description: Indicates if face enhancement is enabled - error: - type: string - description: Error message if any - files: - type: array - items: - type: object - properties: - fileName: - type: string - fileType: - type: string - path: - type: string - createdAt: - type: number - expiresAt: - type: number - originalFileName: - type: string - fileSize: - type: number - downloadLink: - type: string - thumbnailLink: - type: string - finalFileSize: - type: number - processedFileName: - type: string - dimensions: - type: object - properties: - width: - type: number - height: - type: number - model: - type: string - description: The model used for the task - progress: - type: string - description: The progress of the task - scale: - type: string - description: The scale of the task - status: - type: string - description: The status of the task - saveImageAs: - type: string - enum: ["png", "jpg", "webp"] - description: The format to save the image as - compression: - type: number - description: The compression level - creditsDeducted: - type: boolean - description: Indicates if credits were deducted - deductedCredits: - type: number - description: The number of credits deducted + $ref: '#/components/schemas/TaskStatus' + example: + status: success + data: + batchMode: false + enhanceFace: true + model: digital-art + progress: "75" + scale: "4" + status: processing + files: [] "400": - description: Bad request - content: - text/plain: - schema: - type: string - example: "Bad Request: Missing User ID or Task ID" + $ref: '#/components/responses/BadRequest' + "401": + $ref: '#/components/responses/Unauthorized' "404": - description: Not found - content: - text/plain: - schema: - type: string - examples: - noDocument: - value: "No such document" - noFiles: - value: "No files found" - noUser: - value: "User not found" + $ref: '#/components/responses/NotFound' + "429": + $ref: '#/components/responses/TooManyRequests' "500": - description: Internal server error - content: - text/plain: - schema: - type: string - examples: - genericError: - value: "Error getting data" - linkGenerationError: - value: "Error generating links for images" + $ref: '#/components/responses/InternalError' /start-task: post: + tags: + - Tasks + summary: Start Image Upscaling Task + description: | + Initiates a new image upscaling task with specified parameters. + Supports both direct file upload and processing of previously uploaded files. operationId: startTask - summary: Start a new task + security: + - ApiKeyAuth: [] + x-rateLimit: + requests: 50 + period: 1 hour requestBody: + required: true content: multipart/form-data: schema: @@ -357,191 +531,177 @@ paths: files: type: array items: - type: object - properties: - fileName: - description: The file name or the URL of the file - type: string - fileType: - description: The file type - type: string - fileSize: - description: The file size in bytes - type: integer - originalFileName: - description: The original file name - type: string - createdAt: - description: The timestamp when the file was created - type: number - format: float - expiresAt: - description: The timestamp when the file expires - type: number - format: float - description: (Optional) The files to process. Optional if the file is not manually provided in the file property + $ref: '#/components/schemas/UploadedFile' + description: Array of previously uploaded files to process file: type: string format: binary - description: (Optional) A single file to upload, used when startTask is being used to upload the file, not needed if already uploaded s3 files or file links are passed in files array + description: Single file for direct upload (mutually exclusive with files array) enhanceFace: type: boolean - description: Whether to enhance faces in the image - example: false + description: Enable face enhancement + default: false model: type: string - description: The model to use for the task + description: AI model for upscaling + enum: [digital-art, photo-realistic, anime] example: digital-art scale: type: string - description: The scale factor for the task + description: Upscaling factor + enum: ["2", "4", "8"] example: "4" compression: type: number - description: The compression level - example: 0 + description: Output image compression (0-100) + minimum: 0 + maximum: 100 + default: 0 saveImageAs: type: string - enum: ["png", "jpg", "webp"] - description: The format to save the image as - example: jpg + enum: [png, jpg, webp] + description: Output image format + default: jpg responses: "200": - description: Successful operation + description: Task started successfully content: application/json: schema: type: object + required: + - status + - data properties: status: type: string - example: "success" + enum: [success] data: type: object + required: + - taskId + - message properties: - message: - type: string - example: "Task request sent successfully" taskId: type: string - example: "30a89e69-c702-4247-9905-f0a53dfa45ab" + format: uuid + example: 30a89e69-c702-4247-9905-f0a53dfa45ab + message: + type: string + example: Task request sent successfully "400": - description: Bad request - content: - text/plain: - schema: - type: string - examples: - missingUserId: - value: "Bad Request: Missing User ID" - missingFiles: - value: "Bad Request: Missing Files" - missingModelName: - value: "Bad Request: Missing Model Name" - missingScale: - value: "Bad Request: Missing Scale" - missingImageOptions: - value: "Bad Request: Missing Image Options" + $ref: '#/components/responses/BadRequest' + "401": + $ref: '#/components/responses/Unauthorized' "402": - description: Payment required + description: Insufficient credits content: - text/plain: + application/json: schema: - type: string - example: "Insufficient credits" + $ref: '#/components/schemas/Error' + example: + error: INSUFFICIENT_CREDITS + message: Not enough credits to process request + "429": + $ref: '#/components/responses/TooManyRequests' "500": - description: Internal server error - content: - text/plain: - schema: - type: string - example: "Error contacting the server" + $ref: '#/components/responses/InternalError' /complete-multipart-upload: post: + tags: + - Upload + summary: Complete Multipart Upload + description: | + Completes a multipart upload by combining previously uploaded parts in S3. + Must be called after all parts have been uploaded using pre-signed URLs. operationId: completeMultipartUpload - summary: Complete a multipart upload + security: + - ApiKeyAuth: [] + x-rateLimit: + requests: 50 + period: 1 hour requestBody: + required: true content: application/json: schema: type: object + required: + - data properties: data: type: object + required: + - uploadId + - key + - parts properties: uploadId: type: string - description: The upload ID - example: "exampleUploadId" + description: S3 upload ID + example: "abc123def456" key: - type: string - description: The object key - example: "exampleKey" + type: string + description: S3 object key + example: "uploads/image.jpg" parts: type: array + description: List of uploaded parts + minItems: 1 items: type: object + required: + - PartNumber + - ETag properties: - ETag: - type: string - description: The entity tag for the part - example: "exampleETag" PartNumber: type: integer - description: The part number + minimum: 1 + description: Part number example: 1 - required: - - uploadId - - key - - parts + ETag: + type: string + description: ETag from part upload + example: "a1b2c3d4" responses: "200": - description: Successful operation + description: Multipart upload completed successfully content: application/json: schema: type: object + required: + - status + - data properties: status: type: string - example: "success" + enum: [success] data: type: object + required: + - status properties: status: type: string - example: "success" - # Uncomment and add these properties if needed - # location: - # type: string - # example: "http://example.com/location" - # bucket: - # type: string - # example: "exampleBucket" - # key: - # type: string - # example: "exampleKey" - # eTag: - # type: string - # example: "exampleETag" + enum: [success] "400": - description: Bad request + description: Missing or invalid parameters content: - text/plain: + application/json: schema: - type: string - example: "Bad Request: Missing required parameters" + $ref: '#/components/schemas/Error' + example: + error: BAD_REQUEST + message: "Bad Request: Missing required parameters" "401": - description: Unauthorized - content: - text/plain: - schema: - type: string - example: "Unauthorized: Invalid API key" + $ref: '#/components/responses/Unauthorized' "500": - description: Internal server error + description: S3 or internal error content: - text/plain: + application/json: schema: - type: string - example: "Internal Server Error: Error completing multipart upload" \ No newline at end of file + $ref: '#/components/schemas/Error' + example: + error: INTERNAL_SERVER_ERROR + message: "Error completing multipart upload" \ No newline at end of file diff --git a/docs/tasks/check-task-status.mdx b/docs/tasks/check-task-status.mdx new file mode 100644 index 0000000..2ff9273 --- /dev/null +++ b/docs/tasks/check-task-status.mdx @@ -0,0 +1,3 @@ +--- +openapi: post /get-task-status +--- \ No newline at end of file diff --git a/docs/tasks/start-upscaling-task.mdx b/docs/tasks/start-upscaling-task.mdx new file mode 100644 index 0000000..d0246c7 --- /dev/null +++ b/docs/tasks/start-upscaling-task.mdx @@ -0,0 +1,3 @@ +--- +openapi: post /start-task +--- \ No newline at end of file diff --git a/docs/upload/complete-multipart-upload.mdx b/docs/upload/complete-multipart-upload.mdx new file mode 100644 index 0000000..8607bee --- /dev/null +++ b/docs/upload/complete-multipart-upload.mdx @@ -0,0 +1,3 @@ +--- +openapi: post /complete-multipart-upload +--- \ No newline at end of file diff --git a/docs/upload/generate-pre-signed-upload-url.mdx b/docs/upload/generate-pre-signed-upload-url.mdx new file mode 100644 index 0000000..ff3c365 --- /dev/null +++ b/docs/upload/generate-pre-signed-upload-url.mdx @@ -0,0 +1,3 @@ +--- +openapi: post /get-upload-url +--- \ No newline at end of file