Clientes

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

POST
/clientes/import-holded-contactos
X-API-Key<token>

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

filestring

Excel file (.xlsx) of contacts exported from Holded

preview?boolean

If true: parsing and mapping only without importing to DB. If false: parsing + mapping + actual import.

Defaulttrue

Response 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"
  }
}