# 📄 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! 🚀**