API nuby V2
Aquí encontrarás el catálogo detallado de todos los servicios que nuestra plataforma tiene disponibles para ti.
Para que quede súper claro, piensa en esta sección como si fuera el menú de un restaurante o un directorio muy bien organizado. Aquí te vamos a mostrar qué opciones tienes disponibles y cómo pedirnos la información.
En el mundo de la tecnología, a estas opciones las llamamos endpoints (puntos de conexión a los que te diriges para pedir algo específico). A lo largo de este documento te explicaremos:
- Qué hace cada uno de estos endpoints o servicios.
- Qué datos exactos debes enviarnos para que te entendamos (a esto le llamamos parámetros o datos de petición).
- Qué información exacta te va a devolver nuestro sistema como respuesta.
Con este directorio a la mano, tú o tu equipo técnico sabrán exactamente cómo comunicarse con el sistema, permitiendo que tus plataformas externas se integren a la perfección con el ecosistema (al que llamamos "instancia") de tu inmobiliaria en nuby.
¡Explora nuestro directorio y descubre toda la información que puedes consultar y gestionar!
- Autenticación
- Maestras
- Propiedades / Listar Estados
- Propiedades / Listar Clases de Inmueble
- Propiedades / Listar Tipos de Servicios
- Propiedades / Listar Características
- Propiedades / Listar Características por Clase de Inmueble
- Propiedades
- Asesores
- Facturas
- Contabilidad
- Contratos
Autenticación
Bienvenido al filtro de seguridad de nuestra API. Antes de consultar o enviar información, necesitamos validar que tu conexión tenga los permisos necesarios para proteger tus datos en todo momento.
¿Cómo funciona el acceso? Piensa en esta sección como la recepción de un edificio privado. Aquí te explicamos cómo tu aplicación debe "identificarse" para obtener un token (tu llave de acceso temporal).
Reglas clave de tu token de acceso:
- Pase obligatorio: Absolutamente todos los servicios de nuestro sistema te exigirán esta llave antes de procesar tus peticiones.
- Vigencia limitada (1 hora): Por tu seguridad, el token tiene un ciclo de vida corto para evitar accesos no autorizados prolongados.
- Renovación continua: Cuando el tiempo se agote, tu sistema simplemente debe solicitar uno nuevo a través de esta sección para seguir trabajando sin interrupciones.
¡Explora cómo generar tu primera llave para comenzar a integrarte de forma segura!
Login
Antes de que tus sistemas puedan comunicarse con nuestra API, necesitan identificarse. Este servicio es como la recepción de nuestro edificio digital: aquí entregas tus credenciales y, a cambio, recibes un "pase de invitado" temporal (llamado Token). Necesitarás presentar este pase para que el sistema te permita acceder a cualquier otra sección (como contratos, facturas o propiedades).
¿Aún no tienes tus credenciales de acceso?
Para usar este servicio, primero necesitas un usuario y contraseña especiales para tu aplicación. Descubre cómo crear un nuevo cliente OAuth2 en nuby para consumo de la API paso a paso aquí.
1. El Endpoint (La dirección web)
Apunta tu sistema a la siguiente dirección. Recuerda reemplazar {{instancia}} por la dirección web completa que utilizas para ingresar a tu plataforma.
POST https://{{instancia}}/service/v2/public/auth/login
¿Qué debes colocar en {{instancia}}?
Es muy sencillo: corresponde a la dirección web principal que utilizas a diario para ingresar a tu plataforma (incluyendo la terminación .nuby.app o .arrendasoft.co).
Por ejemplo, si para entrar a tu sistema escribes inmobiliaria.nuby.app o inmobiliaria.arrendasoft.co en tu navegador, esa será exactamente tu instancia. Solo asegúrate de no incluir el "https://" ni barras diagonales ("/") al final.
2. La Petición (¿Qué debes enviarnos?)
Tu sistema debe enviarnos un paquete de datos en formato JSON indicando que el contenido es application/json. El cuerpo de tu petición debe verse así:
{
"username": "TU_CLIENT_ID",
"password": "TU_SECRET_KEY"
}
| username | Es el ID del Cliente (OAuth2) que generaste previamente en el sistema. |
| password | Es la Clave Secreta (Secret Key / OAuth2) vinculada a tu usuario. |
3. La Respuesta (¿Qué te entregaremos?)
Si tus credenciales son correctas, el sistema te dará la bienvenida entregándote tu pase de acceso (Token). La respuesta se verá similar a esta:
{
"message": null,
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"expiration": 1690540790
}
| token | Tu llave de acceso. A partir de ahora, en todas tus siguientes consultas a nuestra plataforma, deberás incluir este código en los encabezados (Headers) de tu petición usando el formato: Authorization: Bearer TU_TOKEN_AQUI |
| expiration | La fecha y hora exacta (en formato timestamp) en la que este pase dejará de funcionar. |
| message | Mensaje de confirmación o texto explicativo (en caso de presentarse alguna novedad). |
4. Seguridad y Posibles Errores
¡Tu pase tiene fecha de caducidad!
Por medidas de seguridad, el token que te entregamos solo dura 1 hora. Una vez transcurrido ese tiempo, el pase expirará y el sistema te bloqueará el acceso devolviéndote un error 401 Unauthorized. Cuando esto ocurra, tu sistema simplemente debe volver a consumir este servicio de Login para pedir un pase nuevo y continuar trabajando.
Así se ve el error que te devolverá el sistema cuando tu token se haya vencido o intentes usar un pase inválido:
{
"statusCode": 401,
"error": {
"type": "SERVER_ERROR",
"description": "JWT Token expired."
}
}
5. Ejemplos de integración
Aquí tienes ejemplos de código listos para que tus desarrolladores los adapten a tu plataforma:
cURL
curl -X POST "https://{{instancia}}/service/v2/public/auth/login" \
-H "Content-Type: application/json" \
-d '{
"username": "TU_CLIENT_ID",
"password": "TU_SECRET_KEY"
}'
PHP
<?php
$instance = 'tu_instancia'; // Reemplaza con tu instancia real
$username = 'TU_CLIENT_ID'; // Reemplaza con el ID de cliente proporcionado
$password = 'TU_SECRET_KEY'; // Reemplaza con la clave secreta proporcionada
$url = "https://{$instance}/service/v2/public/auth/login";
$data = json_encode([
'username' => $username,
'password' => $password
]);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Content-Length: ' . strlen($data)
]);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
} else {
echo "Código de estado HTTP: " . $http_code . "\n";
$responseData = json_decode($response, true);
if (isset($responseData['token'])) {
echo "¡Éxito! Tu Token de Autenticación es: " . $responseData['token'] . "\n";
} else {
echo "Autenticación fallida.\n";
}
}
curl_close($ch);
?>
Python
import requests
# 1. Configura tus datos de acceso
instancia = 'mi-inmobiliaria.nuby.app' # Reemplaza con tu dirección web completa
username = 'TU_CLIENT_ID' # Reemplaza con el ID de cliente proporcionado
password = 'TU_SECRET_KEY' # Reemplaza con la clave secreta proporcionada
# 2. Prepara la dirección y los datos a enviar
url = f"https://{instancia}/service/v2/public/auth/login"
headers = {
"Content-Type": "application/json"
}
payload = {
"username": username,
"password": password
}
# 3. Envía la petición a la plataforma y procesa la respuesta
try:
# Enviamos la petición POST (la librería convierte automáticamente el payload a JSON)
response = requests.post(url, json=payload, headers=headers)
print(f"Código de estado HTTP: {response.status_code}")
# Si la petición es exitosa (código 200 OK)
if response.status_code == 200:
data = response.json()
token = data.get("token")
print(f"¡Éxito! Tu Token de Autenticación es: {token}")
else:
print("Autenticación fallida.")
print(f"Detalle del error: {response.text}")
except Exception as e:
print(f"Ocurrió un error de conexión: {e}")
JavaScript
// 1. Configura tus datos de acceso
const instancia = 'mi-inmobiliaria.nuby.app'; // Reemplaza con tu dirección web completa
const username = 'TU_CLIENT_ID'; // Reemplaza con el ID de cliente proporcionado
const password = 'TU_SECRET_KEY'; // Reemplaza con la clave secreta proporcionada
// 2. Prepara la dirección y los datos a enviar
const url = `https://${instancia}/service/v2/public/auth/login`;
const data = {
username: username,
password: password
};
// 3. Función para enviar la petición a la plataforma
async function realizarLogin() {
try {
// Configuramos y enviamos la petición POST
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data) // Convertimos los datos a formato JSON
});
console.log(`Código de estado HTTP: ${response.status}`);
// Si la petición es exitosa (códigos 200-299)
if (response.ok) {
const responseData = await response.json();
console.log(`¡Éxito! Tu Token de Autenticación es: ${responseData.token}`);
} else {
console.log("Autenticación fallida.");
const errorData = await response.text();
console.log(`Detalle del error: ${errorData}`);
}
} catch (error) {
console.error(`Ocurrió un error de conexión: ${error}`);
}
}
// 4. Ejecutamos la función
realizarLogin();
Power Query M (Excel / Power BI)
let
// 1. Configura tus datos de acceso
instancia = "mi-inmobiliaria.nuby.app", // Reemplaza con tu dirección web completa
username = "TU_CLIENT_ID", // Reemplaza con el ID de cliente proporcionado
password = "TU_SECRET_KEY", // Reemplaza con la clave secreta proporcionada
// 2. Prepara la dirección y el cuerpo de la petición (en formato JSON)
url = "https://" & instancia & "/service/v2/public/auth/login",
body = Json.FromValue([
username = username,
password = password
]),
// 3. Envía la petición POST a la plataforma
response = Web.Contents(url, [
Headers = [#"Content-Type"="application/json"],
Content = body
]),
// 4. Decodifica la respuesta JSON y extrae el token
jsonResponse = Json.Document(response),
token = jsonResponse[token]
in
token
Maestras
Bienvenido a la base estructural de tus integraciones. En esta sección detallamos los servicios disponibles para consultar las "entidades maestras" en la API REST de nuby.
¿Qué son exactamente las entidades maestras? Para evitar términos técnicos complejos, piensa en ellas como los diccionarios predefinidos, los catálogos base o las listas desplegables de tu sistema.
¿Por qué son tan importantes para tu conexión?
- Estandarización total: Son listas fijas que organizan la información para que todo se mantenga ordenado y sin ambigüedades (garantizando, por ejemplo, que el sistema identifique correctamente una "Casa" frente a un "Apartamento").
- Sincronización de lenguaje: Permiten que tus plataformas externas lean, entiendan y clasifiquen los datos usando exactamente los mismos parámetros y reglas que utiliza tu inmobiliaria.
¡Explora las opciones a continuación para sincronizar tus catálogos y asegurar que todos tus sistemas hablen el mismo idioma!
Propiedades / Listar Estados
Permite obtener la lista completa de estados posibles que puede tener una propiedad en el sistema. Cada elemento de la respuesta contiene el identificador numérico del estado y su descripción en texto. Este servicio es útil para poblar selectores o filtros de estado en tus integraciones.
¿Para qué sirve este servicio?
Úsalo para conocer los valores válidos del campo estado al momento de filtrar, crear o actualizar propiedades a través de la API. Así te aseguras de enviar siempre un valor reconocido por el sistema.
1. El Endpoint (La dirección web)
Apunta tu sistema a la siguiente dirección. Recuerda reemplazar {{instancia}} por la dirección web completa que utilizas para ingresar a tu plataforma.
GET https://{{instancia}}/service/v2/public/masters/properties/states
¿Qué debes colocar en {{instancia}}?
Es muy sencillo: corresponde a la dirección web principal que utilizas a diario para ingresar a tu plataforma (incluyendo la terminación .nuby.app o .arrendasoft.co).
Por ejemplo, si para entrar a tu sistema escribes inmobiliaria.nuby.app o inmobiliaria.arrendasoft.co en tu navegador, esa será exactamente tu instancia. Solo asegúrate de no incluir el "https://" ni barras diagonales ("/") al final.
2. La Petición (¿Qué debes enviarnos?)
Este servicio no requiere cuerpo en la petición. Solo necesitas enviar los encabezados correctos:
| Método | GET |
| Content-Type | application/json |
| Authorization | Bearer token, Token obtenido al consumir el servicio Login |
¿Aún no tienes tu Token de acceso?
Para consumir este servicio necesitas un Token vigente. Consulta el servicio de Login para aprender cómo obtenerlo.
3. La Respuesta (¿Qué te entregaremos?)
Si tu Token es válido, el sistema te devolverá una lista con todos los estados posibles de una propiedad. La respuesta se verá así:
[
{
"id": 1,
"estado": "Activa"
},
{
"id": 0,
"estado": "Arrendada"
},
{
"id": 2,
"estado": "Inactiva"
},
{
"id": 3,
"estado": "Vendida"
}
]
Tabla con la descripción de cada campo del JSON:
| Clave | Descripción |
|---|---|
| id | Identificador numérico del estado. Utiliza este valor cuando necesites filtrar propiedades por estado o actualizar el estado de una propiedad a través de la API. |
| estado | Nombre descriptivo del estado en texto legible (por ejemplo: "Activa", "Arrendada"). |
4. Seguridad y Posibles Errores
¡Tu pase tiene fecha de caducidad!
Por medidas de seguridad, el token que te entregamos solo dura 1 hora. Una vez transcurrido ese tiempo, el pase expirará y el sistema te bloqueará el acceso devolviéndote un error 401. Cuando esto ocurra, tu sistema simplemente debe volver a consumir el servicio de Login para pedir un pase nuevo y continuar trabajando.
Así se ve el error que te devolverá el sistema cuando tu token se haya vencido o intentes usar un pase inválido:
{
"statusCode": 401,
"error": {
"type": "SERVER_ERROR",
"description": "JWT Token expired."
}
}
Otros posibles errores:
| Código HTTP | Descripción |
|---|---|
| 400 | Token no enviado o con formato incorrecto. Asegúrate de incluir el encabezado Authorization: Bearer TU_TOKEN. |
| 401 | Token expirado o inválido. Solicita uno nuevo a través del servicio de Login. |
| 403 | El cliente OAuth no tiene el scope necesario para esta operación. Para endpoints GET se requiere el scope read. Mensaje: "Insufficient scope. Required: 'read', granted: '{scope_actual}'." |
5. Ejemplos de integración
Aquí tienes ejemplos de código listos para que tus desarrolladores los adapten a tu plataforma:
cURL
curl -X GET "https://{{instancia}}/service/v2/public/masters/properties/states" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer TU_TOKEN_AQUI"
PHP
<?php
$instance = 'tu_instancia'; // Reemplaza con tu instancia real
$token = 'TU_TOKEN_AQUI'; // Token obtenido del servicio de Login
$url = "https://{$instance}/service/v2/public/masters/properties/states";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Authorization: Bearer ' . $token
]);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (curl_errno($ch)) {
echo 'Error: ' . curl_error($ch);
} else {
echo "Código de estado HTTP: " . $http_code . "\n";
if ($http_code === 200) {
$estados = json_decode($response, true);
echo "Estados de propiedades:\n";
foreach ($estados as $estado) {
echo " ID: {$estado['id']} - {$estado['estado']}\n";
}
} else {
echo "Error al consultar los estados.\n";
echo $response . "\n";
}
}
curl_close($ch);
?>
Python
import requests
# 1. Configura tus datos de acceso
instancia = 'mi-inmobiliaria.nuby.app' # Reemplaza con tu dirección web completa
token = 'TU_TOKEN_AQUI' # Token obtenido del servicio de Login
# 2. Prepara la dirección y los encabezados
url = f"https://{instancia}/service/v2/public/masters/properties/states"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {token}"
}
# 3. Envía la petición GET y procesa la respuesta
try:
response = requests.get(url, headers=headers)
print(f"Código de estado HTTP: {response.status_code}")
if response.status_code == 200:
estados = response.json()
print("Estados de propiedades:")
for estado in estados:
print(f" ID: {estado['id']} - {estado['estado']}")
else:
print("Error al consultar los estados.")
print(f"Detalle del error: {response.text}")
except Exception as e:
print(f"Ocurrió un error de conexión: {e}")
JavaScript
// 1. Configura tus datos de acceso
const instancia = 'mi-inmobiliaria.nuby.app'; // Reemplaza con tu dirección web completa
const token = 'TU_TOKEN_AQUI'; // Token obtenido del servicio de Login
// 2. Prepara la dirección
const url = `https://${instancia}/service/v2/public/masters/properties/states`;
// 3. Función para consultar los estados de propiedades
async function consultarEstados() {
try {
const response = await fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
}
});
console.log(`Código de estado HTTP: ${response.status}`);
if (response.ok) {
const estados = await response.json();
console.log('Estados de propiedades:');
estados.forEach(estado => {
console.log(` ID: ${estado.id} - ${estado.estado}`);
});
} else {
console.log('Error al consultar los estados.');
const errorData = await response.text();
console.log(`Detalle del error: ${errorData}`);
}
} catch (error) {
console.error(`Ocurrió un error de conexión: ${error}`);
}
}
// 4. Ejecutamos la función
consultarEstados();
Power Query M (Excel / Power BI)
let
// 1. Configura tus datos de acceso
instancia = "mi-inmobiliaria.nuby.app", // Reemplaza con tu dirección web completa
token = "TU_TOKEN_AQUI", // Token obtenido del servicio de Login
// 2. Prepara la dirección de la petición
url = "https://" & instancia & "/service/v2/public/masters/properties/states",
// 3. Envía la petición GET con el token de autenticación
response = Web.Contents(url, [
Headers = [
#"Content-Type" = "application/json",
#"Authorization" = "Bearer " & token
]
]),
// 4. Decodifica la respuesta JSON y conviértela en tabla
jsonResponse = Json.Document(response),
tabla = Table.FromList(jsonResponse, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
expandido = Table.ExpandRecordColumn(tabla, "Column1", {"id", "estado"}, {"ID", "Estado"})
in
expandido
Propiedades / Listar Clases de Inmueble
Permite obtener la lista completa de clases de inmueble disponibles en el sistema. Cada elemento de la respuesta contiene el identificador único de la clase y su nombre descriptivo. Este servicio es útil para poblar selectores de tipo de inmueble en tus integraciones.
¿Para qué sirve este servicio?
Úsalo para conocer los valores válidos del campo clase de inmueble al momento de filtrar o registrar propiedades a través de la API. Así te aseguras de enviar siempre un valor reconocido por el sistema. Las clases de inmueble disponibles dependen de la configuración de cada instancia.
1. El Endpoint (La dirección web)
Apunta tu sistema a la siguiente dirección. Recuerda reemplazar {{instancia}} por la dirección web completa que utilizas para ingresar a tu plataforma.
GET https://{{instancia}}/service/v2/public/masters/properties/property-classes
¿Qué debes colocar en {{instancia}}?
Es muy sencillo: corresponde a la dirección web principal que utilizas a diario para ingresar a tu plataforma (incluyendo la terminación .nuby.app o .arrendasoft.co).
Por ejemplo, si para entrar a tu sistema escribes inmobiliaria.nuby.app o inmobiliaria.arrendasoft.co en tu navegador, esa será exactamente tu instancia. Solo asegúrate de no incluir el "https://" ni barras diagonales ("/") al final.
2. La Petición (¿Qué debes enviarnos?)
Este servicio no requiere cuerpo en la petición. Solo necesitas enviar los encabezados correctos:
| Método | GET |
| Content-Type | application/json |
| Authorization | Bearer token, Token obtenido al consumir el servicio Login |
¿Aún no tienes tu Token de acceso?
Para consumir este servicio necesitas un Token vigente. Consulta el servicio de Login para aprender cómo obtenerlo.
3. La Respuesta (¿Qué te entregaremos?)
Si tu Token es válido, el sistema te devolverá una lista con todas las clases de inmueble configuradas en tu instancia. La respuesta se verá similar a esta:
[
{
"id": "1367",
"clase": "Amoblados"
},
{
"id": "1253",
"clase": "Apartaestudio"
},
{
"id": "1247",
"clase": "Apartamento"
},
{
"id": "1248",
"clase": "Bodega"
},
{
"id": "1249",
"clase": "Casa"
}
]
Nota: Los valores de id y la cantidad de clases disponibles pueden variar entre instancias, ya que dependen de la configuración particular de cada inmobiliaria. La lista se devuelve ordenada alfabéticamente por el nombre de la clase.
Tabla con la descripción de cada campo del JSON:
| Clave | Descripción |
|---|---|
| id | Identificador único de la clase de inmueble (tipo texto). Utiliza este valor cuando necesites filtrar propiedades por clase de inmueble a través de la API. |
| clase | Nombre descriptivo de la clase de inmueble (por ejemplo: "Apartamento", "Casa", "Bodega"). |
4. Seguridad y Posibles Errores
¡Tu pase tiene fecha de caducidad!
Por medidas de seguridad, el token que te entregamos solo dura 1 hora. Una vez transcurrido ese tiempo, el pase expirará y el sistema te bloqueará el acceso devolviéndote un error 401. Cuando esto ocurra, tu sistema simplemente debe volver a consumir el servicio de Login para pedir un pase nuevo y continuar trabajando.
Así se ve el error que te devolverá el sistema cuando tu token se haya vencido o intentes usar un pase inválido:
{
"statusCode": 401,
"error": {
"type": "SERVER_ERROR",
"description": "JWT Token expired."
}
}
Otros posibles errores:
| Código HTTP | Descripción |
|---|---|
| 400 | Token no enviado o con formato incorrecto. Asegúrate de incluir el encabezado Authorization: Bearer TU_TOKEN. |
| 401 | Token expirado o inválido. Solicita uno nuevo a través del servicio de Login. |
| 403 | El cliente OAuth no tiene el scope necesario para esta operación. Para endpoints GET se requiere el scope read. Mensaje: "Insufficient scope. Required: 'read', granted: '{scope_actual}'." |
5. Ejemplos de integración
Aquí tienes ejemplos de código listos para que tus desarrolladores los adapten a tu plataforma:
cURL
curl -X GET "https://{{instancia}}/service/v2/public/masters/properties/property-classes" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer TU_TOKEN_AQUI"
PHP
<?php
$instance = 'tu_instancia'; // Reemplaza con tu instancia real
$token = 'TU_TOKEN_AQUI'; // Token obtenido del servicio de Login
$url = "https://{$instance}/service/v2/public/masters/properties/property-classes";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Authorization: Bearer ' . $token
]);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (curl_errno($ch)) {
echo 'Error: ' . curl_error($ch);
} else {
echo "Código de estado HTTP: " . $http_code . "\n";
if ($http_code === 200) {
$clases = json_decode($response, true);
echo "Clases de inmueble:\n";
foreach ($clases as $clase) {
echo " ID: {$clase['id']} - {$clase['clase']}\n";
}
} else {
echo "Error al consultar las clases de inmueble.\n";
echo $response . "\n";
}
}
curl_close($ch);
?>
Python
import requests
# 1. Configura tus datos de acceso
instancia = 'mi-inmobiliaria.nuby.app' # Reemplaza con tu dirección web completa
token = 'TU_TOKEN_AQUI' # Token obtenido del servicio de Login
# 2. Prepara la dirección y los encabezados
url = f"https://{instancia}/service/v2/public/masters/properties/property-classes"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {token}"
}
# 3. Envía la petición GET y procesa la respuesta
try:
response = requests.get(url, headers=headers)
print(f"Código de estado HTTP: {response.status_code}")
if response.status_code == 200:
clases = response.json()
print("Clases de inmueble:")
for clase in clases:
print(f" ID: {clase['id']} - {clase['clase']}")
else:
print("Error al consultar las clases de inmueble.")
print(f"Detalle del error: {response.text}")
except Exception as e:
print(f"Ocurrió un error de conexión: {e}")
JavaScript
// 1. Configura tus datos de acceso
const instancia = 'mi-inmobiliaria.nuby.app'; // Reemplaza con tu dirección web completa
const token = 'TU_TOKEN_AQUI'; // Token obtenido del servicio de Login
// 2. Prepara la dirección
const url = `https://${instancia}/service/v2/public/masters/properties/property-classes`;
// 3. Función para consultar las clases de inmueble
async function consultarClasesDeInmueble() {
try {
const response = await fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
}
});
console.log(`Código de estado HTTP: ${response.status}`);
if (response.ok) {
const clases = await response.json();
console.log('Clases de inmueble:');
clases.forEach(clase => {
console.log(` ID: ${clase.id} - ${clase.clase}`);
});
} else {
console.log('Error al consultar las clases de inmueble.');
const errorData = await response.text();
console.log(`Detalle del error: ${errorData}`);
}
} catch (error) {
console.error(`Ocurrió un error de conexión: ${error}`);
}
}
// 4. Ejecutamos la función
consultarClasesDeInmueble();
Power Query M (Excel / Power BI)
let
// 1. Configura tus datos de acceso
instancia = "mi-inmobiliaria.nuby.app", // Reemplaza con tu dirección web completa
token = "TU_TOKEN_AQUI", // Token obtenido del servicio de Login
// 2. Prepara la dirección de la petición
url = "https://" & instancia & "/service/v2/public/masters/properties/property-classes",
// 3. Envía la petición GET con el token de autenticación
response = Web.Contents(url, [
Headers = [
#"Content-Type" = "application/json",
#"Authorization" = "Bearer " & token
]
]),
// 4. Decodifica la respuesta JSON y conviértela en tabla
jsonResponse = Json.Document(response),
tabla = Table.FromList(jsonResponse, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
expandido = Table.ExpandRecordColumn(tabla, "Column1", {"id", "clase"}, {"ID", "Clase"})
in
expandido
Propiedades / Listar Tipos de Servicios
Permite obtener la lista completa de tipos de servicio que puede tener una propiedad en el sistema. Cada elemento de la respuesta contiene el identificador del tipo de servicio y su nombre descriptivo. Este servicio es útil para poblar selectores o filtros de tipo de servicio en tus integraciones.
¿Para qué sirve este servicio?
Úsalo para conocer los valores válidos del campo de tipo de servicio al momento de filtrar o registrar propiedades a través de la API. Así te aseguras de enviar siempre un valor reconocido por el sistema. Los nombres descriptivos pueden variar ligeramente entre instancias según la configuración de cada inmobiliaria, pero los identificadores (id) son siempre los mismos.
1. El Endpoint (La dirección web)
Apunta tu sistema a la siguiente dirección. Recuerda reemplazar {{instancia}} por la dirección web completa que utilizas para ingresar a tu plataforma.
GET https://{{instancia}}/service/v2/public/masters/properties/service-types
¿Qué debes colocar en {{instancia}}?
Es muy sencillo: corresponde a la dirección web principal que utilizas a diario para ingresar a tu plataforma (incluyendo la terminación .nuby.app o .arrendasoft.co).
Por ejemplo, si para entrar a tu sistema escribes inmobiliaria.nuby.app o inmobiliaria.arrendasoft.co en tu navegador, esa será exactamente tu instancia. Solo asegúrate de no incluir el "https://" ni barras diagonales ("/") al final.
2. La Petición (¿Qué debes enviarnos?)
Este servicio no requiere cuerpo en la petición. Solo necesitas enviar los encabezados correctos:
| Método | GET |
| Content-Type | application/json |
| Authorization | Bearer token, Token obtenido al consumir el servicio Login |
¿Aún no tienes tu Token de acceso?
Para consumir este servicio necesitas un Token vigente. Consulta el servicio de Login para aprender cómo obtenerlo.
3. La Respuesta (¿Qué te entregaremos?)
Si tu Token es válido, el sistema te devolverá una lista con los tres tipos de servicio disponibles para propiedades. La respuesta se verá similar a esta:
[
{
"id": "arriendo",
"servicio": "Arriendo"
},
{
"id": "venta",
"servicio": "Venta"
},
{
"id": "venta y arriendo",
"servicio": "Venta y Arriendo"
}
]
Nota: El campo id es de tipo texto (string) y sus valores son fijos: "arriendo", "venta" y "venta y arriendo". El campo servicio muestra el nombre descriptivo, que puede variar ligeramente entre instancias según la configuración de cada inmobiliaria.
Tabla con la descripción de cada campo del JSON:
| Clave | Descripción |
|---|---|
| id | Identificador del tipo de servicio (tipo texto). Valores posibles: "arriendo", "venta", "venta y arriendo". Utiliza este valor cuando necesites filtrar propiedades por tipo de servicio a través de la API. |
| servicio | Nombre descriptivo del tipo de servicio (por ejemplo: "Arriendo", "Venta", "Venta y Arriendo"). |
4. Seguridad y Posibles Errores
¡Tu pase tiene fecha de caducidad!
Por medidas de seguridad, el token que te entregamos solo dura 1 hora. Una vez transcurrido ese tiempo, el pase expirará y el sistema te bloqueará el acceso devolviéndote un error 401. Cuando esto ocurra, tu sistema simplemente debe volver a consumir el servicio de Login para pedir un pase nuevo y continuar trabajando.
Así se ve el error que te devolverá el sistema cuando tu token se haya vencido o intentes usar un pase inválido:
{
"statusCode": 401,
"error": {
"type": "SERVER_ERROR",
"description": "JWT Token expired."
}
}
Otros posibles errores:
| Código HTTP | Descripción |
|---|---|
| 400 | Token no enviado o con formato incorrecto. Asegúrate de incluir el encabezado Authorization: Bearer TU_TOKEN. |
| 401 | Token expirado o inválido. Solicita uno nuevo a través del servicio de Login. |
| 403 | El cliente OAuth no tiene el scope necesario para esta operación. Para endpoints GET se requiere el scope read. Mensaje: "Insufficient scope. Required: 'read', granted: '{scope_actual}'." |
5. Ejemplos de integración
Aquí tienes ejemplos de código listos para que tus desarrolladores los adapten a tu plataforma:
cURL
curl -X GET "https://{{instancia}}/service/v2/public/masters/properties/service-types" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer TU_TOKEN_AQUI"
PHP
<?php
$instance = 'tu_instancia'; // Reemplaza con tu instancia real
$token = 'TU_TOKEN_AQUI'; // Token obtenido del servicio de Login
$url = "https://{$instance}/service/v2/public/masters/properties/service-types";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Authorization: Bearer ' . $token
]);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (curl_errno($ch)) {
echo 'Error: ' . curl_error($ch);
} else {
echo "Código de estado HTTP: " . $http_code . "\n";
if ($http_code === 200) {
$servicios = json_decode($response, true);
echo "Tipos de servicio:\n";
foreach ($servicios as $servicio) {
echo " ID: {$servicio['id']} - {$servicio['servicio']}\n";
}
} else {
echo "Error al consultar los tipos de servicio.\n";
echo $response . "\n";
}
}
curl_close($ch);
?>
Python
import requests
# 1. Configura tus datos de acceso
instancia = 'mi-inmobiliaria.nuby.app' # Reemplaza con tu dirección web completa
token = 'TU_TOKEN_AQUI' # Token obtenido del servicio de Login
# 2. Prepara la dirección y los encabezados
url = f"https://{instancia}/service/v2/public/masters/properties/service-types"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {token}"
}
# 3. Envía la petición GET y procesa la respuesta
try:
response = requests.get(url, headers=headers)
print(f"Código de estado HTTP: {response.status_code}")
if response.status_code == 200:
servicios = response.json()
print("Tipos de servicio:")
for servicio in servicios:
print(f" ID: {servicio['id']} - {servicio['servicio']}")
else:
print("Error al consultar los tipos de servicio.")
print(f"Detalle del error: {response.text}")
except Exception as e:
print(f"Ocurrió un error de conexión: {e}")
JavaScript
// 1. Configura tus datos de acceso
const instancia = 'mi-inmobiliaria.nuby.app'; // Reemplaza con tu dirección web completa
const token = 'TU_TOKEN_AQUI'; // Token obtenido del servicio de Login
// 2. Prepara la dirección
const url = `https://${instancia}/service/v2/public/masters/properties/service-types`;
// 3. Función para consultar los tipos de servicio
async function consultarTiposDeServicio() {
try {
const response = await fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
}
});
console.log(`Código de estado HTTP: ${response.status}`);
if (response.ok) {
const servicios = await response.json();
console.log('Tipos de servicio:');
servicios.forEach(servicio => {
console.log(` ID: ${servicio.id} - ${servicio.servicio}`);
});
} else {
console.log('Error al consultar los tipos de servicio.');
const errorData = await response.text();
console.log(`Detalle del error: ${errorData}`);
}
} catch (error) {
console.error(`Ocurrió un error de conexión: ${error}`);
}
}
// 4. Ejecutamos la función
consultarTiposDeServicio();
Power Query M (Excel / Power BI)
let
// 1. Configura tus datos de acceso
instancia = "mi-inmobiliaria.nuby.app", // Reemplaza con tu dirección web completa
token = "TU_TOKEN_AQUI", // Token obtenido del servicio de Login
// 2. Prepara la dirección de la petición
url = "https://" & instancia & "/service/v2/public/masters/properties/service-types",
// 3. Envía la petición GET con el token de autenticación
response = Web.Contents(url, [
Headers = [
#"Content-Type" = "application/json",
#"Authorization" = "Bearer " & token
]
]),
// 4. Decodifica la respuesta JSON y conviértela en tabla
jsonResponse = Json.Document(response),
tabla = Table.FromList(jsonResponse, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
expandido = Table.ExpandRecordColumn(tabla, "Column1", {"id", "servicio"}, {"ID", "Servicio"})
in
expandido
Propiedades / Listar Características
Permite obtener la lista completa de características que pueden tener las propiedades en el sistema. Cada elemento de la respuesta contiene la información detallada de una característica, incluyendo su tipo de campo, opciones disponibles y la clase de inmueble a la que pertenece. Este servicio es útil para construir formularios dinámicos de propiedades o para conocer qué datos se pueden registrar en cada tipo de inmueble.
¿Para qué sirve este servicio?
Úsalo para obtener el catálogo de características configuradas en la plataforma. Cada característica está vinculada a una clase de inmueble específica (Apartamento, Casa, Bodega, etc.) y tiene un tipo de campo que indica cómo debe capturarse la información (numérico, checkbox, lista desplegable, etc.). Si necesitas consultar solo las características de una clase de inmueble en particular, utiliza el endpoint de Listar Características por Clase de Inmueble.
1. El Endpoint (La dirección web)
Apunta tu sistema a la siguiente dirección. Recuerda reemplazar {{instancia}} por la dirección web completa que utilizas para ingresar a tu plataforma.
GET https://{{instancia}}/service/v2/public/masters/properties/features
¿Qué debes colocar en {{instancia}}?
Es muy sencillo: corresponde a la dirección web principal que utilizas a diario para ingresar a tu plataforma (incluyendo la terminación .nuby.app o .arrendasoft.co).
Por ejemplo, si para entrar a tu sistema escribes inmobiliaria.nuby.app o inmobiliaria.arrendasoft.co en tu navegador, esa será exactamente tu instancia. Solo asegúrate de no incluir el "https://" ni barras diagonales ("/") al final.
2. La Petición (¿Qué debes enviarnos?)
Este servicio no requiere cuerpo en la petición. Solo necesitas enviar los encabezados correctos:
| Método | GET |
| Content-Type | application/json |
| Authorization | Bearer token, Token obtenido al consumir el servicio Login |
¿Aún no tienes tu Token de acceso?
Para consumir este servicio necesitas un Token vigente. Consulta el servicio de Login para aprender cómo obtenerlo.
3. La Respuesta (¿Qué te entregaremos?)
Si tu Token es válido, el sistema te devolverá una lista con todas las características configuradas para las propiedades. La respuesta se verá similar a esta:
[
{
"id": "1",
"descripcion": "Nº De Habitaciones",
"tipo_campo": "numeric",
"opciones_valores": null,
"opciones_descripciones": null,
"orden": "1",
"grupo": "Características del inmueble",
"clase_inmueble_id": "1367",
"clase_inmueble": "Amoblados"
},
{
"id": "2",
"descripcion": "Nº De Baños",
"tipo_campo": "numeric",
"opciones_valores": null,
"opciones_descripciones": null,
"orden": "2",
"grupo": "Características del inmueble",
"clase_inmueble_id": "1367",
"clase_inmueble": "Amoblados"
},
{
"id": "54",
"descripcion": "Oficina",
"tipo_campo": "checkbox",
"opciones_valores": "",
"opciones_descripciones": "",
"orden": "3",
"grupo": "Características del Inmueble",
"clase_inmueble_id": "1248",
"clase_inmueble": "Bodega"
},
{
"id": "13",
"descripcion": "Baño Auxiliar",
"tipo_campo": "checkbox",
"opciones_valores": null,
"opciones_descripciones": null,
"orden": "4",
"grupo": "Características del Inmueble",
"clase_inmueble_id": "1249",
"clase_inmueble": "Casa"
},
{
"id": "38",
"descripcion": "Parqueadero",
"tipo_campo": "select",
"opciones_valores": "propio,visitantes",
"opciones_descripciones": "Propio,Visitantes",
"orden": "12",
"grupo": "Características del Inmueble",
"clase_inmueble_id": "1249",
"clase_inmueble": "Casa"
}
]
Nota: Las características disponibles, sus grupos y las clases de inmueble asociadas dependen de la configuración de cada instancia. La lista se devuelve ordenada por grupo, luego por orden dentro del grupo, y finalmente por descripción alfabéticamente.
Tabla con la descripción de cada campo del JSON:
| Clave | Descripción |
|---|---|
| id | Identificador único de la característica (tipo texto). |
| descripcion | Nombre descriptivo de la característica (por ejemplo: "Nº De Habitaciones", "Parqueadero"). |
| tipo_campo | Tipo de campo que define cómo se captura la información. Valores posibles: numeric (campo numérico), checkbox (casilla de verificación), select (lista desplegable con opciones predefinidas), entre otros. |
| opciones_valores | Valores técnicos de las opciones disponibles, separados por coma. Aplica únicamente cuando tipo_campo es select. Será null o vacío para otros tipos de campo. |
| opciones_descripciones | Descripciones legibles de las opciones disponibles, separadas por coma. Cada descripción corresponde posicionalmente al valor en opciones_valores. Por ejemplo, si opciones_valores es "propio,visitantes", las descripciones serán "Propio,Visitantes". |
| orden | Posición numérica que indica el orden de presentación de la característica dentro de su grupo. |
| grupo | Nombre del grupo al que pertenece la característica (por ejemplo: "Características del Inmueble"). Permite agrupar visualmente las características en un formulario. |
| clase_inmueble_id | Identificador de la clase de inmueble a la que está asociada esta característica. Corresponde al id devuelto por el servicio Listar Clases de Inmueble. |
| clase_inmueble | Nombre descriptivo de la clase de inmueble (por ejemplo: "Amoblados", "Casa", "Bodega"). |
4. Seguridad y Posibles Errores
¡Tu pase tiene fecha de caducidad!
Por medidas de seguridad, el token que te entregamos solo dura 1 hora. Una vez transcurrido ese tiempo, el pase expirará y el sistema te bloqueará el acceso devolviéndote un error 401. Cuando esto ocurra, tu sistema simplemente debe volver a consumir el servicio de Login para pedir un pase nuevo y continuar trabajando.
Así se ve el error que te devolverá el sistema cuando tu token se haya vencido o intentes usar un pase inválido:
{
"statusCode": 401,
"error": {
"type": "SERVER_ERROR",
"description": "JWT Token expired."
}
}
Otros posibles errores:
| Código HTTP | Descripción |
|---|---|
| 400 | Token no enviado o con formato incorrecto. Asegúrate de incluir el encabezado Authorization: Bearer TU_TOKEN. |
| 401 | Token expirado o inválido. Solicita uno nuevo a través del servicio de Login. |
| 403 | El cliente OAuth no tiene el scope necesario para esta operación. Para endpoints GET se requiere el scope read. Mensaje: "Insufficient scope. Required: 'read', granted: '{scope_actual}'." |
5. Endpoint relacionado: Filtrar por Clase de Inmueble
Si necesitas obtener únicamente las características de una clase de inmueble específica, puedes usar el siguiente endpoint en lugar de filtrar la respuesta completa:
GET https://{{instancia}}/service/v2/public/masters/properties/features/property-class/{id}
Donde {id} es el identificador numérico de la clase de inmueble (obtenido del servicio Listar Clases de Inmueble). La respuesta tiene exactamente la misma estructura que este endpoint, pero filtrada a la clase indicada.
Si el parámetro {id} está vacío o no es numérico, el sistema devolverá un error 400:
{
"error": "El ID de la clase del inmueble no puede estar vacío y debe ser de tipo numérico"
}
6. Ejemplos de integración
Aquí tienes ejemplos de código listos para que tus desarrolladores los adapten a tu plataforma:
cURL
# Listar todas las características
curl -X GET "https://{{instancia}}/service/v2/public/masters/properties/features" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer TU_TOKEN_AQUI"
# Listar características de una clase de inmueble específica (ej. ID 1249 = Casa)
curl -X GET "https://{{instancia}}/service/v2/public/masters/properties/features/property-class/1249" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer TU_TOKEN_AQUI"
PHP
<?php
$instance = 'tu_instancia'; // Reemplaza con tu instancia real
$token = 'TU_TOKEN_AQUI'; // Token obtenido del servicio de Login
// Para todas las características:
$url = "https://{$instance}/service/v2/public/masters/properties/features";
// Para filtrar por clase de inmueble (descomentar y reemplazar el ID):
// $claseInmuebleId = 1249; // Ejemplo: Casa
// $url = "https://{$instance}/service/v2/public/masters/properties/features/property-class/{$claseInmuebleId}";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Authorization: Bearer ' . $token
]);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (curl_errno($ch)) {
echo 'Error: ' . curl_error($ch);
} else {
echo "Código de estado HTTP: " . $http_code . "\n";
if ($http_code === 200) {
$caracteristicas = json_decode($response, true);
echo "Características de propiedades:\n";
foreach ($caracteristicas as $car) {
echo " [{$car['clase_inmueble']}] {$car['descripcion']} (tipo: {$car['tipo_campo']})\n";
}
} else {
echo "Error al consultar las características.\n";
echo $response . "\n";
}
}
curl_close($ch);
?>
Python
import requests
# 1. Configura tus datos de acceso
instancia = 'mi-inmobiliaria.nuby.app' # Reemplaza con tu dirección web completa
token = 'TU_TOKEN_AQUI' # Token obtenido del servicio de Login
# 2. Prepara la dirección y los encabezados
# Para todas las características:
url = f"https://{instancia}/service/v2/public/masters/properties/features"
# Para filtrar por clase de inmueble (descomentar y reemplazar el ID):
# clase_inmueble_id = 1249 # Ejemplo: Casa
# url = f"https://{instancia}/service/v2/public/masters/properties/features/property-class/{clase_inmueble_id}"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {token}"
}
# 3. Envía la petición GET y procesa la respuesta
try:
response = requests.get(url, headers=headers)
print(f"Código de estado HTTP: {response.status_code}")
if response.status_code == 200:
caracteristicas = response.json()
print("Características de propiedades:")
for car in caracteristicas:
print(f" [{car['clase_inmueble']}] {car['descripcion']} (tipo: {car['tipo_campo']})")
else:
print("Error al consultar las características.")
print(f"Detalle del error: {response.text}")
except Exception as e:
print(f"Ocurrió un error de conexión: {e}")
JavaScript
// 1. Configura tus datos de acceso
const instancia = 'mi-inmobiliaria.nuby.app'; // Reemplaza con tu dirección web completa
const token = 'TU_TOKEN_AQUI'; // Token obtenido del servicio de Login
// 2. Prepara la dirección
// Para todas las características:
const url = `https://${instancia}/service/v2/public/masters/properties/features`;
// Para filtrar por clase de inmueble (descomentar y reemplazar el ID):
// const claseInmuebleId = 1249; // Ejemplo: Casa
// const url = `https://${instancia}/service/v2/public/masters/properties/features/property-class/${claseInmuebleId}`;
// 3. Función para consultar las características
async function consultarCaracteristicas() {
try {
const response = await fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
}
});
console.log(`Código de estado HTTP: ${response.status}`);
if (response.ok) {
const caracteristicas = await response.json();
console.log('Características de propiedades:');
caracteristicas.forEach(car => {
console.log(` [${car.clase_inmueble}] ${car.descripcion} (tipo: ${car.tipo_campo})`);
});
} else {
console.log('Error al consultar las características.');
const errorData = await response.text();
console.log(`Detalle del error: ${errorData}`);
}
} catch (error) {
console.error(`Ocurrió un error de conexión: ${error}`);
}
}
// 4. Ejecutamos la función
consultarCaracteristicas();
Power Query M (Excel / Power BI)
let
// 1. Configura tus datos de acceso
instancia = "mi-inmobiliaria.nuby.app", // Reemplaza con tu dirección web completa
token = "TU_TOKEN_AQUI", // Token obtenido del servicio de Login
// 2. Prepara la dirección de la petición
url = "https://" & instancia & "/service/v2/public/masters/properties/features",
// 3. Envía la petición GET con el token de autenticación
response = Web.Contents(url, [
Headers = [
#"Content-Type" = "application/json",
#"Authorization" = "Bearer " & token
]
]),
// 4. Decodifica la respuesta JSON y conviértela en tabla
jsonResponse = Json.Document(response),
tabla = Table.FromList(jsonResponse, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
expandido = Table.ExpandRecordColumn(tabla, "Column1",
{"id", "descripcion", "tipo_campo", "opciones_valores", "opciones_descripciones", "orden", "grupo", "clase_inmueble_id", "clase_inmueble"},
{"ID", "Descripcion", "TipoCampo", "OpcionesValores", "OpcionesDescripciones", "Orden", "Grupo", "ClaseInmuebleID", "ClaseInmueble"})
in
expandido
Propiedades / Listar Características por Clase de Inmueble
Permite obtener la lista de características que puede tener una propiedad, filtrada por una clase de inmueble específica. Cada elemento de la respuesta contiene la información detallada de una característica perteneciente a la clase indicada. Este servicio es ideal cuando ya conoces la clase de inmueble y solo necesitas las características aplicables a ese tipo.
¿Para qué sirve este servicio?
Úsalo cuando necesites construir un formulario dinámico para un tipo de inmueble en particular (por ejemplo, solo las características de "Casa" o de "Apartamento"). Si prefieres obtener todas las características de todas las clases de una sola vez, utiliza el endpoint de Listar Características. Para conocer los identificadores válidos de clases de inmueble, consulta el servicio de Listar Clases de Inmueble.
1. El Endpoint (La dirección web)
Apunta tu sistema a la siguiente dirección. Recuerda reemplazar {{instancia}} por la dirección web completa que utilizas para ingresar a tu plataforma, y {{id}} por el identificador numérico de la clase de inmueble que deseas consultar.
GET https://{{instancia}}/service/v2/public/masters/properties/features/property-class/{{id}}
¿Qué debes colocar en {{instancia}}?
Es muy sencillo: corresponde a la dirección web principal que utilizas a diario para ingresar a tu plataforma (incluyendo la terminación .nuby.app o .arrendasoft.co).
Por ejemplo, si para entrar a tu sistema escribes inmobiliaria.nuby.app o inmobiliaria.arrendasoft.co en tu navegador, esa será exactamente tu instancia. Solo asegúrate de no incluir el "https://" ni barras diagonales ("/") al final.
2. La Petición (¿Qué debes enviarnos?)
Este servicio no requiere cuerpo en la petición. Solo necesitas enviar los encabezados correctos y el parámetro de ruta:
| Método | GET |
| Content-Type | application/json |
| Authorization | Bearer token, Token obtenido al consumir el servicio Login |
Parámetro de ruta:
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
| id | Numérico | Sí | Identificador único de la clase de inmueble. Puedes obtener los valores válidos consultando el servicio de Listar Clases de Inmueble. |
¿Aún no tienes tu Token de acceso?
Para consumir este servicio necesitas un Token vigente. Consulta el servicio de Login para aprender cómo obtenerlo.
3. La Respuesta (¿Qué te entregaremos?)
Si tu Token es válido y el id de la clase de inmueble es correcto, el sistema te devolverá una lista con las características asociadas a esa clase. Por ejemplo, para la clase "Casa" (id = 1249), la respuesta se verá similar a esta:
[
{
"id": "1",
"descripcion": "Nº De Habitaciones",
"tipo_campo": "numeric",
"opciones_valores": null,
"opciones_descripciones": null,
"orden": "1",
"grupo": "Características del Inmueble",
"clase_inmueble_id": "1249",
"clase_inmueble": "Casa"
},
{
"id": "31",
"descripcion": "Red de gas",
"tipo_campo": "select",
"opciones_valores": "si,no",
"opciones_descripciones": "Si,No",
"orden": "5",
"grupo": "Características del Inmueble",
"clase_inmueble_id": "1249",
"clase_inmueble": "Casa"
},
{
"id": "22",
"descripcion": "Balcón",
"tipo_campo": "checkbox",
"opciones_valores": null,
"opciones_descripciones": null,
"orden": "10",
"grupo": "Características del Inmueble",
"clase_inmueble_id": "1249",
"clase_inmueble": "Casa"
},
{
"id": "38",
"descripcion": "Parqueadero",
"tipo_campo": "select",
"opciones_valores": "propio,visitantes",
"opciones_descripciones": "Propio,Visitantes",
"orden": "12",
"grupo": "Características del Inmueble",
"clase_inmueble_id": "1249",
"clase_inmueble": "Casa"
}
]
Nota: Las características disponibles y sus grupos dependen de la configuración de cada instancia. La lista se devuelve ordenada por grupo, luego por orden dentro del grupo, y finalmente por descripción alfabéticamente. La estructura de la respuesta es idéntica a la del servicio de Listar Características, pero filtrada a la clase de inmueble indicada.
Tabla con la descripción de cada campo del JSON:
| Clave | Descripción |
|---|---|
| id | Identificador único de la característica (tipo texto). |
| descripcion | Nombre descriptivo de la característica (por ejemplo: "Nº De Habitaciones", "Parqueadero"). |
| tipo_campo | Tipo de campo que define cómo se captura la información. Valores posibles: numeric (campo numérico), checkbox (casilla de verificación), select (lista desplegable con opciones predefinidas), entre otros. |
| opciones_valores | Valores técnicos de las opciones disponibles, separados por coma. Aplica únicamente cuando tipo_campo es select. Será null o vacío para otros tipos de campo. |
| opciones_descripciones | Descripciones legibles de las opciones disponibles, separadas por coma. Cada descripción corresponde posicionalmente al valor en opciones_valores. Por ejemplo, si opciones_valores es "propio,visitantes", las descripciones serán "Propio,Visitantes". |
| orden | Posición numérica que indica el orden de presentación de la característica dentro de su grupo. |
| grupo | Nombre del grupo al que pertenece la característica (por ejemplo: "Características del Inmueble"). Permite agrupar visualmente las características en un formulario. |
| clase_inmueble_id | Identificador de la clase de inmueble a la que está asociada esta característica. Coincidirá con el id enviado en la URL. |
| clase_inmueble | Nombre descriptivo de la clase de inmueble (por ejemplo: "Casa", "Apartamento", "Bodega"). |
4. Seguridad y Posibles Errores
¡Tu pase tiene fecha de caducidad!
Por medidas de seguridad, el token que te entregamos solo dura 1 hora. Una vez transcurrido ese tiempo, el pase expirará y el sistema te bloqueará el acceso devolviéndote un error 401. Cuando esto ocurra, tu sistema simplemente debe volver a consumir el servicio de Login para pedir un pase nuevo y continuar trabajando.
Así se ve el error que te devolverá el sistema cuando tu token se haya vencido o intentes usar un pase inválido:
{
"statusCode": 401,
"error": {
"type": "SERVER_ERROR",
"description": "JWT Token expired."
}
}
Si envías un id vacío o no numérico, el sistema te devolverá un error de validación:
{
"error": "El ID de la clase del inmueble no puede estar vacío y debe ser de tipo numérico"
}
Otros posibles errores:
| Código HTTP | Descripción |
|---|---|
| 400 | Token no enviado, formato incorrecto, o el parámetro id está vacío o no es numérico. |
| 401 | Token expirado o inválido. Solicita uno nuevo a través del servicio de Login. |
| 403 | El cliente OAuth no tiene el scope necesario para esta operación. Para endpoints GET se requiere el scope read. Mensaje: "Insufficient scope. Required: 'read', granted: '{scope_actual}'." |
5. Ejemplos de integración
Aquí tienes ejemplos de código listos para que tus desarrolladores los adapten a tu plataforma. En estos ejemplos se consulta la clase "Casa" con id = 1249:
cURL
curl -X GET "https://{{instancia}}/service/v2/public/masters/properties/features/property-class/1249" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer TU_TOKEN_AQUI"
PHP
<?php
$instance = 'tu_instancia'; // Reemplaza con tu instancia real
$token = 'TU_TOKEN_AQUI'; // Token obtenido del servicio de Login
$claseInmuebleId = 1249; // ID de la clase de inmueble (ej. Casa)
$url = "https://{$instance}/service/v2/public/masters/properties/features/property-class/{$claseInmuebleId}";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Authorization: Bearer ' . $token
]);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (curl_errno($ch)) {
echo 'Error: ' . curl_error($ch);
} else {
echo "Código de estado HTTP: " . $http_code . "\n";
if ($http_code === 200) {
$caracteristicas = json_decode($response, true);
echo "Características de la clase de inmueble (ID {$claseInmuebleId}):\n";
foreach ($caracteristicas as $car) {
echo " {$car['descripcion']} (tipo: {$car['tipo_campo']})\n";
}
} else {
echo "Error al consultar las características.\n";
echo $response . "\n";
}
}
curl_close($ch);
?>
Python
import requests
# 1. Configura tus datos de acceso
instancia = 'mi-inmobiliaria.nuby.app' # Reemplaza con tu dirección web completa
token = 'TU_TOKEN_AQUI' # Token obtenido del servicio de Login
clase_inmueble_id = 1249 # ID de la clase de inmueble (ej. Casa)
# 2. Prepara la dirección y los encabezados
url = f"https://{instancia}/service/v2/public/masters/properties/features/property-class/{clase_inmueble_id}"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {token}"
}
# 3. Envía la petición GET y procesa la respuesta
try:
response = requests.get(url, headers=headers)
print(f"Código de estado HTTP: {response.status_code}")
if response.status_code == 200:
caracteristicas = response.json()
print(f"Características de la clase de inmueble (ID {clase_inmueble_id}):")
for car in caracteristicas:
print(f" {car['descripcion']} (tipo: {car['tipo_campo']})")
else:
print("Error al consultar las características.")
print(f"Detalle del error: {response.text}")
except Exception as e:
print(f"Ocurrió un error de conexión: {e}")
JavaScript
// 1. Configura tus datos de acceso
const instancia = 'mi-inmobiliaria.nuby.app'; // Reemplaza con tu dirección web completa
const token = 'TU_TOKEN_AQUI'; // Token obtenido del servicio de Login
const claseInmuebleId = 1249; // ID de la clase de inmueble (ej. Casa)
// 2. Prepara la dirección
const url = `https://${instancia}/service/v2/public/masters/properties/features/property-class/${claseInmuebleId}`;
// 3. Función para consultar las características por clase de inmueble
async function consultarCaracteristicasPorClase() {
try {
const response = await fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
}
});
console.log(`Código de estado HTTP: ${response.status}`);
if (response.ok) {
const caracteristicas = await response.json();
console.log(`Características de la clase de inmueble (ID ${claseInmuebleId}):`);
caracteristicas.forEach(car => {
console.log(` ${car.descripcion} (tipo: ${car.tipo_campo})`);
});
} else {
console.log('Error al consultar las características.');
const errorData = await response.text();
console.log(`Detalle del error: ${errorData}`);
}
} catch (error) {
console.error(`Ocurrió un error de conexión: ${error}`);
}
}
// 4. Ejecutamos la función
consultarCaracteristicasPorClase();
Power Query M (Excel / Power BI)
let
// 1. Configura tus datos de acceso
instancia = "mi-inmobiliaria.nuby.app", // Reemplaza con tu dirección web completa
token = "TU_TOKEN_AQUI", // Token obtenido del servicio de Login
claseInmuebleId = "1249", // ID de la clase de inmueble (ej. Casa)
// 2. Prepara la dirección de la petición
url = "https://" & instancia & "/service/v2/public/masters/properties/features/property-class/" & claseInmuebleId,
// 3. Envía la petición GET con el token de autenticación
response = Web.Contents(url, [
Headers = [
#"Content-Type" = "application/json",
#"Authorization" = "Bearer " & token
]
]),
// 4. Decodifica la respuesta JSON y conviértela en tabla
jsonResponse = Json.Document(response),
tabla = Table.FromList(jsonResponse, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
expandido = Table.ExpandRecordColumn(tabla, "Column1",
{"id", "descripcion", "tipo_campo", "opciones_valores", "opciones_descripciones", "orden", "grupo", "clase_inmueble_id", "clase_inmueble"},
{"ID", "Descripcion", "TipoCampo", "OpcionesValores", "OpcionesDescripciones", "Orden", "Grupo", "ClaseInmuebleID", "ClaseInmueble"})
in
expandido
Propiedades
Bienvenido al inventario digital de tu inmobiliaria. En esta sección te explicamos cómo conectar tus herramientas externas para gestionar, consultar y mantener sincronizada toda la información de tus inmuebles.
¿Qué puedes hacer en este módulo?
1. Exploración y consulta detallada: Extrae tu catálogo completo utilizando filtros estratégicos (como fechas de creación o actualización) o profundiza en los datos de una propiedad específica. Podrás acceder a sus características precisas, material multimedia (fotografías y videos) y la información de sus propietarios.
2. Gestión segura de estados: ¡No solo puedes leer información, también puedes tomar acción! Mantén tu inventario al día actualizando la disponibilidad de tus inmuebles. Para tu tranquilidad, nuestro sistema cuenta con validaciones inteligentes que protegen tu información y previenen errores accidentales (por ejemplo, bloqueando cambios automáticos si la propiedad ya figura como "Arrendada").
¡Explora las opciones a continuación y sácale el máximo provecho a la gestión automatizada de tu portafolio!
Listar Propiedades
Permite obtener una lista paginada de propiedades registradas en la inmobiliaria, incluyendo información detallada de cada una: datos generales, ubicación, valores económicos, características, propietarios, imágenes, videos y códigos de portales inmobiliarios.
¿Para qué sirve este servicio?
Úsalo para sincronizar el inventario de propiedades con tu sistema externo, alimentar un sitio web, generar reportes o integrar la información de inmuebles con plataformas de terceros. El endpoint soporta paginación y filtros por rangos de fecha para consultas eficientes.
1. El Endpoint (La dirección web)
Apunta tu sistema a la siguiente dirección. Recuerda reemplazar {{instancia}} por la dirección web completa que utilizas para ingresar a tu plataforma.
GET https://{{instancia}}/service/v2/public/properties
¿Qué debes colocar en {{instancia}}?
Es muy sencillo: corresponde a la dirección web principal que utilizas a diario para ingresar a tu plataforma (incluyendo la terminación .nuby.app o .arrendasoft.co).
Por ejemplo, si para entrar a tu sistema escribes inmobiliaria.nuby.app o inmobiliaria.arrendasoft.co en tu navegador, esa será exactamente tu instancia. Solo asegúrate de no incluir el "https://" ni barras diagonales ("/") al final.
2. La Petición (¿Qué debes enviarnos?)
Este servicio requiere autenticación mediante un Token JWT. Envía los encabezados requeridos y opcionalmente los parámetros de filtrado en la URL:
| Método | GET |
| Content-Type | application/json |
| Authorization | Bearer token, Token obtenido al consumir el servicio Login. |
Autenticación requerida
Este servicio requiere un Token de autenticación válido. Debes incluir el encabezado Authorization: Bearer TU_TOKEN en cada petición. El token se obtiene consumiendo el servicio de Login. Adicionalmente, el cliente OAuth debe contar con el scope read para poder consumir este endpoint.
Parámetros de consulta (query string):
| Parámetro | Tipo | Requerido | Por defecto | Descripción |
|---|---|---|---|---|
| page | integer | No | 1 | Número de página de resultados que se desea recuperar. |
| limit | integer | No | 10 | Número máximo de propiedades por página. Valor máximo permitido: 50. |
| listing_start_date | string | No | — | Fecha de inicio del rango de consignación del inmueble. Formato: YYYY-MM-DD (ejemplo: 2024-03-01). |
| listing_end_date | string | No | — | Fecha de fin del rango de consignación del inmueble. Formato: YYYY-MM-DD. |
| created_start_date | string | No | — | Fecha de inicio del rango de creación del inmueble en el sistema. Formato: YYYY-MM-DD. |
| created_end_date | string | No | — | Fecha de fin del rango de creación del inmueble en el sistema. Formato: YYYY-MM-DD. |
| last_modified_start_date | string | No | — | Fecha de inicio del rango de última modificación del inmueble. Formato: YYYY-MM-DD. |
| last_modified_end_date | string | No | — | Fecha de fin del rango de última modificación del inmueble. Formato: YYYY-MM-DD. |
Comportamiento de los filtros de fecha
Para los parámetros de tipo fecha que se componen de un rango (por ejemplo listing_start_date y listing_end_date):
— Si envías solo el start_date: se retornarán registros con fecha mayor o igual (>=) a la indicada.
— Si envías solo el end_date: se retornarán registros con fecha menor o igual (<=) a la indicada.
— Si envías ambos: se retornarán registros dentro de ese rango de fechas (BETWEEN).
— La fecha de inicio no puede ser mayor que la fecha de fin; de lo contrario se devolverá un error de validación.
Ejemplos de peticiones:
GET https://{{instancia}}/service/v2/public/properties
GET https://{{instancia}}/service/v2/public/properties?page=1&limit=10
GET https://{{instancia}}/service/v2/public/properties?page=1&limit=10&listing_start_date=2024-03-26
GET https://{{instancia}}/service/v2/public/properties?page=1&limit=10&listing_start_date=2024-03-01&listing_end_date=2024-03-31
GET https://{{instancia}}/service/v2/public/properties?page=2&limit=20&created_start_date=2024-01-01&created_end_date=2024-06-30
3. La Respuesta (¿Qué te entregaremos?)
El sistema te devolverá una lista con las propiedades que coincidan con los filtros aplicados. Cada propiedad incluye datos generales, ubicación, valores económicos, características, propietarios, imágenes, videos y códigos de portales inmobiliarios. La respuesta se verá similar a esta:
[
{
"codigo": "137",
"titulo": "Apartamento amplio con vista al parque central",
"clase_id": "1247",
"clase_inmueble": "Apartamento",
"tipo_servicio_id": "arriendo",
"tipo_servicio": "Arriendo",
"estrato": "1258",
"estrato_texto": "Cuatro",
"fecha_consignacion": "2024-04-26",
"asesor_id": "5",
"asesor": "María López Ramírez",
"pais_id": "1",
"pais": "COLOMBIA",
"departamento_id": "5",
"departamento": "Antioquia",
"municipio_id": "1",
"municipio": "Medellin",
"barrio_id": "3",
"barrio": "Los Rosales",
"direccion": "CALLE 45 # 32 - 18",
"coordenadas": "6.24830000000000:-75.56120000000000",
"valor_arriendo1": "1600000",
"valor_arriendo2": "0",
"valor_venta1": "0",
"valor_venta2": "0",
"valor_administracion": "0",
"avaluo_catastral": "0",
"impuesto_predial": "0.00",
"area": "75.00",
"observaciones": null,
"propiedad_destacada": "No",
"llaves_en": "oficina",
"llaves_otro": null,
"paga_cuota_sost": "propietario",
"folio_matricula": null,
"referencia_catastral": null,
"edificio_unidad": "urbanizacion",
"estado": "1",
"estado_texto": "Activa",
"cantidad_images": "3",
"cantidad_videos": "1",
"fecha_creacion": "2024-04-26 10:30:00",
"ultima_fecha_modificacion": "2024-05-15 14:22:00",
"caracteristicas": [
{
"id": "1",
"descripcion": "Nº De Habitaciones",
"tipo_campo": "numeric",
"orden": "1",
"grupo": "Características del inmueble",
"valor": "4"
},
{
"id": "2",
"descripcion": "Nº De Baños",
"tipo_campo": "numeric",
"orden": "2",
"grupo": "Características del inmueble",
"valor": "3"
},
{
"id": "31",
"descripcion": "Red de gas",
"tipo_campo": "select",
"orden": "5",
"grupo": "Características del Inmueble",
"valor": "si",
"valor_texto": "Si"
},
{
"id": "14",
"descripcion": "Cocina Integral",
"tipo_campo": "checkbox",
"orden": "5",
"grupo": "Características Internas",
"valor": "1"
}
],
"propietarios": [
{
"id": "272",
"documento": "1020304050",
"nombres": "ANA MARÍA",
"apellidos": "PÉREZ RODRÍGUEZ"
}
],
"imagenes": [
{
"posicion": "1",
"size": "19201080",
"img": "img/fotos/1920x1080_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6.jpeg",
"imagen": "https://mi-inmobiliaria.nuby.app/img/fotos/1920x1080_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6.jpeg"
},
{
"posicion": "2",
"size": "19201080",
"img": "img/fotos/1920x1080_f6e5d4c3b2a1f6e5d4c3b2a1f6e5d4c3.jpeg",
"imagen": "https://mi-inmobiliaria.nuby.app/img/fotos/1920x1080_f6e5d4c3b2a1f6e5d4c3b2a1f6e5d4c3.jpeg"
}
],
"videos": [
{
"url": "dQw4w9WgXcQ",
"tipo": "youtube",
"descripcion": null,
"posicion": "1"
}
],
"codigos_portales": [
{
"nombre_portal": "metrocuadrado",
"id_portal": "MC-12345",
"tipo_servicio": "arriendo"
}
]
}
]
Campos principales de la propiedad
Esta tabla enumera las claves presentes en el JSON de cada propiedad y proporciona una descripción de cada una:
| Clave | Descripción |
|---|---|
| codigo | Código único del inmueble en el sistema. |
| titulo | Título del anuncio del inmueble. |
| clase_id | Identificador de la clase de inmueble. Corresponde al id del servicio Listar Clases de Inmueble. |
| clase_inmueble | Nombre de la clase de inmueble (por ejemplo: "Apartamento", "Casa", "Finca"). |
| tipo_servicio_id | Identificador del tipo de servicio. Valores posibles: "arriendo", "venta", "venta y arriendo". |
| tipo_servicio | Nombre descriptivo del tipo de servicio (por ejemplo: "Arriendo", "Venta"). |
| estrato | Identificador del estrato socioeconómico del inmueble. |
| estrato_texto | Texto descriptivo del estrato (por ejemplo: "Cuatro", "Tres"). |
| fecha_consignacion | Fecha en que el inmueble fue captado/consignado para su gestión. Formato: YYYY-MM-DD. |
| asesor_id | Identificador del asesor asignado al inmueble. Vacío si no tiene asesor asignado. |
| asesor | Nombre completo del asesor asignado. |
| pais_id | Identificador del país donde se ubica el inmueble. |
| pais | Nombre del país. |
| departamento_id | Identificador del departamento/estado/provincia. |
| departamento | Nombre del departamento. |
| municipio_id | Identificador del municipio/ciudad. |
| municipio | Nombre del municipio. |
| barrio_id | Identificador del barrio. Puede ser null si no se ha asignado barrio. |
| barrio | Nombre del barrio. |
| direccion | Dirección física del inmueble. |
| coordenadas | Coordenadas geográficas del inmueble en formato latitud:longitud. |
| valor_arriendo1 | Valor principal de arriendo (canon mensual). |
| valor_arriendo2 | Valor secundario de arriendo. 0 si no aplica. |
| valor_venta1 | Valor principal de venta. |
| valor_venta2 | Valor secundario de venta. 0 si no aplica. |
| valor_administracion | Valor de la cuota de administración. |
| avaluo_catastral | Avalúo catastral del inmueble. |
| impuesto_predial | Valor del impuesto predial. |
| area | Área del inmueble en metros cuadrados. |
| observaciones | Observaciones o descripción adicional del inmueble. Puede ser null. |
| propiedad_destacada | Indica si la propiedad está marcada como destacada. Valores: "Si" o "No". |
| llaves_en | Lugar donde se encuentran las llaves del inmueble (por ejemplo: "oficina"). |
| llaves_otro | Ubicación alternativa de las llaves, si aplica. Puede ser null. |
| paga_cuota_sost | Quién paga la cuota de sostenimiento (por ejemplo: "propietario"). Puede ser null. |
| folio_matricula | Número de folio de matrícula inmobiliaria. Puede ser null. |
| referencia_catastral | Referencia catastral del inmueble. Puede ser null. |
| edificio_unidad | Tipo de agrupamiento del inmueble (por ejemplo: "urbanizacion", "edificio", "conjunto"). |
| estado | Identificador numérico del estado del inmueble. Valores: 0 (Arrendada), 1 (Activa), 2 (Inactiva), 3 (Vendida). |
| estado_texto | Texto descriptivo del estado (por ejemplo: "Activa", "Arrendada"). |
| cantidad_images | Cantidad de imágenes asociadas al inmueble. |
| cantidad_videos | Cantidad de videos asociados al inmueble. |
| fecha_creacion | Fecha y hora de creación del registro en el sistema. Formato: YYYY-MM-DD HH:MM:SS. |
| ultima_fecha_modificacion | Fecha y hora de la última modificación del registro. Formato: YYYY-MM-DD HH:MM:SS. |
| caracteristicas | Lista de características del inmueble (ver tabla detallada abajo). |
| propietarios | Lista de propietarios del inmueble (ver tabla detallada abajo). |
| imagenes | Lista de imágenes del inmueble (ver tabla detallada abajo). |
| videos | Lista de videos del inmueble (ver tabla detallada abajo). |
| codigos_portales | Lista de códigos de publicación en portales inmobiliarios externos (ver tabla detallada abajo). |
Características
Cada elemento dentro de la lista caracteristicas contiene la información de una característica del inmueble y su valor asignado:
| Clave | Descripción |
|---|---|
| id | Identificador de la característica. Corresponde al id del servicio Listar Características. |
| descripcion | Nombre descriptivo de la característica (por ejemplo: "Nº De Habitaciones"). |
| tipo_campo | Tipo de campo: numeric, checkbox, select, entre otros. |
| orden | Posición de la característica dentro de su grupo. |
| grupo | Grupo al que pertenece la característica. |
| valor | Valor asignado a la característica para esta propiedad. Para numeric: un número. Para checkbox: "1" (marcado). Para select: el valor técnico de la opción seleccionada. |
| valor_texto | Descripción legible del valor seleccionado. Solo presente cuando tipo_campo es select (por ejemplo: valor "si" → valor_texto "Si"). |
Propietarios
Cada elemento dentro de la lista propietarios contiene la información de un propietario del inmueble:
| Clave | Descripción |
|---|---|
| id | Identificador del propietario (tercero) en el sistema. |
| documento | Número de documento de identificación del propietario. |
| nombres | Nombres del propietario. |
| apellidos | Apellidos del propietario. |
Imágenes
Cada elemento dentro de la lista imagenes contiene la información de una fotografía del inmueble:
| Clave | Descripción |
|---|---|
| posicion | Posición de ordenamiento de la imagen (1 = principal). |
| size | Resolución de la imagen (por ejemplo: "19201080"). |
| img | Ruta relativa de la imagen en el servidor. |
| imagen | URL completa de la imagen, lista para consumir directamente. |
Videos
Cada elemento dentro de la lista videos contiene la información de un video asociado al inmueble:
| Clave | Descripción |
|---|---|
| url | Identificador o URL del video (por ejemplo, el ID de YouTube: "608AV8w6gL0"). |
| tipo | Plataforma del video (por ejemplo: "youtube"). |
| descripcion | Descripción del video. Puede ser null. |
| posicion | Posición de ordenamiento del video. |
Códigos de Portales
Cada elemento dentro de la lista codigos_portales contiene la información de publicación del inmueble en un portal inmobiliario externo:
| Clave | Descripción |
|---|---|
| nombre_portal | Nombre del portal inmobiliario (por ejemplo: "metrocuadrado", "fincaraiz"). |
| id_portal | Identificador de la propiedad en el portal externo. |
| tipo_servicio | Tipo de servicio bajo el cual fue publicada la propiedad en ese portal. |
4. Seguridad y Posibles Errores
El sistema realiza validaciones de autenticación, scopes y parámetros. Si alguna falla, devolverá un error con su respectivo código HTTP:
| Código HTTP | Descripción |
|---|---|
| 400 | Token faltante o inválido. Posibles causas: — No se envió el encabezado Authorization. Mensaje: "JWT Token required."— El encabezado no tiene el formato Bearer {token}. Mensaje: "JWT Token not send."— El token no fue encontrado en el sistema. Mensaje: "JWT Token not found."Parámetros inválidos. Posibles causas: — page no es numérico.— limit no es numérico o es mayor a 50.— Las fechas no tienen el formato YYYY-MM-DD.— La fecha de inicio es mayor que la fecha de fin en un rango. |
| 401 | El token ha expirado. Debes generar uno nuevo consumiendo el servicio de Login. Mensaje: "JWT Token expired." |
| 403 | El cliente OAuth no tiene el scope necesario para esta operación. Para endpoints GET se requiere el scope read. Mensaje: "Insufficient scope. Required: 'read', granted: '{scope_actual}'." |
5. Ejemplos de integración
Aquí tienes ejemplos de código listos para que tus desarrolladores los adapten a tu plataforma:
cURL
# Listar propiedades con paginación
curl -X GET "https://{{instancia}}/service/v2/public/properties?page=1&limit=10" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer TU_TOKEN_AQUI"
# Filtrar por rango de fecha de consignación
curl -X GET "https://{{instancia}}/service/v2/public/properties?page=1&limit=10&listing_start_date=2024-03-01&listing_end_date=2024-03-31" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer TU_TOKEN_AQUI"
# Filtrar por fecha de creación
curl -X GET "https://{{instancia}}/service/v2/public/properties?page=1&limit=20&created_start_date=2024-01-01" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer TU_TOKEN_AQUI"
PHP
<?php
$instance = 'tu_instancia'; // Reemplaza con tu instancia real
$token = 'TU_TOKEN_AQUI'; // Token obtenido del servicio Login
// Parámetros de consulta
$page = 1;
$limit = 10;
$listingStartDate = '2024-03-01';
$listingEndDate = '2024-03-31';
$queryParams = http_build_query([
'page' => $page,
'limit' => $limit,
'listing_start_date' => $listingStartDate,
'listing_end_date' => $listingEndDate
]);
$url = "https://{$instance}/service/v2/public/properties?{$queryParams}";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
"Authorization: Bearer {$token}"
]);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (curl_errno($ch)) {
echo 'Error: ' . curl_error($ch);
} else {
echo "Código de estado HTTP: " . $http_code . "\n";
if ($http_code === 200) {
$propiedades = json_decode($response, true);
echo "Propiedades encontradas: " . count($propiedades) . "\n";
foreach ($propiedades as $propiedad) {
echo " [{$propiedad['codigo']}] {$propiedad['titulo']} - {$propiedad['estado_texto']}\n";
}
} else {
echo "Error al consultar las propiedades.\n";
echo $response . "\n";
}
}
curl_close($ch);
?>
Python
import requests
# 1. Configura tus datos de acceso
instancia = 'mi-inmobiliaria.nuby.app' # Reemplaza con tu dirección web completa
token = 'TU_TOKEN_AQUI' # Token obtenido del servicio Login
# 2. Prepara la dirección y los parámetros
url = f"https://{instancia}/service/v2/public/properties"
params = {
"page": 1,
"limit": 10,
"listing_start_date": "2024-03-01",
"listing_end_date": "2024-03-31"
}
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {token}"
}
# 3. Envía la petición GET y procesa la respuesta
try:
response = requests.get(url, params=params, headers=headers)
print(f"Código de estado HTTP: {response.status_code}")
if response.status_code == 200:
propiedades = response.json()
print(f"Propiedades encontradas: {len(propiedades)}")
for prop in propiedades:
print(f" [{prop['codigo']}] {prop['titulo']} - {prop['estado_texto']}")
else:
print("Error al consultar las propiedades.")
print(f"Detalle del error: {response.text}")
except Exception as e:
print(f"Ocurrió un error de conexión: {e}")
JavaScript
// 1. Configura tus datos de acceso
const instancia = 'mi-inmobiliaria.nuby.app'; // Reemplaza con tu dirección web completa
const token = 'TU_TOKEN_AQUI'; // Token obtenido del servicio Login
// 2. Prepara la dirección con parámetros
const params = new URLSearchParams({
page: 1,
limit: 10,
listing_start_date: '2024-03-01',
listing_end_date: '2024-03-31'
});
const url = `https://${instancia}/service/v2/public/properties?${params}`;
// 3. Función para consultar las propiedades
async function consultarPropiedades() {
try {
const response = await fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
}
});
console.log(`Código de estado HTTP: ${response.status}`);
if (response.ok) {
const propiedades = await response.json();
console.log(`Propiedades encontradas: ${propiedades.length}`);
propiedades.forEach(prop => {
console.log(` [${prop.codigo}] ${prop.titulo} - ${prop.estado_texto}`);
});
} else {
console.log('Error al consultar las propiedades.');
const errorData = await response.text();
console.log(`Detalle del error: ${errorData}`);
}
} catch (error) {
console.error(`Ocurrió un error de conexión: ${error}`);
}
}
// 4. Ejecutamos la función
consultarPropiedades();
Power Query M (Excel / Power BI)
let
// 1. Configura tus datos de acceso
instancia = "mi-inmobiliaria.nuby.app", // Reemplaza con tu dirección web completa
token = "TU_TOKEN_AQUI", // Token obtenido del servicio Login
// 2. Prepara la dirección de la petición con parámetros
url = "https://" & instancia & "/service/v2/public/properties?page=1&limit=50",
// 3. Envía la petición GET
response = Web.Contents(url, [
Headers = [
#"Content-Type" = "application/json",
#"Authorization" = "Bearer " & token
]
]),
// 4. Decodifica la respuesta JSON y conviértela en tabla
jsonResponse = Json.Document(response),
tabla = Table.FromList(jsonResponse, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
expandido = Table.ExpandRecordColumn(tabla, "Column1",
{"codigo", "titulo", "clase_inmueble", "tipo_servicio", "estado_texto", "direccion", "municipio", "departamento", "area", "valor_arriendo1", "valor_venta1", "fecha_consignacion"},
{"Codigo", "Titulo", "ClaseInmueble", "TipoServicio", "Estado", "Direccion", "Municipio", "Departamento", "Area", "ValorArriendo", "ValorVenta", "FechaConsignacion"})
in
expandido
Buscar Propiedad por Código
Permite obtener la información completa de una propiedad específica a partir de su código único. La respuesta incluye datos generales, ubicación, valores económicos, características, propietarios, imágenes, videos y códigos de portales inmobiliarios.
¿Para qué sirve este servicio?
Úsalo cuando ya conoces el código del inmueble y necesitas consultar toda su información detallada. Es ideal para mostrar la ficha completa de una propiedad en tu sitio web, sincronizar datos de un inmueble puntual o verificar la información registrada en el sistema.
1. El Endpoint (La dirección web)
Apunta tu sistema a la siguiente dirección. Recuerda reemplazar {{instancia}} por la dirección web completa que utilizas para ingresar a tu plataforma, y {{code}} por el código numérico del inmueble que deseas consultar.
GET https://{{instancia}}/service/v2/public/properties/{{code}}
¿Qué debes colocar en {{instancia}}?
Es muy sencillo: corresponde a la dirección web principal que utilizas a diario para ingresar a tu plataforma (incluyendo la terminación .nuby.app o .arrendasoft.co).
Por ejemplo, si para entrar a tu sistema escribes inmobiliaria.nuby.app o inmobiliaria.arrendasoft.co en tu navegador, esa será exactamente tu instancia. Solo asegúrate de no incluir el "https://" ni barras diagonales ("/") al final.
2. La Petición (¿Qué debes enviarnos?)
Este servicio requiere autenticación mediante un Token JWT. Construye la URL con el código de la propiedad como parte de la ruta e incluye los encabezados requeridos:
| Método | GET |
| Content-Type | application/json |
| Authorization | Bearer token, Token obtenido al consumir el servicio Login. |
Autenticación requerida
Este servicio requiere un Token de autenticación válido. Debes incluir el encabezado Authorization: Bearer TU_TOKEN en cada petición. El token se obtiene consumiendo el servicio de Login. Adicionalmente, el cliente OAuth debe contar con el scope read para poder consumir este endpoint.
Parámetro de ruta:
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
| code | integer | Sí | Código numérico único del inmueble que se desea consultar. Debe ser un número entero positivo. |
Ejemplos de peticiones:
GET https://{{instancia}}/service/v2/public/properties/137
GET https://{{instancia}}/service/v2/public/properties/2045
3. La Respuesta (¿Qué te entregaremos?)
El sistema te devolverá un objeto JSON con toda la información de la propiedad solicitada. Si el código no corresponde a ningún inmueble registrado, se devolverá un arreglo vacío [].
Respuesta como objeto, no como lista
A diferencia del servicio Listar Propiedades que devuelve un arreglo de objetos [{...}, {...}], este servicio devuelve directamente un único objeto {...} con la información del inmueble consultado.
La respuesta exitosa se verá similar a esta:
{
"codigo": "137",
"titulo": "Apartamento amplio con vista al parque central",
"clase_id": "1247",
"clase_inmueble": "Apartamento",
"tipo_servicio_id": "arriendo",
"tipo_servicio": "Arriendo",
"estrato": "1258",
"estrato_texto": "Cuatro",
"fecha_consignacion": "2024-04-26",
"asesor_id": "5",
"asesor": "María López Ramírez",
"pais_id": "1",
"pais": "COLOMBIA",
"departamento_id": "5",
"departamento": "Antioquia",
"municipio_id": "1",
"municipio": "Medellin",
"barrio_id": "3",
"barrio": "Los Rosales",
"direccion": "CALLE 45 # 32 - 18",
"coordenadas": "6.24830000000000:-75.56120000000000",
"valor_arriendo1": "1600000",
"valor_arriendo2": "0",
"valor_venta1": "0",
"valor_venta2": "0",
"valor_administracion": "250000",
"avaluo_catastral": "185000000",
"impuesto_predial": "1250000.00",
"area": "75.00",
"observaciones": "Inmueble ubicado en zona residencial tranquila, cerca de centros comerciales y transporte público.",
"propiedad_destacada": "No",
"llaves_en": "oficina",
"llaves_otro": null,
"paga_cuota_sost": "propietario",
"folio_matricula": "001-123456",
"referencia_catastral": "05001010203040",
"edificio_unidad": "urbanizacion",
"estado": "1",
"estado_texto": "Activa",
"cantidad_images": "3",
"cantidad_videos": "1",
"fecha_creacion": "2024-04-26 10:30:00",
"ultima_fecha_modificacion": "2024-05-15 14:22:00",
"caracteristicas": [
{
"id": "1",
"descripcion": "Nº De Habitaciones",
"tipo_campo": "numeric",
"orden": "1",
"grupo": "Características del inmueble",
"valor": "4"
},
{
"id": "2",
"descripcion": "Nº De Baños",
"tipo_campo": "numeric",
"orden": "2",
"grupo": "Características del inmueble",
"valor": "3"
},
{
"id": "5",
"descripcion": "Nº De Piso",
"tipo_campo": "numeric",
"orden": "3",
"grupo": "Características del inmueble",
"valor": "1"
},
{
"id": "4",
"descripcion": "Antigüedad del Inmueble",
"tipo_campo": "numeric",
"orden": "5",
"grupo": "Características del Inmueble",
"valor": "3"
},
{
"id": "14",
"descripcion": "Cocina Integral",
"tipo_campo": "checkbox",
"orden": "5",
"grupo": "Características Internas",
"valor": "1"
},
{
"id": "34",
"descripcion": "Sala",
"tipo_campo": "checkbox",
"orden": "6",
"grupo": "Características del Inmueble",
"valor": "1"
},
{
"id": "31",
"descripcion": "Red de gas",
"tipo_campo": "select",
"orden": "5",
"grupo": "Características del Inmueble",
"valor": "si",
"valor_texto": "Si"
},
{
"id": "63",
"descripcion": "Garaje",
"tipo_campo": "checkbox",
"orden": "10",
"grupo": "Características Internas",
"valor": "1"
}
],
"propietarios": [
{
"id": "272",
"documento": "1020304050",
"nombres": "ANA MARÍA",
"apellidos": "PÉREZ RODRÍGUEZ"
}
],
"imagenes": [
{
"posicion": "1",
"size": "19201080",
"img": "img/fotos/1920x1080_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6.jpeg",
"imagen": "https://mi-inmobiliaria.nuby.app/img/fotos/1920x1080_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6.jpeg"
},
{
"posicion": "2",
"size": "19201080",
"img": "img/fotos/1920x1080_f6e5d4c3b2a1f6e5d4c3b2a1f6e5d4c3.jpeg",
"imagen": "https://mi-inmobiliaria.nuby.app/img/fotos/1920x1080_f6e5d4c3b2a1f6e5d4c3b2a1f6e5d4c3.jpeg"
},
{
"posicion": "3",
"size": "19201080",
"img": "img/fotos/1920x1080_b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8.jpeg",
"imagen": "https://mi-inmobiliaria.nuby.app/img/fotos/1920x1080_b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8.jpeg"
}
],
"videos": [
{
"url": "dQw4w9WgXcQ",
"tipo": "youtube",
"descripcion": null,
"posicion": "1"
}
],
"codigos_portales": [
{
"nombre_portal": "metrocuadrado",
"id_portal": "MC-98765",
"tipo_servicio": "arriendo"
}
]
}
Cuando el código no corresponde a ningún inmueble, la respuesta será:
[]
Campos principales de la propiedad
Esta tabla enumera las claves presentes en el JSON de la propiedad y proporciona una descripción de cada una:
| Clave | Descripción |
|---|---|
| codigo | Código único del inmueble en el sistema. |
| titulo | Título del anuncio del inmueble. |
| clase_id | Identificador de la clase de inmueble. Corresponde al id del servicio Listar Clases de Inmueble. |
| clase_inmueble | Nombre de la clase de inmueble (por ejemplo: "Apartamento", "Casa", "Finca"). |
| tipo_servicio_id | Identificador del tipo de servicio. Valores posibles: "arriendo", "venta", "venta y arriendo". |
| tipo_servicio | Nombre descriptivo del tipo de servicio (por ejemplo: "Arriendo", "Venta"). |
| estrato | Identificador del estrato socioeconómico del inmueble. |
| estrato_texto | Texto descriptivo del estrato (por ejemplo: "Cuatro", "Tres"). |
| fecha_consignacion | Fecha en que el inmueble fue captado/consignado para su gestión. Formato: YYYY-MM-DD. |
| asesor_id | Identificador del asesor asignado al inmueble. Cadena vacía si no tiene asesor asignado. |
| asesor | Nombre completo del asesor asignado. |
| pais_id | Identificador del país donde se ubica el inmueble. |
| pais | Nombre del país. |
| departamento_id | Identificador del departamento/estado/provincia. |
| departamento | Nombre del departamento. |
| municipio_id | Identificador del municipio/ciudad. |
| municipio | Nombre del municipio. |
| barrio_id | Identificador del barrio. Puede ser null si no se ha asignado barrio. |
| barrio | Nombre del barrio. |
| direccion | Dirección física del inmueble. |
| coordenadas | Coordenadas geográficas del inmueble en formato latitud:longitud. |
| valor_arriendo1 | Valor principal de arriendo (canon mensual). |
| valor_arriendo2 | Valor secundario de arriendo. 0 si no aplica. |
| valor_venta1 | Valor principal de venta. |
| valor_venta2 | Valor secundario de venta. 0 si no aplica. |
| valor_administracion | Valor de la cuota de administración. |
| avaluo_catastral | Avalúo catastral del inmueble. |
| impuesto_predial | Valor del impuesto predial. |
| area | Área del inmueble en metros cuadrados. |
| observaciones | Observaciones o descripción adicional del inmueble. Puede ser null. |
| propiedad_destacada | Indica si la propiedad está marcada como destacada. Valores: "Si" o "No". |
| llaves_en | Lugar donde se encuentran las llaves del inmueble (por ejemplo: "oficina"). |
| llaves_otro | Ubicación alternativa de las llaves, si aplica. Puede ser null. |
| paga_cuota_sost | Quién paga la cuota de sostenimiento (por ejemplo: "propietario"). Puede ser null. |
| folio_matricula | Número de folio de matrícula inmobiliaria. Puede ser null. |
| referencia_catastral | Referencia catastral del inmueble. Puede ser null. |
| edificio_unidad | Tipo de agrupamiento del inmueble (por ejemplo: "urbanizacion", "edificio", "conjunto"). |
| estado | Identificador numérico del estado del inmueble. Valores: 0 (Arrendada), 1 (Activa), 2 (Inactiva), 3 (Vendida). |
| estado_texto | Texto descriptivo del estado (por ejemplo: "Activa", "Arrendada"). |
| cantidad_images | Cantidad de imágenes asociadas al inmueble. |
| cantidad_videos | Cantidad de videos asociados al inmueble. |
| fecha_creacion | Fecha y hora de creación del registro en el sistema. Formato: YYYY-MM-DD HH:MM:SS. |
| ultima_fecha_modificacion | Fecha y hora de la última modificación del registro. Formato: YYYY-MM-DD HH:MM:SS. |
| caracteristicas | Lista de características del inmueble (ver tabla detallada abajo). |
| propietarios | Lista de propietarios del inmueble (ver tabla detallada abajo). |
| imagenes | Lista de imágenes del inmueble (ver tabla detallada abajo). |
| videos | Lista de videos del inmueble (ver tabla detallada abajo). |
| codigos_portales | Lista de códigos de publicación en portales inmobiliarios externos (ver tabla detallada abajo). |
Características
Cada elemento dentro de la lista caracteristicas contiene la información de una característica del inmueble y su valor asignado:
| Clave | Descripción |
|---|---|
| id | Identificador de la característica. Corresponde al id del servicio Listar Características. |
| descripcion | Nombre descriptivo de la característica (por ejemplo: "Nº De Habitaciones"). |
| tipo_campo | Tipo de campo: numeric, checkbox, select, entre otros. |
| orden | Posición de la característica dentro de su grupo. |
| grupo | Grupo al que pertenece la característica. |
| valor | Valor asignado a la característica para esta propiedad. Para numeric: un número. Para checkbox: "1" (marcado). Para select: el valor técnico de la opción seleccionada. |
| valor_texto | Descripción legible del valor seleccionado. Solo presente cuando tipo_campo es select (por ejemplo: valor "si" → valor_texto "Si"). |
Propietarios
Cada elemento dentro de la lista propietarios contiene la información de un propietario del inmueble:
| Clave | Descripción |
|---|---|
| id | Identificador del propietario (tercero) en el sistema. |
| documento | Número de documento de identificación del propietario. |
| nombres | Nombres del propietario. |
| apellidos | Apellidos del propietario. |
Imágenes
Cada elemento dentro de la lista imagenes contiene la información de una fotografía del inmueble:
| Clave | Descripción |
|---|---|
| posicion | Posición de ordenamiento de la imagen (1 = principal). |
| size | Resolución de la imagen (por ejemplo: "19201080"). |
| img | Ruta relativa de la imagen en el servidor. |
| imagen | URL completa de la imagen, lista para consumir directamente. |
Videos
Cada elemento dentro de la lista videos contiene la información de un video asociado al inmueble:
| Clave | Descripción |
|---|---|
| url | Identificador o URL del video (por ejemplo, el ID de YouTube: "dQw4w9WgXcQ"). |
| tipo | Plataforma del video (por ejemplo: "youtube"). |
| descripcion | Descripción del video. Puede ser null. |
| posicion | Posición de ordenamiento del video. |
Códigos de Portales
Cada elemento dentro de la lista codigos_portales contiene la información de publicación del inmueble en un portal inmobiliario externo:
| Clave | Descripción |
|---|---|
| nombre_portal | Nombre del portal inmobiliario (por ejemplo: "metrocuadrado", "fincaraiz"). |
| id_portal | Identificador de la propiedad en el portal externo. |
| tipo_servicio | Tipo de servicio bajo el cual fue publicada la propiedad en ese portal. |
4. Seguridad y Posibles Errores
El sistema realiza validaciones de autenticación, scopes y parámetros de ruta:
Cuando el código es numérico pero no corresponde a ningún inmueble registrado, el sistema no devuelve un error. En su lugar, responde con un HTTP 200 y un arreglo vacío:
[]
Importante
Asegúrate de validar en tu integración si la respuesta es un arreglo vacío [] para manejar correctamente el caso en que la propiedad no exista.
| Código HTTP | Descripción |
|---|---|
| 200 | Respuesta exitosa. Contiene el objeto JSON de la propiedad, o un arreglo vacío [] si no se encontró ningún inmueble con ese código. |
| 400 | Token faltante o inválido. Posibles causas: — No se envió el encabezado Authorization. Mensaje: "JWT Token required."— El encabezado no tiene el formato Bearer {token}. Mensaje: "JWT Token not send."— El token no fue encontrado en el sistema. Mensaje: "JWT Token not found." |
| 401 | El token ha expirado. Debes generar uno nuevo consumiendo el servicio de Login. Mensaje: "JWT Token expired." |
| 403 | El cliente OAuth no tiene el scope necesario para esta operación. Para endpoints GET se requiere el scope read. Mensaje: "Insufficient scope. Required: 'read', granted: '{scope_actual}'." |
| 404 | La ruta no fue encontrada. Ocurre cuando el valor de code no es numérico (por ejemplo: /properties/abc). |
5. Ejemplos de integración
Aquí tienes ejemplos de código listos para que tus desarrolladores los adapten a tu plataforma:
cURL
# Consultar propiedad por código
curl -X GET "https://{{instancia}}/service/v2/public/properties/137" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer TU_TOKEN_AQUI"
PHP
<?php
$instance = 'tu_instancia'; // Reemplaza con tu instancia real
$token = 'TU_TOKEN_AQUI'; // Token obtenido del servicio Login
$code = 137; // Código de la propiedad a consultar
$url = "https://{$instance}/service/v2/public/properties/{$code}";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
"Authorization: Bearer {$token}"
]);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (curl_errno($ch)) {
echo 'Error: ' . curl_error($ch);
} else {
echo "Código de estado HTTP: " . $http_code . "\n";
if ($http_code === 200) {
$propiedad = json_decode($response, true);
if (!empty($propiedad)) {
echo "Propiedad encontrada:\n";
echo " Código: {$propiedad['codigo']}\n";
echo " Título: {$propiedad['titulo']}\n";
echo " Estado: {$propiedad['estado_texto']}\n";
echo " Dirección: {$propiedad['direccion']}\n";
echo " Imágenes: {$propiedad['cantidad_images']}\n";
} else {
echo "No se encontró ninguna propiedad con el código {$code}.\n";
}
} else {
echo "Error al consultar la propiedad.\n";
echo $response . "\n";
}
}
curl_close($ch);
?>
Python
import requests
# 1. Configura tus datos de acceso
instancia = 'mi-inmobiliaria.nuby.app' # Reemplaza con tu dirección web completa
token = 'TU_TOKEN_AQUI' # Token obtenido del servicio Login
codigo = 137 # Código de la propiedad a consultar
# 2. Prepara la dirección de la petición
url = f"https://{instancia}/service/v2/public/properties/{codigo}"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {token}"
}
# 3. Envía la petición GET y procesa la respuesta
try:
response = requests.get(url, headers=headers)
print(f"Código de estado HTTP: {response.status_code}")
if response.status_code == 200:
propiedad = response.json()
if propiedad:
print(f"Propiedad encontrada:")
print(f" Código: {propiedad['codigo']}")
print(f" Título: {propiedad['titulo']}")
print(f" Estado: {propiedad['estado_texto']}")
print(f" Dirección: {propiedad['direccion']}")
print(f" Características: {len(propiedad['caracteristicas'])}")
else:
print(f"No se encontró ninguna propiedad con el código {codigo}.")
else:
print("Error al consultar la propiedad.")
print(f"Detalle del error: {response.text}")
except Exception as e:
print(f"Ocurrió un error de conexión: {e}")
JavaScript
// 1. Configura tus datos de acceso
const instancia = 'mi-inmobiliaria.nuby.app'; // Reemplaza con tu dirección web completa
const token = 'TU_TOKEN_AQUI'; // Token obtenido del servicio Login
const codigo = 137; // Código de la propiedad a consultar
// 2. Prepara la dirección de la petición
const url = `https://${instancia}/service/v2/public/properties/${codigo}`;
// 3. Función para consultar la propiedad
async function consultarPropiedad() {
try {
const response = await fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
}
});
console.log(`Código de estado HTTP: ${response.status}`);
if (response.ok) {
const propiedad = await response.json();
if (propiedad && !Array.isArray(propiedad)) {
console.log(`Propiedad encontrada:`);
console.log(` Código: ${propiedad.codigo}`);
console.log(` Título: ${propiedad.titulo}`);
console.log(` Estado: ${propiedad.estado_texto}`);
console.log(` Dirección: ${propiedad.direccion}`);
console.log(` Imágenes: ${propiedad.cantidad_images}`);
} else {
console.log(`No se encontró ninguna propiedad con el código ${codigo}.`);
}
} else {
console.log('Error al consultar la propiedad.');
const errorData = await response.text();
console.log(`Detalle del error: ${errorData}`);
}
} catch (error) {
console.error(`Ocurrió un error de conexión: ${error}`);
}
}
// 4. Ejecutamos la función
consultarPropiedad();
Power Query M (Excel / Power BI)
let
// 1. Configura tus datos de acceso
instancia = "mi-inmobiliaria.nuby.app", // Reemplaza con tu dirección web completa
token = "TU_TOKEN_AQUI", // Token obtenido del servicio Login
codigo = "137", // Código de la propiedad a consultar
// 2. Prepara la dirección de la petición
url = "https://" & instancia & "/service/v2/public/properties/" & codigo,
// 3. Envía la petición GET
response = Web.Contents(url, [
Headers = [
#"Content-Type" = "application/json",
#"Authorization" = "Bearer " & token
]
]),
// 4. Decodifica la respuesta JSON y conviértela en registro
jsonResponse = Json.Document(response),
resultado = Record.ToTable(jsonResponse),
expandido = Table.Pivot(resultado, List.Distinct(resultado[Name]), "Name", "Value")
in
expandido
Actualizar Estado de la Propiedad
Permite actualizar el estado de una propiedad específica a partir de su código único. Este servicio es útil para cambiar el estado de un inmueble entre los estados permitidos por el sistema.
¿Para qué sirve este servicio?
Úsalo cuando necesites cambiar el estado de un inmueble desde tu sistema externo, por ejemplo: marcar una propiedad como inactiva cuando se retira del mercado, reactivarla cuando vuelve a estar disponible, o registrar que fue vendida.
1. El Endpoint (La dirección web)
Apunta tu sistema a la siguiente dirección. Recuerda reemplazar {{instancia}} por la dirección web completa que utilizas para ingresar a tu plataforma, y {{code}} por el código numérico del inmueble cuyo estado deseas actualizar.
PATCH https://{{instancia}}/service/v2/public/properties/{{code}}/status
¿Qué debes colocar en {{instancia}}?
Es muy sencillo: corresponde a la dirección web principal que utilizas a diario para ingresar a tu plataforma (incluyendo la terminación .nuby.app o .arrendasoft.co).
Por ejemplo, si para entrar a tu sistema escribes inmobiliaria.nuby.app o inmobiliaria.arrendasoft.co en tu navegador, esa será exactamente tu instancia. Solo asegúrate de no incluir el "https://" ni barras diagonales ("/") al final.
2. La Petición (¿Qué debes enviarnos?)
Debes enviar una petición PATCH con el nuevo estado en el cuerpo de la solicitud en formato JSON:
| Método | PATCH |
| Content-Type | application/json |
| Authorization | Bearer token, Token obtenido al consumir el servicio Login. |
Autenticación requerida
Este servicio requiere un Token de autenticación válido. Debes incluir el encabezado Authorization: Bearer TU_TOKEN en cada petición. El token se obtiene consumiendo el servicio de Login. Adicionalmente, el cliente OAuth debe contar con el scope update para poder consumir este endpoint.
Parámetro de ruta:
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
| code | integer | Sí | Código numérico único del inmueble cuyo estado se desea actualizar. |
Cuerpo de la petición (Body):
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
| status | integer | Sí | Nuevo estado que se desea asignar a la propiedad. Los valores válidos son:1 = Activa2 = Inactiva3 = Vendida |
Restricción importante sobre el estado "Arrendada" (0)
Aunque el estado 0 (Arrendada) existe en el sistema, no es posible asignar este estado a través de la API. El estado "Arrendada" se gestiona internamente por el sistema cuando se registra un contrato de arrendamiento asociado al inmueble.
Estados válidos del sistema
| ID | Estado | Descripción |
|---|---|---|
| 0 | Arrendada | El inmueble tiene un contrato de arrendamiento vigente. No se puede asignar vía API. |
| 1 | Activa | El inmueble está disponible en el mercado para arriendo o venta. |
| 2 | Inactiva | El inmueble fue retirado temporalmente del mercado. |
| 3 | Vendida | El inmueble fue vendido. |
Reglas de transición de estado
El sistema solo permite cambiar el estado de una propiedad cuando su estado actual es Activa (1) o Inactiva (2). Las transiciones posibles son:
| Estado actual | Puede cambiar a |
|---|---|
| Activa (1) | 2 (Inactiva) o 3 (Vendida) |
| Inactiva (2) | 1 (Activa) o 3 (Vendida) |
| Arrendada (0) | No se permite cambiar el estado vía API. |
| Vendida (3) | No se permite cambiar el estado vía API. |
¿Por qué no se puede modificar el estado de una propiedad "Arrendada" o "Vendida"?
Estos son estados terminales que representan transacciones completadas. El cambio de estos estados se gestiona internamente a través de los procesos de negocio del sistema (por ejemplo, al finalizar un contrato de arrendamiento o reversar una venta).
Ejemplo de petición:
PATCH https://{{instancia}}/service/v2/public/properties/137/status
{
"status": 2
}
3. La Respuesta (¿Qué te entregaremos?)
Si la actualización fue exitosa, el sistema responderá con HTTP 200 y un mensaje de confirmación:
{
"message": "Se actualizo el estado de la propiedad correctamente"
}
| Clave | Descripción |
|---|---|
| message | Mensaje indicando que el estado de la propiedad fue actualizado correctamente. |
4. Seguridad y Posibles Errores
El sistema realiza validaciones de autenticación, scopes y datos de la petición. Si alguna falla, devolverá un error con su respectivo código HTTP:
| Código HTTP | Descripción | Ejemplo de respuesta |
|---|---|---|
| 400 | Token faltante o inválido. Posibles causas: — No se envió el encabezado Authorization. Mensaje: "JWT Token required."— El encabezado no tiene el formato Bearer {token}. Mensaje: "JWT Token not send."— El token no fue encontrado en el sistema. Mensaje: "JWT Token not found."Parámetros inválidos. El campo status no fue enviado o no es numérico. |
|
| 401 | El token ha expirado. Debes generar uno nuevo consumiendo el servicio de Login. |
|
| 403 | El cliente OAuth no tiene el scope necesario. Para endpoints PATCH se requiere el scope update. |
|
| 404 | No se encontró ninguna propiedad con el código indicado. |
|
| 422 | El valor de status no corresponde a un estado válido del sistema (no es 0, 1, 2 o 3). |
|
| 422 | El estado actual de la propiedad no permite la modificación (por ejemplo: la propiedad está en estado "Arrendada" o "Vendida"). |
|
| 500 | Error interno del servidor. No se pudo ejecutar la actualización en la base de datos. |
|
5. Ejemplos de integración
Aquí tienes ejemplos de código listos para que tus desarrolladores los adapten a tu plataforma:
cURL
# Cambiar estado de propiedad 137 a Inactiva (2)
curl -X PATCH "https://{{instancia}}/service/v2/public/properties/137/status" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer TU_TOKEN_AQUI" \
-d '{"status": 2}'
# Cambiar estado de propiedad 2045 a Vendida (3)
curl -X PATCH "https://{{instancia}}/service/v2/public/properties/2045/status" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer TU_TOKEN_AQUI" \
-d '{"status": 3}'
# Reactivar propiedad 890 (de Inactiva a Activa)
curl -X PATCH "https://{{instancia}}/service/v2/public/properties/890/status" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer TU_TOKEN_AQUI" \
-d '{"status": 1}'
PHP
<?php
$instance = 'tu_instancia'; // Reemplaza con tu instancia real
$token = 'TU_TOKEN_AQUI'; // Token obtenido del servicio Login
$code = 137; // Código de la propiedad
$nuevoEstado = 2; // 1 = Activa, 2 = Inactiva, 3 = Vendida
$url = "https://{$instance}/service/v2/public/properties/{$code}/status";
$body = json_encode([
'status' => $nuevoEstado
]);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
"Authorization: Bearer {$token}"
]);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (curl_errno($ch)) {
echo 'Error: ' . curl_error($ch);
} else {
echo "Código de estado HTTP: " . $http_code . "\n";
$data = json_decode($response, true);
if ($http_code === 200) {
echo "Éxito: " . $data['message'] . "\n";
} else {
echo "Error: " . ($data['error'] ?? 'Error desconocido') . "\n";
}
}
curl_close($ch);
?>
Python
import requests
import json
# 1. Configura tus datos de acceso
instancia = 'mi-inmobiliaria.nuby.app' # Reemplaza con tu dirección web completa
token = 'TU_TOKEN_AQUI' # Token obtenido del servicio Login
codigo = 137 # Código de la propiedad
nuevo_estado = 2 # 1 = Activa, 2 = Inactiva, 3 = Vendida
# 2. Prepara la dirección y el cuerpo de la petición
url = f"https://{instancia}/service/v2/public/properties/{codigo}/status"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {token}"
}
body = {
"status": nuevo_estado
}
# 3. Envía la petición PATCH y procesa la respuesta
try:
response = requests.patch(url, headers=headers, json=body)
print(f"Código de estado HTTP: {response.status_code}")
data = response.json()
if response.status_code == 200:
print(f"Éxito: {data['message']}")
else:
error_msg = data.get('error', 'Error desconocido')
print(f"Error: {error_msg}")
except Exception as e:
print(f"Ocurrió un error de conexión: {e}")
JavaScript
// 1. Configura tus datos de acceso
const instancia = 'mi-inmobiliaria.nuby.app'; // Reemplaza con tu dirección web completa
const token = 'TU_TOKEN_AQUI'; // Token obtenido del servicio Login
const codigo = 137; // Código de la propiedad
const nuevoEstado = 2; // 1 = Activa, 2 = Inactiva, 3 = Vendida
// 2. Prepara la dirección de la petición
const url = `https://${instancia}/service/v2/public/properties/${codigo}/status`;
// 3. Función para actualizar el estado
async function actualizarEstadoPropiedad() {
try {
const response = await fetch(url, {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({
status: nuevoEstado
})
});
console.log(`Código de estado HTTP: ${response.status}`);
const data = await response.json();
if (response.ok) {
console.log(`Éxito: ${data.message}`);
} else {
console.log(`Error: ${data.error || 'Error desconocido'}`);
}
} catch (error) {
console.error(`Ocurrió un error de conexión: ${error}`);
}
}
// 4. Ejecutamos la función
actualizarEstadoPropiedad();
Power Query M (Excel / Power BI)
let
// 1. Configura tus datos de acceso
instancia = "mi-inmobiliaria.nuby.app", // Reemplaza con tu dirección web completa
token = "TU_TOKEN_AQUI", // Token obtenido del servicio Login
codigo = "137", // Código de la propiedad
nuevoEstado = 2, // 1 = Activa, 2 = Inactiva, 3 = Vendida
// 2. Prepara la dirección y el cuerpo de la petición
url = "https://" & instancia & "/service/v2/public/properties/" & codigo & "/status",
body = Json.FromValue([status = nuevoEstado]),
// 3. Envía la petición PATCH
response = Web.Contents(url, [
Headers = [
#"Content-Type" = "application/json",
#"Authorization" = "Bearer " & token
],
Content = body
]),
// 4. Decodifica la respuesta JSON
jsonResponse = Json.Document(response)
in
jsonResponse
Crear Propiedad
Permite registrar una nueva propiedad en el sistema de forma integral. A través de este servicio, es posible guardar la información básica de la propiedad, asociar propietarios (existentes o creados dinámicamente en la misma petición), registrar características personalizadas, coordenadas geográficas, videos de recorridos, fotos del inmueble y relacionar otras propiedades.
¿Para qué sirve este servicio?
Úsalo cuando necesites automatizar el ingreso de propiedades a nuby desde portales externos, aplicaciones móviles o sistemas de captación propios. Este endpoint está diseñado bajo un modelo transaccional robusto, asegurando que si algún paso crítico falla (por ejemplo, validación de un propietario o falta de características obligatorias del tipo de propiedad), toda la operación se cancele de forma automática para evitar datos inconsistentes en tu base de datos.
1. El Endpoint (La dirección web)
Apunta tu sistema a la siguiente dirección de petición POST. Recuerda reemplazar {{instancia}} por la dirección web completa que utilizas para ingresar a tu plataforma.
POST https://{{instancia}}/service/v2/public/properties
¿Qué debes colocar en {{instancia}}?
Es muy sencillo: corresponde a la dirección web principal que utilizas a diario para ingresar a tu plataforma (incluyendo la terminación .nuby.app o .arrendasoft.co).
Por ejemplo, si para entrar a tu sistema escribes inmobiliaria.nuby.app o inmobiliaria.arrendasoft.co en tu navegador, esa será exactamente tu instancia. Solo asegúrate de no incluir el "https://" ni barras diagonales ("/") al final.
2. La Petición (¿Qué debes enviarnos?)
Este servicio requiere autenticación mediante un Token JWT. Envía los encabezados requeridos y estructura la petición con un cuerpo (Body) en formato JSON que contenga las secciones detalladas a continuación:
| Método | POST |
| Content-Type | application/json |
| Authorization | Bearer token, Token obtenido al consumir el servicio Login. |
Autenticación requerida
Este servicio requiere un Token de autenticación válido. Debes incluir el encabezado Authorization: Bearer TU_TOKEN en cada petición. El token se obtiene consumiendo el servicio de Login. Adicionalmente, el cliente OAuth debe contar con el scope write para poder consumir este endpoint.
Cuerpo de la petición (JSON Body - Estructura General)
La raíz del JSON enviado debe estructurarse con las siguientes llaves principales:
| Elemento Raíz | Tipo | Requerido | Descripción |
|---|---|---|---|
| Propiedad | object | Sí | Contiene la información básica del inmueble (Título, tipo, ubicación, valores, etc.). |
| Propietarios | array | Sí | Lista de propietarios asociados. Puede ser un arreglo de IDs existentes o de objetos con datos de nuevos propietarios. |
| Caracteristicas | object | No | Mapeo de características de la propiedad en formato llave-valor {"id_caracteristica": "valor"}. |
| Videos | array | No | Listado de enlaces a videos del inmueble. |
| Fotos | array | No | Listado de imágenes del inmueble en formato base64 o URLs públicas. |
| PropiedadesRelacionadas | array | No | Arreglo de códigos numéricos de propiedades que se desea relacionar de forma recíproca. |
| Coordenadas | string | object | No | Coordenadas de latitud y longitud. Ejemplo de texto: "6.2089,-75.5678". |
Estructura Detallada de las Secciones
2.1 Sección "Propiedad" 🏢
Contiene la información comercial y técnica base del inmueble. Los siguientes campos son validados estrictamente bajo validación rápida (Fail-Fast):
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
| txtTitulo | string | Sí | Título descriptivo o publicitario del inmueble. Máximo 255 caracteres. |
| tipo_id | integer | Sí | ID de la clase de propiedad (Ej: apartamento, casa, local). Debe ser una clase existente en la maestra de clases de inmueble. |
| propiedad_tipo | string | Sí | Modalidad de comercialización. Valores válidos: "arriendo", "venta", o "venta y arriendo". |
| municipio_id | integer | Sí | ID de la ciudad o municipio donde se ubica el inmueble (debe existir en la maestra de municipios). |
| direccion | string | Sí | Dirección exacta del inmueble. El sistema validará que no exista otra propiedad con la misma dirección en el mismo municipio para evitar duplicados accidentales. |
| estrato | integer | Sí | Estrato socioeconómico del inmueble. Debe ser un número entero entre 1 y 6. |
| barrio_id | integer | No | ID del barrio (debe existir en la maestra de barrios de la ciudad). |
| urbanizacion | string | No | Nombre del edificio, conjunto cerrado o urbanización. |
| valor_arriendo | numeric | No | Canon mensual del arriendo (monto mayor o igual a 0). |
| valor_venta | numeric | No | Precio de venta solicitado (monto mayor o igual a 0). |
| valor_administracion | numeric | No | Costo de la cuota de administración de la copropiedad. |
| propiedad_area | numeric | No | Área privada del inmueble en metros cuadrados. Se envía estrictamente con el nombre físico de columna. |
| observaciones | string | No | Descripción comercial extensa del inmueble. |
| llaves_en | string | No | Ubicación física de las llaves. Valores válidos: "oficina", "propiedad", o "otro". |
| paga_cuota_sost | string | No | Establece quién asume el pago de la cuota de administración. Valores válidos: "propietario" o "inquilino". |
| folio_matricula | string | No | Número de matrícula inmobiliaria del inmueble. |
| referencia_catastral | string | No | Número de referencia catastral asignado por el municipio. |
2.2 Sección "Propietarios" 👥
Cada propiedad en nuby requiere obligatoriamente tener asociado al menos un propietario. El arreglo acepta dos formatos de datos, los cuales pueden combinarse:
Formato A: Propietario Existente (Por ID)
Si el propietario ya se encuentra registrado en el ERP nuby, simplemente envía su identificador único (ID de tercero) como un entero dentro del arreglo:
"Propietarios": [1528, 4390]
Formato B: Creación Dinámica de Propietario (Objeto de Datos)
Si el propietario no existe, puedes enviar sus datos completos estructurados en un objeto. El sistema validará su información, lo creará automáticamente en la base de datos de nuby, y lo asociará al inmueble bajo una misma transacción comercial:
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
| persona | integer | Sí | Naturaleza jurídica del tercero: 1 = Persona Natural, 2 = Persona Jurídica. |
| documento | string | Sí | Número de documento de identidad o NIT. |
| tipo_doc_id | integer | Sí | ID de la maestra de tipos de documentos (Cédula, NIT, Pasaporte, etc.). |
| nombre1 | string | Sí | Primer nombre del propietario o razón social completa. |
| apellido1 | string | Sí (para Natural) | Primer apellido del propietario (requerido si persona = 1). |
| direccion1 | string | Sí | Dirección de domicilio del propietario. |
| municipio_id | integer | Sí | ID del municipio de residencia (debe existir en la base de datos). |
| string | Sí | Correo electrónico para envío de facturas and notificaciones. Debe tener formato de email válido. | |
| telefono | string | Sí | Número telefónico o celular de contacto. |
| tipo_persona_id | integer | Sí (para Natural) | ID de tipo de persona tributaria (requerido si persona = 1). |
| regimen_id | integer | Sí (para Natural) | ID del régimen tributario del propietario (requerido si persona = 1). |
| resp_fiscal_id | integer | Sí (para Natural) | ID de la responsabilidad fiscal (requerido si persona = 1). |
2.3 Sección "Caracteristicas" ⚙️
Permite registrar valores para las características personalizadas del inmueble. Se envía en formato de objeto clave-valor, donde la clave es el ID numérico de la característica y el valor es el contenido a asignar:
"Caracteristicas": {
"1": "3", // ID 1 (Habitaciones) = 3
"2": "2", // ID 2 (Baños) = 2
"31": "si", // ID 31 (Red de gas) = si (Obligatoria)
"63": "1" // ID 63 (Garaje) = 1 (Checkbox de Garaje activo)
}
Validación de Características Obligatorias por Tipo
El motor de validación del sistema nuby verificará qué características están configuradas en el ERP como obligatorias para el tipo de propiedad seleccionado (tipo_id). Si omites alguna de estas características obligatorias en la petición, o el formato del valor es erróneo (por ejemplo, enviar texto en un campo netamente numérico), el endpoint devolverá un código de estado 422 Unprocessable Entity y se revertirá todo el proceso de guardado.
Nota: En una configuración estándar, el apartamento (1247) y la casa (1249) exigen de forma obligatoria las características de: N° de Habitaciones (ID 1), N° de Baños (ID 2) y Red de gas (ID 31).
2.4 Sección "Fotos" 📸
Permite adjuntar imágenes del inmueble de forma directa. El procesamiento de imágenes está automatizado y realiza optimizaciones de rendimiento y de presentación visual (redimensionamiento, corrección de orientación por metadatos EXIF, e inserción de la marca de agua corporativa configurada en el sistema).
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
| url | string | Sí | Contenido de la imagen. Puede enviarse como una cadena Base64 válida (data:image/jpeg;base64,...) o como una URL accesible públicamente para su descarga. |
| nombre | string | No | Nombre del archivo o descripción física para almacenar el documento. |
2.5 Sección "Videos" 🎥
Permite registrar recorridos en video de las propiedades (por ejemplo, cargados en plataformas como YouTube o Vimeo):
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
| video_url | string | Sí | URL completa o código físico del video. Ejemplo: "https://www.youtube.com/watch?v=...". |
| video_tipo | string | No | Tipo o plataforma emisora del video (Ej: "youtube" o "vimeo"). |
| video_descripcion | string | No | Descripción del video. |
| video_posicion | integer | No | Posición de visualización de este video. |
2.6 Sección "PropiedadesRelacionadas" y "Coordenadas" 📍
- PropiedadesRelacionadas → Permite enlazar propiedades entre sí (ideal para bodegas subdivididas, oficinas del mismo centro de negocios, etc.). Recibe una lista de códigos de inmuebles:
[137, 1042]. El sistema nuby creará una asociación recíproca: la propiedad creada apuntará a estas asociadas, y estas asociadas apuntarán automáticamente a la nueva propiedad. - Coordenadas → Coordenadas de geolocalización. Se recomienda enviar como una cadena de texto separada por comas
"latitud,longitud"(Ej:"6.2089,-75.5678"). El motor de nuby se encarga de analizar la cadena, validar su rango físico geográfico y guardarlo bajo el formato propietario del sistema.
3. La Respuesta (¿Qué te entregaremos?)
Esta sección describe la respuesta que recibirás del sistema cuando la creación del inmueble sea completamente exitosa.
Respuesta Exitosa (201 Created)
Se genera cuando la propiedad y todos sus componentes asociados han sido validados e insertados con éxito. Se retorna el identificador único físico asignado al inmueble:
{
"error": false,
"type": "success",
"msg": "La propiedad ha sido creada exitosamente.",
"propiedad_id": 7786,
"warnings": []
}
¿Qué contiene la sección "warnings"?
Si se incluyen fotos o videos y el almacenamiento en la nube o procesamiento de marcas de agua tiene algún inconveniente no letal (por ejemplo, formato no soportado o redimensión fallida de una imagen en particular), el inmueble se creará con éxito, pero se devolverán advertencias en esta sección para que puedas corregir los archivos de forma manual. Esto no interrumpe el registro del inmueble.
4. Seguridad y Posibles Errores
El sistema realiza validaciones de autenticación, permisos (scopes) y estructura de datos. Si alguna falla, devolverá un error con su respectivo código HTTP y un mensaje descriptivo:
| Código HTTP | Significado y Solución |
|---|---|
| 400 Bad Request | Causa: La estructura de la petición es incorrecta o faltan datos esenciales. Ocurre antes de que se intente procesar la lógica de negocio. Ejemplos comunes:
|
| 401 Unauthorized | Causa: El Token JWT de autenticación no es válido o ha expirado. Solución: Vuelve a consumir el servicio de Login para generar un nuevo token de acceso y úsalo en el encabezado Authorization. |
| 403 Forbidden | Causa: El token es válido, pero el cliente OAuth con el que fue generado no tiene los permisos (scopes) necesarios para esta operación. Solución: Verifica la configuración de tu cliente OAuth en nuby y asegúrate de que tenga asignado el scope write. |
| 422 Unprocessable Entity | Causa: La petición es sintácticamente correcta, pero incumple una regla de negocio del sistema. Ejemplos comunes:
msg del JSON de error. Te indicará exactamente qué regla de negocio se infringió para que puedas corregir los datos enviados. |
Operación Atómica y de Transacción Segura
nuby implementa transacciones anidadas en sus modelos de negocio. Si el endpoint responde con un código 422 (o un fallo 500 del servidor), toda la creación física del inmueble es cancelada de forma automática (ROLLBACK). No tendrás propiedades huérfanas sin propietario ni registros incompletos en las tablas del sistema.
5. Ejemplos de integración
Aquí tienes ejemplos de código listos para que tus desarrolladores los adapten a tu plataforma:
Ejemplos de JSON Body
Ejemplo 1: Creación de propiedad con propietario existente
{
"Propiedad": {
"txtTitulo": "Penthouse Duplex El Poblado con Terraza",
"tipo_id": 1247,
"propiedad_tipo": "arriendo",
"municipio_id": 1,
"direccion": "Carrera 35 # 10B - 120, Apartamento 1201",
"estrato": 1260,
"barrio_id": 5,
"valor_arriendo": 4800000,
"valor_administracion": 650000,
"urbanizacion": "Torres de San Lucas",
"observaciones": "Espectacular penthouse con vista de 360 grados, tina de hidromasajes en terraza principal, 3 alcobas cada una con baño.",
"propiedad_area": 185.4,
"llaves_en": "oficina",
"paga_cuota_sost": "propietario"
},
"Propietarios": [
1247
],
"Caracteristicas": {
"1": "3", // Alcobas
"2": "4", // Baños
"31": "si", // Red de gas (Obligatoria)
"63": "1" // Garaje (Checkbox de Garaje - ID 63 en nuby)
},
"Coordenadas": "6.205210,-75.561240"
}
Ejemplo 2: Creación de propiedad con propietario nuevo, videos y fotos
{
"Propiedad": {
"txtTitulo": "Casa de Campo en Llanogrande",
"tipo_id": 1249,
"propiedad_tipo": "venta",
"municipio_id": 2,
"direccion": "Vía Llanogrande Kilómetro 4, Parcelación La Sofía",
"estrato": 1259,
"valor_venta": 1250000000,
"valor_administracion": 300000,
"observaciones": "Hermosa casa de un solo nivel, amplias zonas verdes, deck con zona BBQ, acabados campestres modernos.",
"propiedad_area": 320.0,
"paga_cuota_sost": "propietario"
},
"Propietarios": [
{
"persona": 1,
"documento": "1024567890",
"tipo_doc_id": 1,
"nombre1": "Alejandro",
"apellido1": "Restrepo",
"direccion1": "Transversal 39B # 4G - 85",
"municipio_id": 1,
"email": "alejandro.restrepo@email.com",
"telefono": "3104567890",
"tipo_persona_id": 1,
"regimen_id": 2,
"resp_fiscal_id": 11
}
],
"Caracteristicas": {
"1": "4",
"2": "5",
"31": "si", // Red de gas (Obligatoria)
"63": "1", // Garaje (Checkbox de Garaje - ID 63 en nuby)
"8": "Sí"
},
"Videos": [
{
"video_url": "https://www.youtube.com/watch?v=abc123xyz",
"video_tipo": "youtube",
"video_descripcion": "Video aéreo con Dron de la parcelación"
}
],
"Fotos": [
{
"url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==",
"nombre": "foto_fachada_casa_campo.jpg"
}
]
}
cURL
# Define tu token y tu instancia
TOKEN="TU_TOKEN_AQUI"
INSTANCIA="tu-inmobiliaria.nuby.app"
# Prepara el cuerpo de la petición utilizando estrictamente los nombres de campos físicos
PAYLOAD='{
"Propiedad": {
"txtTitulo": "Apartamento para prueba cURL",
"tipo_id": 1247,
"propiedad_tipo": "arriendo",
"municipio_id": 127,
"direccion": "Calle Falsa 123 via cURL",
"estrato": 1258,
"propiedad_area": 97
},
"Propietarios": [1],
"Caracteristicas": {
"1": "3",
"2": "3",
"31": "si",
"63": "1"
}
}'
curl -X POST "https://${INSTANCIA}/service/v2/public/properties" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${TOKEN}" \
-d "${PAYLOAD}"
PHP
<?php
$instancia = 'tu-inmobiliaria.nuby.app';
$token = 'TU_TOKEN_AQUI';
$url = "https://{$instancia}/service/v2/public/properties";
$payload = [
'Propiedad' => [
'txtTitulo' => 'Propiedad creada desde PHP',
'tipo_id' => 1247,
'propiedad_tipo' => 'venta',
'municipio_id' => 127,
'direccion' => 'Avenida Siempreviva 742, PHP',
'estrato' => 1258,
'propiedad_area' => 97 // Nombre exacto de la columna física
],
'Propietarios' => [1], // ID de un propietario existente
'Caracteristicas' => [
'1' => '3', // Habitaciones
'2' => '3', // Baños
'31' => 'si', // Red de gas (Obligatoria)
'63' => '1' // Garaje (Checkbox de Garaje - ID 63 en nuby)
]
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
"Authorization: Bearer {$token}"
]);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo "Código de estado HTTP: {$http_code}\n";
echo "Respuesta del servidor:\n";
print_r($response);
?>
Python
import requests
import json
instancia = 'tu-inmobiliaria.nuby.app'
token = 'TU_TOKEN_AQUI'
url = f"https://{instancia}/service/v2/public/properties"
payload = {
"Propiedad": {
"txtTitulo": "Propiedad Creada desde Python",
"tipo_id": 1247,
"propiedad_tipo": "venta",
"municipio_id": 127,
"direccion": "Calle de Python, 101",
"estrato": 1258,
"propiedad_area": 97
},
"Propietarios": [1], # ID de un propietario existente
"Caracteristicas": {
"1": "3",
"2": "3",
"31": "si",
"63": "1"
}
}
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {token}"
}
try:
response = requests.post(url, headers=headers, data=json.dumps(payload))
print(f"Código de estado HTTP: {response.status_code}")
print("Respuesta del servidor:")
print(response.json())
except requests.exceptions.RequestException as e:
print(f"Ocurrió un error en la petición: {e}")
JavaScript (Fetch API)
const instancia = 'tu-inmobiliaria.nuby.app';
const token = 'TU_TOKEN_AQUI';
const url = `https://${instancia}/service/v2/public/properties`;
const payload = {
"Propiedad": {
"txtTitulo": "Propiedad Creada desde JavaScript",
"tipo_id": 1247,
"propiedad_tipo": "arriendo",
"municipio_id": 127,
"direccion": "Avenida JavaScript, Lote 5",
"estrato": 1258,
"propiedad_area": 97
},
"Propietarios": [1], // ID de un propietario existente
"Caracteristicas": {
"1": "3",
"2": "3",
"31": "si",
"63": "1"
}
};
async function crearPropiedad() {
try {
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify(payload)
});
const data = await response.json();
console.log(`Código de estado HTTP: ${response.status}`);
console.log('Respuesta del servidor:');
console.log(data);
} catch (error) {
console.error('Error en la petición:', error);
}
}
crearPropiedad();
Power Query M (Excel / Power BI)
let
instancia = "tu-inmobiliaria.nuby.app",
token = "TU_TOKEN_AQUI",
url = "https://" & instancia & "/service/v2/public/properties",
payload = [
Propiedad = [
txtTitulo = "Propiedad desde Power Query",
tipo_id = 1247,
propiedad_tipo = "venta",
municipio_id = 127,
direccion = "Calle Power BI, 4.0",
estrato = 1258,
propiedad_area = 97
],
Propietarios = {1}, // ID de un propietario existente
Caracteristicas = [
#"1" = "3",
#"2" = "3",
#"31" = "si",
#"63" = "1"
]
],
jsonPayload = Json.FromValue(payload),
response = Web.Contents(url, [
Headers = [
#"Content-Type" = "application/json",
#"Authorization" = "Bearer " & token
],
Content = jsonPayload
]),
jsonResponse = Json.Document(response)
in
jsonResponse
Asesores
Bienvenido al directorio digital de personal de tu inmobiliaria. En esta sección agrupamos las herramientas necesarias para que tus aplicaciones externas consulten y sincronicen la información de tu equipo de asesores.
¿Cuál es el objetivo de este módulo? Garantizar que tu ecosistema de herramientas siempre sepa quiénes conforman tu equipo de trabajo. Ya sea que necesites extraer tu plantilla completa o ubicar a alguien en particular de manera rápida, tus plataformas podrán acceder a estos datos de forma totalmente automática.
¿Qué datos obtendrás en tus consultas? Por cada asesor, el sistema devolverá una "tarjeta de presentación" digital completa y lista para usar, que incluye:
- Identificación: Nombre completo y número de documento de identidad.
- Contacto: Número de teléfono y correo electrónico.
- Recurso visual: Enlace directo a su fotografía de perfil.
¡Explora las opciones a continuación para que tus plataformas externas mantengan la información de tu equipo perfectamente actualizada!
Listar Asesores
Permite obtener la lista completa de asesores registrados en el sistema. Cada elemento de la respuesta contiene los datos básicos de contacto de cada asesor: documento de identidad, nombre completo, teléfono, correo electrónico y fotografía.
¿Para qué sirve este servicio?
Úsalo cuando necesites conocer los asesores disponibles en la inmobiliaria, por ejemplo para mostrar un directorio de agentes en tu sitio web, poblar un selector de asesores en un formulario de contacto, o sincronizar la información de los agentes con tu sistema externo.
1. El Endpoint (La dirección web)
Apunta tu sistema a la siguiente dirección. Recuerda reemplazar {{instancia}} por la dirección web completa que utilizas para ingresar a tu plataforma.
GET https://{{instancia}}/service/v2/public/agents
¿Qué debes colocar en {{instancia}}?
Es muy sencillo: corresponde a la dirección web principal que utilizas a diario para ingresar a tu plataforma (incluyendo la terminación .nuby.app o .arrendasoft.co).
Por ejemplo, si para entrar a tu sistema escribes inmobiliaria.nuby.app o inmobiliaria.arrendasoft.co en tu navegador, esa será exactamente tu instancia. Solo asegúrate de no incluir el "https://" ni barras diagonales ("/") al final.
2. La Petición (¿Qué debes enviarnos?)
Este servicio no requiere cuerpo en la petición ni parámetros adicionales. Solo necesitas enviar los encabezados correctos:
| Método | GET |
| Content-Type | application/json |
| Authorization | Bearer token, Token obtenido al consumir el servicio Login |
¿Aún no tienes tu Token de acceso?
Para consumir este servicio necesitas un Token vigente. Consulta el servicio de Login para aprender cómo obtenerlo.
3. La Respuesta (¿Qué te entregaremos?)
Si tu Token es válido, el sistema te devolverá una lista con todos los asesores registrados (excluyendo usuarios internos del sistema). Los asesores se devuelven ordenados alfabéticamente por nombre. La respuesta se verá similar a esta:
[
{
"id": "3",
"documento": "52498731",
"nombre": "ANDREA MILENA CASTRO ROJAS",
"telefono": "3104567890",
"email": "andrea.castro@miredinmobiliaria.com",
"path_photo": "https://mi-inmobiliaria.nuby.app/pic/usuarios/foto_andrea_castro.jpg"
},
{
"id": "7",
"documento": "80213654",
"nombre": "CARLOS EDUARDO PINEDA VARGAS",
"telefono": "3209876543",
"email": "carlos.pineda@miredinmobiliaria.com",
"path_photo": "https://mi-inmobiliaria.nuby.app/pic/usuarios/foto_carlos_pineda.jpg"
},
{
"id": "12",
"documento": "1098745231",
"nombre": "JULIANA PATRICIA RÍOS MENDOZA",
"telefono": "3156781234",
"email": "juliana.rios@miredinmobiliaria.com",
"path_photo": "https://mi-inmobiliaria.nuby.app/pic/iconos/user_photo.png"
}
]
Descripción de cada campo:
| Campo | Tipo | Descripción |
|---|---|---|
id |
string | Identificador único del usuario en el sistema. |
documento |
string | Número de documento de identidad del asesor. |
nombre |
string | Nombre completo del asesor (compuesto por primer nombre, segundo nombre, primer apellido y segundo apellido). |
telefono |
string | Número de teléfono del asesor. |
email |
string | Dirección de correo electrónico del asesor. |
path_photo |
string | URL completa de la fotografía del asesor. Si el asesor no tiene foto registrada, se devuelve la imagen genérica del sistema. |
Nota sobre la respuesta
El listado excluye automáticamente los usuarios internos del sistema (cuentas de administración y soporte). Solo se devuelven los asesores reales de la inmobiliaria. Si no hay asesores registrados, la respuesta será un arreglo vacío [].
4. Seguridad y Posibles Errores
¡Tu pase tiene fecha de caducidad!
Por medidas de seguridad, el token que te entregamos solo dura 1 hora. Una vez transcurrido ese tiempo, el pase expirará y el sistema te bloqueará el acceso devolviéndote un error 401. Cuando esto ocurra, tu sistema simplemente debe volver a consumir el servicio de Login para pedir un pase nuevo y continuar trabajando.
Así se ve el error que te devolverá el sistema cuando tu token se haya vencido o intentes usar un pase inválido:
{
"statusCode": 401,
"error": {
"type": "SERVER_ERROR",
"description": "JWT Token expired."
}
}
Otros posibles errores:
| Código HTTP | Descripción |
|---|---|
| 400 | Token no enviado o con formato incorrecto. Asegúrate de incluir el encabezado Authorization: Bearer TU_TOKEN. |
| 401 | Token expirado o inválido. Solicita uno nuevo a través del servicio de Login. |
| 403 | El cliente OAuth no tiene el scope necesario para esta operación. Para endpoints GET se requiere el scope read. Mensaje: "Insufficient scope. Required: 'read', granted: '{scope_actual}'." |
5. Ejemplos de integración
Aquí tienes ejemplos de código listos para que tus desarrolladores los adapten a tu plataforma:
cURL
curl -X GET "https://{{instancia}}/service/v2/public/agents" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer TU_TOKEN_AQUI"
PHP
<?php
$instance = 'tu_instancia'; // Reemplaza con tu instancia real
$token = 'TU_TOKEN_AQUI'; // Token obtenido del servicio Login
$url = "https://{$instance}/service/v2/public/agents";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
"Authorization: Bearer {$token}"
]);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (curl_errno($ch)) {
echo 'Error: ' . curl_error($ch);
} else {
echo "Código de estado HTTP: " . $http_code . "\n";
if ($http_code === 200) {
$asesores = json_decode($response, true);
echo "Asesores encontrados: " . count($asesores) . "\n";
foreach ($asesores as $asesor) {
echo " [{$asesor['id']}] {$asesor['nombre']} - {$asesor['email']}\n";
}
} else {
echo "Error al consultar los asesores.\n";
echo $response . "\n";
}
}
curl_close($ch);
?>
Python
import requests
# 1. Configura tus datos de acceso
instancia = 'mi-inmobiliaria.nuby.app' # Reemplaza con tu dirección web completa
token = 'TU_TOKEN_AQUI' # Token obtenido del servicio Login
# 2. Prepara la dirección de la petición
url = f"https://{instancia}/service/v2/public/agents"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {token}"
}
# 3. Envía la petición GET y procesa la respuesta
try:
response = requests.get(url, headers=headers)
print(f"Código de estado HTTP: {response.status_code}")
if response.status_code == 200:
asesores = response.json()
print(f"Asesores encontrados: {len(asesores)}")
for asesor in asesores:
print(f" [{asesor['id']}] {asesor['nombre']} - {asesor['email']}")
else:
print("Error al consultar los asesores.")
print(f"Detalle del error: {response.text}")
except Exception as e:
print(f"Ocurrió un error de conexión: {e}")
JavaScript
// 1. Configura tus datos de acceso
const instancia = 'mi-inmobiliaria.nuby.app'; // Reemplaza con tu dirección web completa
const token = 'TU_TOKEN_AQUI'; // Token obtenido del servicio Login
// 2. Prepara la dirección de la petición
const url = `https://${instancia}/service/v2/public/agents`;
// 3. Función para consultar los asesores
async function consultarAsesores() {
try {
const response = await fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
}
});
console.log(`Código de estado HTTP: ${response.status}`);
if (response.ok) {
const asesores = await response.json();
console.log(`Asesores encontrados: ${asesores.length}`);
asesores.forEach(asesor => {
console.log(` [${asesor.id}] ${asesor.nombre} - ${asesor.email}`);
});
} else {
console.log('Error al consultar los asesores.');
const errorData = await response.text();
console.log(`Detalle del error: ${errorData}`);
}
} catch (error) {
console.error(`Ocurrió un error de conexión: ${error}`);
}
}
// 4. Ejecutamos la función
consultarAsesores();
Power Query M (Excel / Power BI)
let
// 1. Configura tus datos de acceso
instancia = "mi-inmobiliaria.nuby.app", // Reemplaza con tu dirección web completa
token = "TU_TOKEN_AQUI", // Token obtenido del servicio Login
// 2. Prepara la dirección de la petición
url = "https://" & instancia & "/service/v2/public/agents",
// 3. Envía la petición GET
response = Web.Contents(url, [
Headers = [
#"Content-Type" = "application/json",
#"Authorization" = "Bearer " & token
]
]),
// 4. Decodifica la respuesta JSON y conviértela en tabla
jsonResponse = Json.Document(response),
tabla = Table.FromList(jsonResponse, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
expandido = Table.ExpandRecordColumn(tabla, "Column1",
{"id", "documento", "nombre", "telefono", "email", "path_photo"},
{"ID", "Documento", "Nombre", "Telefono", "Email", "Foto"})
in
expandido
Buscar Asesor por Documento
Permite obtener la información de un asesor específico a partir de su número de documento de identidad. La respuesta contiene los datos básicos de contacto del asesor: documento, nombre completo, teléfono, correo electrónico y fotografía.
¿Para qué sirve este servicio?
Úsalo cuando ya conoces el número de documento del asesor y necesitas consultar su información detallada. Es ideal para mostrar la ficha de un agente en particular, verificar datos de un asesor asignado a una propiedad o sincronizar la información de un agente puntual con tu sistema externo.
1. El Endpoint (La dirección web)
Apunta tu sistema a la siguiente dirección. Recuerda reemplazar {{instancia}} por la dirección web completa que utilizas para ingresar a tu plataforma, y {{document}} por el número de documento de identidad del asesor que deseas consultar.
GET https://{{instancia}}/service/v2/public/agents/{{document}}
¿Qué debes colocar en {{instancia}}?
Es muy sencillo: corresponde a la dirección web principal que utilizas a diario para ingresar a tu plataforma (incluyendo la terminación .nuby.app o .arrendasoft.co).
Por ejemplo, si para entrar a tu sistema escribes inmobiliaria.nuby.app o inmobiliaria.arrendasoft.co en tu navegador, esa será exactamente tu instancia. Solo asegúrate de no incluir el "https://" ni barras diagonales ("/") al final.
2. La Petición (¿Qué debes enviarnos?)
Este servicio no requiere cuerpo en la petición. Solo necesitas construir la URL con el número de documento del asesor como parte de la ruta e incluir los encabezados requeridos:
| Método | GET |
| Content-Type | application/json |
| Authorization | Bearer token, Token obtenido al consumir el servicio Login |
¿Aún no tienes tu Token de acceso?
Para consumir este servicio necesitas un Token vigente. Consulta el servicio de Login para aprender cómo obtenerlo.
Parámetro de ruta:
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
document |
string | Sí | Número de documento de identidad del asesor que se desea consultar. Se envía directamente en la URL. |
Ejemplo de petición:
GET https://mi-inmobiliaria.nuby.app/service/v2/public/agents/52498731
3. La Respuesta (¿Qué te entregaremos?)
Si tu Token es válido y el documento corresponde a un asesor registrado, el sistema te devolverá un objeto JSON con la información del asesor. La respuesta se verá similar a esta:
{
"id": "3",
"documento": "52498731",
"nombre": "ANDREA MILENA CASTRO ROJAS",
"telefono": "3104567890",
"email": "andrea.castro@miredinmobiliaria.com",
"path_photo": "https://mi-inmobiliaria.nuby.app/pic/usuarios/foto_andrea_castro.jpg"
}
Descripción de cada campo:
| Campo | Tipo | Descripción |
|---|---|---|
id |
string | Identificador único del usuario en el sistema. |
documento |
string | Número de documento de identidad del asesor. |
nombre |
string | Nombre completo del asesor (compuesto por primer nombre, segundo nombre, primer apellido y segundo apellido). |
telefono |
string | Número de teléfono del asesor. |
email |
string | Dirección de correo electrónico del asesor. |
path_photo |
string | URL completa de la fotografía del asesor. Si el asesor no tiene foto registrada, se devuelve la imagen genérica del sistema. |
Importante: asesor no encontrado
Cuando el documento no corresponde a ningún asesor registrado, el sistema no devuelve un error. En su lugar, responde con un HTTP 200 y un arreglo vacío:
[]
Asegúrate de validar en tu integración si la respuesta es un arreglo vacío [] para manejar correctamente el caso en que el asesor no exista.
4. Seguridad y Posibles Errores
¡Tu pase tiene fecha de caducidad!
Por medidas de seguridad, el token que te entregamos solo dura 1 hora. Una vez transcurrido ese tiempo, el pase expirará y el sistema te bloqueará el acceso devolviéndote un error 401. Cuando esto ocurra, tu sistema simplemente debe volver a consumir el servicio de Login para pedir un pase nuevo y continuar trabajando.
Así se ve el error que te devolverá el sistema cuando tu token se haya vencido o intentes usar un pase inválido:
{
"statusCode": 401,
"error": {
"type": "SERVER_ERROR",
"description": "JWT Token expired."
}
}
Otros posibles errores:
| Código HTTP | Descripción |
|---|---|
| 200 | Respuesta exitosa. Contiene el objeto JSON del asesor, o un arreglo vacío [] si no se encontró ningún asesor con ese documento. |
| 400 | Token no enviado o con formato incorrecto. Asegúrate de incluir el encabezado Authorization: Bearer TU_TOKEN. |
| 401 | Token expirado o inválido. Solicita uno nuevo a través del servicio de Login. |
| 403 | El cliente OAuth no tiene el scope necesario para esta operación. Para endpoints GET se requiere el scope read. Mensaje: "Insufficient scope. Required: 'read', granted: '{scope_actual}'." |
5. Ejemplos de integración
Aquí tienes ejemplos de código listos para que tus desarrolladores los adapten a tu plataforma:
cURL
# Consultar asesor por documento
curl -X GET "https://{{instancia}}/service/v2/public/agents/52498731" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer TU_TOKEN_AQUI"
PHP
<?php
$instance = 'tu_instancia'; // Reemplaza con tu instancia real
$token = 'TU_TOKEN_AQUI'; // Token obtenido del servicio Login
$documento = '52498731'; // Documento del asesor a consultar
$url = "https://{$instance}/service/v2/public/agents/{$documento}";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
"Authorization: Bearer {$token}"
]);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (curl_errno($ch)) {
echo 'Error: ' . curl_error($ch);
} else {
echo "Código de estado HTTP: " . $http_code . "\n";
if ($http_code === 200) {
$asesor = json_decode($response, true);
if (!empty($asesor)) {
echo "Asesor encontrado:\n";
echo " ID: {$asesor['id']}\n";
echo " Nombre: {$asesor['nombre']}\n";
echo " Email: {$asesor['email']}\n";
echo " Teléfono: {$asesor['telefono']}\n";
} else {
echo "No se encontró ningún asesor con el documento {$documento}.\n";
}
} else {
echo "Error al consultar el asesor.\n";
echo $response . "\n";
}
}
curl_close($ch);
?>
Python
import requests
# 1. Configura tus datos de acceso
instancia = 'mi-inmobiliaria.nuby.app' # Reemplaza con tu dirección web completa
token = 'TU_TOKEN_AQUI' # Token obtenido del servicio Login
documento = '52498731' # Documento del asesor a consultar
# 2. Prepara la dirección de la petición
url = f"https://{instancia}/service/v2/public/agents/{documento}"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {token}"
}
# 3. Envía la petición GET y procesa la respuesta
try:
response = requests.get(url, headers=headers)
print(f"Código de estado HTTP: {response.status_code}")
if response.status_code == 200:
asesor = response.json()
if asesor:
print(f"Asesor encontrado:")
print(f" ID: {asesor['id']}")
print(f" Nombre: {asesor['nombre']}")
print(f" Email: {asesor['email']}")
print(f" Teléfono: {asesor['telefono']}")
else:
print(f"No se encontró ningún asesor con el documento {documento}.")
else:
print("Error al consultar el asesor.")
print(f"Detalle del error: {response.text}")
except Exception as e:
print(f"Ocurrió un error de conexión: {e}")
JavaScript
// 1. Configura tus datos de acceso
const instancia = 'mi-inmobiliaria.nuby.app'; // Reemplaza con tu dirección web completa
const token = 'TU_TOKEN_AQUI'; // Token obtenido del servicio Login
const documento = '52498731'; // Documento del asesor a consultar
// 2. Prepara la dirección de la petición
const url = `https://${instancia}/service/v2/public/agents/${documento}`;
// 3. Función para consultar el asesor
async function consultarAsesor() {
try {
const response = await fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
}
});
console.log(`Código de estado HTTP: ${response.status}`);
if (response.ok) {
const asesor = await response.json();
if (asesor && !Array.isArray(asesor)) {
console.log(`Asesor encontrado:`);
console.log(` ID: ${asesor.id}`);
console.log(` Nombre: ${asesor.nombre}`);
console.log(` Email: ${asesor.email}`);
console.log(` Teléfono: ${asesor.telefono}`);
} else {
console.log(`No se encontró ningún asesor con el documento ${documento}.`);
}
} else {
console.log('Error al consultar el asesor.');
const errorData = await response.text();
console.log(`Detalle del error: ${errorData}`);
}
} catch (error) {
console.error(`Ocurrió un error de conexión: ${error}`);
}
}
// 4. Ejecutamos la función
consultarAsesor();
Power Query M (Excel / Power BI)
let
// 1. Configura tus datos de acceso
instancia = "mi-inmobiliaria.nuby.app", // Reemplaza con tu dirección web completa
token = "TU_TOKEN_AQUI", // Token obtenido del servicio Login
documento = "52498731", // Documento del asesor a consultar
// 2. Prepara la dirección de la petición
url = "https://" & instancia & "/service/v2/public/agents/" & documento,
// 3. Envía la petición GET
response = Web.Contents(url, [
Headers = [
#"Content-Type" = "application/json",
#"Authorization" = "Bearer " & token
]
]),
// 4. Decodifica la respuesta JSON y conviértela en registro
jsonResponse = Json.Document(response),
resultado = Record.ToTable(jsonResponse),
expandido = Table.Pivot(resultado, List.Distinct(resultado[Name]), "Name", "Value")
in
expandido
Facturas
Bienvenido a la caja registradora virtual de tu inmobiliaria. En esta sección centralizamos las conexiones para que tus plataformas externas gestionen automáticamente todo el ciclo de facturación y cobros.
¿Qué puedes lograr en este módulo?
1. Consulta sincronizada: Tus aplicaciones podrán revisar el historial de cuentas, buscar saldos pendientes por cliente y obtener enlaces seguros para descargar documentos en PDF. Además, tendrás acceso a configuraciones clave como tus resoluciones de facturación y medios de pago habilitados.
2. Acción directa sobre tu cartera: ¡Esta sección no es de solo lectura! Si recibes un pago en una plataforma externa, tu sistema puede reportarnos el monto y la fecha. Nosotros nos encargamos del trabajo pesado: calculamos el saldo, registramos el abono (ya sea parcial o total), generamos el recibo de ingreso y creamos el documento contable de forma automática.
Explora las opciones a continuación para automatizar tus cobros y mantener las finanzas de tus clientes siempre al día.
Listar Facturas
Permite obtener la lista paginada de todas las facturas registradas en el sistema. Cada elemento incluye el número de factura, resolución, fechas, valor total, saldo pendiente, tercero facturado, estado, información DIAN y datos de auditoría.
¿Para qué sirve este servicio?
Úsalo para sincronizar la información de facturación con tu sistema externo, generar reportes de cartera, alimentar dashboards con indicadores de facturación, validar el estado de cobro de los contratos o exportar la información a Excel y Power BI.
1. El Endpoint (La dirección web)
Apunta tu sistema a la siguiente dirección. Recuerda reemplazar {{instancia}} por la dirección web completa que utilizas para ingresar a tu plataforma.
GET https://{{instancia}}/service/v2/public/invoices/list
¿Qué debes colocar en {{instancia}}?
Es muy sencillo: corresponde a la dirección web principal que utilizas a diario para ingresar a tu plataforma (incluyendo la terminación .nuby.app o .arrendasoft.co).
Por ejemplo, si para entrar a tu sistema escribes inmobiliaria.nuby.app o inmobiliaria.arrendasoft.co en tu navegador, esa será exactamente tu instancia. Solo asegúrate de no incluir el "https://" ni barras diagonales ("/") al final.
2. La Petición (¿Qué debes enviarnos?)
Este servicio no requiere cuerpo en la petición. Envía los encabezados requeridos y opcionalmente los parámetros de paginación en la URL:
| Método | GET |
| Content-Type | application/json |
| Authorization | Bearer token, Token obtenido al consumir el servicio Login |
¿Aún no tienes tu Token de acceso?
Para consumir este servicio necesitas un Token vigente. Consulta el servicio de Login para aprender cómo obtenerlo.
Parámetros de consulta (query string):
| Parámetro | Tipo | Requerido | Por defecto | Descripción |
|---|---|---|---|---|
page |
integer | No | 1 | Número de página de resultados que se desea recuperar. Debe ser un número positivo. |
page_size |
integer | No | 10 | Número máximo de facturas por página. Debe ser un número positivo. Valor máximo permitido: 1000. |
Ejemplos de petición:
GET https://mi-inmobiliaria.nuby.app/service/v2/public/invoices/list
GET https://mi-inmobiliaria.nuby.app/service/v2/public/invoices/list?page=2
GET https://mi-inmobiliaria.nuby.app/service/v2/public/invoices/list?page_size=50
GET https://mi-inmobiliaria.nuby.app/service/v2/public/invoices/list?page=3&page_size=100
3. La Respuesta (¿Qué te entregaremos?)
Si tu Token es válido, el sistema te devolverá un objeto JSON con el estado de la respuesta, el listado de facturas y la información de paginación. Los resultados están ordenados por fecha de factura descendente (más recientes primero). La respuesta se verá similar a esta:
{
"status": 200,
"message": null,
"body": [
{
"factura_id": 15230,
"factura_numero": 8745,
"resolucion": "FECO - 18764000002851",
"fecha_factura": "2025-04-01",
"fecha_vencimiento": "2025-04-06",
"valor_total": "2850000.00",
"saldo": "2850000.00",
"documento_tercero": "80213654",
"nombre_tercero": "CARLOS EDUARDO PINEDA VARGAS",
"estado": "Facturada",
"estado_dian": "Aceptada",
"estado_cliente_dian": "Recibida",
"notas": 0,
"creado_por": "Sandra",
"fecha_envio_dian": "2025-04-01 08:30:15",
"fecha_creacion": "2025-04-01 07:45:22"
},
{
"factura_id": 15229,
"factura_numero": 8744,
"resolucion": "FECO - 18764000002851",
"fecha_factura": "2025-04-01",
"fecha_vencimiento": "2025-04-06",
"valor_total": "4500000.00",
"saldo": "0.00",
"documento_tercero": "1098745231",
"nombre_tercero": "JULIANA PATRICIA RÍOS MENDOZA",
"estado": "Pagada",
"estado_dian": "Aceptada",
"estado_cliente_dian": "Recibida",
"notas": 0,
"creado_por": "Sandra",
"fecha_envio_dian": "2025-04-01 08:31:02",
"fecha_creacion": "2025-04-01 07:46:10"
},
{
"factura_id": 15210,
"factura_numero": 8730,
"resolucion": "0 - 18764000002851",
"fecha_factura": "2025-03-01",
"fecha_vencimiento": "2025-03-06",
"valor_total": "1200000.00",
"saldo": "1200000.00",
"documento_tercero": "43876123",
"nombre_tercero": "DIANA MARCELA OSPINA VELÁSQUEZ",
"estado": "Facturada",
"estado_dian": null,
"estado_cliente_dian": null,
"notas": 1,
"creado_por": "Administrador",
"fecha_envio_dian": null,
"fecha_creacion": "2025-03-01 09:12:33"
},
{
"factura_id": 14850,
"factura_numero": 8520,
"resolucion": "FECO - 18764000002851",
"fecha_factura": "2025-02-01",
"fecha_vencimiento": "2025-02-06",
"valor_total": "3950000.00",
"saldo": "3950000.00",
"documento_tercero": "900456789",
"nombre_tercero": "INVERSIONES HORIZONTE S.A.S.",
"estado": "Anulada por NC",
"estado_dian": "Aceptada",
"estado_cliente_dian": null,
"notas": 1,
"creado_por": "Sandra",
"fecha_envio_dian": "2025-02-01 10:05:44",
"fecha_creacion": "2025-02-01 08:20:15"
}
],
"pagination": {
"total_records": 15230,
"total_pages": 305,
"current_page": 1,
"page_size": 50,
"current_page_records": 4,
"has_next_page": true,
"has_previous_page": false
}
}
Estructura principal de la respuesta
| Campo | Tipo | Descripción |
|---|---|---|
status |
integer | Código del estado de la respuesta. 200 para exitoso, 400 para error de validación, 500 para error interno. |
message |
string | null | Cuando la respuesta es exitosa vale null. Si no se encuentran facturas, contiene el mensaje informativo. Si hay error, describe el problema. |
body |
array | null | Listado de facturas devueltas. Arreglo vacío [] si no hay resultados. null en caso de error. |
pagination |
object | null | Información de paginación para recorrer los resultados. null en caso de error. |
Campos de cada factura (body)
Cada elemento dentro del arreglo body contiene las siguientes claves:
| Campo | Tipo | Descripción |
|---|---|---|
factura_id |
integer | Identificador único de la factura en el sistema. |
factura_numero |
integer | Número consecutivo de la factura. |
resolucion |
string | Prefijo y número de la resolución de facturación en formato PREFIJO - NÚMERO (ej. "FECO - 18764000002851"). |
fecha_factura |
string | Fecha de emisión de la factura en formato YYYY-MM-DD. |
fecha_vencimiento |
string | Fecha de vencimiento de la factura en formato YYYY-MM-DD. |
valor_total |
string | Valor total de la factura con decimales (ej. "2850000.00"). |
saldo |
string | Saldo pendiente de pago de la factura con decimales (ej. "0.00" cuando está pagada). |
documento_tercero |
string | Número de documento de identidad del tercero/cliente facturado. |
nombre_tercero |
string | Nombre completo del tercero/cliente facturado. |
estado |
string | Estado textual de la factura. Valores posibles: Facturada, Anulada, Pagada, Borrador, Anulada por NC, Contabilizada. |
estado_dian |
string | null | Estado de la factura en la DIAN cuando es factura electrónica (ej. "Aceptada"). null si no aplica o no se ha enviado. |
estado_cliente_dian |
string | null | Estado de aceptación/rechazo del cliente ante la DIAN cuando es factura electrónica. null si no aplica. |
notas |
integer | Cantidad de notas débito o crédito asociadas a la factura. |
creado_por |
string | Nombre del usuario que creó la factura en el sistema. |
fecha_envio_dian |
string | null | Fecha y hora de envío de la factura a la DIAN en formato YYYY-MM-DD HH:MM:SS. null si no se ha enviado. |
fecha_creacion |
string | Fecha y hora de creación del registro en formato YYYY-MM-DD HH:MM:SS. |
Campos de paginación (pagination)
El objeto pagination contiene las siguientes claves:
| Campo | Tipo | Descripción |
|---|---|---|
total_records |
integer | Total de facturas registradas en el sistema. |
total_pages |
integer | Cantidad total de páginas disponibles (total de registros dividido por el tamaño de página). |
current_page |
integer | Número de la página actual consultada. |
page_size |
integer | Tamaño de la página (cantidad de registros solicitados por consulta). |
current_page_records |
integer | Cantidad de registros efectivamente devueltos en la página actual. |
has_next_page |
boolean | true si existen páginas posteriores que se pueden consultar. |
has_previous_page |
boolean | true si existen páginas anteriores que se pueden consultar. |
Nota sobre facturas sin resultados
Si no existen facturas registradas en el sistema, la respuesta tendrá HTTP 200 con body vacío ([]), un message informativo: "No se encontraron facturas en el sistema." y los valores de paginación en cero.
4. Seguridad y Posibles Errores
¡Tu pase tiene fecha de caducidad!
Por medidas de seguridad, el token que te entregamos solo dura 1 hora. Una vez transcurrido ese tiempo, el pase expirará y el sistema te bloqueará el acceso devolviéndote un error 401. Cuando esto ocurra, tu sistema simplemente debe volver a consumir el servicio de Login para pedir un pase nuevo y continuar trabajando.
Así se ve el error que te devolverá el sistema cuando tu token se haya vencido o intentes usar un pase inválido:
{
"statusCode": 401,
"error": {
"type": "SERVER_ERROR",
"description": "JWT Token expired."
}
}
Si alguno de los parámetros de paginación no cumple con las validaciones, el sistema devolverá un error 400. Por ejemplo:
{
"status": 400,
"message": "El parámetro \"page_size\" debe ser un número positivo.",
"body": null,
"pagination": null
}
Posibles errores:
| Código HTTP | Descripción |
|---|---|
| 400 | Token faltante o inválido. Posibles causas: — No se envió el encabezado Authorization. Mensaje: "JWT Token required."— El encabezado no tiene el formato Bearer {token}. Mensaje: "JWT Token not send."— El token no fue encontrado en el sistema. Mensaje: "JWT Token not found."Parámetros inválidos. Posibles causas: — page no es numérico o no es positivo. Mensaje: "El parámetro \"page\" debe ser un número positivo."— page_size no es numérico o no es positivo. Mensaje: "El parámetro \"page_size\" debe ser un número positivo." |
| 401 | El token ha expirado. Debes generar uno nuevo consumiendo el servicio de Login. Mensaje: "JWT Token expired." |
| 403 | El cliente OAuth no tiene el scope necesario para esta operación. Para endpoints GET se requiere el scope read. Mensaje: "Insufficient scope. Required: 'read', granted: '{scope_actual}'." |
| 500 | Error interno del servidor al procesar la consulta de facturas. Mensaje: "Error interno del servidor al obtener las facturas." |
5. Ejemplos de integración
Aquí tienes ejemplos de código listos para que tus desarrolladores los adapten a tu plataforma:
cURL
# Listar facturas con paginación por defecto
curl -X GET "https://{{instancia}}/service/v2/public/invoices/list" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer TU_TOKEN_AQUI"
# Listar facturas página 3 con 100 registros por página
curl -X GET "https://{{instancia}}/service/v2/public/invoices/list?page=3&page_size=100" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer TU_TOKEN_AQUI"
PHP
<?php
$instance = 'tu_instancia'; // Reemplaza con tu instancia real
$token = 'TU_TOKEN_AQUI'; // Token obtenido del servicio Login
// Parámetros de paginación
$page = 1;
$page_size = 50;
$queryParams = http_build_query([
'page' => $page,
'page_size' => $page_size
]);
$url = "https://{$instance}/service/v2/public/invoices/list?{$queryParams}";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
"Authorization: Bearer {$token}"
]);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (curl_errno($ch)) {
echo 'Error: ' . curl_error($ch);
} else {
echo "Código de estado HTTP: " . $http_code . "\n";
$info = json_decode($response, true);
$body = $info['body'] ?? [];
if ($http_code === 200 && !empty($body)) {
$pagination = $info['pagination'];
echo "Facturas encontradas: {$pagination['total_records']} (página {$pagination['current_page']} de {$pagination['total_pages']})\n";
foreach ($body as $factura) {
echo " Factura #{$factura['factura_numero']} - {$factura['nombre_tercero']} - {$factura['estado']} - Total: \${$factura['valor_total']} - Saldo: \${$factura['saldo']}\n";
}
} else {
echo "Mensaje: " . ($info['message'] ?? 'Sin resultados') . "\n";
}
}
curl_close($ch);
?>
Python
import requests
# 1. Configura tus datos de acceso
instancia = 'mi-inmobiliaria.nuby.app' # Reemplaza con tu dirección web completa
token = 'TU_TOKEN_AQUI' # Token obtenido del servicio Login
# 2. Prepara la dirección y los parámetros
url = f"https://{instancia}/service/v2/public/invoices/list"
params = {
"page": 1,
"page_size": 50
}
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {token}"
}
# 3. Envía la petición GET y procesa la respuesta
try:
response = requests.get(url, params=params, headers=headers)
print(f"Código de estado HTTP: {response.status_code}")
if response.status_code == 200:
info = response.json()
body = info.get('body', [])
pagination = info.get('pagination', {})
if body:
print(f"Facturas: {pagination['total_records']} total (página {pagination['current_page']} de {pagination['total_pages']})")
for factura in body:
print(f" #{factura['factura_numero']} - {factura['nombre_tercero']} - {factura['estado']} - Total: ${factura['valor_total']} - Saldo: ${factura['saldo']}")
else:
print(f"Mensaje: {info.get('message', 'Sin resultados')}")
else:
print("Error al consultar las facturas.")
print(f"Detalle del error: {response.text}")
except Exception as e:
print(f"Ocurrió un error de conexión: {e}")
JavaScript
// 1. Configura tus datos de acceso
const instancia = 'mi-inmobiliaria.nuby.app'; // Reemplaza con tu dirección web completa
const token = 'TU_TOKEN_AQUI'; // Token obtenido del servicio Login
// 2. Prepara la dirección con parámetros
const params = new URLSearchParams({
page: 1,
page_size: 50
});
const url = `https://${instancia}/service/v2/public/invoices/list?${params}`;
// 3. Función para consultar las facturas
async function consultarFacturas() {
try {
const response = await fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
}
});
console.log(`Código de estado HTTP: ${response.status}`);
if (response.ok) {
const info = await response.json();
const body = info.body || [];
const pagination = info.pagination || {};
if (body.length > 0) {
console.log(`Facturas: ${pagination.total_records} total (página ${pagination.current_page} de ${pagination.total_pages})`);
body.forEach(factura => {
console.log(` #${factura.factura_numero} - ${factura.nombre_tercero} - ${factura.estado} - Total: $${factura.valor_total} - Saldo: $${factura.saldo}`);
});
} else {
console.log(`Mensaje: ${info.message || 'Sin resultados'}`);
}
} else {
console.log('Error al consultar las facturas.');
const errorData = await response.text();
console.log(`Detalle del error: ${errorData}`);
}
} catch (error) {
console.error(`Ocurrió un error de conexión: ${error}`);
}
}
// 4. Ejecutamos la función
consultarFacturas();
Power Query M (Excel / Power BI)
let
// 1. Configura tus datos de acceso
instancia = "mi-inmobiliaria.nuby.app", // Reemplaza con tu dirección web completa
token = "TU_TOKEN_AQUI", // Token obtenido del servicio Login
// 2. Prepara la dirección de la petición con parámetros
url = "https://" & instancia & "/service/v2/public/invoices/list?page=1&page_size=1000",
// 3. Envía la petición GET
response = Web.Contents(url, [
Headers = [
#"Content-Type" = "application/json",
#"Authorization" = "Bearer " & token
]
]),
// 4. Decodifica la respuesta JSON
jsonResponse = Json.Document(response),
body = jsonResponse[body],
// 5. Convierte el listado en tabla
tabla = Table.FromList(body, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
expandido = Table.ExpandRecordColumn(tabla, "Column1",
{"factura_id", "factura_numero", "resolucion", "fecha_factura", "fecha_vencimiento", "valor_total", "saldo", "documento_tercero", "nombre_tercero", "estado", "estado_dian", "notas", "creado_por", "fecha_creacion"},
{"FacturaID", "Numero", "Resolucion", "FechaFactura", "FechaVencimiento", "ValorTotal", "Saldo", "DocTercero", "NombreTercero", "Estado", "EstadoDian", "Notas", "CreadoPor", "FechaCreacion"})
in
expandido
Registrar Pago de Factura
Permite registrar el pago de una factura existente en el sistema. Si no se especifica la forma de pago, el sistema intentará determinarla automáticamente basándose en el cliente OAuth2 autenticado o utilizará la forma de pago por defecto configurada (Consignación bancaria).
Endpoint: https://{{instancia}}.arrendasoft.co/service/v2/public/invoices/register-payment
{{instancia}}: Hace referencia a la instancia de cada inmobiliaria.
Petición
| Método | POST |
| Content-Type | application/json |
| Authorization | Bearer token, Token obtenido al consumir el servicio Login |
| Parámetros del Body (JSON) | ||||
| Parámetro | Tipo | Obligatorio | Valor por defecto | Descripción |
| factura_id | integer | Sí | - | Identificador único de la factura a la cual se registrará el pago. Debe ser un número entero positivo y coincidir con una factura en el sistema. |
| monto | float | Sí | - | Monto del pago a registrar. Debe ser un número positivo y no puede exceder el saldo pendiente de la factura. |
| fecha_pago | string | Sí | - |
Fecha y hora en que se realizó el pago. Formato: Y-m-d H:i:s (ej: 2026-02-05 14:30:00).
|
| forma_pago_id | integer | No | Auto | ID de la forma de pago. Si no se proporciona, se determina automáticamente según el cliente o la configuración por defecto. |
| n_comprobante | string | No | - | Número de comprobante o referencia del pago realizado. Máximo 100 caracteres. Solo se permiten letras, números, guiones (-), guiones bajos (_), puntos (.) y espacios. |
Ejemplo de petición (Body JSON)
{
"factura_id": 366,
"monto": 50000,
"fecha_pago": "2026-02-05 14:30:00",
"forma_pago_id": 1,
"n_comprobante": "REF123456"
}
Ejemplo mínimo (solo campos requeridos):
{
"factura_id": 366,
"monto": 50000,
"fecha_pago": "2026-02-05 10:00:00"
}
Respuestas
Respuesta Exitosa (200)
Cuando el pago se registra correctamente, la respuesta incluye los detalles completos del pago registrado, incluyendo los IDs de los registros generados en el sistema (pago, recibo de ingreso y documento contable) así como el estado actualizado de la factura.
{
"success": true,
"status": 200,
"message": "Pago registrado exitosamente.",
"body": {
"factura_id": 366,
"pago_id": 142,
"recibo_id": 589,
"documento_contable_id": 1023,
"monto_pagado": 50000,
"fecha_pago": "2026-02-05 14:30:00",
"forma_pago_id": 1,
"forma_pago": "Consignación bancaria",
"n_comprobante": "REF123456",
"saldo_anterior": 150000,
"saldo_actual": 100000,
"estado_factura": "Facturada",
"gateway": null,
"client_name": "MiAplicacion"
}
}
Claves y Descripciones del JSON de Respuesta
| Clave | Tipo | Descripción |
|---|---|---|
|
|
Booleano | Indica si la operación fue exitosa (true) o fallida (false). |
status |
Entero | Código HTTP de la respuesta: 200 (exitoso), 400 (error de validación), 404 (no encontrado), 422 (error de negocio), 500 (error interno). |
message |
Texto | Mensaje descriptivo del resultado de la operación. |
body |
Objeto | Contiene los detalles del pago registrado cuando la operación es exitosa. Es nulo cuando hay error. |
errors |
Array | Lista de errores de validación. Solo presente cuando status es 400. |
Cuerpo de Respuesta Exitosa (body)
Cuando la operación es exitosa, el objeto body contiene las siguientes claves:
| Clave | Tipo | Descripción |
|---|---|---|
factura_id |
Entero | ID de la factura a la que se aplicó el pago. |
pago_id |
Entero | ID del registro de pago creado en el sistema. |
recibo_id |
Entero | ID del recibo de caja generado. |
documento_contable_id |
Entero | ID del documento contable creado. |
monto_pagado |
Numérico | Monto del pago registrado. |
fecha_pago |
Texto | Fecha y hora del pago en formato Y-m-d H:i:s. |
forma_pago_id |
Entero | ID de la forma de pago utilizada. |
forma_pago |
Texto | Nombre de la forma de pago utilizada. |
n_comprobante |
Texto | Número de comprobante o referencia del pago. Máximo 100 caracteres. Nulo si no se proporcionó. |
saldo_anterior |
Numérico | Saldo de la factura antes de aplicar el pago. |
saldo_actual |
Numérico | Saldo de la factura después de aplicar el pago. Si es 0, la factura quedó totalmente pagada. |
estado_factura |
Texto | Estado de la factura después de aplicar el pago (ej: "Facturada", "Pagada"). |
gateway |
Texto | Nombre de la pasarela de pago si aplica. Nulo si no se usó pasarela. |
client_name |
Texto | Nombre del cliente OAuth autenticado que realizó la petición. |
Respuestas de Error
Error de Validación (400)
Se retorna cuando los parámetros enviados no cumplen con las validaciones requeridas.
{
"success": false,
"status": 400,
"message": "Errores de validación",
"body": null,
"errors": [
"El parámetro \"factura_id\" es requerido.",
"El parámetro \"monto\" debe ser un número positivo.",
"El parámetro \"fecha_pago\" debe tener el formato Y-m-d H:i:s (ej: 2026-02-02 14:30:00).",
"El parámetro \"n_comprobante\" no puede exceder 100 caracteres.",
"El parámetro \"n_comprobante\" contiene caracteres no permitidos. Solo se aceptan letras, números, guiones, guiones bajos, puntos y espacios."
]
}
Factura No Encontrada (404)
Se retorna cuando no existe una factura con el ID proporcionado.
{
"success": false,
"status": 404,
"message": "No se encontró la factura con el ID proporcionado.",
"body": null
}
Error de Negocio (422)
Se retorna cuando la factura existe pero no puede recibir el pago por razones de negocio.
Factura no activa:
{
"success": false,
"status": 422,
"message": "La factura no está en estado activo/pendiente de pago. Estado actual: Pagada",
"body": null
}
Monto excede saldo:
{
"success": false,
"status": 422,
"message": "El monto a pagar (100000) excede el saldo de la factura (50000).",
"body": null
}
Forma de pago no determinada:
{
"success": false,
"status": 422,
"message": "No se pudo determinar la forma de pago automáticamente. Por favor especifique el parámetro \"forma_pago_id\".",
"body": null
}
Factura sin detalles:
{
"success": false,
"status": 422,
"message": "La factura no tiene detalles asociados. No es posible registrar el pago.",
"body": null
}
Forma de pago sin cuenta contable:
{
"success": false,
"status": 422,
"message": "La forma de pago seleccionada no tiene una cuenta contable configurada. No es posible registrar el pago.",
"body": null
}
Periodo contable no activo:
{
"success": false,
"status": 422,
"message": "No existe un periodo contable activo para la fecha 2026-01-15. Verifique que el periodo esté abierto en el módulo de contabilidad.",
"body": null
}
Error Interno (500)
Se retorna cuando ocurre un error inesperado en el servidor o cuando el proceso de registro del pago falla.
Error general:
{
"success": false,
"status": 500,
"message": "Error interno del servidor al registrar el pago.",
"body": null
}
Error al generar recibo de ingreso:
{
"success": false,
"status": 500,
"message": "Error al crear el recibo de ingreso para el pago de la factura.",
"body": null
}
Pago procesado sin confirmación de ID:
{
"success": false,
"status": 500,
"message": "El pago se procesó pero no se pudo obtener el ID del registro de pago. Verifique manualmente en el sistema.",
"body": null
}
Códigos de Respuesta HTTP
| Código | Descripción |
|---|---|
| 200 | Pago registrado exitosamente. La respuesta incluye los IDs del pago, recibo y documento contable generados. |
| 400 | Error de validación en los parámetros enviados, forma de pago inexistente, o n_comprobante con formato inválido. |
| 404 | La factura especificada no existe. |
| 422 |
Error de regla de negocio: factura no activa, monto excede saldo, factura sin detalles, forma de pago sin cuenta contable, periodo contable no activo, o no se pudo determinar forma de pago.
|
| 500 | Error interno del servidor, error al generar recibo de ingreso, o pago procesado sin confirmación de ID. |
Notas Importantes
-
Determinación Automática de Forma de Pago: Si no se proporciona
forma_pago_id, el sistema intentará:- Primero, determinar la forma de pago basándose en el cliente OAuth autenticado (integración con pasarelas de pago).
- Si no encuentra una pasarela asociada, buscará la forma de pago por defecto configurada con código DIAN 42 (Consignación bancaria).
-
Estados de Factura: Solo se pueden registrar pagos en facturas con estado "Facturada" (estado_id = 1). Los estados posibles son:
- 1: Facturada (permite pagos)
- 2: Anulada
- 3: Pagada
- 5: Borrador
- 6: Anulada por NC
-
Pagos Parciales: El sistema permite pagos parciales. El monto debe ser mayor a cero y no puede exceder el saldo pendiente de la factura. Tras un pago parcial, la respuesta incluye `saldo_anterior` y `saldo_actual` para verificar la diferencia.
-
Formas de Pago: Para obtener el listado de formas de pago disponibles, consulte el endpoint Listar Formas de Pago.
-
Verificación del Pago: La respuesta exitosa incluye `pago_id`, `recibo_id` y `documento_contable_id` que permiten verificar que el pago, el recibo de ingreso y el asiento contable se crearon correctamente en el sistema.
-
Estado de la Factura: El campo `estado_factura` en la respuesta indica el estado actualizado de la factura tras el pago. Si el saldo queda en 0, la factura pasará automáticamente a estado "Pagada".
-
Validación de n_comprobante: El número de comprobante tiene las siguientes restricciones:
-
Máximo 100 caracteres.
-
Solo se permiten: letras (a-z, A-Z), números (0-9), guiones (-), guiones bajos (\_), puntos (.) y espacios.
-
No se permiten caracteres especiales como comillas, signos de mayor/menor, punto y coma, etc.
-
-
Periodo Contable: La fecha del pago debe corresponder a un periodo contable activo en el sistema. Si la fecha está fuera de un periodo activo, se retornará un error 422 indicando que debe verificarse la configuración de periodos en el módulo de contabilidad.
-
Validación de forma_pago_id: Si se proporciona el parámetro `forma_pago_id`, debe ser un número entero positivo.
Ejemplos
Curl
curl -X POST "https://{{instancia}}.arrendasoft.co/service/v2/public/invoices/register-payment" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_AUTHENTICATION_TOKEN" \
-d '{
"factura_id": 366,
"monto": 50000,
"fecha_pago": "2026-02-05 10:00:00",
"n_comprobante": "REF123456"
}'
PHP Curl
<?php
$instance = 'your_instance'; // Reemplace con su instancia actual
$token = 'YOUR_AUTHENTICATION_TOKEN'; // Reemplace con el token obtenido desde el servicio de login
// Datos del pago a registrar
$paymentData = [
'factura_id' => 366,
'monto' => 50000,
'fecha_pago' => '2026-02-05 14:30:00',
'forma_pago_id' => 1, // Opcional
'n_comprobante' => 'REF123456' // Opcional
];
$url = "https://{$instance}.arrendasoft.co/service/v2/public/invoices/register-payment";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($paymentData));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Authorization: Bearer ' . $token
]);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (curl_errno($ch)) {
echo 'Error: ' . curl_error($ch);
} else {
echo "HTTP Status Code: " . $http_code . "\n";
echo "Response: " . $response . "\n";
// Procesar la respuesta
$result = json_decode($response, true);
if ($result['success']) {
echo "Pago registrado exitosamente.\n";
echo "Factura: " . $result['body']['factura_id'] . "\n";
echo "Pago ID: " . $result['body']['pago_id'] . "\n";
echo "Recibo ID: " . $result['body']['recibo_id'] . "\n";
echo "Documento Contable ID: " . $result['body']['documento_contable_id'] . "\n";
echo "Monto pagado: " . $result['body']['monto_pagado'] . "\n";
echo "Forma de pago: " . $result['body']['forma_pago'] . "\n";
echo "Saldo anterior: " . $result['body']['saldo_anterior'] . "\n";
echo "Saldo actual: " . $result['body']['saldo_actual'] . "\n";
echo "Estado factura: " . $result['body']['estado_factura'] . "\n";
} else {
echo "Error: " . $result['message'] . "\n";
if (isset($result['errors'])) {
foreach ($result['errors'] as $error) {
echo "- " . $error . "\n";
}
}
}
}
curl_close($ch);
?>
JavaScript Fetch
const instance = 'your_instance'; // Reemplace con su instancia actual
const token = 'YOUR_AUTHENTICATION_TOKEN'; // Reemplace con el token obtenido
const paymentData = {
factura_id: 366,
monto: 50000,
fecha_pago: '2026-02-05 14:30:00',
n_comprobante: 'REF123456'
};
fetch(`https://${instance}.arrendasoft.co/service/v2/public/invoices/register-payment`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify(paymentData)
})
.then(response => response.json())
.then(data => {
if (data.success) {
console.log('Pago registrado exitosamente');
console.log('Factura:', data.body.factura_id);
console.log('Pago ID:', data.body.pago_id);
console.log('Recibo ID:', data.body.recibo_id);
console.log('Documento Contable ID:', data.body.documento_contable_id);
console.log('Monto pagado:', data.body.monto_pagado);
console.log('Forma de pago:', data.body.forma_pago);
console.log('Saldo anterior:', data.body.saldo_anterior);
console.log('Saldo actual:', data.body.saldo_actual);
console.log('Estado factura:', data.body.estado_factura);
} else {
console.error('Error:', data.message);
if (data.errors) {
data.errors.forEach(error => console.error('-', error));
}
}
})
.catch(error => console.error('Error de conexión:', error));
Listar Formas de Pago
Permite obtener las formas de pago configuradas de la inmobiliaria. Solo devuelve las formas de pago que tengan una cuenta contable (PUC) relacionada.
Endpoint: https://{{instancia}}.arrendasoft.co/service/v2/public/invoices/payment-methods
{{instancia}}: Hace referencia a la instancia de cada inmobiliaria.
Petición
| Método | GET |
| Content-Type | application/json |
| Authorization | Bearer token, Token obtenido al consumir el servicio Login |
| Parámetros | ||||
| Parámetro | Tipo | Obligatorio | Valor por defecto | Descripción |
| codigo_dian | string | No | - | Filtra formas de pago por el código DIAN del medio de pago (ej: 42 para Consignación bancaria). |
| cuenta_puc | string | No | - | Filtra formas de pago por código de cuenta PUC. La búsqueda es por prefijo (ej: 1110 retorna todas las cuentas que inicien con ese código). |
Ejemplos de peticiones
https://{{instancia}}.arrendasoft.co/service/v2/public/invoices/payment-methods
https://{{instancia}}.arrendasoft.co/service/v2/public/invoices/payment-methods?codigo_dian=42
https://{{instancia}}.arrendasoft.co/service/v2/public/invoices/payment-methods?cuenta_puc=1110
https://{{instancia}}.arrendasoft.co/service/v2/public/invoices/payment-methods?codigo_dian=42&cuenta_puc=1110
Respuesta
Lista de formas de pago configuradas con información del medio de pago DIAN y cuenta contable asociada.
{
"success": true,
"status": 200,
"message": null,
"body": [
{
"formaPagoId": 1,
"nombre": "Consignación Bancolombia",
"cuentaPuc": "11100501",
"codigoDian": "42",
"medioPago": "Consignación bancaria"
},
{
"formaPagoId": 2,
"nombre": "Transferencia Davivienda",
"cuentaPuc": "11100502",
"codigoDian": "31",
"medioPago": "Transferencia débito bancaria"
},
{
"formaPagoId": 3,
"nombre": "Pago con tarjeta de crédito",
"cuentaPuc": "11100503",
"codigoDian": "48",
"medioPago": "Tarjeta de crédito"
}
],
"filters_applied": null
}
Claves y Descripciones del JSON de Respuesta
Esta tabla enumera las claves presentes en el JSON principal de la respuesta y proporciona una breve descripción de cada una.
| Clave | Tipo | Descripción |
|---|---|---|
success |
Booleano | Indica si la operación fue exitosa (true) o fallida (false). |
status |
Entero | Código HTTP de la respuesta: 200 para exitoso, 500 para error interno. |
message |
Texto | Mensaje descriptivo. Es nulo cuando hay resultados, o contiene un mensaje informativo cuando no se encontraron formas de pago. |
body |
Array | Contiene el listado de formas de pago. Es un array vacío si no hay resultados. |
filters_applied |
Objeto | Contiene los filtros que fueron aplicados en la consulta. Es nulo si no se aplicaron filtros. |
Cuerpo
Cada elemento dentro de la lista body tiene las siguientes claves:
| Clave | Tipo | Descripción |
|---|---|---|
formaPagoId |
Entero | Identificador único de la forma de pago. Use este valor para el parámetro `forma_pago_id` al registrar un pago. |
nombre |
Texto | Nombre descriptivo de la forma de pago configurada por la inmobiliaria. |
cuentaPuc |
Texto | Código de la cuenta contable (PUC) asociada a la forma de pago. |
codigoDian |
Texto | Código del medio de pago según la clasificación DIAN. |
medioPago |
Texto | Nombre del medio de pago según la clasificación DIAN. |
Filtros Aplicados
El objeto filters_applied contiene los filtros que fueron utilizados en la consulta. Solo se incluye en la respuesta cuando se aplican filtros. Las posibles claves son:
| Clave | Tipo | Descripción |
|---|---|---|
codigo_dian |
Texto | Código DIAN del medio de pago utilizado como filtro. |
cuenta_puc |
Texto | Código de cuenta PUC utilizado como filtro (búsqueda por prefijo). |
Respuesta con Filtros Aplicados
{
"success": true,
"status": 200,
"message": null,
"body": [
{
"formaPagoId": 1,
"nombre": "Consignación Bancolombia",
"cuentaPuc": "11100501",
"codigoDian": "42",
"medioPago": "Consignación bancaria"
}
],
"filters_applied": {
"codigo_dian": "42"
}
}
Respuesta Sin Resultados
{
"success": true,
"status": 200,
"message": "No se encontraron formas de pago con los criterios especificados.",
"body": [],
"filters_applied": {
"codigo_dian": "99"
}
}
Respuesta de Error
Error Interno (500)
Se retorna cuando ocurre un error inesperado en el servidor.
{
"success": false,
"status": 500,
"message": "Error interno del servidor al obtener las formas de pago.",
"body": null,
"filters_applied": null
}
Códigos de Respuesta HTTP
| Código | Descripción |
|---|---|
| 200 | Consulta exitosa. El cuerpo de la respuesta contiene las formas de pago (puede ser un array vacío si no hay resultados). |
| 500 | Error interno del servidor. |
Códigos DIAN de Medios de Pago
Referencia de códigos DIAN comunes para medios de pago:
| Código | Medio de Pago |
|---|---|
| 10 | Efectivo |
| 31 | Transferencia Débito |
| 42 | Consignación bancaria |
| 47 | Transferencia Débito Bancaria |
| 48 | Tarjeta Crédito |
| 49 | Tarjeta Débito |
Para consultar el listado completo de códigos de medios de pago, visite la Documentación Técnica de Factura Electrónica - DIAN.
Notas Importantes
-
Solo formas de pago configuradas: Este endpoint solo retorna las formas de pago que tengan una cuenta contable (PUC) asociada. Las formas de pago sin cuenta contable no aparecerán en los resultados.
-
Uso con registro de pagos: El
formaPagoIdretornado puede usarse como valor del parámetroforma_pago_iden el endpoint Registrar Pago de Factura. -
Búsqueda por cuenta PUC: El filtro
cuenta_pucrealiza una búsqueda por prefijo, lo que permite filtrar por grupos de cuentas (ej:1110retorna todas las cuentas PUC que inicien con ese código).
Ejemplos
Curl
curl -X GET "https://{{instancia}}.arrendasoft.co/service/v2/public/invoices/payment-methods" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_AUTHENTICATION_TOKEN"
Con filtros:
curl -X GET "https://{{instancia}}.arrendasoft.co/service/v2/public/invoices/payment-methods?codigo_dian=42" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_AUTHENTICATION_TOKEN"
PHP Curl
<?php
$instance = 'your_instance'; // Reemplace con su instancia actual
$token = 'YOUR_AUTHENTICATION_TOKEN'; // Reemplace con el token obtenido desde el servicio de login
// Parámetros de filtro opcionales
$codigoDian = '42'; // Opcional: filtrar por código DIAN
$cuentaPuc = null; // Opcional: filtrar por cuenta PUC
$url = "https://{$instance}.arrendasoft.co/service/v2/public/invoices/payment-methods";
// Agregar parámetros de filtro si existen
$queryParams = [];
if (!empty($codigoDian)) {
$queryParams['codigo_dian'] = $codigoDian;
}
if (!empty($cuentaPuc)) {
$queryParams['cuenta_puc'] = $cuentaPuc;
}
if (!empty($queryParams)) {
$url .= '?' . http_build_query($queryParams);
}
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Authorization: Bearer ' . $token
]);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (curl_errno($ch)) {
echo 'Error: ' . curl_error($ch);
} else {
echo "HTTP Status Code: " . $http_code . "\n";
echo "Response: " . $response . "\n";
// Procesar la respuesta
$result = json_decode($response, true);
if ($result['success'] && !empty($result['body'])) {
echo "Se encontraron " . count($result['body']) . " formas de pago.\n\n";
foreach ($result['body'] as $formaPago) {
echo "ID: " . $formaPago['formaPagoId'] . "\n";
echo "Nombre: " . $formaPago['nombre'] . "\n";
echo "Cuenta PUC: " . $formaPago['cuentaPuc'] . "\n";
echo "Código DIAN: " . $formaPago['codigoDian'] . "\n";
echo "Medio de Pago: " . $formaPago['medioPago'] . "\n";
echo "---\n";
}
} else {
echo $result['message'] ?? "No se encontraron formas de pago.\n";
}
}
curl_close($ch);
?>
JavaScript Fetch
const instance = 'your_instance'; // Reemplace con su instancia actual
const token = 'YOUR_AUTHENTICATION_TOKEN'; // Reemplace con el token obtenido
// Parámetros de filtro opcionales
const params = new URLSearchParams();
// params.append('codigo_dian', '42'); // Opcional: descomentar para filtrar
// params.append('cuenta_puc', '1110'); // Opcional: descomentar para filtrar
const url = `https://${instance}.arrendasoft.co/service/v2/public/invoices/payment-methods${params.toString() ? '?' + params.toString() : ''}`;
fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
}
})
.then(response => response.json())
.then(data => {
if (data.success && data.body.length > 0) {
console.log(`Se encontraron ${data.body.length} formas de pago:`);
data.body.forEach(formaPago => {
console.log(`- ${formaPago.nombre} (ID: ${formaPago.formaPagoId})`);
console.log(` Cuenta PUC: ${formaPago.cuentaPuc}`);
console.log(` Medio DIAN: ${formaPago.medioPago} (${formaPago.codigoDian})`);
});
} else {
console.log(data.message || 'No se encontraron formas de pago.');
}
})
.catch(error => console.error('Error de conexión:', error));
Listar Resoluciones
Permite obtener el listado de resoluciones de facturación configuradas en la inmobiliaria. Retorna tanto las resoluciones de facturación como las de documento soporte, con soporte para paginación y múltiples filtros.
Endpoint: https://{{instancia}}.arrendasoft.co/service/v2/public/invoices/resolutions
{{instancia}}: Hace referencia a la instancia de cada inmobiliaria.
Petición
| Método | GET |
| Content-Type | application/json |
| Authorization | Bearer token, Token obtenido al consumir el servicio Login |
| Parámetros | ||||
| Parámetro | Tipo | Obligatorio | Valor por defecto | Descripción |
| page | integer | No | 1 | Especifica la página de resultados que se desea recuperar al realizar la solicitud. |
| page_size | integer | No | 10 | Especifica el número máximo de elementos que se deben devolver en la solicitud, el límite máximo es de 1000. |
| activa | string | No | - | Filtra resoluciones por estado activo. Valores válidos: SI (activas) o NO (inactivas). |
| tipo_doc_id | integer | No | - | Filtra resoluciones por el ID del tipo de documento contable asociado. |
| fact_electronica | string | No | - | Filtra resoluciones por facturación electrónica. Valores válidos: SI o NO. |
| resolucion_para | integer | No | - | Filtra resoluciones por tipo. Valores válidos: 1 (Factura de Venta) o 2 (Documento Soporte). Si no se especifica, retorna ambos tipos. |
| fecha_desde | string | No | - | Fecha mínima de la resolución. Formato: YYYY-MM-DD (ej: 2025-01-01). |
| fecha_hasta | string | No | - | Fecha máxima de la resolución. Formato: YYYY-MM-DD (ej: 2026-12-31). |
| fecha_vigencia_desde | string | No | - | Fecha mínima de vigencia de la resolución. Formato: YYYY-MM-DD. |
| fecha_vigencia_hasta | string | No | - | Fecha máxima de vigencia de la resolución. Formato: YYYY-MM-DD. |
Ejemplos de peticiones
https://{{instancia}}.arrendasoft.co/service/v2/public/invoices/resolutions
https://{{instancia}}.arrendasoft.co/service/v2/public/invoices/resolutions?page=1&page_size=50
https://{{instancia}}.arrendasoft.co/service/v2/public/invoices/resolutions?activa=SI
https://{{instancia}}.arrendasoft.co/service/v2/public/invoices/resolutions?resolucion_para=1
https://{{instancia}}.arrendasoft.co/service/v2/public/invoices/resolutions?resolucion_para=2&activa=SI
https://{{instancia}}.arrendasoft.co/service/v2/public/invoices/resolutions?fact_electronica=SI&page_size=100
https://{{instancia}}.arrendasoft.co/service/v2/public/invoices/resolutions?fecha_desde=2024-01-01&fecha_hasta=2026-12-31
https://{{instancia}}.arrendasoft.co/service/v2/public/invoices/resolutions?resolucion_para=1&activa=SI&fact_electronica=SI&page_size=50
Respuesta
Lista de resoluciones de facturación con información del tipo de documento asociado, datos de consecutivos, fechas, estado y metadatos de paginación.
{
"status": 200,
"message": null,
"body": [
{
"resolucion_id": 4,
"tipo_doc_id": 7,
"tipo_doc": "Factura",
"resolucion_numero": "18700052960",
"consecutivo_iniciar": 1,
"consecutivo_inicial": 1,
"consecutivo_final": 20000,
"fecha": "2025-07-24",
"fecha_vigencia": "2026-07-24",
"prefijo": "FE",
"dias_vencimiento": 5,
"activa": "SI",
"codigo_barra": "NO",
"codigo_ean": null,
"tipo_resolucion": null,
"creadopor": 5,
"fechacreacion": "2025-07-24 12:00:01",
"modificadopor": null,
"fechamodificacion": null,
"fact_electronica": "SI",
"resolucion_para": 1
},
{
"resolucion_id": 2,
"tipo_doc_id": 39,
"tipo_doc": "Documento Soporte",
"resolucion_numero": "18760000012",
"consecutivo_iniciar": 1,
"consecutivo_inicial": 1,
"consecutivo_final": 1000000,
"fecha": "2022-09-01",
"fecha_vigencia": "2024-05-31",
"prefijo": "DS",
"dias_vencimiento": 5,
"activa": "SI",
"codigo_barra": "NO",
"codigo_ean": null,
"tipo_resolucion": null,
"creadopor": 5,
"fechacreacion": "2024-05-02 15:01:48",
"modificadopor": 5,
"fechamodificacion": "2024-05-06 15:05:23",
"fact_electronica": "SI",
"resolucion_para": 2
}
],
"pagination": {
"total_records": 4,
"total_pages": 2,
"current_page": 1,
"page_size": 2,
"current_page_records": 2,
"has_next_page": true,
"has_previous_page": false
},
"filters_applied": null
}
Claves y Descripciones del JSON de Respuesta
Esta tabla enumera las claves presentes en el JSON principal de la respuesta y proporciona una breve descripción de cada una.
| Clave | Tipo | Descripción |
|---|---|---|
status |
Entero | Código del estado de la respuesta: 200 para exitoso, 400 para errores de validación, 500 para error interno. |
message |
Texto | Cuando la respuesta es exitosa, es nulo, y cuando hay error o no se encontraron resultados, contiene el mensaje descriptivo. |
body |
Array | Contiene el listado de resoluciones retornadas por la API. Es un array vacío si no hay resultados. |
pagination |
Objeto | Contiene toda la información de paginación de la consulta. |
filters_applied |
Objeto | Contiene los filtros que fueron aplicados en la consulta. Es nulo si no se aplicaron filtros. |
Cuerpo
Cada elemento dentro de la lista body tiene las siguientes claves:
| Clave | Tipo | Descripción |
|---|---|---|
resolucion_id |
Entero | Identificador único de la resolución. Use este valor para el parámetro resolucion_id al filtrar facturas en el endpoint Listar Facturas. |
tipo_doc_id |
Entero | Identificador del tipo de documento contable asociado a la resolución. Puede ser nulo. |
tipo_doc |
Texto | Nombre del tipo de documento contable (ej: "Factura", "Documento Soporte"). Puede ser nulo si no tiene tipo de documento asociado. |
resolucion_numero |
Texto | Número de la resolución asignado por la DIAN. |
consecutivo_iniciar |
Entero | Consecutivo a partir del cual se empezará a facturar. Debe estar entre el consecutivo inicial y final. |
consecutivo_inicial |
Entero | Consecutivo inicial autorizado por la DIAN. |
consecutivo_final |
Entero | Consecutivo final autorizado por la DIAN. |
fecha |
Texto | Fecha de expedición de la resolución. Formato: YYYY-MM-DD. |
fecha_vigencia |
Texto | Fecha de vigencia (vencimiento) de la resolución. Formato: YYYY-MM-DD. |
prefijo |
Texto | Prefijo asignado a la resolución (ej: "FE", "DS", "PR"). |
dias_vencimiento |
Entero | Días de vencimiento configurados para las facturas generadas con esta resolución. |
activa |
Texto | Estado de la resolución: SI (activa) o NO (inactiva). |
codigo_barra |
Texto | Indica si la resolución tiene código de barras habilitado: SI o NO. |
codigo_ean |
Texto | Código EAN asociado a la resolución. Puede ser nulo si no se ha configurado. |
tipo_resolucion |
Entero | Tipo interno de la resolución. Puede ser nulo. |
creadopor |
Entero | Identificador del usuario que creó la resolución. Puede ser nulo. |
fechacreacion |
Texto | Fecha y hora de creación de la resolución. Formato: YYYY-MM-DD HH:MM:SS. |
modificadopor |
Entero | Identificador del usuario que modificó la resolución por última vez. Puede ser nulo. |
fechamodificacion |
Texto | Fecha y hora de la última modificación de la resolución. Puede ser nulo. Formato: YYYY-MM-DD HH:MM:SS. |
fact_electronica |
Texto | Indica si la resolución es de facturación electrónica: SI o NO. |
resolucion_para |
Entero | Tipo de resolución: 1 = Factura de Venta, 2 = Documento Soporte (no obligados a facturar). |
Paginación
El objeto pagination tiene las siguientes claves:
| Clave | Tipo | Descripción |
|---|---|---|
total_records |
Numérico | Total de resoluciones que coinciden con los filtros aplicados. |
total_pages |
Numérico | Cantidad de páginas, corresponde al total de registros dividido por el tamaño de la página. |
current_page |
Numérico | Página actual de la consulta. |
page_size |
Numérico | Tamaño de la página, es decir, cantidad máxima de registros por consulta. |
current_page_records |
Numérico | Cantidad de registros retornados en la página actual. |
has_next_page |
Booleano | Verdadero si hay siguientes páginas que se pueden consultar, falso en otro caso. |
has_previous_page |
Booleano | Verdadero si existen páginas previas que se pueden consultar, falso en otro caso. |
Filtros Aplicados
El objeto filters_applied contiene los filtros que fueron utilizados en la consulta. Solo se incluye en la respuesta cuando se aplican filtros. Las posibles claves son:
| Clave | Tipo | Descripción |
|---|---|---|
activa |
Texto | Estado activo utilizado como filtro: SI o NO. |
tipo_doc_id |
Entero | ID del tipo de documento contable utilizado como filtro. |
fact_electronica |
Texto | Filtro de facturación electrónica utilizado: SI o NO. |
resolucion_para |
Entero | Tipo de resolución utilizado como filtro: 1 (Factura) o 2 (Documento Soporte). |
fecha_desde |
Texto | Fecha mínima de resolución utilizada como filtro. |
fecha_hasta |
Texto | Fecha máxima de resolución utilizada como filtro. |
fecha_vigencia_desde |
Texto | Fecha mínima de vigencia utilizada como filtro. |
fecha_vigencia_hasta |
Texto | Fecha máxima de vigencia utilizada como filtro. |
Respuesta con Filtros Aplicados
{
"status": 200,
"message": null,
"body": [
{
"resolucion_id": 4,
"tipo_doc_id": 7,
"tipo_doc": "Factura",
"resolucion_numero": "18700052960",
"consecutivo_iniciar": 1,
"consecutivo_inicial": 1,
"consecutivo_final": 20000,
"fecha": "2025-07-24",
"fecha_vigencia": "2026-07-24",
"prefijo": "FE",
"dias_vencimiento": 5,
"activa": "SI",
"codigo_barra": "NO",
"codigo_ean": null,
"tipo_resolucion": null,
"creadopor": 5,
"fechacreacion": "2025-07-24 12:00:01",
"modificadopor": null,
"fechamodificacion": null,
"fact_electronica": "SI",
"resolucion_para": 1
}
],
"pagination": {
"total_records": 3,
"total_pages": 1,
"current_page": 1,
"page_size": 10,
"current_page_records": 3,
"has_next_page": false,
"has_previous_page": false
},
"filters_applied": {
"resolucion_para": 1,
"activa": "SI"
}
}
Respuesta Sin Resultados
{
"status": 200,
"message": "No se encontraron resoluciones con los criterios especificados.",
"body": [],
"pagination": {
"total_records": 0,
"total_pages": 0,
"current_page": 1,
"page_size": 10,
"current_page_records": 0,
"has_next_page": false,
"has_previous_page": false
},
"filters_applied": {
"activa": "NO"
}
}
Respuesta de Error
Error de Validación (400)
Se retorna cuando se envía un parámetro con un valor no válido.
{
"status": 400,
"message": "El parámetro \"activa\" debe ser \"SI\" o \"NO\".",
"body": null,
"pagination": null,
"filters_applied": null
}
{
"status": 400,
"message": "El parámetro \"resolucion_para\" debe ser 1 (Factura) o 2 (Documento Soporte).",
"body": null,
"pagination": null,
"filters_applied": null
}
{
"status": 400,
"message": "El parámetro \"fecha_desde\" debe tener el formato Y-m-d (ej: 2026-01-15).",
"body": null,
"pagination": null,
"filters_applied": null
}
Error Interno (500)
Se retorna cuando ocurre un error inesperado en el servidor.
{
"status": 500,
"message": "Error interno del servidor al obtener las resoluciones.",
"body": null,
"pagination": null,
"filters_applied": null
}
Códigos de Respuesta HTTP
| Código | Descripción |
|---|---|
| 200 | Consulta exitosa. El cuerpo de la respuesta contiene las resoluciones (puede ser un array vacío si no hay resultados). |
| 400 | Error de validación. Algún parámetro tiene un valor no válido. El campo message indica el parámetro y los valores aceptados. |
| 500 | Error interno del servidor. |
Valores de Referencia
Valores de resolucion_para
| Valor | Descripción |
|---|---|
| 1 | Factura de Venta — Resoluciones utilizadas para la emisión de facturas de venta |
| 2 | Documento Soporte — Resoluciones utilizadas para documento soporte de no obligados a facturar |
Valores de activa
| Valor | Descripción |
|---|---|
| SI | La resolución está activa y disponible para facturación |
| NO | La resolución está inactiva y no se puede usar para facturar |
Notas Importantes
-
Relación con facturas: El
resolucion_idretornado puede usarse como valor del parámetroresolucion_iden el endpoint Listar Facturas para filtrar facturas que pertenecen a una resolución específica. -
Tipo de resolución: El campo
resolucion_paradiferencia las resoluciones de facturación (1) de las de documento soporte (2). En el sistema, las resoluciones de facturación se configuran en Configuraciones > Facturación y las de documento soporte en Configuraciones > Facturas de Compra. -
Filtros de fecha: Los filtros
fecha_desde/fecha_hastaaplican sobre la fecha de expedición de la resolución, mientras quefecha_vigencia_desde/fecha_vigencia_hastaaplican sobre la fecha de vigencia. Ambos rangos pueden combinarse en una misma consulta. -
Ordenamiento: Las resoluciones se retornan ordenadas por
resolucion_idde forma descendente (las más recientes primero).
Ejemplos
Curl
curl -X GET "https://{{instancia}}.arrendasoft.co/service/v2/public/invoices/resolutions" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_AUTHENTICATION_TOKEN"
Con filtros:
curl -X GET "https://{{instancia}}.arrendasoft.co/service/v2/public/invoices/resolutions?resolucion_para=1&activa=SI&page_size=50" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_AUTHENTICATION_TOKEN"
PHP Curl
<?php
$instance = 'your_instance'; // Reemplace con su instancia actual
$token = 'YOUR_AUTHENTICATION_TOKEN'; // Reemplace con el token obtenido desde el servicio de login
// Parámetros de ejemplo
$page = 1;
$pageSize = 50;
// Parámetros de filtro opcionales
$resolucionPara = 1; // Opcional: 1 = Factura, 2 = Documento Soporte
$activa = 'SI'; // Opcional: 'SI' o 'NO'
$factElectronica = null; // Opcional: 'SI' o 'NO'
$url = "https://{$instance}.arrendasoft.co/service/v2/public/invoices/resolutions";
// Construir parámetros de consulta
$queryParams = [
'page' => $page,
'page_size' => $pageSize
];
if (!empty($resolucionPara)) {
$queryParams['resolucion_para'] = $resolucionPara;
}
if (!empty($activa)) {
$queryParams['activa'] = $activa;
}
if (!empty($factElectronica)) {
$queryParams['fact_electronica'] = $factElectronica;
}
$url .= '?' . http_build_query($queryParams);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Authorization: Bearer ' . $token
]);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (curl_errno($ch)) {
echo 'Error: ' . curl_error($ch);
} else {
echo "HTTP Status Code: " . $http_code . "\n";
echo "Response: " . $response . "\n";
// Procesar la respuesta
$result = json_decode($response, true);
if ($http_code == 200 && !empty($result['body'])) {
echo "Se encontraron " . $result['pagination']['total_records'] . " resoluciones.\n\n";
foreach ($result['body'] as $resolucion) {
echo "ID: " . $resolucion['resolucion_id'] . "\n";
echo "Número: " . $resolucion['resolucion_numero'] . "\n";
echo "Prefijo: " . $resolucion['prefijo'] . "\n";
echo "Tipo: " . $resolucion['tipo_doc'] . "\n";
echo "Activa: " . $resolucion['activa'] . "\n";
echo "Vigencia: " . $resolucion['fecha_vigencia'] . "\n";
echo "---\n";
}
} else {
echo $result['message'] ?? "No se encontraron resoluciones.\n";
}
}
curl_close($ch);
?>
JavaScript Fetch
const instance = 'your_instance'; // Reemplace con su instancia actual
const token = 'YOUR_AUTHENTICATION_TOKEN'; // Reemplace con el token obtenido
// Parámetros de filtro opcionales
const params = new URLSearchParams();
params.append('page', '1');
params.append('page_size', '50');
params.append('resolucion_para', '1'); // Opcional: 1 = Factura, 2 = Documento Soporte
params.append('activa', 'SI'); // Opcional: 'SI' o 'NO'
// params.append('fact_electronica', 'SI'); // Opcional: descomentar para filtrar
const url = `https://${instance}.arrendasoft.co/service/v2/public/invoices/resolutions?${params.toString()}`;
fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
}
})
.then(response => response.json())
.then(data => {
if (data.status === 200 && data.body.length > 0) {
console.log(`Se encontraron ${data.pagination.total_records} resoluciones:`);
data.body.forEach(res => {
console.log(`- ${res.prefijo} ${res.resolucion_numero} (ID: ${res.resolucion_id})`);
console.log(` Tipo: ${res.tipo_doc} | Activa: ${res.activa}`);
console.log(` Consecutivos: ${res.consecutivo_inicial} - ${res.consecutivo_final}`);
console.log(` Vigencia: ${res.fecha} a ${res.fecha_vigencia}`);
});
// Información de paginación
console.log(`\nPágina ${data.pagination.current_page} de ${data.pagination.total_pages}`);
} else {
console.log(data.message || 'No se encontraron resoluciones.');
}
})
.catch(error => console.error('Error de conexión:', error));
Contabilidad
Bienvenido al libro contable digital de tu inmobiliaria. En este apartado centralizamos las herramientas de conexión para que tus plataformas externas consulten y sincronicen tu información financiera de forma automática.
¿Para qué sirve este módulo? El objetivo principal es eliminar los procesos manuales en la extracción de datos financieros. En lugar de descargar informes a mano, tus sistemas podrán consultar directamente el historial y los movimientos de tus cuentas contables. Podrás utilizar filtros estratégicos —como rangos de fechas o grupos de cuentas— para extraer exactamente la información que necesitas sin sobrecargar tus integraciones.
Explora el listado a continuación para descubrir cómo alimentar tus tableros de análisis y mantener tus números perfectamente organizados, auditables y sincronizados.
Reporte Auxiliar General
Permite obtener el reporte contable Auxiliar General, que presenta los movimientos detallados de cada cuenta del Plan Único de Cuentas (PUC) dentro de un período y rango de cuentas. Cada elemento incluye el saldo anterior, débitos, créditos, saldo actual, base de retención, y el desglose por tercero con sus respectivos documentos contables.
¿Para qué sirve este servicio?
Úsalo para alimentar reportes contables en tu ERP, conciliar saldos con sistemas externos, generar informes de auditoría, exportar movimientos detallados a Excel o Power BI, o validar la contabilidad de un período específico.
1. El Endpoint (La dirección web)
Apunta tu sistema a la siguiente dirección. Recuerda reemplazar {{instancia}} por la dirección web completa que utilizas para ingresar a tu plataforma.
GET https://{{instancia}}/service/v2/public/accounting/general-ledger
¿Qué debes colocar en {{instancia}}?
Es muy sencillo: corresponde a la dirección web principal que utilizas a diario para ingresar a tu plataforma (incluyendo la terminación .nuby.app o .arrendasoft.co).
Por ejemplo, si para entrar a tu sistema escribes inmobiliaria.nuby.app o inmobiliaria.arrendasoft.co en tu navegador, esa será exactamente tu instancia. Solo asegúrate de no incluir el "https://" ni barras diagonales ("/") al final.
2. La Petición (¿Qué debes enviarnos?)
Este servicio no requiere cuerpo en la petición. Envía los encabezados requeridos y opcionalmente los parámetros de filtro en la URL:
| Método | GET |
| Content-Type | application/json |
| Authorization | Bearer token, Token obtenido al consumir el servicio Login |
¿Aún no tienes tu Token de acceso?
Para consumir este servicio necesitas un Token vigente. Consulta el servicio de Login para aprender cómo obtenerlo.
Parámetros de consulta (query string):
| Parámetro | Tipo | Requerido | Por defecto | Descripción |
|---|---|---|---|---|
fecha_ini |
string | No | Primer día del año en curso | Fecha inicial del rango a consultar. Formato: YYYY-MM-DD. |
fecha_fin |
string | No | Último día del mes en curso | Fecha final del rango a consultar. Formato: YYYY-MM-DD. Debe ser mayor o igual a fecha_ini. |
cuenta_ini |
string | No | 1 | Código inicial de cuenta PUC. Solo permite valores numéricos. Debe ser mayor o igual a 1. |
cuenta_fin |
string | No | 9 | Código final de cuenta PUC. Solo permite valores numéricos. Debe ser mayor o igual a cuenta_ini. |
Ejemplos de petición:
GET https://mi-inmobiliaria.nuby.app/service/v2/public/accounting/general-ledger
GET https://mi-inmobiliaria.nuby.app/service/v2/public/accounting/general-ledger?fecha_ini=2025-01-01
GET https://mi-inmobiliaria.nuby.app/service/v2/public/accounting/general-ledger?fecha_ini=2025-01-01&fecha_fin=2025-06-30
GET https://mi-inmobiliaria.nuby.app/service/v2/public/accounting/general-ledger?fecha_ini=2025-01-01&fecha_fin=2025-06-30&cuenta_ini=1
GET https://mi-inmobiliaria.nuby.app/service/v2/public/accounting/general-ledger?fecha_ini=2025-01-01&fecha_fin=2025-06-30&cuenta_ini=1&cuenta_fin=4
3. La Respuesta (¿Qué te entregaremos?)
Si tu Token es válido y los parámetros son correctos, el sistema te devolverá un objeto JSON con el listado de cuentas contables, sus terceros y los movimientos detallados de cada uno. La respuesta tiene una estructura jerárquica de tres niveles: Cuenta → Tercero → Detalle.
{
"error": false,
"message": "",
"body": [
{
"cuenta": "11050501",
"nombre_cuenta": "Caja general moneda nacional",
"saldo_anterior": 8750320.45,
"debitos": 12480000,
"creditos": 9230000,
"saldo_actual": 12000320.45,
"base_retencion": 0,
"terceros": {
"42": {
"documento_tercero": "80213654",
"nombre_tercero": "CARLOS EDUARDO PINEDA VARGAS",
"saldo_anterior": 3250120.45,
"debitos": 7500000,
"creditos": 4230000,
"saldo_actual": 6520120.45,
"base_retencion": 0,
"detalles": [
{
"fecha_documento": "2025-02-05",
"consecutivo_documento": "RC-10450",
"detalle_documento": "Pago canon arrendamiento febrero Apto 501",
"debitos": 2850000,
"creditos": 0,
"base_retencion": 0
},
{
"fecha_documento": "2025-03-03",
"consecutivo_documento": "RC-10512",
"detalle_documento": "Pago canon arrendamiento marzo Apto 501",
"debitos": 2850000,
"creditos": 0,
"base_retencion": 0
},
{
"fecha_documento": "2025-03-15",
"consecutivo_documento": "EG-4021",
"detalle_documento": "Consignación propietario marzo",
"debitos": 0,
"creditos": 4230000,
"base_retencion": 0
}
]
},
"73": {
"documento_tercero": "1098745231",
"nombre_tercero": "JULIANA PATRICIA RÍOS MENDOZA",
"saldo_anterior": 1500200,
"debitos": 4980000,
"creditos": 5000000,
"saldo_actual": 1480200,
"base_retencion": 0,
"detalles": [
{
"fecha_documento": "2025-01-10",
"consecutivo_documento": "RC-10389",
"detalle_documento": "Pago canon arrendamiento enero Local 3",
"debitos": 4500000,
"creditos": 0,
"base_retencion": 0
},
{
"fecha_documento": "2025-01-20",
"consecutivo_documento": "EG-3998",
"detalle_documento": "Consignación propietario enero",
"debitos": 0,
"creditos": 5000000,
"base_retencion": 0
}
]
}
}
},
{
"cuenta": "13050501",
"nombre_cuenta": "Arrendamientos por cobrar",
"saldo_anterior": 15400000,
"debitos": 9350000,
"creditos": 12480000,
"saldo_actual": 12270000,
"base_retencion": 0,
"terceros": {
"55": {
"documento_tercero": "43876123",
"nombre_tercero": "DIANA MARCELA OSPINA VELÁSQUEZ",
"saldo_anterior": 2400000,
"debitos": 3600000,
"creditos": 4800000,
"saldo_actual": 1200000,
"base_retencion": 0,
"detalles": [
{
"fecha_documento": "2025-01-01",
"consecutivo_documento": "FV-8901",
"detalle_documento": "Factura arrendamiento enero Cll 23 # 56 - 78",
"debitos": 1200000,
"creditos": 0,
"base_retencion": 0
},
{
"fecha_documento": "2025-01-15",
"consecutivo_documento": "RC-10401",
"detalle_documento": "Recibo de caja pago enero",
"debitos": 0,
"creditos": 1200000,
"base_retencion": 0
},
{
"fecha_documento": "2025-02-01",
"consecutivo_documento": "FV-8950",
"detalle_documento": "Factura arrendamiento febrero Cll 23 # 56 - 78",
"debitos": 1200000,
"creditos": 0,
"base_retencion": 0
},
{
"fecha_documento": "2025-02-10",
"consecutivo_documento": "RC-10465",
"detalle_documento": "Recibo de caja pago febrero",
"debitos": 0,
"creditos": 1200000,
"base_retencion": 0
}
]
}
}
},
{
"cuenta": "24080501",
"nombre_cuenta": "Retención en la fuente arrendamientos 3.5%",
"saldo_anterior": -875000,
"debitos": 0,
"creditos": 249375,
"saldo_actual": -1124375,
"base_retencion": 7125000,
"terceros": {
"65": {
"documento_tercero": "900456789",
"nombre_tercero": "INVERSIONES HORIZONTE S.A.S.",
"saldo_anterior": -875000,
"debitos": 0,
"creditos": 249375,
"saldo_actual": -1124375,
"base_retencion": 7125000,
"detalles": [
{
"fecha_documento": "2025-01-31",
"consecutivo_documento": "EG-3985",
"detalle_documento": "Retención arrendamiento enero Local 3",
"debitos": 0,
"creditos": 157500,
"base_retencion": 4500000
},
{
"fecha_documento": "2025-02-28",
"consecutivo_documento": "EG-4050",
"detalle_documento": "Retención arrendamiento febrero Local 3",
"debitos": 0,
"creditos": 91875,
"base_retencion": 2625000
}
]
}
}
}
]
}
Estructura principal de la respuesta
| Campo | Tipo | Descripción |
|---|---|---|
error |
boolean | Estado de la respuesta. false para exitoso, true cuando ocurre un error. |
message |
string | Cadena vacía cuando la respuesta es exitosa. Si no hay resultados, contiene un mensaje informativo. Si hay error, describe el problema presentado. |
body |
array | null | Listado de cuentas contables con sus movimientos. null cuando no hay resultados o hay un error. |
Campos de cada cuenta (body)
Cada elemento dentro del arreglo body representa una cuenta contable y contiene las siguientes claves:
| Campo | Tipo | Descripción |
|---|---|---|
cuenta |
string | Código numérico de la cuenta en el Plan Único de Cuentas (PUC). |
nombre_cuenta |
string | Nombre descriptivo de la cuenta PUC. |
saldo_anterior |
number | Saldo acumulado de la cuenta antes de la fecha inicial del rango consultado. Puede ser negativo. |
debitos |
number | Suma total de los débitos de la cuenta en el período consultado. |
creditos |
number | Suma total de los créditos de la cuenta en el período consultado. |
saldo_actual |
number | Saldo resultante de la cuenta al final del período. El cálculo varía según la clase de cuenta: para activos, gastos y costos (clases 1, 5 y 6) es saldo_anterior + débitos - créditos; para las demás clases es saldo_anterior + créditos - débitos. Puede ser negativo. |
base_retencion |
number | Valor acumulado de la base de retención de la cuenta en el período. |
terceros |
object | Objeto que contiene los terceros vinculados a la cuenta. Cada clave del objeto es el tercero_id del sistema (o "sin_tercero" si el movimiento no tiene tercero asociado). |
Campos de cada tercero (terceros)
Cada entrada dentro del objeto terceros contiene las siguientes claves:
| Campo | Tipo | Descripción |
|---|---|---|
documento_tercero |
string | Número de documento de identidad del tercero. Si no tiene tercero asociado, muestra "Sin tercero". |
nombre_tercero |
string | Nombre completo del tercero. Si no tiene tercero asociado, muestra "Sin tercero". |
saldo_anterior |
number | Saldo acumulado del tercero en esta cuenta antes de la fecha inicial. Puede ser negativo. |
debitos |
number | Suma total de los débitos del tercero en esta cuenta durante el período. |
creditos |
number | Suma total de los créditos del tercero en esta cuenta durante el período. |
saldo_actual |
number | Saldo resultante del tercero en esta cuenta al final del período. Mismo criterio de cálculo que el saldo de la cuenta. |
base_retencion |
number | Valor acumulado de la base de retención del tercero en esta cuenta. |
detalles |
array | Listado de documentos contables (movimientos individuales) del tercero en esta cuenta durante el período. |
Campos de cada detalle (detalles)
Cada elemento dentro del arreglo detalles representa un documento contable individual:
| Campo | Tipo | Descripción |
|---|---|---|
fecha_documento |
string | Fecha del documento contable en formato YYYY-MM-DD. |
consecutivo_documento |
string | Consecutivo del documento contable con su prefijo, en formato PREFIJO-NÚMERO (ej. RC-10450, FV-8901, EG-4021). |
detalle_documento |
string | Descripción u observaciones del documento contable. |
debitos |
number | Valor del débito del documento contable. |
creditos |
number | Valor del crédito del documento contable. |
base_retencion |
number | Valor de la base de retención del documento contable. |
Nota sobre resultados vacíos
Si no existen movimientos contables para los parámetros indicados, la respuesta tendrá HTTP 200 con error: false, body: null y un message informativo: "No se encontraron registros con los parámetros indicados."
Nota sobre el cálculo de saldos
El cálculo del saldo_actual depende de la clase contable de la cuenta (primer dígito del código PUC):
— Clases 1 (Activos), 5 (Gastos) y 6 (Costos): saldo_anterior + débitos - créditos
— Clases 2 (Pasivos), 3 (Patrimonio), 4 (Ingresos) y demás: saldo_anterior + créditos - débitos
Este comportamiento puede variar según la configuración del sistema (parámetro interno de la plataforma).
4. Seguridad y Posibles Errores
¡Tu pase tiene fecha de caducidad!
Por medidas de seguridad, el token que te entregamos solo dura 1 hora. Una vez transcurrido ese tiempo, el pase expirará y el sistema te bloqueará el acceso devolviéndote un error 401. Cuando esto ocurra, tu sistema simplemente debe volver a consumir el servicio de Login para pedir un pase nuevo y continuar trabajando.
Así se ve el error que te devolverá el sistema cuando tu token se haya vencido o intentes usar un pase inválido:
{
"statusCode": 401,
"error": {
"type": "SERVER_ERROR",
"description": "JWT Token expired."
}
}
Si alguno de los parámetros no cumple con las validaciones, el sistema devolverá un error 400. Por ejemplo:
{
"error": true,
"message": "La fecha inicial no tiene un formato válido (Y-m-d) o no es una fecha válida.",
"body": null
}
Posibles errores:
| Código HTTP | Descripción |
|---|---|
| 400 | Token faltante o inválido. Posibles causas: — No se envió el encabezado Authorization. Mensaje: "JWT Token required."— El encabezado no tiene el formato Bearer {token}. Mensaje: "JWT Token not send."— El token no fue encontrado en el sistema. Mensaje: "JWT Token not found."Parámetros inválidos. Posibles causas: — fecha_ini no tiene formato YYYY-MM-DD válido. Mensaje: "La fecha inicial no tiene un formato válido (Y-m-d) o no es una fecha válida."— fecha_fin no tiene formato YYYY-MM-DD válido. Mensaje: "La fecha final no tiene un formato válido (Y-m-d) o no es una fecha válida."— fecha_ini es posterior a fecha_fin. Mensaje: "La fecha inicial debe ser menor o igual que la fecha final."— cuenta_ini no es numérico. Mensaje: "La cuenta inicial debe ser un valor numérico."— cuenta_fin no es numérico. Mensaje: "La cuenta final debe ser un valor numérico."— cuenta_ini es mayor que cuenta_fin. Mensaje: "La cuenta inicial debe ser menor o igual que la cuenta final."— cuenta_ini es menor que 1. Mensaje: "La cuenta inicial debe ser mayor o igual que 1." |
| 401 | El token ha expirado. Debes generar uno nuevo consumiendo el servicio de Login. Mensaje: "JWT Token expired." |
| 403 | El cliente OAuth no tiene el scope necesario para esta operación. Para endpoints GET se requiere el scope read. Mensaje: "Insufficient scope. Required: 'read', granted: '{scope_actual}'." |
| 500 | Error interno del servidor al procesar la consulta del auxiliar general. Mensaje: "Ocurrió un error al tratar de obtener el auxiliar general." |
5. Ejemplos de integración
Aquí tienes ejemplos de código listos para que tus desarrolladores los adapten a tu plataforma:
cURL
# Consultar auxiliar general con parámetros por defecto (año actual, todas las cuentas)
curl -X GET "https://{{instancia}}/service/v2/public/accounting/general-ledger" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer TU_TOKEN_AQUI"
# Consultar auxiliar general de enero a junio 2025, cuentas de activos y pasivos (1 a 2)
curl -X GET "https://{{instancia}}/service/v2/public/accounting/general-ledger?fecha_ini=2025-01-01&fecha_fin=2025-06-30&cuenta_ini=1&cuenta_fin=2" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer TU_TOKEN_AQUI"
PHP
<?php
$instance = 'tu_instancia'; // Reemplaza con tu instancia real
$token = 'TU_TOKEN_AQUI'; // Token obtenido del servicio Login
// Parámetros de consulta
$fecha_ini = '2025-01-01';
$fecha_fin = '2025-06-30';
$cuenta_ini = '1';
$cuenta_fin = '4';
$queryParams = http_build_query([
'fecha_ini' => $fecha_ini,
'fecha_fin' => $fecha_fin,
'cuenta_ini' => $cuenta_ini,
'cuenta_fin' => $cuenta_fin
]);
$url = "https://{$instance}/service/v2/public/accounting/general-ledger?{$queryParams}";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
"Authorization: Bearer {$token}"
]);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (curl_errno($ch)) {
echo 'Error: ' . curl_error($ch);
} else {
echo "Código de estado HTTP: " . $http_code . "\n";
$info = json_decode($response, true);
$body = $info['body'] ?? [];
if ($http_code === 200 && !empty($body)) {
echo "Se consultaron " . count($body) . " cuentas contables.\n\n";
foreach ($body as $cuenta) {
echo "Cuenta: {$cuenta['cuenta']} - {$cuenta['nombre_cuenta']}\n";
echo " Saldo anterior: $" . number_format($cuenta['saldo_anterior'], 2) . "\n";
echo " Débitos: $" . number_format($cuenta['debitos'], 2) . "\n";
echo " Créditos: $" . number_format($cuenta['creditos'], 2) . "\n";
echo " Saldo actual: $" . number_format($cuenta['saldo_actual'], 2) . "\n";
foreach ($cuenta['terceros'] as $terceroId => $tercero) {
echo " Tercero: {$tercero['documento_tercero']} - {$tercero['nombre_tercero']}\n";
echo " Movimientos: " . count($tercero['detalles']) . "\n";
}
echo "\n";
}
} else {
echo "Mensaje: " . ($info['message'] ?? 'Sin resultados') . "\n";
}
}
curl_close($ch);
?>
Python
import requests
# 1. Configura tus datos de acceso
instancia = 'mi-inmobiliaria.nuby.app' # Reemplaza con tu dirección web completa
token = 'TU_TOKEN_AQUI' # Token obtenido del servicio Login
# 2. Prepara la dirección y los parámetros
url = f"https://{instancia}/service/v2/public/accounting/general-ledger"
params = {
"fecha_ini": "2025-01-01",
"fecha_fin": "2025-06-30",
"cuenta_ini": "1",
"cuenta_fin": "4"
}
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {token}"
}
# 3. Envía la petición GET y procesa la respuesta
try:
response = requests.get(url, params=params, headers=headers)
print(f"Código de estado HTTP: {response.status_code}")
if response.status_code == 200:
info = response.json()
body = info.get('body') or []
if body:
print(f"Cuentas encontradas: {len(body)}\n")
for cuenta in body:
print(f"Cuenta: {cuenta['cuenta']} - {cuenta['nombre_cuenta']}")
print(f" Saldo anterior: ${cuenta['saldo_anterior']:,.2f}")
print(f" Débitos: ${cuenta['debitos']:,.2f}")
print(f" Créditos: ${cuenta['creditos']:,.2f}")
print(f" Saldo actual: ${cuenta['saldo_actual']:,.2f}")
for tercero_id, tercero in cuenta['terceros'].items():
print(f" Tercero [{tercero_id}]: {tercero['documento_tercero']} - {tercero['nombre_tercero']}")
print(f" Movimientos: {len(tercero['detalles'])}")
print()
else:
print(f"Mensaje: {info.get('message', 'Sin resultados')}")
else:
print("Error al consultar el auxiliar general.")
print(f"Detalle del error: {response.text}")
except Exception as e:
print(f"Ocurrió un error de conexión: {e}")
JavaScript
// 1. Configura tus datos de acceso
const instancia = 'mi-inmobiliaria.nuby.app'; // Reemplaza con tu dirección web completa
const token = 'TU_TOKEN_AQUI'; // Token obtenido del servicio Login
// 2. Prepara la dirección con parámetros
const params = new URLSearchParams({
fecha_ini: '2025-01-01',
fecha_fin: '2025-06-30',
cuenta_ini: '1',
cuenta_fin: '4'
});
const url = `https://${instancia}/service/v2/public/accounting/general-ledger?${params}`;
// 3. Función para consultar el auxiliar general
async function consultarAuxiliarGeneral() {
try {
const response = await fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
}
});
console.log(`Código de estado HTTP: ${response.status}`);
if (response.ok) {
const info = await response.json();
const body = info.body || [];
if (body.length > 0) {
console.log(`Cuentas encontradas: ${body.length}\n`);
body.forEach(cuenta => {
console.log(`Cuenta: ${cuenta.cuenta} - ${cuenta.nombre_cuenta}`);
console.log(` Saldo anterior: $${cuenta.saldo_anterior.toLocaleString()}`);
console.log(` Débitos: $${cuenta.debitos.toLocaleString()}`);
console.log(` Créditos: $${cuenta.creditos.toLocaleString()}`);
console.log(` Saldo actual: $${cuenta.saldo_actual.toLocaleString()}`);
for (const [terceroId, tercero] of Object.entries(cuenta.terceros)) {
console.log(` Tercero [${terceroId}]: ${tercero.documento_tercero} - ${tercero.nombre_tercero}`);
console.log(` Movimientos: ${tercero.detalles.length}`);
}
console.log('');
});
} else {
console.log(`Mensaje: ${info.message || 'Sin resultados'}`);
}
} else {
console.log('Error al consultar el auxiliar general.');
const errorData = await response.text();
console.log(`Detalle del error: ${errorData}`);
}
} catch (error) {
console.error(`Ocurrió un error de conexión: ${error}`);
}
}
// 4. Ejecutamos la función
consultarAuxiliarGeneral();
Power Query M (Excel / Power BI)
let
// 1. Configura tus datos de acceso
instancia = "mi-inmobiliaria.nuby.app", // Reemplaza con tu dirección web completa
token = "TU_TOKEN_AQUI", // Token obtenido del servicio Login
// 2. Prepara la dirección con parámetros
url = "https://" & instancia & "/service/v2/public/accounting/general-ledger?fecha_ini=2025-01-01&fecha_fin=2025-06-30&cuenta_ini=1&cuenta_fin=4",
// 3. Envía la petición GET
response = Web.Contents(url, [
Headers = [
#"Content-Type" = "application/json",
#"Authorization" = "Bearer " & token
]
]),
// 4. Decodifica la respuesta JSON
jsonResponse = Json.Document(response),
body = jsonResponse[body],
// 5. Convierte el listado de cuentas en tabla
tablaCuentas = Table.FromList(body, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
expandidoCuentas = Table.ExpandRecordColumn(tablaCuentas, "Column1",
{"cuenta", "nombre_cuenta", "saldo_anterior", "debitos", "creditos", "saldo_actual", "base_retencion", "terceros"},
{"Cuenta", "NombreCuenta", "SaldoAnterior", "Debitos", "Creditos", "SaldoActual", "BaseRetencion", "Terceros"}),
// 6. (Opcional) Expandir terceros para obtener detalle por tercero
// Nota: La estructura de terceros es un objeto con claves dinámicas.
// Para un análisis más detallado, es recomendable procesar los terceros
// con Record.FieldValues y luego expandir los detalles.
tercerosList = Table.AddColumn(expandidoCuentas, "TercerosLista", each Record.FieldValues([Terceros])),
expandidoTerceros = Table.ExpandListColumn(tercerosList, "TercerosLista"),
expandidoTercerosCampos = Table.ExpandRecordColumn(expandidoTerceros, "TercerosLista",
{"documento_tercero", "nombre_tercero", "saldo_anterior", "debitos", "creditos", "saldo_actual", "base_retencion"},
{"DocTercero", "NombreTercero", "SaldoAntTercero", "DebitosTercero", "CreditosTercero", "SaldoActTercero", "BaseRetTercero"})
in
expandidoTercerosCampos
Contratos
Bienvenido al archivador legal digital de tu inmobiliaria. En esta sección agrupamos todas las opciones de conexión para que tus plataformas externas interactúen con los acuerdos de arrendamiento.
¿Cuál es el propósito de este módulo? Facilitar la sincronización de tu ecosistema. Aquí encontrarás las herramientas necesarias para que tus sistemas consulten y extraigan automáticamente los detalles de cualquier contrato, eliminando por completo la necesidad de realizar búsquedas manuales o revisar documentos físicos en nuestra plataforma.
Explora el listado de abajo para descubrir cómo consultar términos, información financiera, estados y fechas de tus inmuebles alquilados.
Listar Contratos
Permite obtener la lista paginada de todos los contratos de arrendamiento registrados en el sistema. Cada elemento incluye la información completa del contrato: propiedad asociada, propietarios, inquilinos, valores económicos, fechas, estado y observaciones.
¿Para qué sirve este servicio?
Úsalo para sincronizar el inventario de contratos con tu sistema externo, generar reportes de gestión inmobiliaria, alimentar dashboards con información contractual o consultar el estado general de los contratos administrados.
1. El Endpoint (La dirección web)
Apunta tu sistema a la siguiente dirección. Recuerda reemplazar {{instancia}} por la dirección web completa que utilizas para ingresar a tu plataforma.
GET https://{{instancia}}/service/v2/public/contracts/list
¿Qué debes colocar en {{instancia}}?
Es muy sencillo: corresponde a la dirección web principal que utilizas a diario para ingresar a tu plataforma (incluyendo la terminación .nuby.app o .arrendasoft.co).
Por ejemplo, si para entrar a tu sistema escribes inmobiliaria.nuby.app o inmobiliaria.arrendasoft.co en tu navegador, esa será exactamente tu instancia. Solo asegúrate de no incluir el "https://" ni barras diagonales ("/") al final.
2. La Petición (¿Qué debes enviarnos?)
Este servicio no requiere cuerpo en la petición. Envía los encabezados requeridos y opcionalmente los parámetros de paginación en la URL:
| Método | GET |
| Content-Type | application/json |
| Authorization | Bearer token, Token obtenido al consumir el servicio Login |
¿Aún no tienes tu Token de acceso?
Para consumir este servicio necesitas un Token vigente. Consulta el servicio de Login para aprender cómo obtenerlo.
Parámetros de consulta (query string):
| Parámetro | Tipo | Requerido | Por defecto | Descripción |
|---|---|---|---|---|
page |
integer | No | 1 | Número de página de resultados que se desea recuperar. Debe ser un número positivo. |
page_size |
integer | No | 10 | Número máximo de contratos por página. Debe ser un número positivo. Valor máximo permitido: 1000. |
Ejemplos de petición:
GET https://mi-inmobiliaria.nuby.app/service/v2/public/contracts/list
GET https://mi-inmobiliaria.nuby.app/service/v2/public/contracts/list?page=2
GET https://mi-inmobiliaria.nuby.app/service/v2/public/contracts/list?page_size=50
GET https://mi-inmobiliaria.nuby.app/service/v2/public/contracts/list?page=3&page_size=100
3. La Respuesta (¿Qué te entregaremos?)
Si tu Token es válido, el sistema te devolverá un objeto JSON con el estado de la respuesta, el listado de contratos y la información de paginación. La respuesta se verá similar a esta:
{
"status": 200,
"message": null,
"body": [
{
"contrato_id": 45,
"consecutivo": "45",
"propiedad_id": 312,
"propiedad": "312 - Cll 78 # 12 - 34 Apto 501",
"estrato_propiedad": "Cuatro",
"propietario": "[1] 52498731 - ANDREA MILENA CASTRO ROJAS",
"propietarios_id": "18",
"inquilino": "[1] 80213654 - CARLOS EDUARDO PINEDA VARGAS",
"inquilinos_id": "42",
"valor_canon_individual": "2850000",
"canon_total": 2850000,
"porcentaje_comision": "10.00 %",
"periodicidad": "Mensual",
"escenario": "CANON DE ARRENDAMIENTO SIN IVA, CON RETEFUENTE 3.5%, SIN RETEIVA, SIN RETEICA",
"estado": "Activo",
"estado_id": 1,
"fecha_inicio": "2024-06-01",
"fecha_fin": "2025-05-31",
"fecha_terminacion": null,
"observaciones": "Contrato renovado automáticamente por un año adicional.",
"uso": "Vivienda",
"fecha_creacion": "2024-05-28 14:32:10",
"creado_por": "Sandra"
},
{
"contrato_id": 46,
"consecutivo": "46",
"propiedad_id": 589,
"propiedad": "589 - Cra 45 # 90 - 12 Local 3",
"estrato_propiedad": "Comercial",
"propietario": "[1] 900456789 - INVERSIONES HORIZONTE S.A.S.",
"propietarios_id": "65",
"inquilino": "[1] 1098745231 - JULIANA PATRICIA RÍOS MENDOZA",
"inquilinos_id": "73",
"valor_canon_individual": "4500000",
"canon_total": 4500000,
"porcentaje_comision": "8.50 %",
"periodicidad": "Mensual",
"escenario": "CANON DE ARRENDAMIENTO CON IVA 19%, CON RETEFUENTE 3.5%, CON RETEIVA 15%, SIN RETEICA",
"estado": "Activo",
"estado_id": 1,
"fecha_inicio": "2023-09-01",
"fecha_fin": "2025-08-31",
"fecha_terminacion": null,
"observaciones": null,
"uso": "Comercial",
"fecha_creacion": "2023-08-25 09:15:44",
"creado_por": "Administrador"
},
{
"contrato_id": 12,
"consecutivo": "12",
"propiedad_id": 104,
"propiedad": "104 - Cll 23 # 56 - 78",
"estrato_propiedad": "Tres",
"propietario": "[1] 71654321 - HÉCTOR FABIO MORENO AGUILAR",
"propietarios_id": "31",
"inquilino": "[1] 43876123 - DIANA MARCELA OSPINA VELÁSQUEZ",
"inquilinos_id": "55",
"valor_canon_individual": "1200000",
"canon_total": 1200000,
"porcentaje_comision": "12.00 %",
"periodicidad": "Mensual",
"escenario": "CANON DE ARRENDAMIENTO SIN IVA, SIN RETEFUENTE, SIN RETEIVA, SIN RETEICA",
"estado": "Terminado",
"estado_id": 2,
"fecha_inicio": "2022-01-15",
"fecha_fin": "2023-01-14",
"fecha_terminacion": "2022-11-30",
"observaciones": "Terminación anticipada por mutuo acuerdo.",
"uso": "Vivienda",
"fecha_creacion": "2021-12-20 16:40:33",
"creado_por": "Sandra"
}
],
"pagination": {
"total_records": 347,
"total_pages": 116,
"current_page": 1,
"page_size": 3,
"current_page_records": 3,
"has_next_page": true,
"has_previous_page": false
}
}
Estructura principal de la respuesta
| Campo | Tipo | Descripción |
|---|---|---|
status |
integer | Código del estado de la respuesta. 200 para exitoso, 400 para error de validación, 500 para error interno. |
message |
string | null | Cuando la respuesta es exitosa vale null. Si no se encuentran contratos, contiene el mensaje informativo. Si hay error, describe el problema. |
body |
array | Listado de contratos devueltos. Arreglo vacío [] si no hay resultados. |
pagination |
object | Información de paginación para recorrer los resultados. |
Campos de cada contrato (body)
Cada elemento dentro del arreglo body contiene las siguientes claves:
| Campo | Tipo | Descripción |
|---|---|---|
contrato_id |
integer | Identificador único del contrato en el sistema. |
consecutivo |
string | Número consecutivo interno del contrato. |
propiedad_id |
integer | Identificador de la propiedad asociada al contrato. |
propiedad |
string | Etiqueta descriptiva de la propiedad en formato {id} - {dirección}. |
estrato_propiedad |
string | Estrato socioeconómico asignado a la propiedad (ej. "Tres", "Cuatro", "Comercial"). |
propietario |
string | Cadena con el consecutivo del detalle, documento y nombre completo del propietario o propietarios. Formato: [n] documento - NOMBRE. Si hay varios, van separados por coma. |
propietarios_id |
string | ID(s) del/los propietario(s) en el sistema. Si hay varios, van separados por coma. |
inquilino |
string | Cadena con el consecutivo del detalle, documento y nombre completo del inquilino o inquilinos. Mismo formato que propietario. |
inquilinos_id |
string | ID(s) del/los inquilino(s) en el sistema. Si hay varios, van separados por coma. |
valor_canon_individual |
string | Valor del canon por cada detalle del contrato. Si hay varios detalles, los valores van separados por coma. |
canon_total |
number | null | Valor total del canon de arrendamiento del contrato. |
porcentaje_comision |
string | Porcentaje de comisión de la inmobiliaria con formato "X.XX %". |
periodicidad |
string | Frecuencia de pago del canon (ej. "Mensual"). |
escenario |
string | Descripción del escenario tributario y de facturación aplicado al contrato. |
estado |
string | Estado textual del contrato. Valores posibles: Activo, Terminado, En Construcción. |
estado_id |
integer | Identificador numérico del estado: 1 = Activo, 2 = Terminado, 3 = En Construcción. |
fecha_inicio |
string | Fecha de inicio del contrato en formato YYYY-MM-DD. |
fecha_fin |
string | Fecha de finalización prevista del contrato en formato YYYY-MM-DD. |
fecha_terminacion |
string | null | Fecha de terminación efectiva del contrato (si aplica). null si el contrato sigue vigente. |
observaciones |
string | null | Observaciones o notas asociadas al contrato. null si no hay. |
uso |
string | Tipo de uso de la propiedad: Vivienda o Comercial. |
fecha_creacion |
string | Fecha y hora de creación del registro en formato YYYY-MM-DD HH:MM:SS. |
creado_por |
string | Nombre del usuario que creó el contrato en el sistema. |
Campos de paginación (pagination)
El objeto pagination contiene las siguientes claves:
| Campo | Tipo | Descripción |
|---|---|---|
total_records |
integer | Total de contratos registrados en el sistema. |
total_pages |
integer | Cantidad total de páginas disponibles (total de registros dividido por el tamaño de página). |
current_page |
integer | Número de la página actual consultada. |
page_size |
integer | Tamaño de la página (cantidad de registros solicitados por consulta). |
current_page_records |
integer | Cantidad de registros efectivamente devueltos en la página actual. |
has_next_page |
boolean | true si existen páginas posteriores que se pueden consultar. |
has_previous_page |
boolean | true si existen páginas anteriores que se pueden consultar. |
Nota sobre contratos sin resultados
Si no existen contratos registrados en el sistema, la respuesta tendrá HTTP 200 con body vacío ([]), un message informativo y los valores de paginación en cero.
4. Seguridad y Posibles Errores
¡Tu pase tiene fecha de caducidad!
Por medidas de seguridad, el token que te entregamos solo dura 1 hora. Una vez transcurrido ese tiempo, el pase expirará y el sistema te bloqueará el acceso devolviéndote un error 401. Cuando esto ocurra, tu sistema simplemente debe volver a consumir el servicio de Login para pedir un pase nuevo y continuar trabajando.
Así se ve el error que te devolverá el sistema cuando tu token se haya vencido o intentes usar un pase inválido:
{
"statusCode": 401,
"error": {
"type": "SERVER_ERROR",
"description": "JWT Token expired."
}
}
Si alguno de los parámetros de paginación no cumple con las validaciones, el sistema devolverá un error 400 con la estructura estándar. Por ejemplo:
{
"status": 400,
"message": "El parámetro \"page_size\" debe ser un número positivo.",
"body": null,
"pagination": null
}
Posibles errores:
| Código HTTP | Descripción |
|---|---|
| 400 | Token faltante o inválido. Posibles causas: — No se envió el encabezado Authorization. Mensaje: "JWT Token required."— El encabezado no tiene el formato Bearer {token}. Mensaje: "JWT Token not send."— El token no fue encontrado en el sistema. Mensaje: "JWT Token not found."Parámetros inválidos. Posibles causas: — page no es numérico o no es positivo.— page_size no es numérico o no es positivo. |
| 401 | El token ha expirado. Debes generar uno nuevo consumiendo el servicio de Login. Mensaje: "JWT Token expired." |
| 403 | El cliente OAuth no tiene el scope necesario para esta operación. Para endpoints GET se requiere el scope read. Mensaje: "Insufficient scope. Required: 'read', granted: '{scope_actual}'." |
| 500 | Error interno del servidor al procesar la consulta de contratos. |
5. Ejemplos de integración
Aquí tienes ejemplos de código listos para que tus desarrolladores los adapten a tu plataforma:
cURL
# Listar contratos con paginación por defecto
curl -X GET "https://{{instancia}}/service/v2/public/contracts/list" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer TU_TOKEN_AQUI"
# Listar contratos página 3 con 100 registros por página
curl -X GET "https://{{instancia}}/service/v2/public/contracts/list?page=3&page_size=100" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer TU_TOKEN_AQUI"
PHP
<?php
$instance = 'tu_instancia'; // Reemplaza con tu instancia real
$token = 'TU_TOKEN_AQUI'; // Token obtenido del servicio Login
// Parámetros de paginación
$page = 1;
$page_size = 50;
$queryParams = http_build_query([
'page' => $page,
'page_size' => $page_size
]);
$url = "https://{$instance}/service/v2/public/contracts/list?{$queryParams}";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
"Authorization: Bearer {$token}"
]);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (curl_errno($ch)) {
echo 'Error: ' . curl_error($ch);
} else {
echo "Código de estado HTTP: " . $http_code . "\n";
$info = json_decode($response, true);
$body = $info['body'] ?? [];
if ($http_code === 200 && !empty($body)) {
$pagination = $info['pagination'];
echo "Contratos encontrados: {$pagination['total_records']} (página {$pagination['current_page']} de {$pagination['total_pages']})\n";
foreach ($body as $contrato) {
echo " [{$contrato['consecutivo']}] {$contrato['propiedad']} - {$contrato['estado']} - Canon: \${$contrato['canon_total']}\n";
}
} else {
echo "Mensaje: " . ($info['message'] ?? 'Sin resultados') . "\n";
}
}
curl_close($ch);
?>
Python
import requests
# 1. Configura tus datos de acceso
instancia = 'mi-inmobiliaria.nuby.app' # Reemplaza con tu dirección web completa
token = 'TU_TOKEN_AQUI' # Token obtenido del servicio Login
# 2. Prepara la dirección y los parámetros
url = f"https://{instancia}/service/v2/public/contracts/list"
params = {
"page": 1,
"page_size": 50
}
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {token}"
}
# 3. Envía la petición GET y procesa la respuesta
try:
response = requests.get(url, params=params, headers=headers)
print(f"Código de estado HTTP: {response.status_code}")
if response.status_code == 200:
info = response.json()
body = info.get('body', [])
pagination = info.get('pagination', {})
if body:
print(f"Contratos: {pagination['total_records']} total (página {pagination['current_page']} de {pagination['total_pages']})")
for contrato in body:
print(f" [{contrato['consecutivo']}] {contrato['propiedad']} - {contrato['estado']} - Canon: ${contrato['canon_total']}")
else:
print(f"Mensaje: {info.get('message', 'Sin resultados')}")
else:
print("Error al consultar los contratos.")
print(f"Detalle del error: {response.text}")
except Exception as e:
print(f"Ocurrió un error de conexión: {e}")
JavaScript
// 1. Configura tus datos de acceso
const instancia = 'mi-inmobiliaria.nuby.app'; // Reemplaza con tu dirección web completa
const token = 'TU_TOKEN_AQUI'; // Token obtenido del servicio Login
// 2. Prepara la dirección con parámetros
const params = new URLSearchParams({
page: 1,
page_size: 50
});
const url = `https://${instancia}/service/v2/public/contracts/list?${params}`;
// 3. Función para consultar los contratos
async function consultarContratos() {
try {
const response = await fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
}
});
console.log(`Código de estado HTTP: ${response.status}`);
if (response.ok) {
const info = await response.json();
const body = info.body || [];
const pagination = info.pagination || {};
if (body.length > 0) {
console.log(`Contratos: ${pagination.total_records} total (página ${pagination.current_page} de ${pagination.total_pages})`);
body.forEach(contrato => {
console.log(` [${contrato.consecutivo}] ${contrato.propiedad} - ${contrato.estado} - Canon: $${contrato.canon_total}`);
});
} else {
console.log(`Mensaje: ${info.message || 'Sin resultados'}`);
}
} else {
console.log('Error al consultar los contratos.');
const errorData = await response.text();
console.log(`Detalle del error: ${errorData}`);
}
} catch (error) {
console.error(`Ocurrió un error de conexión: ${error}`);
}
}
// 4. Ejecutamos la función
consultarContratos();
Power Query M (Excel / Power BI)
let
// 1. Configura tus datos de acceso
instancia = "mi-inmobiliaria.nuby.app", // Reemplaza con tu dirección web completa
token = "TU_TOKEN_AQUI", // Token obtenido del servicio Login
// 2. Prepara la dirección de la petición con parámetros
url = "https://" & instancia & "/service/v2/public/contracts/list?page=1&page_size=1000",
// 3. Envía la petición GET
response = Web.Contents(url, [
Headers = [
#"Content-Type" = "application/json",
#"Authorization" = "Bearer " & token
]
]),
// 4. Decodifica la respuesta JSON
jsonResponse = Json.Document(response),
body = jsonResponse[body],
// 5. Convierte el listado en tabla
tabla = Table.FromList(body, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
expandido = Table.ExpandRecordColumn(tabla, "Column1",
{"contrato_id", "consecutivo", "propiedad", "estrato_propiedad", "propietario", "inquilino", "canon_total", "porcentaje_comision", "periodicidad", "estado", "fecha_inicio", "fecha_fin", "fecha_terminacion", "uso", "creado_por"},
{"ContratoID", "Consecutivo", "Propiedad", "Estrato", "Propietario", "Inquilino", "Canon", "Comision", "Periodicidad", "Estado", "FechaInicio", "FechaFin", "FechaTerminacion", "Uso", "CreadoPor"})
in
expandido