Skip to content

API pública del ERP

iEnTop incluye una API REST pública para que su tienda online, su TPV o cualquier software a medida trabaje directamente con los datos del ERP: clientes y proveedores, direcciones, catálogo y stock, documentos de venta y cobros. Cada llamada ejecuta la misma lógica de negocio que usa el propio ERP — mismas validaciones, mismas relaciones entre datos y mismo ciclo fiscal — por lo que un cliente o una factura creados por la API son indistinguibles de los creados a mano.

La API está incluida en la suscripción, sin coste adicional.

Para quién es esta página

Está pensada para la persona (interna o externa) que va a programar la integración. No se necesita ningún conocimiento del ERP más allá de lo que se explica aquí.

1. Obtención del token

Las credenciales se generan desde el propio ERP, sin tickets de soporte:

📍 SISTEMA › Configuración Empresa › Identidad › sección Acceso API

  1. Pulse Generar token.
  2. Escriba un nombre descriptivo (por ejemplo, "Tienda online" o "TPV mostrador"). Aparecerá en el registro de auditoría de cada operación que haga esa integración.
  3. Elija la caducidad: sin caducidad, 90 días, 180 días o 1 año.
  4. Marque los permisos del token — lectura o escritura por cada área (ver permisos). Conceda solo lo que la integración necesite.
  5. Pulse Generar token y cópielo en ese momento: por seguridad, el token completo no se vuelve a mostrar nunca. Si lo pierde, revóquelo y genere otro.

El token tiene esta forma:

iek_MXwzfDd8MTR8N2E4… (una sola línea, ~120 caracteres)

Trátelo como una contraseña

El token da acceso a los datos de su empresa. No lo comparta por canales inseguros, no lo publique en repositorios de código y guárdelo en la configuración segura de su aplicación. Desde la misma pantalla puede revocarlo en cualquier momento: deja de funcionar en menos de un minuto.

2. Autenticación

Todas las peticiones se autentican con el token en la cabecera Authorization, esquema Bearer:

http
GET /tms/xdata/tenant/terceros/v1/list?text=&offset=0&limit=25&filterTipo=Cliente HTTP/1.1
Host: terceros.xdata.formaticati.com
Authorization: Bearer iek_MXwzfDd8MTR8N2E4…
  • El token identifica a su empresa (no a un usuario) y opera con visibilidad completa del tenant.
  • No hay que renovar sesiones ni hacer login: cada petición viaja autenticada por sí misma.
  • Una petición sin token, con token revocado o caducado recibe 401; una petición a un recurso para el que el token no tiene permiso recibe 403.

3. Permisos (scopes)

Cada token lleva una lista de permisos por área. La escritura incluye siempre la lectura de su misma área.

PermisoConcede
tercerosLectura de clientes/proveedores, sus direcciones, contactos y maestros de pago
terceros:writeAlta y edición de clientes y proveedores (con direcciones embebidas) y contactos
catalogoLectura de productos, precios y stock
catalogo:writeAlta y edición de productos
ventasLectura de documentos, maestros de facturación y cálculo previo
ventas:writeCrear, emitir y convertir documentos; venta TPV; rectificativas
cobrosLectura de vencimientos
cobros:writeRegistro de cobros (liquidar vencimientos)
contabilidadLectura de diario, mayor, balance, PyG, plan de cuentas y ejercicios
contabilidad:writeCreación de asientos (con sus apuntes) y validación

Las direcciones viajan con el tercero

No existe un dominio de direcciones: una dirección solo tiene sentido ligada a su tercero. En el alta se envían embebidas como array de textos y el servidor resuelve país, provincia, población y vía por búsqueda; la lectura es siempre por tercero. Ver 5.2.

4. Convenciones generales

Hosts. Cada dominio funcional se sirve desde su propio host. La base de todas las rutas es https://<host>/tms/xdata:

DominioHost
Terceros, direcciones, geografía, maestros de pagoterceros.xdata.formaticati.com
Facturación, tesorería, venta TPVfacturacion.xdata.formaticati.com
Catálogo y stockcatalogo.xdata.formaticati.com
Contabilidad (asientos, mayor, informes)contafin.xdata.formaticati.com

Formato. Peticiones y respuestas en JSON (Content-Type: application/json). Muchas respuestas de listado envuelven el resultado en un campo value que contiene un JSON serializado — decodifíquelo con su librería JSON habitual.

Parámetros GET. Pase todos los parámetros de consulta del endpoint aunque vayan vacíos (el servidor los exige). Atención a las mayúsculas: Terceros y Facturación usan minúsculas (filter, order_by, offset, limit…) y Catálogo los usa capitalizados (Filter, OrderBy, Offset, Limit).

Identificadores. Los id son enteros de 64 bits. Las altas devuelven el id del registro creado en {"value": <id>}.

5. Endpoints

5.1 Clientes y proveedores — tenant/terceros/v1

MétodoRutaParámetrosDescripción
GETlisttext, offset, limit, filterTipo (Cliente|Proveedor)Listado paginado con búsqueda
GETgetidFicha completa del tercero
GETget-by-cifnifcifnifBúsqueda exacta por NIF — útil para no duplicar antes de crear
GETvalidate-cifnifcifnif, pais (ES)Valida el NIF y avisa si ya existe
GETtiposarea (vacío = todos)Catálogo de tipos/roles; el campo nombre es el valor que espera add-role
POSTclientes/createbody: razon_social, cifnif, email, telefono, movil, direcciones (array, opcional)Alta de cliente en una llamada: crea el tercero con todas sus relaciones, el rol de cliente y sus direcciones embebidas
POSTproveedores/createbody: ídemAlta de proveedor en una llamada (con direcciones embebidas)
POSTcreatebody: ídemAlta del tercero sin rol comercial (se asigna después con add-role)
POSTadd-rolebody: tercero_id, tipo (nombre del tipo, p. ej. Cliente)Asigna un rol a un tercero existente
POSTdetail/savebody: ficha completa (id = 0 para alta)Edición completa del tercero
GETpersonas-contacto/list-by-tercerotercerosIdPersonas de contacto del tercero
POSTpersonas-contacto/create-and-assignbody: datos de la persona + tercerosIdCrea una persona de contacto y la asigna

Maestros de pago — tenant/pagos/v1 (permiso terceros):

MétodoRutaParámetrosDescripción
GETpayment-methods/listonly_activeFormas de pago de la empresa
GETpayment-terms/listonly_activeCondiciones de pago

5.2 Direcciones embebidas en el alta

Las direcciones se envían dentro de clientes/create / proveedores/create, en el campo direcciones (array). Cada elemento es texto plano — no hay que consultar ningún catálogo ni enviar identificadores: el servidor resuelve el país, la comunidad, la provincia, la población y la vía por búsqueda (tolerante a mayúsculas y tildes), compone el texto de la dirección y garantiza una única dirección Principal y una Fiscal por tercero.

json
"direcciones": [{
  "tipo_via": "Calle",          // código ('CL', 'AV'…) o nombre
  "via": "San Juan del Puerto",
  "numero": "19",
  "complemento": "", "bloque": "", "escalera": "",
  "piso": "3", "puerta": "B",
  "cp": "10195",
  "poblacion": "Cáceres",
  "provincia": "Cáceres",
  "region": "Extremadura",      // opcional
  "pais": "ES",                 // código o nombre; vacío = España
  "es_principal": true,
  "es_fiscal": true
}]

Reglas: la primera dirección del tercero queda marcada automáticamente como Principal y Fiscal; los tipos de vía y las calles se crean si no existen; las provincias y poblaciones se buscan en los maestros del ERP — si no hay coincidencia razonable, la dirección se guarda sin ese componente (no se crean duplicados en los catálogos).

Lectura de las direcciones de un tercero:

MétodoRutaParámetrosDescripción
GETtenant/direcciones/v1/by-tercerotercero_idDirecciones del tercero (permiso terceros)

5.3 Catálogo y stock — almacen-svc/v1

MétodoRutaParámetrosDescripción
GETproductsFilter, OrderBy, Offset, LimitListado de productos
GETproducts/{id}Ficha del producto
GETproducts/lookupqAutocompletado por texto
GETpricing/resolve/{id}qty, clienteIdMotor de precios: mejor tarifa para ese cliente y cantidad
GETstock/actualfiltros opcionalesStock físico
GETstock/disponible/{id}Disponible (físico − reservas)
POSTproductsbody: datos del productoAlta de producto
PUTproducts/{id}body: datos del productoEdición de producto

5.4 Documentos de venta — facturacion-svc

MétodoRutaParámetrosDescripción
POSTdocumentos/savebody: cabecera + líneas (+ tipo)Creación transaccional del documento con impuestos y vencimientos. El mismo endpoint crea presupuestos, pedidos, albaranes y facturas según el tipo
POSTdocumentos/cambiar-estadobody: id, estado destinoEmisión fiscal (borrador → validado): numeración de serie, VeriFactu, libro y asiento
POSTdocumentos/convertirbody: id, tipo destinoPresupuesto → pedido → albarán → factura
POSTtpv/emitirbody: venta de mostradorVenta TPV completa en una llamada
POSTtesoreria/crear-rectificativadoc_id, motivo, modalidad, vf_tipoRectificativa (la vía legal para anular una factura emitida)
GETdocumentos/listfilter, order_by, offset, limit, search, grupo, estadoListado de documentos
GETdocumentos/getidDocumento completo
POSTdocumentos/generate-taxesbody: líneasPrevisualización de impuestos y totales, sin guardar nada
POSTdocumentos/generate-vencimientosbody: condicionesPrevisualización de vencimientos
GETconfig/impuestos/listsolo_activosTipos de IVA de la empresa
GETcatalogos/series · tipos-doc · monedas · estadosMaestros necesarios para montar documentos

5.5 Cobros — facturacion-svc/tesoreria

MétodoRutaParámetrosDescripción
GETtesoreria/vencimientoses_cobro=1 + filtrosVencimientos (cartera de cobros)
POSTtesoreria/liquidar-vencimientobody: vencimiento + datos del cobroRegistra el cobro con su asiento. Caso típico: su pasarela de pago confirma un cobro y la integración lo anota en el ERP

5.6 Contabilidad: asientos y apuntes — contabilidad-svc

Para software contable y asesorías: volcar asientos en el ERP y extraer el diario, el mayor y los informes. El alta es transaccional — cabecera y apuntes viajan juntos, y el sistema controla la cuadratura (debe = haber).

MétodoRutaParámetrosDescripción
POSTdiario/asientobody (ver ejemplo)Crea el asiento con sus apuntes. Devuelve {id, numero, cuadrado}
POSTdiario/validarbody: {id}Pasa el asiento de BORRADOR a VALIDADO
GETdiario/listfilter, estado, origen, periodo, fecha_desde, fecha_hasta, solo_descuadrados, orden_campo, orden_dir, offset, limit, filtro_apunteDiario paginado
GETdiario/asientoidAsiento completo con sus apuntes (data.lineas)
GETinformes/mayorcuenta, periodo, fecha_desde, fecha_hastaLibro mayor: apuntes de una cuenta
GETinformes/balance · informes/pyg · informes/sumas-saldos(nivel en sumas-saldos)Informes de situación
GETpgc/listnivel_max, grupo, solo_con_saldoPlan de cuentas
GETpgc/searchq, solo_auxiliares, prefijos, solo_mayores, min_len=0, max_len=0Búsqueda de cuentas
GETpgc/cuentaidFicha de la cuenta
GETejercicios/listEjercicios contables

Ejemplo de alta de asiento:

json
POST contabilidad-svc/diario/asiento
{
  "fecha": "12/07/2026",
  "concepto": "Traspaso de caja a banco",
  "lineas": [
    { "cuenta_codigo": "5720000000", "concepto": "Ingreso en banco", "debe": 100, "haber": 0 },
    { "cuenta_codigo": "5700000000", "concepto": "Salida de caja",   "debe": 0,   "haber": 100 }
  ]
}

Las cuentas se indican por su código (o por cuenta_id); si una cuenta auxiliar de 10 dígitos no existe, se crea automáticamente colgando de su mayor. La fecha va siempre en formato español DD/MM/YYYY. No se pueden eliminar, desvalidar ni sellar asientos por la API, ni cerrar ejercicios: esas operaciones se reservan al ERP.

6. Errores

Las respuestas de error tienen siempre este cuerpo:

json
{ "success": false, "error": "<código>", "message": "<explicación>" }
HTTPerrorSignificado
401invalid_api_tokenToken mal formado, firma inválida o inexistente
401api_token_expiredToken caducado
401api_token_revokedToken revocado desde el ERP
403not_in_public_apiLa ruta no forma parte de la API pública
403insufficient_scopeAl token le falta el permiso indicado en message
429rate_limitedSuperado el límite de peticiones — espere unos segundos y reintente
503api_unavailableIncidencia temporal del servicio; reintente

7. Límites y buenas prácticas

  • Límite de peticiones: 120 por minuto y por token. Al superarlo, 429.
  • Revocación: efectiva en menos de un minuto.
  • Un token por integración: facilita auditar cada aplicación y revocar una sin afectar a las demás.
  • Permisos mínimos: si la integración solo lee stock, no le conceda escrituras.
  • Idempotencia: antes de crear un cliente, consulte get-by-cifnif para no duplicarlo.
  • Sin borrados: la API no permite eliminar registros. La anulación de una factura emitida es la rectificativa, como exige la normativa.
  • Los entornos de demostración rechazan las escrituras (error DEMO_…).

8. Ejemplo completo

Alta de un cliente y consulta de su ficha:

bash
BASE="https://terceros.xdata.formaticati.com/tms/xdata"
TOKEN="iek_…"   # generado en Sistema › Configuración Empresa › Identidad

# ¿Existe ya? (búsqueda exacta por NIF)
curl -s "$BASE/tenant/terceros/v1/get-by-cifnif?cifnif=B12345678" \
  -H "Authorization: Bearer $TOKEN"

# Alta de cliente en una llamada, con su dirección fiscal embebida
# (textos, sin identificadores) → {"value": <id>}
curl -s -X POST "$BASE/tenant/terceros/v1/clientes/create" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{
    "razon_social":"ACME SL","cifnif":"B12345678","email":"admin@acme.es",
    "telefono":"","movil":"",
    "direcciones":[{
      "tipo_via":"Calle","via":"Mayor","numero":"5","cp":"28001",
      "poblacion":"Madrid","provincia":"Madrid","pais":"ES",
      "es_principal":true,"es_fiscal":true
    }]
  }'

# Su ficha y sus direcciones
curl -s "$BASE/tenant/terceros/v1/get?id=1042" \
  -H "Authorization: Bearer $TOKEN"
curl -s "$BASE/tenant/direcciones/v1/by-tercero?tercero_id=1042" \
  -H "Authorization: Bearer $TOKEN"

¿Necesita ayuda con su integración?

Escríbanos a saas@ientop.es y le acompañamos: ejemplos en su lenguaje, revisión del diseño de la integración y resolución de dudas.

El ecosistema español de software de gestión en la nube. Un producto de FORMATICA.FORMATICA«Tecnología punta y máxima seguridad, para que tú solo te ocupes de tu negocio.»FORMATICA · saas@ientop.es