Skip to main content
POST
/
api
/
upload-excel
Upload Excel/CSV
curl --request POST \
  --url https://api.example.com/api/upload-excel \
  --header 'Content-Type: <content-type>' \
  --data '{}'
{
  "success": true,
  "message": "<string>",
  "count": 123,
  "errors": [
    {}
  ],
  "transactions": [
    {}
  ],
  "error": "<string>",
  "details": "<string>",
  "hint": "<string>"
}
Upload and process CSV files containing multiple transactions. This endpoint validates the CSV format, processes each row, and inserts valid transactions into the database in a single batch operation.

Endpoint

POST /api/upload-excel

Request

Headers

Content-Type
string
required
Must be multipart/form-data for file upload

Body Parameters

file
File
required
CSV file containing transactions to importFile requirements:
  • File extension must be .csv
  • Must include header row with column names
  • UTF-8 encoding recommended

CSV Format

Required Columns

The CSV file must include these columns in the header row:
fecha
string
required
Transaction date in ISO format: YYYY-MM-DDExample: 2025-10-06
tipo
string
required
Transaction type (case-insensitive)Valid values: gasto (expense) or ingreso (income)
categoria
string
required
Category name (must match exactly, including accents)Valid expense categories: Alimentación, Transporte, Vivienda, Salud, Entretenimiento, Educación, Suscripciones, Otros GastosValid income categories: Salario, Ventas, Servicios, Inversiones, Tours, Comedor, Reservaciones, Anticipos, Otros Ingresos
monto
number
required
Transaction amount (positive number, use decimal point)Example: 1200.50

Optional Columns

descripcion
string
Description or notes about the transaction
num_pax
integer
Number of people (useful for tour/restaurant businesses)
metodo_pago
string
Payment methodValid values: Efectivo, Tarjeta, TransferenciaDefault: Efectivo
registrado_por
string
Name of person who registered the transactionDefault: Armando

Response

Success Response (200)

success
boolean
Indicates successful import
message
string
Summary message with number of transactions imported
count
number
Number of transactions successfully imported
errors
array
Array of error messages for rows that failed validation (if any)
transactions
array
Array of inserted transaction objects with their database IDs

Error Response (400/500)

error
string
Error message describing what went wrong
details
string
Additional error details (if available)
hint
string
Helpful hint for fixing the error (for format errors)

Examples

Example CSV File

fecha,tipo,categoria,monto,descripcion,num_pax,metodo_pago,registrado_por
2025-10-06,ingreso,Tours,1200,Tour grupal,15,Efectivo,Armando
2025-10-06,gasto,Alimentación,350,Comida para grupo,15,Tarjeta,Maria
2025-10-07,gasto,Transporte,450,Gasolina,,Efectivo,Carlos
2025-10-07,ingreso,Ventas,800,Venta de productos,,Transferencia,Armando

Successful Upload

const formData = new FormData();
formData.append('file', csvFile);

const response = await fetch('/api/upload-excel', {
  method: 'POST',
  body: formData
});

const result = await response.json();
console.log(result);
// {
//   success: true,
//   message: "Se registraron 4 transacciones exitosamente",
//   count: 4,
//   transactions: [...]
// }

Upload with Validation Errors

If some rows fail validation, they will be skipped and reported in the errors array:
{
  "success": true,
  "message": "Se registraron 3 transacciones exitosamente",
  "count": 3,
  "errors": [
    "Fila 2: Tipo debe ser 'gasto' o 'ingreso'",
    "Fila 5: Monto inválido"
  ],
  "transactions": [...]
}

Error: Missing Required Columns

{
  "error": "Faltan columnas requeridas: fecha, monto",
  "hint": "Formato esperado: fecha,tipo,categoria,monto,descripcion,num_pax,metodo_pago,registrado_por"
}

Error: Invalid File Type

{
  "error": "Solo se permiten archivos CSV (.csv)"
}

Error: Empty File

{
  "error": "El archivo está vacío o no tiene datos"
}

Validation Rules

The endpoint validates each row before insertion. Invalid rows are skipped and reported in the errors array, but valid rows are still imported.
Row-level validations:
  • All required columns must have values
  • tipo must be exactly gasto or ingreso (case-insensitive)
  • monto must be a valid positive number
  • fecha must be in valid date format (YYYY-MM-DD)
  • Number of columns in each row must match header
File-level validations:
  • File must be CSV format (.csv extension)
  • Must have at least 2 lines (header + data)
  • Must include all required columns: fecha, tipo, categoria, monto

Best Practices

Test with a small file first: Upload a CSV with 2-3 transactions to verify the format before bulk importing.
Use the template: Download the template from the Upload Excel UI page to ensure correct format.
Check category names: Category names must match exactly, including accents. Alimentacion (without accent) will fail validation.
Batch size: The endpoint can handle large files, but for very large imports (1000+ transactions), consider splitting into smaller batches.

Common Errors

This error occurs when a row has more or fewer values than the header row.Solution: Check for extra commas or missing values in the CSV.
The tipo column contains an invalid value.Solution: Use only gasto or ingreso (case-insensitive).
The monto column contains a non-numeric value or zero/negative number.Solution: Use positive numbers with decimal point (e.g., 150.50).
Database error during insertion.Solution: Check that all category names are valid and Supabase connection is working.

Transactions API

Fetch imported transactions

Excel Import Feature

User guide for the Excel import UI

Build docs developers (and LLMs) love