Import contacts from Holded Excel
Imports multiple clients from an Excel file exported from Holded. **Key features**: - **Specific parsing**: Reads exact structure of Holded contacts Excel (29 columns) - **Automatic mapping**: Converts Holded contacts to Client entities automatically - **Full validation**: Validates NIFs, addresses and required data - **Preview mode**: Allows viewing parsed data before importing **Recommended flow**: 1. **Initial upload**: Call with `preview=true` to get preview 2. **Display data**: Frontend shows parsed Holded contacts 3. **Final import**: Call with `preview=false` to import definitively **Expected Excel structure** (contacts exported from Holded): - Sheet: "Holded" - Rows to skip: 2 (header + empty) - Headers in row 2: Created, Name, ID, Email, Phone, Mobile, etc. (29 columns) - Footer: "Report created automatically with Holded..." **Security limits**: - Max size: 10MB - Max 5,000 records per file - Rate limiting: 5 imports per hour **Automatic Holded → Client mapping**: - Name → nombreFiscal - ID → identifier (NIF/CIF) - Email → email - Phone/Mobile → phone (prioritizes mobile) - Full address → address - Tags → notes
API Key authentication.
Format: X-API-Key: beel_sk_<key>
Obtaining Keys: API Keys are managed from the BeeL dashboard
Security: API Keys are secret credentials. Do not share them or store them in source code
In: header
Excel file (.xlsx) of contacts exported from Holded
If true: parsing and mapping only without importing to DB. If false: parsing + mapping + actual import.
trueResponse Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://app.beel.es/api/v1/clientes/import-holded-contactos" \ -F file="string"{
"success": true,
"data": {
"metadata": {
"total_clientes": 10,
"is_dry_run": true,
"processing_time_ms": 450,
"source_type": "CSV_IMPORT",
"filename": "clientes_enero.csv",
"file_size_bytes": 1048576,
"total_rows": 250
},
"clientes_validation": [
{
"index": 0,
"cliente": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"nombre_fiscal": "Empresa Cliente SL",
"nombre_comercial": "EmpresaCliente",
"nif": "12345678A",
"direccion": {
"calle": "Calle Mayor, 123",
"numero": "123",
"piso": "2º A",
"puerta": "A",
"codigo_postal": "28001",
"poblacion": "Madrid",
"provincia": "Madrid",
"pais": "España",
"codigo_pais": "ES"
},
"telefono": "+34 600 123 456",
"email": "user@example.com",
"emails_facturacion": [
"usuario@ejemplo.com"
],
"persona_contacto": "María García",
"notas": "string",
"forma_pago_preferida": {
"metodo": "NINGUNO",
"iban": "ES1234567890123456789012",
"swift": "ABCDESMMXXX",
"plazo_dias": 30
},
"descuento_general": 0,
"activo": true,
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z",
"id_otro": {
"tipo": "02",
"numero": "string",
"codigo_pais": "st"
}
},
"status": "VALID",
"errores": [
{
"campo": "nif",
"valor": "12345678X",
"mensaje": "NIF no encontrado en censo AEAT"
}
],
"warnings": [
{
"campo": "email",
"mensaje": "Email no proporcionado, se usará el NIF para facturación"
}
],
"row_number": 15
}
],
"statistics": {
"total_procesados": 10,
"validos": 6,
"con_warnings": 2,
"con_errores": 2,
"duplicados": 1,
"nifs_invalidos": 1,
"importados": 0,
"tasa_exito": 0.8,
"importables": 8,
"no_importables": 2
}
},
"meta": {
"timestamp": "2025-01-15T10:30:00Z",
"request_id": "123e4567-e89b-12d3-a456-426614174000"
}
}{
"success": false,
"error": {
"code": "BAD_REQUEST",
"message": "Invalid request"
},
"meta": {
"timestamp": "2025-01-15T10:30:00Z",
"request_id": "123e4567-e89b-12d3-a456-426614174000"
}
}{
"success": false,
"error": {
"code": "UNAUTHORIZED",
"message": "Authentication required"
},
"meta": {
"timestamp": "2025-01-15T10:30:00Z",
"request_id": "123e4567-e89b-12d3-a456-426614174000"
}
}{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "The provided data is not valid",
"details": {
"campo": "specific error message"
}
},
"meta": {
"timestamp": "2025-01-15T10:30:00Z",
"request_id": "123e4567-e89b-12d3-a456-426614174000"
}
}{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation error",
"details": {
"field_name": "Field is required"
}
},
"meta": {
"timestamp": "2025-01-15T10:30:00Z",
"request_id": "123e4567-e89b-12d3-a456-426614174000"
}
}{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "The provided data is not valid",
"details": {
"campo": "specific error message"
}
},
"meta": {
"timestamp": "2025-01-15T10:30:00Z",
"request_id": "123e4567-e89b-12d3-a456-426614174000"
}
}{
"success": false,
"error": {
"code": "INTERNAL_ERROR",
"message": "Internal server error"
},
"meta": {
"timestamp": "2025-01-15T10:30:00Z",
"request_id": "123e4567-e89b-12d3-a456-426614174000"
}
}Import clients from CSV with structured preview POST
Imports multiple clients from a CSV file with full preview of all records. **Key features**: - **Structured preview**: Returns all parsed records (valid and with errors) - **Parallel validation**: NIFs validated concurrently against VeriFactu - **Granular feedback**: Client-specific errors and warnings - **Editable data**: Structured JSON for editable table in frontend **Recommended flow**: 1. **Initial upload**: Call with `dry_run=true` to get preview 2. **Display table**: Frontend shows parsed data with errors/warnings 3. **Inline editing**: User corrects data directly in the table 4. **Final import**: Send corrected data with `dry_run=false` **Format**: Must follow CSV template format (downloadable from `/clientes/template-csv`). **Security limits**: - Max size: 5MB - Max 1,000 records per file - Rate limiting: 3 imports per hour **Validation**: - Required headers per template - Full validation of each row with business rules - Parallel NIF validation against AEAT registry (VeriFactu) - Duplicate detection in CSV and database **Validation statuses**: - `VALID`: Client valid, ready to import - `WARNING`: Client valid but with warnings (eg: missing email) - `ERROR`: Client invalid, cannot process - `DUPLICATE`: Duplicate client (in CSV or DB) - `NIF_INVALID`: NIF invalid in AEAT registry
List clients GET
Returns a paginated list of clients with optional filters