Listar Terceros [BETA]

Funcionalidad en desarrollo y pruebas: este servicio está disponible en el ambiente de pruebas y todavía no debe usarse en producción. El funcionamiento, los campos y los mensajes de error pueden cambiar antes del despliegue definitivo.

Este servicio devuelve una lista paginada de terceros registrados en nuby, con sus datos principales de identificación y contacto. Puedes filtrar por documento exacto, por coincidencia parcial en el nombre y por tipo de documento.

Úsalo para buscar un tercero del que no conoces el identificador interno, para conciliar tus clientes con los de nuby o para construir un buscador en tu propia interfaz.

¿Para qué sirve este servicio?
Los casos de uso más frecuentes de este servicio son:

  • Buscar un tercero del que no conoces el identificador interno, por documento exacto o por coincidencia parcial en el nombre.
  • Conciliar tus clientes con los que ya están en nuby.
  • Construir un buscador en tu propia interfaz, con paginación.
  • Obtener el tercero_id que necesitan los demás servicios de la API.

1. El Endpoint (La dirección web)

Método y dirección
Dato Valor
Método GET
Recurso /third-parties/list
Cuerpo de la petición No se envía cuerpo
GET https://{{instancia}}/service/v2/public/third-parties/list

¿Qué debes colocar en {{instancia}}? La dirección web principal con la que ingresas a tu plataforma, incluyendo la terminación .nuby.app o .arrendasoft.co, sin https:// y sin barras diagonales al final.

Encabezados requeridos
Encabezado Valor
Authorization Bearer <token>, con el token obtenido en el servicio Login.
Permiso requerido (scope)

Este servicio es de solo lectura y exige el permiso catalogs:read en el cliente OAuth. Si el token es válido pero al cliente le falta el permiso, la respuesta es 403 con el código RECURSO_NO_AUTORIZADO.

Si aún no tienes un token, consulta la página Login del libro API nuby V2.

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

Todos los parámetros son opcionales y se envían en la dirección web (query string). Si no envías ninguno, recibes la primera página con los primeros 50 terceros ordenados por documento.

Parámetro Tipo Requerido Valor por defecto Descripción
documento texto No — Busca por documento exacto. Es el filtro más preciso: úsalo cuando ya conoces el documento del tercero.
nombre texto No — Busca una coincidencia parcial en nombre1, nombre2, apellido1 y apellido2. No distingue entre nombres y apellidos.
tipo_doc_id entero No — Filtra por tipo de documento exacto. Debe ser un entero mayor que cero.
page entero No 1 Número de página, empezando en 1.
page_size entero No 50 Cantidad de registros por página. Si envías un valor mayor a 1000, nuby lo ajusta a 1000.

Importante: page y page_size deben ser números positivos. Un valor en cero, negativo o con letras produce 400; no se corrige automáticamente.

Los filtros se combinan. Si envías documento y tipo_doc_id al mismo tiempo, la búsqueda exige que se cumplan ambos.

Ejemplos de dirección
GET /third-parties/list?page=1&page_size=50
GET /third-parties/list?documento=900123456
GET /third-parties/list?nombre=acme&page_size=10
GET /third-parties/list?tipo_doc_id=1&page=2
Validaciones de parámetros

La consulta se valida antes de ejecutarse. Si un parámetro no cumple su regla, la respuesta es 400 VALIDATION_ERROR y no se devuelve ningún tercero:

Parámetro Regla Mensaje 400
page Entero positivo. 0, negativos o texto no son válidos. El parámetro "page" debe ser un número positivo.
page_size Entero positivo. Si supera 1000, nuby lo ajusta a 1000. El parámetro "page_size" debe ser un número positivo.
tipo_doc_id Entero positivo; se compara exactamente contra el tipo de documento. El parámetro "tipo_doc_id" debe ser un número entero positivo.
documento, nombre Texto libre. Se comparan como se describe en la tabla de filtros. No generan 400 por formato.
Cuándo usar cada filtro
Filtro Caso de uso Precisión
documento Buscar un tercero concreto del que ya conoces el documento. Exacta: devuelve el registro con ese documento.
nombre Búsqueda exploratoria cuando no tienes el documento. Parcial sobre nombre1, nombre2, apellido1 y apellido2; puede devolver varios.
tipo_doc_id Segmentar por tipo de documento (por ejemplo, solo NIT). Exacta sobre el identificador del tipo.
documento + tipo_doc_id Confirmar que el documento encontrado es del tipo esperado. Exacta: los filtros se combinan con AND.
page / page_size Recorrer un resultado largo sin traer todo de una vez. No filtra: controla el tamaño y la posición de la página.

3. La Respuesta (¿Qué te entregaremos?)

La respuesta tiene una estructura uniforme para todas las consultas de la API: los datos van en body y la información de paginación en pagination.

{
  "status": 200,
  "message": null,
  "body": [
    {
      "tercero_id": 123,
      "documento": "900123456",
      "tipo_doc_id": 1,
      "tipo_doc": "NIT",
      "nombre_completo": "ACME SAS",
      "email": "cuenta@acme.co",
      "telefono1": "6040000000",
      "direccion1": "CL 1 #2-3",
      "municipio_id": 1,
      "tipo_tercero_id": "1,2"
    }
  ],
  "pagination": {
    "page": 1,
    "page_size": 50,
    "total": 1,
    "total_pages": 1
  },
  "filters_applied": {
    "documento": "900123456"
  }
}
Variantes de respuesta

El listado cambia el contenido de filters_applied y de message según los filtros y las coincidencias. Maneja estos tres casos:

Con filtros
{
  "status": 200,
  "message": null,
  "body": [
    {
      "tercero_id": 123,
      "documento": "900123456",
      "tipo_doc_id": 1,
      "tipo_doc": "NIT",
      "nombre_completo": "ACME SAS",
      "email": "cuenta@acme.co",
      "telefono1": "6040000000",
      "direccion1": "CL 1 #2-3",
      "municipio_id": 1,
      "tipo_tercero_id": "1,2"
    }
  ],
  "pagination": { "page": 1, "page_size": 50, "total": 1, "total_pages": 1 },
  "filters_applied": { "documento": "900123456" }
}
Sin filtros

Sin parámetros, filters_applied es null y recibes la primera página de todos los terceros, ordenados por documento ascendente.

{
  "status": 200,
  "message": null,
  "body": [
    {
      "tercero_id": 123,
      "documento": "900123456",
      "tipo_doc_id": 1,
      "tipo_doc": "NIT",
      "nombre_completo": "ACME SAS",
      "email": "cuenta@acme.co",
      "telefono1": "6040000000",
      "direccion1": "CL 1 #2-3",
      "municipio_id": 1,
      "tipo_tercero_id": "1,2"
    },
    {
      "tercero_id": 124,
      "documento": "901234567",
      "tipo_doc_id": 1,
      "tipo_doc": "NIT",
      "nombre_completo": "INVERSIONES ANDINAS SAS",
      "email": null,
      "telefono1": "6044445555",
      "direccion1": "CR 43A #1-50",
      "municipio_id": 1,
      "tipo_tercero_id": "1"
    }
  ],
  "pagination": { "page": 1, "page_size": 50, "total": 2, "total_pages": 1 },
  "filters_applied": null
}
Lista vacía

No es un error: se responde 200 con body: [] y un mensaje informativo. Si enviaste filtros, filters_applied sigue reflejándolos.

{
  "status": 200,
  "message": "No se encontraron terceros con los filtros aplicados.",
  "body": [],
  "pagination": { "page": 1, "page_size": 50, "total": 0, "total_pages": 0 },
  "filters_applied": { "nombre": "zzz" }
}
Campos de cada tercero en la lista

Importante: la columna “Puede ser null” describe el contrato del endpoint para terceros creados o actualizados por la API. En terceros históricos de nuby algunos campos que hoy son obligatorios pueden estar vacíos o en null; no asumas que un campo marcado “No” siempre trae valor.

Campo Tipo Puede ser null Descripción
tercero_id entero No Identificador interno del tercero. Úsalo para consultar el detalle.
documento texto No Número de documento o NIT.
tipo_doc_id entero No Identificador del tipo de documento.
tipo_doc texto No Nombre del tipo de documento (por ejemplo, NIT).
nombre_completo texto No Nombre unificado: nombres y apellidos separados por espacios, sin duplicar espacios.
email texto Sí Correo electrónico del tercero, si está registrado.
telefono1 texto Sí Teléfono principal, si está registrado.
direccion1 texto Sí Dirección principal, si está registrada.
municipio_id entero No Identificador del municipio. El nombre del municipio se obtiene en el detalle.
tipo_tercero_id texto Sí Tipos del tercero en una sola cadena separada por comas, por ejemplo "1,2". Es null si el tercero no tiene tipos.
Lista vs. detalle
Dato En el listado En el detalle
Nombres y apellidos separados No: solo nombre_completo Sí: nombre1, nombre2, apellido1 y apellido2
Ubicación Solo municipio_id municipio, departamento y pais
Información tributaria No Sí
Tipos del tercero Cadena "1,2" Cadena y arreglo [1, 2]
Información bancaria No Sí
Paginación
Campo Descripción
page Página devuelta.
page_size Cantidad de registros por página efectivamente aplicada.
total Total de terceros que cumplen los filtros.
total_pages Total de páginas disponibles. Cuando no hay resultados, este valor es 0.
filters_applied y message
  • Si no enviaste filtros, filters_applied es null.
  • Si enviaste filtros, filters_applied es un objeto con los filtros usados.
  • Si hay resultados, message es null.
  • Si no hay resultados, message es No se encontraron terceros con los filtros aplicados. y body es una lista vacía [].
Comportamiento de filters_applied y message
Situación filters_applied message
Sin filtros y con resultados null null
Con filtros y con resultados Objeto con los filtros aplicados null
Con filtros y sin resultados Objeto con los filtros aplicados No se encontraron terceros con los filtros aplicados.
Sin filtros y sin resultados null No se encontraron terceros con los filtros aplicados.
Campos del envelope
Campo Contenido Cuándo cambia
status 200 en una lectura exitosa. Los errores usan su propio código HTTP y agregan error_code.
message Texto informativo o null. Deja de ser null cuando no hay coincidencias.
body Arreglo de terceros con los campos del listado. Es [] cuando no hay coincidencias.
pagination Objeto con page, page_size, total y total_pages. total y total_pages pasan a 0 sin resultados.
filters_applied Objeto con los filtros usados, o null. Es null solo cuando no enviaste ningún filtro.

Una lista vacía no es un error. Cuando ningún tercero coincide con los filtros, el servicio responde 200 con body: []. Revisa pagination.total para confirmar que no hay coincidencias.

Orden de los resultados: la lista se ordena por documento ascendente y, cuando hay documentos repetidos, por tercero_id ascendente. El orden es estable entre páginas.

4. Seguridad y Posibles Errores

HTTP error_code Cuándo ocurre y cómo resolverlo
400 VALIDATION_ERROR page o page_size no son números positivos, o tipo_doc_id no es un entero positivo. Corrige el valor y repite la consulta.
401 — No enviaste el encabezado Authorization, o el token no existe o expiró. Vuelve a consumir Login.
403 CONSUMIDOR_NO_AUTENTICADO El token es válido, pero no corresponde a un cliente OAuth habilitado para consumir la API.
403 RECURSO_NO_AUTORIZADO Al cliente OAuth le falta el permiso catalogs:read.
500 INTERNAL_ERROR Fallo interno al consultar. Reintenta; si persiste, contacta a soporte.
Ejemplo de parámetro inválido (400)
{
  "success": false,
  "status": 400,
  "message": "El parámetro \"page\" debe ser un número positivo.",
  "error_code": "VALIDATION_ERROR"
}

5. Ejemplos de integración

cURL
TOKEN="TU_TOKEN_AQUI"
INSTANCIA="tu-inmobiliaria.nuby.app"

# Buscar por documento exacto
curl -G "https://${INSTANCIA}/service/v2/public/third-parties/list" \
  --data-urlencode "documento=900123456" \
  -H "Authorization: Bearer ${TOKEN}"

# Buscar por nombre, página 1 de 10 registros
curl -G "https://${INSTANCIA}/service/v2/public/third-parties/list" \
  --data-urlencode "nombre=acme" \
  --data-urlencode "page=1" \
  --data-urlencode "page_size=10" \
  -H "Authorization: Bearer ${TOKEN}"
PHP
<?php

$instancia = 'tu-inmobiliaria.nuby.app';
$token = 'TU_TOKEN_AQUI';

$query = http_build_query([
    'documento' => '900123456',
    'page' => 1,
    'page_size' => 50,
]);

$url = "https://{$instancia}/service/v2/public/third-parties/list?{$query}";

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Authorization: Bearer {$token}",
]);

$respuesta = curl_exec($ch);
$codigo = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$datos = json_decode($respuesta, true);

echo "HTTP: {$codigo}\n";
echo "Total: " . ($datos['pagination']['total'] ?? 0) . "\n";

foreach ($datos['body'] as $tercero) {
    echo $tercero['documento'] . ' - ' . $tercero['nombre_completo'] . "\n";
}
Python
import requests

instancia = "tu-inmobiliaria.nuby.app"
token = "TU_TOKEN_AQUI"
url = f"https://{instancia}/service/v2/public/third-parties/list"

headers = {
    "Authorization": f"Bearer {token}",
}

pagina = 1
total_paginas = 1

while pagina <= total_paginas:
    respuesta = requests.get(
        url,
        headers=headers,
        params={"nombre": "acme", "page": pagina, "page_size": 50},
        timeout=30,
    )

    if respuesta.status_code != 200:
        print(respuesta.status_code, respuesta.json())
        break

    datos = respuesta.json()
    total_paginas = datos["pagination"]["total_pages"]

    for tercero in datos["body"]:
        print(tercero["documento"], tercero["nombre_completo"])

    pagina += 1
JavaScript (Fetch API)
const instancia = 'tu-inmobiliaria.nuby.app';
const token = 'TU_TOKEN_AQUI';

const params = new URLSearchParams({
  nombre: 'acme',
  page: '1',
  page_size: '10'
});

const url = `https://${instancia}/service/v2/public/third-parties/list?${params}`;

const respuesta = await fetch(url, {
  headers: { 'Authorization': `Bearer ${token}` }
});

const data = await respuesta.json();

if (respuesta.ok) {
  console.log(`Página ${data.pagination.page} de ${data.pagination.total_pages}`);
  data.body.forEach(t => console.log(t.documento, t.nombre_completo));
} else {
  console.error(`${respuesta.status} ${data.error_code}: ${data.message}`);
}
Power Query M (Excel / Power BI)

Power Query consulta una página por vez con Web.Contents. Puedes cambiar nombre por documento o tipo_doc_id en la cadena de la dirección.

let
    // 1. Configura tus datos de acceso
    instancia = "tu-inmobiliaria.nuby.app",
    token = "TU_TOKEN_AQUI",

    // 2. Prepara la dirección con el filtro y la página
    url = "https://" & instancia & "/service/v2/public/third-parties/list?nombre=acme&page=1&page_size=1000",

    // 3. Envía la petición GET
    response = Web.Contents(url, [
        Headers = [
            #"Authorization" = "Bearer " & token
        ]
    ]),

    // 4. Decodifica el envelope
    jsonResponse = Json.Document(response),
    body = jsonResponse[body],
    pagination = jsonResponse[pagination],

    // 5. Convierte el listado en tabla
    tabla = Table.FromList(body, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
    expandido = Table.ExpandRecordColumn(tabla, "Column1",
        {"tercero_id", "documento", "tipo_doc_id", "tipo_doc", "nombre_completo",
         "email", "telefono1", "direccion1", "municipio_id", "tipo_tercero_id"},
        {"TerceroID", "Documento", "TipoDocID", "TipoDoc", "NombreCompleto",
         "Email", "Telefono1", "Direccion1", "MunicipioID", "TipoTerceroID"}),
    tipos = Table.TransformColumnTypes(expandido, {
        {"TerceroID", Int64.Type},
        {"TipoDocID", Int64.Type},
        {"MunicipioID", Int64.Type}
    }),
    totalPaginas = pagination[total_pages]
in
    tipos

6. Buenas prácticas y límites conocidos

  • Para buscar un tercero concreto, usa documento. Es coincidencia exacta y devuelve el registro correcto sin ambigüedad.
  • Usa nombre solo para búsquedas exploratorias. Es coincidencia parcial y puede devolver varios terceros.
  • No pidas page_size=1000 "por si acaso". Pagina con un tamaño razonable y recorre con page.
  • Recorre hasta total_pages y no hasta que una página venga vacía: si el filtro no tiene resultados, total_pages es 0.
  • No uses la lista como detalle. Para nombres y apellidos separados, ubicación completa, información tributaria y arreglo de tipos, consulta la página Buscar Tercero por Código.
  • Guarda el tercero_id que encuentres: evita volver a buscar por documento en cada operación.

Si el tercero que buscas no existe en nuby, puedes crearlo con el servicio Crear o Resolver Tercero.


Revisión #1
Creado el 28 octubre 2026 14:21:50 por Jorge Iván González
Actualizado el 28 octubre 2026 14:23:01 por Jorge Iván González