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 · estados—Maestros 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/list—Ejercicios 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