← Volver al inicio
# 📄 Extractor de RUT - Documentación para Clientes

## 🎯 ¿Qué es?

El **Extractor de RUT** es una API que extrae automáticamente información de documentos RUT (Registro Único Tributario) colombianos en formato PDF usando inteligencia artificial.

**Función principal:** 
- Sube un PDF de RUT
- Obtén todos los datos extraídos en formato JSON
- Úsalos en tu aplicación

---

## 🚀 Inicio Rápido (30 segundos)

### **Opción 1: Interfaz Web (La más fácil)**

1. Abre: `https://datosrut.codepyme.com`
2. Arrastra tu RUT en PDF
3. Click en "Extraer Información"
4. ¡Listo! Ves todos los datos

### **Opción 2: Integración en tu código**

Elige tu lenguaje:
- [Python](#-python)
- [JavaScript](#-javascript)
- [Node.js](#-nodejs)
- [cURL](#-curl)
- [C#](#-csharp)

---

## 📋 Endpoint de la API

```
URL:     https://datosrut.codepyme.com/procesar
Método:  POST
Entrada: Archivo PDF
Salida:  JSON con datos extraídos
```

---

## 🐍 Python

### **Instalación**

```bash
pip install requests
```

### **Código**

```python
import requests
import json

def extraer_rut(ruta_pdf):
    """
    Extrae información de un RUT PDF
    
    Args:
        ruta_pdf: ruta al archivo PDF (ej: "rut.pdf")
        
    Returns:
        dict con los datos extraídos o None si hay error
    """
    
    url = 'https://datosrut.codepyme.com/procesar'
    
    try:
        with open(ruta_pdf, 'rb') as archivo:
            files = {'file': archivo}
            response = requests.post(url, files=files)
            response.raise_for_status()
            
            data = response.json()
            
            if data.get('error'):
                print(f"❌ Error: {data['error']}")
                return None
            
            print("✅ Datos extraídos exitosamente")
            return data['datos']
            
    except Exception as e:
        print(f"❌ Error: {e}")
        return None

# EJEMPLO DE USO
if __name__ == '__main__':
    resultado = extraer_rut('rut.pdf')
    
    if resultado:
        # Ver todos los datos
        print(json.dumps(resultado, indent=2, ensure_ascii=False))
        
        # Acceder a datos específicos
        nit = resultado['identificacion']['nit']
        razon_social = resultado['datos_juridicos']['razon_social']
        email = resultado['ubicacion']['correo_electronico']
        
        print(f"\n📊 Datos Extraídos:")
        print(f"NIT: {nit}")
        print(f"Razón Social: {razon_social}")
        print(f"Email: {email}")
```

### **Uso en Django/Flask**

```python
from flask import Flask, request, jsonify
import requests

app = Flask(__name__)

@app.route('/procesar-rut', methods=['POST'])
def procesar_rut():
    if 'file' not in request.files:
        return jsonify({'error': 'No se proporcionó archivo'}), 400
    
    archivo = request.files['file']
    
    # Enviar a la API
    url = 'https://datosrut.codepyme.com/procesar'
    files = {'file': (archivo.filename, archivo.stream, archivo.content_type)}
    
    try:
        response = requests.post(url, files=files)
        data = response.json()
        
        return jsonify(data)
    except Exception as e:
        return jsonify({'error': str(e)}), 500

if __name__ == '__main__':
    app.run(debug=True)
```

---

## 🌐 JavaScript / Fetch

### **HTML Simple**

```html
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <title>Extractor RUT</title>
</head>
<body>
    <h1>Extractor de RUT</h1>
    
    <input type="file" id="fileInput" accept=".pdf" />
    <button onclick="extraerRUT()">Extraer</button>
    
    <pre id="resultado"></pre>
    
    <script>
        async function extraerRUT() {
            const archivo = document.getElementById('fileInput').files[0];
            
            if (!archivo) {
                alert('Selecciona un PDF primero');
                return;
            }
            
            const formData = new FormData();
            formData.append('file', archivo);
            
            try {
                const response = await fetch('https://datosrut.codepyme.com/procesar', {
                    method: 'POST',
                    body: formData
                });
                
                const data = await response.json();
                
                if (data.error) {
                    alert('Error: ' + data.error);
                    return;
                }
                
                document.getElementById('resultado').textContent = 
                    JSON.stringify(data.datos, null, 2);
                    
            } catch (error) {
                alert('Error: ' + error.message);
            }
        }
    </script>
</body>
</html>
```

### **Con manejo de errores**

```javascript
async function extraerRUT(archivoPDF) {
    const formData = new FormData();
    formData.append('file', archivoPDF);
    
    try {
        const response = await fetch('https://datosrut.codepyme.com/procesar', {
            method: 'POST',
            body: formData
        });
        
        if (!response.ok) {
            throw new Error(`Error HTTP: ${response.status}`);
        }
        
        const data = await response.json();
        
        if (data.error) {
            console.error('Error en API:', data.error);
            return null;
        }
        
        console.log('✅ Datos extraídos:', data.datos);
        
        // Acceder a datos específicos
        const nit = data.datos.identificacion.nit;
        const razónSocial = data.datos.datos_juridicos.razon_social;
        
        return data.datos;
        
    } catch (error) {
        console.error('Error en la solicitud:', error);
        return null;
    }
}

// USO
const fileInput = document.getElementById('fileInput');
fileInput.addEventListener('change', async (e) => {
    const resultado = await extraerRUT(e.target.files[0]);
    if (resultado) {
        console.log(resultado);
    }
});
```

---

## 📦 Node.js / Express

### **Instalación**

```bash
npm install express multer axios
```

### **Servidor**

```javascript
const express = require('express');
const multer = require('multer');
const axios = require('axios');
const fs = require('fs');
const FormData = require('form-data');

const app = express();
const upload = multer({ dest: 'uploads/' });

app.post('/procesar-rut', upload.single('file'), async (req, res) => {
    try {
        if (!req.file) {
            return res.status(400).json({ error: 'No se proporcionó archivo' });
        }
        
        const formData = new FormData();
        formData.append('file', fs.createReadStream(req.file.path));
        
        const response = await axios.post(
            'https://datosrut.codepyme.com/procesar',
            formData,
            { headers: formData.getHeaders() }
        );
        
        // Limpiar archivo temporal
        fs.unlinkSync(req.file.path);
        
        res.json(response.data);
        
    } catch (error) {
        res.status(500).json({ error: error.message });
    }
});

app.listen(3000, () => {
    console.log('✅ Servidor en http://localhost:3000');
});
```

### **Cliente Node.js**

```javascript
const axios = require('axios');
const fs = require('fs');
const FormData = require('form-data');

async function extraerRUT(rutaArchivo) {
    try {
        const formData = new FormData();
        formData.append('file', fs.createReadStream(rutaArchivo));
        
        const response = await axios.post(
            'https://datosrut.codepyme.com/procesar',
            formData,
            { headers: formData.getHeaders() }
        );
        
        console.log('✅ Datos extraídos:');
        console.log(JSON.stringify(response.data.datos, null, 2));
        
        return response.data.datos;
        
    } catch (error) {
        console.error('❌ Error:', error.message);
        return null;
    }
}

// USO
extraerRUT('rut.pdf');
```

---

## 🐚 cURL

### **Comando básico**

```bash
curl -X POST \
  -F "file=@rut.pdf" \
  https://datosrut.codepyme.com/procesar
```

### **Guardar resultado en archivo**

```bash
curl -X POST \
  -F "file=@rut.pdf" \
  https://datosrut.codepyme.com/procesar > resultado.json
```

### **Con formato bonito (requiere jq)**

```bash
curl -X POST \
  -F "file=@rut.pdf" \
  https://datosrut.codepyme.com/procesar | jq '.'
```

---

## 🔷 C# / .NET

### **Instalación**

```bash
dotnet add package Newtonsoft.Json
```

### **Código**

```csharp
using System;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json;

class Program
{
    static async Task Main(string[] args)
    {
        await ExtraerRUT("rut.pdf");
    }
    
    static async Task ExtraerRUT(string rutaArchivo)
    {
        using (var client = new HttpClient())
        {
            using (var content = new MultipartFormDataContent())
            {
                var fileContent = new ByteArrayContent(
                    File.ReadAllBytes(rutaArchivo)
                );
                fileContent.Headers.ContentType = 
                    new System.Net.Http.Headers.MediaTypeHeaderValue("application/pdf");
                
                content.Add(fileContent, "file", Path.GetFileName(rutaArchivo));
                
                try
                {
                    var response = await client.PostAsync(
                        "https://datosrut.codepyme.com/procesar",
                        content
                    );
                    
                    var resultado = await response.Content.ReadAsStringAsync();
                    var datos = JsonConvert.DeserializeObject(resultado);
                    
                    Console.WriteLine(JsonConvert.SerializeObject(
                        datos, 
                        Formatting.Indented
                    ));
                }
                catch (Exception e)
                {
                    Console.WriteLine($"❌ Error: {e.Message}");
                }
            }
        }
    }
}
```

---

## 📊 Estructura de Respuesta

Cuando envías un RUT, recibes un JSON como este:

```json
{
  "archivo": "rut.pdf",
  "exito": true,
  "datos": {
    "tipo_persona": "juridica",
    "identificacion": {
      "nit": "9015648075",
      "digito_verificacion": "5",
      "tipo_documento": "Persona jurídica",
      "numero_documento": null,
      "fecha_expedicion": null
    },
    "datos_juridicos": {
      "razon_social": "CODEPYME SAS",
      "nombre_comercial": null,
      "sigla": null
    },
    "ubicacion": {
      "pais": "COLOMBIA",
      "departamento": "Antioquia",
      "ciudad_municipio": "Medellín",
      "direccion_principal": "CL 9 SUR 79 C 139 AP 416",
      "codigo_postal": null,
      "telefono_1": "3005237052",
      "telefono_2": "3226327304",
      "correo_electronico": "contabilidad@codepyme.com"
    },
    "actividad_economica": {
      "codigo_principal": "6201",
      "descripcion_principal": null,
      "codigo_secundaria": "4741",
      "fecha_inicio_principal": "2025-04-02",
      "fecha_inicio_secundaria": "2025-04-02"
    },
    "responsabilidades": {
      "codigos": ["05", "07", "14", "42", "48", "55"],
      "descripciones": [...]
    },
    "representante_legal": {
      "nombre": "ESTEBAN ARROYAVE URREGO",
      "tipo_documento": "Cédula de Ciudadanía",
      "numero_documento": "1039447608",
      "digito_verificacion": "8",
      "cargo": "Representante Legal Principal",
      "fecha_inicio": "2025-04-28"
    },
    "revisor_fiscal": {
      "nombre": "JUAN CARLOS COLLAZOS VELASCO",
      "tipo_documento": "Cédula de Ciudadanía",
      "numero_documento": "1054933706"
    },
    "contador": {
      "nombre": null,
      "tipo_documento": null,
      "numero_documento": null
    },
    "socios": [
      {
        "nombre": "JAIME ANDRES FLOREZ MONCADA",
        "documento": "717590688",
        "porcentaje_participacion": "20%"
      }
    ],
    "establecimientos": []
  }
}
```

---

## ❓ Preguntas Frecuentes

### **¿Qué formatos de archivo soporta?**
Solo PDF. Asegúrate que el archivo sea un PDF válido.

### **¿Cuánto tiempo tarda?**
Entre 10-30 segundos dependiendo de la complejidad del RUT.

### **¿Hay límite de solicitudes?**
No hay límite actualmente.

### **¿Cómo manejo los errores?**
Verifica si `data.error` existe en la respuesta:
```javascript
if (data.error) {
    console.error('Error:', data.error);
}
```

### **¿Qué pasa si un campo no está en el PDF?**
Se devuelve `null` para ese campo.

### **¿Es segura mi información?**
Sí, los archivos se procesan y eliminan inmediatamente. No se almacenan.

---

## 🔗 Contacto

Si tienes problemas o necesitas soporte, contacta al equipo de desarrollo.

**URL de la API:** `https://datosrut.codepyme.com`  
**Interfaz Web:** `https://datosrut.codepyme.com`

---

**¡Listo para usar! 🚀**