# 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.

<p class="callout info">**¿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**.</p>

---

#### **1. El Endpoint (La dirección web)**

Apunta tu sistema a la siguiente dirección. Recuerda reemplazar <span style="color: rgb(241, 196, 15);">**{{instancia}}**</span> por la dirección web completa que utilizas para ingresar a tu plataforma.

```http
GET https://{{instancia}}/service/v2/public/masters/properties/features
```

<p class="callout info">**¿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.</p>

#### **2. La Petición (¿Qué debes enviarnos?)**

Este servicio no requiere cuerpo en la petición. Solo necesitas enviar los encabezados correctos:

<table border="1" id="bkmrk-m%C3%A9todo-get-content-t" style="border-collapse: collapse; width: 100%;"><colgroup><col style="width: 20%;"></col><col style="width: 80%;"></col></colgroup><tbody><tr><td>**Método**</td><td>GET</td></tr><tr><td>**Content-Type**</td><td>application/json</td></tr><tr><td>**Authorization**</td><td>**Bearer token**, Token obtenido al consumir el servicio [Login](https://docs.nuby.ai/books/api-nuby-v2/page/login "Login")</td></tr></tbody></table>

<p class="callout warning">**¿Aún no tienes tu Token de acceso?**  
Para consumir este servicio necesitas un Token vigente. Consulta el servicio de [Login](https://docs.nuby.ai/books/api-nuby-v2/page/login) para aprender cómo obtenerlo.</p>

#### **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:

```json
[
    {
        "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"
    }
]
```

<p class="callout info">**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.</p>

Tabla con la descripción de cada campo del JSON:

<table border="1" id="bkmrk-clave-descripci%C3%B3n-id" style="border-collapse: collapse; width: 100%;"><colgroup><col style="width: 20%;"></col><col style="width: 80%;"></col></colgroup><thead><tr><th>Clave</th><th>Descripción</th></tr></thead><tbody><tr><td>**id**</td><td>Identificador único de la característica (tipo texto).</td></tr><tr><td>**descripcion**</td><td>Nombre descriptivo de la característica (por ejemplo: "Nº De Habitaciones", "Parqueadero").</td></tr><tr><td>**tipo\_campo**</td><td>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.</td></tr><tr><td>**opciones\_valores**</td><td>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.</td></tr><tr><td>**opciones\_descripciones**</td><td>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"`.</td></tr><tr><td>**orden**</td><td>Posición numérica que indica el orden de presentación de la característica dentro de su grupo.</td></tr><tr><td>**grupo**</td><td>Nombre del grupo al que pertenece la característica (por ejemplo: "Características del Inmueble"). Permite agrupar visualmente las características en un formulario.</td></tr><tr><td>**clase\_inmueble\_id**</td><td>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**.</td></tr><tr><td>**clase\_inmueble**</td><td>Nombre descriptivo de la clase de inmueble (por ejemplo: "Amoblados", "Casa", "Bodega").</td></tr></tbody></table>

#### **4. Seguridad y Posibles Errores**

<p class="callout danger">**¡Tu pase tiene fecha de caducidad!**</p>

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](https://docs.nuby.ai/books/api-nuby-v2/page/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:

```json
{
    "statusCode": 401,
    "error": {
        "type": "SERVER_ERROR",
        "description": "JWT Token expired."
    }
}
```

Otros posibles errores:

<table border="1" id="bkmrk-c%C3%B3digo-http-descripc" style="border-collapse: collapse; width: 100%;"><colgroup><col style="width: 20%;"></col><col style="width: 80%;"></col></colgroup><thead><tr><th>Código HTTP</th><th>Descripción</th></tr></thead><tbody><tr><td>**400**</td><td>Token no enviado o con formato incorrecto. Asegúrate de incluir el encabezado `Authorization: Bearer TU_TOKEN`.</td></tr><tr><td>**401**</td><td>Token expirado o inválido. Solicita uno nuevo a través del servicio de Login.</td></tr><tr><td>**403**</td><td>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}'."`</td></tr></tbody></table>

---

#### **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:

```http
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`:

```json
{
    "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:

<details id="bkmrk-curl-%23-listar-todas-"><summary>cURL</summary>

```bash
# 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"
```

</details><details id="bkmrk-php-%3C%3Fphp-%24instance-"><summary>PHP</summary>

```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);

?>
```

</details><details id="bkmrk-python-import-reques"><summary>Python</summary>

```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}")

```

</details><details id="bkmrk-javascript-%2F%2F-1.-con"><summary>JavaScript</summary>

```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();

```

</details><details id="bkmrk-power-query-m-%28excel"><summary>Power Query M (Excel / Power BI)</summary>

```powerquery
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
```

</details>