Skip to main content

Overview

The upload endpoints allow authenticated users to upload files to the system. There are three dedicated endpoints, each configured for specific file types and storage locations:
  1. Solicitud (Request) - For supporting documents attached to requests
  2. Comunicado (Announcement) - For media files in announcements (Admin only)
  3. Documento (Document) - For general administrative documents (Admin only)

Authentication

All upload endpoints require JWT authentication. Admin-specific endpoints additionally require Admin or Super Admin role.

POST /api/uploads/solicitud

Upload supporting documents for employee requests (vacation requests, permission requests, etc.).

Authorization

All Authenticated Users

Any authenticated employee can upload files for their own requests

Request

Content-Type: multipart/form-data
file
file
required
File to upload. Accepted file types and size limits are configured in the middleware.

Response

success
boolean
Whether the upload succeeded
message
string
Success or error message
url
string
Public URL to access the uploaded file. Format: {BASE_URL}/uploads/solicitudes/{filename}

Code Examples

cURL
curl -X POST 'https://api.example.com/api/uploads/solicitud' \
  -H 'Authorization: Bearer YOUR_JWT_TOKEN' \
  -F 'file=@/path/to/document.pdf'
JavaScript
const formData = new FormData();
formData.append('file', fileInput.files[0]);

const response = await fetch('https://api.example.com/api/uploads/solicitud', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_JWT_TOKEN'
  },
  body: formData
});

const result = await response.json();
if (result.success) {
  console.log('File uploaded:', result.url);
}
Python
import requests

url = 'https://api.example.com/api/uploads/solicitud'
headers = {'Authorization': 'Bearer YOUR_JWT_TOKEN'}
files = {'file': open('document.pdf', 'rb')}

response = requests.post(url, headers=headers, files=files)
result = response.json()

if result['success']:
    print(f"File uploaded: {result['url']}")

Example Response

{
  "success": true,
  "message": "Archivo subido con éxito.",
  "url": "https://api.example.com/uploads/solicitudes/1710234567890-document.pdf"
}

POST /api/uploads/comunicado

Upload media files for announcements (images, PDFs, etc.).

Authorization

Admin Access Required

Only Admin and Super Admin users can upload announcement media

Request

Content-Type: multipart/form-data
file
file
required
Media file to upload (image, PDF, etc.)

Response

success
boolean
Whether the upload succeeded
message
string
Success or error message
url
string
Public URL to access the uploaded file. Format: {BASE_URL}/uploads/comunicados/{filename}

Code Examples

cURL
curl -X POST 'https://api.example.com/api/uploads/comunicado' \
  -H 'Authorization: Bearer YOUR_ADMIN_JWT_TOKEN' \
  -F 'file=@/path/to/announcement-image.jpg'
JavaScript
const formData = new FormData();
formData.append('file', imageFile);

const response = await fetch('https://api.example.com/api/uploads/comunicado', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_ADMIN_JWT_TOKEN'
  },
  body: formData
});

const result = await response.json();
if (result.success) {
  console.log('Announcement media uploaded:', result.url);
}
Python
import requests

url = 'https://api.example.com/api/uploads/comunicado'
headers = {'Authorization': 'Bearer YOUR_ADMIN_JWT_TOKEN'}
files = {'file': open('announcement-image.jpg', 'rb')}

response = requests.post(url, headers=headers, files=files)
result = response.json()

if result['success']:
    print(f"Media uploaded: {result['url']}")

Example Response

{
  "success": true,
  "message": "Archivo subido con éxito.",
  "url": "https://api.example.com/uploads/comunicados/1710234567890-announcement-image.jpg"
}

POST /api/uploads/documento

Upload general administrative documents.

Authorization

Admin Access Required

Only Admin and Super Admin users can upload administrative documents

Request

Content-Type: multipart/form-data
file
file
required
Document file to upload

Response

success
boolean
Whether the upload succeeded
message
string
Success or error message
url
string
Public URL to access the uploaded file. Format: {BASE_URL}/uploads/documentos/{filename}

Code Examples

cURL
curl -X POST 'https://api.example.com/api/uploads/documento' \
  -H 'Authorization: Bearer YOUR_ADMIN_JWT_TOKEN' \
  -F 'file=@/path/to/policy-document.pdf'
JavaScript
const formData = new FormData();
formData.append('file', documentFile);

const response = await fetch('https://api.example.com/api/uploads/documento', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_ADMIN_JWT_TOKEN'
  },
  body: formData
});

const result = await response.json();
if (result.success) {
  console.log('Document uploaded:', result.url);
}
Python
import requests

url = 'https://api.example.com/api/uploads/documento'
headers = {'Authorization': 'Bearer YOUR_ADMIN_JWT_TOKEN'}
files = {'file': open('policy-document.pdf', 'rb')}

response = requests.post(url, headers=headers, files=files)
result = response.json()

if result['success']:
    print(f"Document uploaded: {result['url']}")

Example Response

{
  "success": true,
  "message": "Archivo subido con éxito.",
  "url": "https://api.example.com/uploads/documentos/1710234567890-policy-document.pdf"
}

Error Responses

All upload endpoints return the same error format:
400
object
No file attached or invalid file
{
  "success": false,
  "message": "No se adjuntó ningún archivo o el archivo no es válido."
}
403
object
Forbidden (for admin-only endpoints)
{
  "message": "No tienes permisos para acceder a este recurso."
}
500
object
Internal server error
{
  "success": false,
  "message": "Error interno al procesar el archivo subido."
}

Storage Locations

Solicitudes

public/uploads/solicitudes/Request supporting documents

Comunicados

public/uploads/comunicados/Announcement media files

Documentos

public/uploads/documentos/Administrative documents

Implementation Notes

  • Files are processed by Multer middleware configured in uploadMiddleware.js
  • Each endpoint has its own Multer configuration:
    • uploadSolicitud - For request documents
    • uploadComunicado - For announcement media
    • uploadDocumento - For administrative documents
  • File naming: Timestamp prefix is added to prevent name collisions (e.g., 1710234567890-filename.pdf)
  • The BASE_URL environment variable determines the full URL returned
  • Files are stored in the public/uploads/ directory and served as static assets
  • File type restrictions and size limits are configured in the respective middleware

Usage Workflow

1. Upload File

Call the appropriate upload endpoint with the file

2. Receive URL

Get the public URL from the response

3. Store Reference

Save the URL in your request/announcement/document record

Build docs developers (and LLMs) love