API Go

GoSoft · Módulo Realty

API Go

Lectura de contratos de venta de inmuebles y de sus recibos de cobro, pensada para que SAP Business One tome de GoSoft exactamente lo que muestra la ficha del contrato: estado, titular, detalle, pagos y último plan. JSON plano, siempre por unidad de negocio.

Controladores app/Controllers/Api/Go/ Formato JSON · UTF-8 Auth Bearer token Moneda la del contrato Modo sólo lectura

Convenciones

Los cuatro endpoints comparten autenticación, envoltura de error, paginación y el modo de nombrar la unidad de negocio. Conviene leer esto antes que los endpoints.

URL base

El host identifica a la empresa (multi-tenant). Todo cuelga de /api/go/v1.

Producción
https://{empresa}.gosoft.app/api/go/v1/contratos
https://{empresa}.gosoft.app/api/go/v1/recibos

Autenticación

Cada llamada lleva un token Bearer. El token lo emite GoSoft para la cuenta de servicio del sistema externo en esa empresa; es una cadena de 64 caracteres hexadecimales y no vence. Si se filtra, GoSoft lo rota y el anterior deja de servir en el acto.

Cabecera
Authorization: Bearer 3f9c1e0b7a2d4c8e6f5a9b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e
Token por query string

Se acepta también ?token=... en la URL, para pruebas rápidas desde un navegador. No lo uses desde el ERP: queda en el historial y en los logs de acceso. La integración manda siempre la cabecera.

Envoltura de respuesta

A diferencia de la API Multi Pagos, acá el status HTTP es real: 200 es éxito y cualquier otro es error. El éxito devuelve el objeto pedido directamente, sin envoltura. El error trae un codigo estable para ramificar; el mensaje es para humanos y puede cambiar de redacción.

Éxito200
{
  "codigo": 6557,
  "unidad": { ... },
  "estado": { ... }
  // el objeto, tal cual
}
Error4xx
{
  "error": {
    "codigo": "RANGO_EXCEDIDO",
    "mensaje": "El rango no puede superar 31 días; se pidieron 45."
  }
}
Una excepción

El 401 por token ausente o inválido lo emite el filtro de autenticación compartido con la app móvil, y tiene otra forma: {"ok": false, "error": "unauthorized", "message": "..."}. Trátalo por el status HTTP, no por el cuerpo.

La unidad de negocio

Toda consulta lleva ?unidad=. El código es el mininame de la unidad seguido de su id, con guión: VALL1-7. Se aceptan además las variantes VALL17, VALL1 y 7; si el mininame no corresponde al id (VALL1-1) la unidad no existe.

Un contrato pertenece a su unidad

Pedir el contrato 6557 con unidad=TERR1-1 responde no encontrado aunque el contrato exista, porque es de LOS VALLES. Un token no puede pasear por las unidades cambiando el número a mano.

Cabeceras

CabeceraValorNota
AuthorizationBearer <token>Obligatoria en los cuatro endpoints.
Acceptapplication/jsonRecomendada. Todo es GET, no hay cuerpo que enviar.

Paginación (endpoints 02 y 04)

ParámetroDefaultMáximoNota
pagina1Se recorre hasta paginacion.paginas.
por_pagina50200Un valor mayor se recorta a 200 sin error.

Flujo de integración

No hay handshake: con el token y el código de unidad se consulta directo.

PASO 1

Recibir el token

GoSoft crea la cuenta de servicio en la empresa y entrega el token una sola vez.

PASO 2

Conocer las unidades

GoSoft informa los códigos de unidad de la empresa (TERR1-1, VALL1-7, ...).

PASO 3

Consultar

Por código cuando se conoce el contrato o recibo; por período para sincronizar el mes.

PASO 4

Paginar

Recorrer pagina hasta paginas; el orden es estable por fecha e id.


ENDPOINT 01

Un contrato

GET /api/go/v1/contratos/{codigo}?unidad=VALL1-7

Todo lo que muestra la ficha del contrato: estado actual, titular principal, detalle del inmueble, recibos de cobro y último plan de pagos con su cronograma.

Parámetros

CampoDóndeDescripción
codigorutareqCódigo del contrato. Es el mismo número que ve el operador en la ficha.
unidadqueryreqUnidad de negocio a la que pertenece el contrato.

Ejemplo de llamada

cURL
curl "https://demo.gosoft.app/api/go/v1/contratos/6557?unidad=VALL1-7" \
  -H "Authorization: Bearer 3f9c1e0b7a2d4c8e6f5a9b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e"
Respuesta200
{
  "codigo": 6557,
  "unidad": {
    "codigo": "VALL1-7",
    "nombre": "LOS VALLES"
  },
  "estado": {
    "nombre": "Vigente",
    "moneda": "USD",
    "fecha_contrato": "2024-01-30",
    "registrado_en": "2026-02-23 16:19:14"
  },
  "titular": {
    "id": 1661,
    "nombre": "MARIO ANDRES CASTELLANOS REYES",
    "documento": "0501199001234",
    "celular": "99001122",
    "email": "mario.castellanos@ejemplo.hn",
    "direccion": ""
  },
  "detalle": {
    "moneda": "USD",
    "items": [
      {
        "codigo": "BAL27LV",
        "descripcion": "",
        "tipo": "Terreno urbano",
        "ubicacion": "LOS VALLES",
        "manzano": "A",
        "numero": "27",
        "uv": "A27",
        "piso": "0",
        "area_m2": 180,
        "area_varas": 258.17,
        "precio_lista": 46470.6,
        "descuento": 0,
        "precio": 46470.6
      }
    ],
    "precio_total": 46470.6,
    "descuento_total": 0,
    "monto_final": 46470.6
  },
  "pagos": {
    "total": 7218.94,
    "cantidad": 12,
    "anulados": 0,
    "items": [
      {
        "recibo": 6692,
        "numero": "0000",
        "referencia": "586201964",
        "fecha": "2024-01-30",
        "monto": 4683.03,
        "moneda": "USD",
        "monto_local": 116000.06,
        "tc": 24.7703,
        "documento": "CI",
        "glosa": "Contrato 6557 Periodos:  0, Parcial 1",
        "cuenta": {
          "codigo": "01.01.01.002.144",
          "nombre": "BAC - 730398681 HNL - CHEQUES"
        },
        "contrato_nro": 6557,
        "persona": "MARIO ANDRES CASTELLANOS REYES",
        "unidad": {
          "codigo": "VALL1-7",
          "nombre": "LOS VALLES"
        },
        "estado": "Vigente"
      }
      // ... un item por recibo, vigente o anulado
    ]
  },
  "plan": {
    "id": 2200,
    "numero": 1,
    "metodo": "Clásico",
    "estado": "Vigente",
    "moneda": "USD",
    "capital": 41823.54,
    "saldo_inicial": 46470.6,
    "descuento": 0,
    "cuotas": 1,
    "frecuencia": 1,
    "interes_anual": 0,
    "tipo_interes": "Anual",
    "fecha_inicio": "2027-03-02",
    "creado_en": "2026-02-23",
    "cronograma": [
      {
        "periodo": 0,
        "vencimiento": "2026-03-01",
        "cuota": 4647.06,
        "interes": 0,
        "amortizacion": 4647.06,
        "saldo": 41823.54,
        "pagado": 4647.06,
        "descuento": 0,
        "sancion": 0,
        "por_pagar": 0
      },
      {
        "periodo": 1,
        "vencimiento": "2027-03-02",
        "cuota": 41823.54,
        "interes": 0,
        "amortizacion": 41823.54,
        "saldo": 0,
        "pagado": 2571.88,
        "descuento": 0,
        "sancion": 0,
        "por_pagar": 39251.66
      }
    ]
  }
}

Campos de estado

CampoDescripción
nombreEstado actual: Reservado, Vigente, Finalizado, Revertido, Pendiente, Retenido, Devuelto, Pagado, Anulado, Eliminado.
monedaMoneda del contrato. Todos los importes de detalle, pagos.monto y plan están en esta moneda.
fecha_contratoFecha del contrato. Es la que usa el filtro por período del endpoint 02.
registrado_enFecha y hora en que se cargó en el sistema.

Campos de detalle

CampoDescripción
items[]Un item por inmueble vendido. Normalmente uno: un contrato es un terreno.
items[].codigoCódigo del inmueble en el catálogo.
items[].tipo · ubicacionTipo de inmueble y urbanización o edificio que lo contiene.
items[].manzano · numero · uv · pisoUbicación del lote.
items[].area_m2 · area_varasSuperficie en metros cuadrados y en varas cuadradas.
items[].precio_listaPrecio bruto: superficie por precio unitario, según el detalle de construcción.
items[].descuentoDescuento negociado al firmar. Baja el precio del contrato.
items[].precioprecio_lista − descuento.
precio_total · descuento_total · monto_finalSumas de los items. monto_final es el precio del contrato.
items_sin_fichaSólo aparece si es mayor a cero. Líneas del contrato cuyo inmueble ya no existe en el catálogo. Ver reglas de negocio.

Campos de pagos

CampoDescripción
totalSuma de los recibos vigentes, en la moneda del contrato. Los anulados no suman.
cantidadRecibos vigentes.
anuladosRecibos anulados. items trae cantidad + anulados elementos.
items[]Un recibo por elemento, con la misma forma que devuelve el endpoint 03. Ver allí el detalle de cada campo.

Campos de plan

CampoDescripción
id · numeroIdentificador del plan y su número de orden dentro del contrato. Se devuelve siempre el último plan activo.
metodoForma de cálculo: Clásico, Manual_Pure, Personalizado, ...
estadoVigente o Finalizado.
capitalMonto financiado por el plan.
saldo_inicialSaldo del contrato al arrancar el plan.
descuentoDescuento aplicado en la reprogramación. Baja el saldo, no el precio.
cuotas · frecuenciaCantidad de cuotas y periodicidad en meses.
interes_anual · tipo_interesTasa y tipo.
cronograma[]Una fila por cuota. periodo 0 es la cuota inicial o enganche; puede haber más de una fila con periodo 0.
cronograma[].cuota · interes · amortizacionImporte de la cuota y su apertura en interés y capital, según el plan.
cronograma[].saldoSaldo del plan después de esa cuota.
cronograma[].pagado · descuento · sancionLo cobrado contra la cuota, el descuento otorgado al pagar y la mora cobrada.
cronograma[].por_pagarcuota − pagado − descuento, nunca negativo.
Contrato de otra unidad, o inexistente404
{
  "error": {
    "codigo": "CONTRATO_NO_ENCONTRADO",
    "mensaje": "No existe el contrato 6557 en la unidad TERR1-1."
  }
}
Sin unidad400
{
  "error": {
    "codigo": "UNIDAD_REQUERIDA",
    "mensaje": "Falta el parámetro unidad (por ejemplo VALL1-7)."
  }
}
Ojo con el estado

El estado viaja sólo como texto. Los nombres de los estados son configurables por unidad en GoSoft (una empresa puede llamar Apartado a la Reserva), así que conviene mapearlos por tabla y avisar si aparece uno nuevo, en vez de asumir la lista fija.

ENDPOINT 02

Contratos por período

GET /api/go/v1/contratos?unidad=VALL1-7&desde=2026-08-01&hasta=2026-08-31

Contratos de una unidad cuya fecha de contrato cae en el rango. Cada elemento es el objeto completo del endpoint 01.

Parámetros (query string)

CampoTipoDescripción
unidadstringreqUnidad de negocio.
desdeYYYY-MM-DDreqInicio del rango, inclusive.
hastaYYYY-MM-DDreqFin del rango, inclusive. Máximo 31 días contados desde desde.
paginaintopcDefault 1.
por_paginaintopcDefault 50, máximo 200.

Ejemplo de llamada

cURL · agosto, de a 50
curl "https://demo.gosoft.app/api/go/v1/contratos?unidad=VALL1-7&desde=2026-08-01&hasta=2026-08-31&pagina=1" \
  -H "Authorization: Bearer 3f9c1e0b7a2d4c8e6f5a9b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e"
Respuesta200
{
  "unidad": {
    "codigo": "VALL1-7",
    "nombre": "LOS VALLES"
  },
  "desde": "2026-08-01",
  "hasta": "2026-08-31",
  "paginacion": {
    "pagina": 1,
    "por_pagina": 50,
    "total": 49,
    "paginas": 1
  },
  "contratos": [
    {
      "codigo": 10338,
      "unidad": { "codigo": "VALL1-7", "nombre": "LOS VALLES" },
      "estado": { "nombre": "Revertido", "moneda": "USD", "fecha_contrato": "2026-08-01", "registrado_en": "2026-08-01 10:12:44" },
      "titular": { ... },
      "detalle": { ... },
      "pagos": { ... },
      "plan": { ... }
    }
    // ... ordenados por fecha_contrato y código, ascendente
  ]
}
Más de un mes400
{
  "error": {
    "codigo": "RANGO_EXCEDIDO",
    "mensaje": "El rango no puede superar 31 días; se pidieron 45."
  }
}
Sin contratos en el rango200
{
  "unidad": { "codigo": "VALL1-7", "nombre": "LOS VALLES" },
  "desde": "2026-12-01",
  "hasta": "2026-12-31",
  "paginacion": { "pagina": 1, "por_pagina": 50, "total": 0, "paginas": 0 },
  "contratos": []
}
Todos los estados

El período devuelve los contratos en cualquier estado, incluidos revertidos y anulados. Si el ERP sólo quiere los vigentes, filtra por estado.nombre del lado del integrador: así una reversión posterior también se ve al re-sincronizar el mes.

ENDPOINT 03

Un recibo

GET /api/go/v1/recibos/{recibo}?unidad=VALL1-7

Un recibo de cobro suelto, con la misma forma que tiene adentro de pagos.items[] del contrato. Un mapeo sirve para los dos lugares.

Parámetros

CampoDóndeDescripción
reciborutareqNúmero de recibo. Es el recibo de pagos.items[].
unidadqueryreqUnidad del terreno del contrato al que pertenece el recibo. Ver reglas de negocio.

Ejemplo de llamada

cURL
curl "https://demo.gosoft.app/api/go/v1/recibos/10787?unidad=TERR1-1" \
  -H "Authorization: Bearer 3f9c1e0b7a2d4c8e6f5a9b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e"
Recibo vigente200
{
  "recibo": 6700,
  "numero": "0000",
  "referencia": "412400753",
  "fecha": "2024-04-08",
  "monto": 282.4,
  "moneda": "USD",
  "monto_local": 7000.02,
  "tc": 24.7876,
  "documento": "CI",
  "glosa": "Contrato 6557 Periodos:  Parcial 1",
  "cuenta": {
    "codigo": "01.01.01.002.144",
    "nombre": "BAC - 730398681 HNL - CHEQUES"
  },
  "contrato_nro": 6557,
  "persona": "MARIO ANDRES CASTELLANOS REYES",
  "unidad": {
    "codigo": "VALL1-7",
    "nombre": "LOS VALLES"
  },
  "estado": "Vigente"
}
Recibo anulado200
{
  "recibo": 10787,
  "numero": "0000",
  "referencia": "FT26231ZRY5B",
  "fecha": "2026-08-19",
  "monto": 5075,
  "moneda": "USD",
  "monto_local": 133722.7,
  "tc": 26.3493,
  "documento": "CI",
  "glosa": "Contrato 4162 · Periodos: Parcial 1",
  "cuenta": {
    "codigo": "01.01.01.002.179",
    "nombre": "FICOHSA - 200011495809 USD - CHE"
  },
  "contrato_nro": 4162,
  "persona": "CLAUDIA PATRICIA MEJIA ORDOÑEZ",
  "unidad": {
    "codigo": "TERR1-1",
    "nombre": "TERRALTA"
  },
  "estado": "Anulado",
  "anulacion": {
    "fecha": "2026-08-20 18:13:11",
    "por": "ROSA MARIA FLORES PADILLA",
    "motivo": "ANULACION POR TASA DE CAMBIO INCORRECTA"
  }
}

Campos del recibo

CampoDescripción
reciboNúmero del comprobante de ingreso en GoSoft. Es el que aparece en los reportes contables.
numero · referenciaNúmero y referencia del documento de pago (cheque, transferencia, factura del banco).
fechaFecha del cobro. Es la que usa el filtro por período del endpoint 04.
monto · monedaImporte en la moneda del contrato.
monto_local · tcImporte en moneda local del asiento y tipo de cambio aplicado.
documentoTipo de documento: CI comprobante de ingreso, Recibo, Transaccion, ...
glosaConcepto del comprobante. Nombra el contrato y las cuotas cubiertas.
cuentaCuenta contable donde entró el dinero, con su código del plan de cuentas. Es el lado debe del asiento: caja o banco. null si el recibo no tiene asiento de débito.
cuentas[]Sólo aparece si hay más de una. Cobro partido entre varias cuentas, cada una con su monto y monto_local. cuenta queda con la mayor.
contrato_nroCódigo del contrato al que pertenece. Es el codigo del endpoint 01.
personaQuién pagó. Casi siempre es el titular, pero puede ser un tercero.
unidadUnidad de negocio del terreno del contrato.
estadoVigente o Anulado. No hay otros.
anulacionSólo en anulados. Fecha y hora, usuario que anuló y motivo. Alguno puede venir null en recibos muy viejos.
Recibo de otra unidad, o inexistente404
{
  "error": {
    "codigo": "RECIBO_NO_ENCONTRADO",
    "mensaje": "No existe el recibo 5989 en la unidad MARS2-6."
  }
}
Sin token401
{
  "ok": false,
  "error": "unauthorized",
  "message": "Missing token"
}
ENDPOINT 04

Recibos por período

GET /api/go/v1/recibos?unidad=VALL1-7&desde=2026-06-01&hasta=2026-06-30

Recibos de una unidad cuya fecha de cobro cae en el rango. Es la consulta para conciliar el mes: trae vigentes y anulados, salvo que se filtre.

Parámetros (query string)

CampoTipoDescripción
unidadstringreqUnidad de negocio del terreno.
desdeYYYY-MM-DDreqInicio del rango, inclusive.
hastaYYYY-MM-DDreqFin del rango, inclusive. Máximo 31 días.
estadostringopcvigente o anulado. Sin el parámetro salen los dos.
paginaintopcDefault 1.
por_paginaintopcDefault 50, máximo 200.

Ejemplo de llamada

cURL · sólo vigentes de junio
curl "https://demo.gosoft.app/api/go/v1/recibos?unidad=VALL1-7&desde=2026-06-01&hasta=2026-06-30&estado=vigente&por_pagina=200" \
  -H "Authorization: Bearer 3f9c1e0b7a2d4c8e6f5a9b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e"
Respuesta200
{
  "unidad": {
    "codigo": "VALL1-7",
    "nombre": "LOS VALLES"
  },
  "desde": "2026-06-01",
  "hasta": "2026-06-30",
  "estado": "Vigente",
  "paginacion": {
    "pagina": 1,
    "por_pagina": 200,
    "total": 91,
    "paginas": 1
  },
  "recibos": [
    {
      "recibo": 9034,
      "numero": "0000",
      "referencia": "412516204",
      "fecha": "2026-06-01",
      "monto": 165.42,
      "moneda": "USD",
      "monto_local": 4300.05,
      "tc": 25.9945,
      "documento": "CI",
      "glosa": "Contrato 7912 · Periodos: Parcial 4",
      "cuenta": { "codigo": "01.01.01.002.144", "nombre": "BAC - 730398681 HNL - CHEQUES" },
      "contrato_nro": 7912,
      "persona": "ANA LUCIA MARTINEZ PONCE",
      "unidad": { "codigo": "VALL1-7", "nombre": "LOS VALLES" },
      "estado": "Vigente"
    }
    // ... ordenados por fecha y número de recibo, ascendente
  ]
}
estado fuera de la lista400
{
  "error": {
    "codigo": "ESTADO_INVALIDO",
    "mensaje": "estado debe ser vigente o anulado."
  }
}
Fechas al revés400
{
  "error": {
    "codigo": "RANGO_INVERTIDO",
    "mensaje": "La fecha desde no puede ser posterior a hasta."
  }
}
El campo estado de la cabecera

Repite el filtro aplicado: Vigente, Anulado o Todos. Sirve para que una respuesta guardada diga por sí sola qué se pidió.


Tabla de errores

El status HTTP es real. El codigo es estable; el mensaje puede cambiar de redacción.

HTTPcodigoCausa y qué hacer
401unauthorizedToken ausente, con formato inválido, o de una cuenta deshabilitada. Otra envoltura: ver Convenciones. Pedir a GoSoft que verifique la cuenta de servicio.
400UNIDAD_REQUERIDAFalta ?unidad=.
404UNIDAD_NO_ENCONTRADAEl código no corresponde a ninguna unidad activa, o el mininame no coincide con el id.
400CODIGO_INVALIDOEl código de contrato no es un entero positivo.
404CONTRATO_NO_ENCONTRADOEl contrato no existe, o pertenece a otra unidad.
400RECIBO_INVALIDOEl número de recibo no es un entero positivo.
404RECIBO_NO_ENCONTRADOEl recibo no existe, o el terreno de su contrato es de otra unidad.
400RANGO_REQUERIDOFalta desde o hasta.
400FECHA_INVALIDAUna fecha no tiene formato YYYY-MM-DD o no existe en el calendario.
400RANGO_INVERTIDOdesde es posterior a hasta.
400RANGO_EXCEDIDOMás de 31 días. Partir la consulta por mes.
400ESTADO_INVALIDOestado no es vigente ni anulado.
500Fallo inesperado del servidor. Es sólo lectura: reintentar tal cual es seguro.

Reglas de negocio

Decisiones del lado de GoSoft que explican por qué los números son los que son.

El precio del contrato

El precio no se toma del importe guardado en la cabecera del contrato, que en algunos registros históricos está duplicado. Se recalcula igual que la ficha: superficie por precio unitario del detalle de construcción, menos el descuento negociado al firmar. Es la misma fórmula de las auditorías y de los reportes de saldos, así que monto_final coincide con lo que ve el operador en pantalla.

La unidad de un recibo es la de su terreno

Un cobro puede haberse registrado estando parado en otra unidad de negocio, y la unidad que quedó grabada en el comprobante es la equivocada. Por eso unidad del recibo, y el filtro ?unidad= de los endpoints 03 y 04, salen del lote que se vendió y no del comprobante. Es la regla que hace que un recibo aparezca siempre donde está su contrato.

Los anulados se listan, no suman

pagos.total y pagos.cantidad cuentan sólo recibos vigentes; los anulados se listan aparte en anulados y vienen en items[] con su bloque anulacion. Un cobro revertido es información, pero no es plata que entró.

La cuenta contable del recibo

cuenta es el lado debe del asiento del comprobante: la caja o el banco donde entró el dinero, con su código del plan de cuentas. Se conserva también en los recibos anulados, porque la cuenta por la que pasó la plata sigue siendo un dato aunque el cobro se haya revertido. Un recibo tiene una sola cuenta; si alguna vez hay varias, aparecen todas en cuentas[] con su importe.

Claves que aparecen sólo cuando hace falta

ClaveCuándo apareceQué significa
detalle.items_sin_fichaSi es mayor a ceroLíneas del contrato cuyo inmueble ya no existe en el catálogo. La ficha web también las omite, así que monto_final coincide con la pantalla, pero está incompleto: hay que revisar el contrato.
pagos.items[].cuentasSi hay más de una cuentaCobro partido entre caja y banco.
pagos.items[].anulacionSi estado es AnuladoFecha, usuario y motivo de la anulación.

La respuesta normal no trae ninguna de las tres. El mapeo del ERP debe tolerar su ausencia y su presencia.

Rango de un mes

Los endpoints por período aceptan hasta 31 días, contados en días y no en meses de calendario: del 1 al 31 de agosto entra, del 1 de junio al 15 de julio no. El tope existe para que una consulta no barra el histórico entero; para cargar años anteriores se recorre mes a mes.

Recomendaciones de integración

  • Manda el token en la cabecera Authorization, nunca en la URL.
  • Guarda recibo y contrato_nro como llaves: son los números que aparecen en los reportes contables del cliente.
  • Para conciliar un mes, pide los recibos por período sin filtrar estado: así las anulaciones posteriores también se reflejan al re-sincronizar.
  • Mapea estado.nombre del contrato por tabla y avisa si llega un valor nuevo.
  • Trata el 401 por status HTTP; su cuerpo tiene otra forma.
  • Ante un 500 o un timeout, reintenta: la API no escribe nada.