diff --git a/api-reference/openapi/upload.json b/api-reference/openapi/upload.json new file mode 100644 index 0000000..670fe30 --- /dev/null +++ b/api-reference/openapi/upload.json @@ -0,0 +1,163 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "Recoup API - Upload", + "description": "API documentation for the Recoup platform - an AI agent platform for the music industry", + "license": { + "name": "MIT" + }, + "version": "1.0.0" + }, + "security": [ + { "apiKeyAuth": [] }, + { "bearerAuth": [] } + ], + "paths": { + "/api/upload": { + "post": { + "description": "Uploads a file and returns a permanent CDN-fronted HTTPS URL. Accepts a single file via multipart/form-data under the field name `file`. The caller's accountId is stamped onto the storage object's metadata as `uploaded_by` for audit purposes.", + "requestBody": { + "required": true, + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "required": ["file"], + "properties": { + "file": { + "type": "string", + "format": "binary", + "description": "The file bytes to upload. The file's Content-Type must be on the server allowlist (image/*, application/pdf, text/csv, text/markdown, text/plain, application/json, audio/mpeg, audio/wav, audio/x-m4a, audio/webm). Typeless / octet-stream uploads are rejected." + } + } + } + } + } + }, + "responses": { + "200": { + "description": "File uploaded successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UploadResponse" + } + } + } + }, + "400": { + "description": "Bad request — multipart body could not be parsed or no `file` field was provided.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UploadErrorResponse" + } + } + } + }, + "401": { + "description": "Missing or invalid authentication. Provide either an `Authorization: Bearer ` header or `x-api-key`.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UploadErrorResponse" + } + } + } + }, + "415": { + "description": "Unsupported file type — the file's Content-Type is not on the server allowlist or is empty / `application/octet-stream`.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UploadErrorResponse" + } + } + } + }, + "500": { + "description": "Internal storage error. Full details are logged server-side.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UploadErrorResponse" + } + } + } + } + } + } + } + }, + "components": { + "securitySchemes": { + "apiKeyAuth": { + "type": "apiKey", + "in": "header", + "name": "x-api-key" + }, + "bearerAuth": { + "type": "http", + "scheme": "bearer" + } + }, + "schemas": { + "UploadResponse": { + "type": "object", + "required": [ + "success", + "fileName", + "fileType", + "fileSize", + "url" + ], + "properties": { + "success": { + "type": "boolean", + "description": "Always `true` on a 200 response.", + "example": true + }, + "fileName": { + "type": "string", + "description": "The original file name from the upload.", + "example": "cover.png" + }, + "fileType": { + "type": "string", + "description": "The MIME type of the uploaded file, exactly as provided by the client. Must be on the server allowlist.", + "example": "image/png" + }, + "fileSize": { + "type": "integer", + "description": "The size of the uploaded file in bytes.", + "example": 24576 + }, + "url": { + "type": "string", + "description": "Permanent fetchable HTTPS URL for the uploaded file.", + "example": "https://example.supabase.co/storage/v1/object/public/public-uploads/abc123.png" + } + } + }, + "UploadErrorResponse": { + "type": "object", + "required": [ + "success", + "error" + ], + "properties": { + "success": { + "type": "boolean", + "description": "Always `false` on an error response.", + "example": false + }, + "error": { + "type": "string", + "description": "Human-readable error message. For 500 errors this is intentionally generic; full details are logged server-side.", + "example": "No file provided" + } + } + } + } + } +} diff --git a/api-reference/upload/file.mdx b/api-reference/upload/file.mdx new file mode 100644 index 0000000..137c943 --- /dev/null +++ b/api-reference/upload/file.mdx @@ -0,0 +1,4 @@ +--- +title: 'Upload File' +openapi: '/api-reference/openapi/upload.json POST /api/upload' +--- diff --git a/docs.json b/docs.json index 43aa475..45fce75 100644 --- a/docs.json +++ b/docs.json @@ -213,6 +213,12 @@ "api-reference/posts/get", "api-reference/comments/get" ] + }, + { + "group": "Upload", + "pages": [ + "api-reference/upload/file" + ] } ] },