# Register file upload Register a completed file upload after using the resumable upload flow. Register a file after successfully uploading it to cloud storage using the resumable upload URL. This endpoint validates that the file exists in storage, verifies the file type and size, and creates the database record. This endpoint is the final step in the [resumable upload flow](/docs/api-reference/files/upload-url). For simpler uploads under 100MB, use the [direct upload endpoint](/docs/api-reference/files/upload) instead. #### Path Parameters **`organization_id`** string required The unique identifier of the organization. #### Request Body **`filename`** string required Original filename (1-255 characters). **`gcs_path`** string required Cloud storage path where the file was uploaded. This is returned from the [generate upload URL](/docs/api-reference/files/upload-url) endpoint. **`file_size`** integer required File size in bytes. Must be greater than 0. **`mime_type`** string required MIME type of the file. ## Returns Returns a [File object](/docs/api-reference/objects/file-object) with complete metadata. The file is now ready to be used in vector stores or AI conversations. Request ```bash cURL curl -X POST https://api.aitronos.com/v1/organizations/org_123/files \ -H "X-API-Key: $FREDDY_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filename": "large_video.mp4", "gcs_path": "files/org_123/file_abc123xyz789/large_video.mp4", "file_size": 524288000, "mime_type": "video/mp4" }' ``` ```python Python import os import requests api_key = os.environ["FREDDY_API_KEY"] org_id = "org_123" url = f"https://api.aitronos.com/v1/organizations/{org_id}/files" headers = {"X-API-Key": api_key} data = { "filename": "large_video.mp4", "gcs_path": "files/org_123/file_abc123xyz789/large_video.mp4", "file_size": 524288000, "mime_type": "video/mp4" } response = requests.post(url, headers=headers, json=data) file_obj = response.json() print(f"File registered: {file_obj['id']}") ``` ```javascript JavaScript const apiKey = process.env.FREDDY_API_KEY; const orgId = 'org_123'; const data = { filename: 'large_video.mp4', gcs_path: 'files/org_123/file_abc123xyz789/large_video.mp4', file_size: 524288000, mime_type: 'video/mp4' }; fetch(`https://api.aitronos.com/v1/organizations/${orgId}/files`, { method: 'POST', headers: { 'X-API-Key': apiKey, 'Content-Type': 'application/json' }, body: JSON.stringify(data) }) .then(res => res.json()) .then(file => console.log('File registered:', file.id)); ``` Response ```json 201 Created { "id": "file_abc123xyz789", "original_filename": "large_video.mp4", "file_size": 524288000, "mime_type": "video/mp4", "storage_path": "files/org_123/file_abc123xyz789/large_video.mp4", "organization_id": "org_123", "uploaded_by": "usr_user123", "uploaded_by_api_key_id": null, "uploaded_at": "2025-12-22T15:30:00Z" } ``` ```json 400 Bad Request - File not found in storage { "success": false, "error": { "code": "FILE_NOT_FOUND", "message": "File not found in cloud storage", "type": "client_error", "status": 400, "details": { "gcs_path": "files/org_123/file_abc123xyz789/large_video.mp4" }, "trace_id": "abc-123-def", "timestamp": "2025-12-22T15:30:00Z" } } ``` ```json 400 Bad Request - Invalid file type { "success": false, "error": { "code": "INVALID_FILE_TYPE", "message": "File type not supported", "type": "client_error", "status": 400, "details": { "mime_type": "application/x-executable", "supported_types": ["application/pdf", "text/plain", "image/png"] }, "trace_id": "abc-123-def", "timestamp": "2025-12-22T15:30:00Z" } } ``` ```json 403 Forbidden { "success": false, "error": { "code": "ORGANIZATION_ACCESS_DENIED", "message": "You do not have access to this organization", "type": "client_error", "status": 403, "details": { "organization_id": "org_123" }, "trace_id": "abc-123-def", "timestamp": "2025-12-22T15:30:00Z" } } ``` ## Complete Resumable Upload Flow ```python import os import requests api_key = os.environ["FREDDY_API_KEY"] org_id = "org_123" file_path = "/path/to/large_video.mp4" # Step 1: Generate upload URL upload_url_endpoint = f"https://api.aitronos.com/v1/organizations/{org_id}/files/upload-url" headers = {"X-API-Key": api_key} with open(file_path, 'rb') as f: file_size = len(f.read()) upload_url_data = { "filename": "large_video.mp4", "file_size": file_size, "mime_type": "video/mp4" } response = requests.post(upload_url_endpoint, headers=headers, json=upload_url_data) session = response.json() # Step 2: Upload file to GCS with open(file_path, 'rb') as f: upload_headers = {'Content-Type': 'video/mp4'} requests.put(session['upload_url'], headers=upload_headers, data=f) # Step 3: Register the completed upload register_endpoint = f"https://api.aitronos.com/v1/organizations/{org_id}/files" register_data = { "filename": "large_video.mp4", "gcs_path": session['gcs_path'], "file_size": file_size, "mime_type": "video/mp4" } response = requests.post(register_endpoint, headers=headers, json=register_data) file_obj = response.json() print(f"Upload complete! File ID: {file_obj['id']}") ``` ## Upload Process 1. Call [generate upload URL](/docs/api-reference/files/upload-url) to get an upload session 2. Upload file to the returned URL using resumable upload protocol 3. Call this endpoint to validate and register the completed upload ## Related Resources - [Generate Upload URL](/docs/api-reference/files/upload-url) - Start the resumable upload process - [Upload File](/docs/api-reference/files/upload) - Simple upload for files under 100MB - [List Files](/docs/api-reference/files/list) - [File Object](/docs/api-reference/objects/file-object)