DrivErp REST API

DrivErp REST API

Web services para las integraciones bajo API REST para el consumo de servicios de DrivErp desde aplicaciones de terceros.

Requests

Las peticiones se realizan a la misma URL base de la instancia del ERP (producción o pruebas) según corresponda — generalmente https://<compania>.driverp.com o dominio propio si cuenta con él. Para realizar pruebas de conexión es necesario solicitar a su consultor funcional o técnico de DrivErp una instancia habilitada para tal fin.

Las peticiones pueden ser tipo POST, GET o PUT según la definición de cada endpoint documentado. El cuerpo de las peticiones es siempre JSON con header Content-Type: application/json.

curl -X GET 'https://<instancia>/integration/api/test' \
  -H 'Content-Type: application/json' \
  -d '{}'

Habilitación por compañía

La mayoría de los endpoints requieren habilitación previa por compañía (indicada en cada endpoint con su bandera api_allow_*). Si el servicio no está habilitado, la respuesta será el código R009. Contacte a su gerente de proyecto de DrivErp para habilitar los servicios que su integración necesita.

Autenticación

El método de autenticación es JWT. Para acceder a los métodos restringidos primero debe autenticarse con el endpoint /integration/api/login enviando su user y api_key. Para obtener su usuario y api_key deberá solicitarla a su consultor funcional o técnico de DrivErp.

Como respuesta obtendrá un token válido por 8 horas, que deberá enviarse en el header X-Access-Token de cada petición protegida.

curl -X POST 'https://<instancia>/integration/api/login' \
  -H 'Content-Type: application/json' \
  -d '{
    "user": "integracion@empresa.com",
    "api_key": "<su-api-key>"
  }'
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
  }
}

Con el token en mano, toda petición protegida se autentica así:

curl -X GET 'https://<instancia>/integration/api/authme' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{}'

Cuando el token expira, cualquier petición protegida responde con un error JSON-RPC de primer nivel (Invalid JWT Token: Signature has expired); basta con autenticarse de nuevo para obtener un token fresco.

Estructura de las respuestas

Toda petición recibida correctamente devuelve un objeto con la estructura JSON-RPC propia del framework: la versión jsonrpc, un id y el result, que contiene la respuesta específica de la petición y es donde debe concentrarse la integración.

Petición exitosa

El result contiene un status_code igual a "00" acompañado del keyword response, que puede ser desde un string hasta una lista de objetos según el endpoint.

{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": "..."
  }
}

A partir de la documentación del método de autenticación, cada endpoint documenta únicamente el contenido del elemento response.

Petición rechazada por validación

Si la petición es rechazada durante la validación de datos, el status_code es "99" y llega acompañado del keyword novelty: un objeto con el código de error interno, su descripción general, y el keyword key con el detalle del error o el campo del JSON que lo generó.

{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "99",
    "novelty": {
      "R001": "Un campo requerido no fue enviado en la peticion",
      "key": "partners"
    }
  }
}

Error interno del ERP

Si se genera un error interno en los procesos del ERP (controles, validaciones de negocio o cualquier error lógico no capturado), la respuesta contiene el item error en lugar de result, con el detalle del error ocasionado durante la ejecución:

{
  "jsonrpc": "2.0",
  "id": null,
  "error": {
    "code": 200,
    "message": "Odoo Server Error",
    "data": {
      "name": "odoo.exceptions.AccessDenied",
      "message": "Invalid JWT Token: Signature has expired",
      "exception_type": "access_denied"
    }
  }
}

Manejo de errores

Además de los códigos HTTP de primer nivel y de los códigos 00/99 de procesamiento de segundo nivel, existen códigos de novedad de tercer nivel que especifican con mejor detalle las razones por las que una petición es rechazada por el ERP.

Cada código llega dentro del objeto novelty junto con el keyword key, que precisa el campo o registro que originó la novedad. La tabla de la sección Códigos de error se genera automáticamente desde el código fuente del módulo, por lo que siempre está actualizada.

Códigos de error

Códigos de novedad devueltos en novelty cuando status_code es 99. Esta tabla se genera automáticamente desde el código.

CódigoDescripción
A001 El usuario o la apiKey no fue encontrada en la petición
A002 Credenciales invalidas
P001 Las credenciales suministradas son incorrectas
R001 Un campo requerido no fue enviado en la peticion
R002 El registro no existe en la base de datos del ERP
R003 El valor suministrado es invalido
R004 Se requiere de una parametrización interna adicional para completar esta operacion
R005 El registro enviado ya existe en la base de datos del ERP
R006 La solicitud de actualizacion para este modelo no es permitido
R007 El campo suministrado esta protegido contra escritura
R008 Excepcion interna de proceso de ERP
R009 El servicio consumido no esta disponible para esta compañia

General

Descargar archivo binario

POST /integration/api/binary/<string:model>/<int:record_id>/<string:field_name>/<string:file_name>
JWT · header X-Access-Token

Descarga el contenido de un campo binario de cualquier modelo del ERP. A diferencia del resto de endpoints, es de tipo http: los parámetros van en los segmentos de la ruta (no en el body JSON) y la respuesta es el archivo binario directamente, sin envelope JSON-RPC, con headers Content-Type: application/octet-stream y Content-Disposition: attachment; filename=<nombre>. El ERP decodifica el base64 almacenado en el campo y entrega los bytes originales del archivo.

El último segmento (file_name) define el nombre del archivo: si coincide con un campo del registro (ej. number en una factura), se usa el valor de ese campo; en caso contrario se usa el texto literal del segmento. Si el registro no existe, el campo no existe o está vacío, responde 404 Not Found.

Parámetros

ParámetroTipoDescripción
model requerido string Segmento de ruta: nombre técnico del modelo Odoo que contiene el campo binario (ej. account.invoice, signature.request.document).
record_id requerido integer Segmento de ruta: ID interno del registro.
field_name requerido string Segmento de ruta: nombre del campo binario (almacenado en base64) cuyo contenido se descarga (ej. ei_pdf, signed_document).
file_name requerido string Segmento de ruta: nombre de un campo del registro cuyo valor se usa como nombre del archivo descargado (ej. number). Si el registro no tiene un campo con ese nombre, el segmento se usa literalmente como nombre de archivo.
Request
curl -X POST 'https://<instancia>/integration/api/binary/account.invoice/5678/ei_pdf/number' \
  -H 'X-Access-Token: <token>' \
  --output factura.pdf

Consultar campos de un modelo

POST /integration/api/fields
JWT · header X-Access-Token

Devuelve el diccionario de campos de un modelo del ERP: nombre técnico (name), etiqueta (field_description), tipo (ttype), texto de ayuda (help), si se almacena en base de datos (store) y, para campos relacionales, el modelo destino (relation). Es el complemento natural de los endpoints genéricos /integration/api/query, /integration/api/create y /integration/api/update: permite conocer qué campos existen y de qué tipo son antes de leerlos o escribirlos.

Si falta model responde R001; si el modelo no existe en el ERP responde R002.

Parámetros

ParámetroTipoDescripción
model requerido string Nombre técnico del modelo Odoo cuyos campos se quieren consultar (ej. res.partner, product.product).
Request
curl -X POST 'https://<instancia>/integration/api/fields' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{"model": "res.partner"}'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {
        "id": 4321,
        "name": "vat",
        "field_description": "NIT",
        "ttype": "char",
        "help": false,
        "store": true,
        "relation": false
      },
      {
        "id": 4322,
        "name": "city_id",
        "field_description": "Ciudad",
        "ttype": "many2one",
        "help": false,
        "store": true,
        "relation": "res.country.city"
      }
    ]
  }
}

Sincronizar firma digital (webhook)

POST /integration/api/signature
Pública

Webhook público que consume el proveedor de firma digital (Viafirma) para notificar al ERP los cambios de estado de un set de firmas. Al recibir la notificación, el ERP localiza la solicitud de firma (signature.request) por su set_code, actualiza el estado global del set y el de cada uno de sus documentos; cuando un documento queda firmado (estado RESPONSED), se descarga y almacena automáticamente el PDF firmado.

Usa autenticación public (no requiere token) porque es el proveedor externo quien invoca la URL como callback de sus procesos de firma; no está pensado para ser consumido directamente por integraciones de terceros. La respuesta exitosa devuelve únicamente status_code 00, sin payload adicional.

Parámetros

ParámetroTipoDescripción
code requerido string Código del set de firmas asignado por el proveedor al crear la solicitud (campo set_code de signature.request). Identifica la solicitud a sincronizar.
status requerido string Estado global del set reportado por el proveedor (ej. WAITING, RESPONSED, REJECTED, EXPIRED).
messages requerido array Lista de documentos del set con su estado individual.
code requerido string Código del documento dentro del set (document_code).
status requerido string Estado del documento. Cuando pasa a RESPONSED el ERP descarga automáticamente el PDF firmado.
Request
curl -X POST 'https://<instancia>/integration/api/signature' \
  -H 'Content-Type: application/json' \
  -d '{
    "code": "8f3a2b1c-set",
    "status": "RESPONSED",
    "messages": [
      {"code": "d41d8cd9-doc", "status": "RESPONSED"}
    ]
  }'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00"
  }
}

Probar conexión

GET /integration/api/test
Sin autenticación

Verifica la conectividad con el servidor del ERP. No requiere autenticación y no recibe parámetros; es el primer paso recomendado al configurar una integración.

Request
curl -X GET 'https://<instancia>/integration/api/test' \
  -H 'Content-Type: application/json' \
  -d '{}'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": "Prueba ejecutada satisfactoriamente desde ip 190.0.0.1"
  }
}

Crear usuarios

POST /integration/api/user
JWT · header X-Access-Token Requiere api_allow_user

Crea un usuario del sistema (res.users) a partir de sus datos de identificación. Si ya existe un tercero (res.partner) con el mismo vat, el usuario se asocia a ese tercero; de lo contrario, el ERP crea primero el tercero como persona natural con facturación electrónica habilitada, componiendo el nombre completo a partir de nombres y apellidos. El login del usuario creado es el número de identificación (vat).

Si el tercero ya tiene un usuario del sistema asociado responde R005 indicando la identificación y el nombre. Requiere habilitación por compañía (política api_allow_user); si el servicio no está habilitado responde R009. Si falta un campo requerido responde R001; si el tipo de documento o la ciudad no existen responde R002; si un valor tiene un tipo inválido responde R003.

Parámetros

ParámetroTipoDescripción
first_name requerido string Primer nombre del usuario.
other_name string Segundo nombre.
first_lastname requerido string Primer apellido.
other_lastname string Segundo apellido.
document_type requerido string Código interno o código DIAN del tipo de documento (ej. 13 = cédula de ciudadanía). Si no existe responde R002.
vat requerido string Número de identificación del usuario. Se usa para buscar o crear el tercero asociado y como login del usuario del sistema.
address requerido string Dirección física del usuario.
city requerido reference res.country.city por code Código DANE de la ciudad (res.country.city, campo code).
email requerido string Correo electrónico principal.
phone string Teléfono de contacto; se registra como teléfono fijo y móvil del tercero.
Request
curl -X POST 'https://<instancia>/integration/api/user' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{
    "first_name": "Andrés",
    "other_name": "Felipe",
    "first_lastname": "Rojas",
    "other_lastname": "Martínez",
    "document_type": "13",
    "vat": "1015432876",
    "address": "Cra 45 # 12-34",
    "city": "05001",
    "email": "andres.rojas@ejemplo.com",
    "phone": "3109876543"
  }'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {
        "id": 87,
        "partner_id": [2456, "Andrés Felipe Rojas Martínez"],
        "name": "Andrés Felipe Rojas Martínez"
      }
    ]
  }
}

Autenticación

Verificar token

GET /integration/api/authme
JWT · header X-Access-Token

Verifica que el token JWT enviado en el header X-Access-Token sea válido y vigente. Útil para diagnosticar problemas de autenticación sin ejecutar operaciones de negocio.

Request
curl -X GET 'https://<instancia>/integration/api/authme' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{}'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": "Token válido para el usuario Integración Empresa"
  }
}

Iniciar sesión (obtener token)

POST /integration/api/login
Sin autenticación

Autentica al usuario de integración y devuelve un token JWT válido por 8 horas. El token debe enviarse en el header X-Access-Token de todas las peticiones protegidas.

Si el usuario o la api_key no se envían, responde A001; si las credenciales no son válidas, responde A002.

Request
curl -X POST 'https://<instancia>/integration/api/login' \
  -H 'Content-Type: application/json' \
  -d '{
    "user": "integracion@empresa.com",
    "api_key": "<su-api-key>"
  }'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
  }
}

Terceros

Crear terceros

POST /integration/api/partner/create
JWT · header X-Access-Token Requiere api_allow_partner

Crea uno o varios terceros (res.partner). Según los flags enviados puede crear también el paciente asociado (vertical salud) y/o el usuario del sistema.

Cuando is_customer es verdadero, el ERP aplica la parametrización comercial definida en la configuración API de la compañía (vendedor, lista de precios, plazo de pago, cuentas contables, obligaciones tributarias). Si falta alguna de esas parametrizaciones, responde R004 indicando el campo faltante.

Parámetros

ParámetroTipoDescripción
partners requerido array Lista de terceros a crear. Cada elemento es un objeto con los campos descritos abajo.
name string Razón social o nombre completo. Para personas naturales puede omitirse si se envían first_name y apellidos: el ERP lo compone.
document_type requerido string Código interno o código DIAN del tipo de documento (ej. 13 = cédula, 31 = NIT).
vat requerido string Número de identificación sin dígito de verificación. Solo dígitos, salvo tipos de documento que soporten alfanuméricos.
address requerido string Dirección física del tercero.
city requerido reference res.country.city por code Código DANE de la ciudad (res.country.city, campo code).
email requerido string Correo electrónico principal.
phone string Teléfono fijo.
mobile string Teléfono móvil.
partner_type requerido string J = persona jurídica, N = persona natural.
Valores: J N
is_patient requerido boolean Crea además el registro de paciente (requiere vertical salud).
Default: False
is_customer requerido boolean Marca el tercero como cliente y aplica la parametrización comercial por defecto de la compañía (lista de precios, plazo de pago, cuentas, etc.).
Default: según configuración de la compañía
is_employee requerido boolean Marca el tercero como empleado.
Default: False
is_user requerido boolean Crea además un usuario del sistema asociado al tercero.
Default: False
first_name string Primer nombre (personas naturales).
other_name string Segundo nombre (personas naturales).
first_lastname string Primer apellido (personas naturales).
other_lastname string Segundo apellido (personas naturales).
skip_created boolean Si es true, los terceros que ya existen (mismo vat) se omiten sin error; si es false, un tercero existente responde R005.
Default: False
Request
curl -X POST 'https://<instancia>/integration/api/partner/create' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{
    "skip_created": true,
    "partners": [
      {
        "document_type": "13",
        "vat": "1020304050",
        "partner_type": "N",
        "first_name": "Laura",
        "first_lastname": "Gómez",
        "address": "Cra 10 # 20-30",
        "city": "11001",
        "email": "laura@ejemplo.com",
        "mobile": "3001234567",
        "is_customer": true,
        "is_patient": false,
        "is_employee": false,
        "is_user": false
      }
    ]
  }'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {"id": 1234, "vat": "1020304050", "name": "Laura Gómez"}
    ]
  }
}

Consultar tercero

POST /integration/api/partner/read
JWT · header X-Access-Token Requiere api_allow_partner_read

Consulta un tercero por su número de identificación y devuelve sus datos básicos: identificación, tipo de documento, nombre, contacto, condición de cliente, lista de precios y ubicación.

Si no existe un tercero con ese vat, responde R002.

Parámetros

ParámetroTipoDescripción
vat requerido reference res.partner por vat Número de identificación del tercero a consultar (res.partner, campo vat).
Request
curl -X POST 'https://<instancia>/integration/api/partner/read' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{"vat": "1020304050"}'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {
        "id": 1234,
        "vat": "1020304050",
        "document_type_id": [1, "Cédula de ciudadanía"],
        "name": "Laura Gómez",
        "email": "laura@ejemplo.com",
        "phone": "3001234567",
        "customer": true,
        "type_partner": "natural",
        "product_pricelist_id": [1, "Lista pública"],
        "street": "Cra 10 # 20-30",
        "city_id": [149, "Bogotá D.C."],
        "state_id": [3, "Bogotá"],
        "country_id": [49, "Colombia"]
      }
    ]
  }
}

Facturación

Consultar procesos asíncronos

POST /integration/api/async/read
JWT · header X-Access-Token Requiere api_allow_invoice_read

Consulta el estado de los procesos de facturación asíncrona encolados con /integration/api/invoice/async. Para los procesos que ya generaron factura, la respuesta incluye además número, estado contable y estado de facturación electrónica.

Parámetros

ParámetroTipoDescripción
asyncs requerido array Lista de ids de procesos asíncronos (los async_id devueltos al encolar facturas).
Request
curl -X POST 'https://<instancia>/integration/api/async/read' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{"asyncs": [91, 92]}'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {
        "async_id": 91,
        "customer_ref": "REF-001",
        "async_state": "done",
        "message": null,
        "process_date": "2026-07-01 10:15:00",
        "transaction_id": "T-881",
        "number": "FE12345",
        "state": "open",
        "ei_state": "accepted",
        "ei_uuid": "cufe-..."
      }
    ]
  }
}

Crear facturas (síncrono)

POST /integration/api/invoice
Alias: /integration/api/invoice/create
JWT · header X-Access-Token Requiere api_allow_invoice

Crea, valida y contabiliza facturas de venta de forma síncrona: la respuesta llega cuando todas las facturas del lote terminaron de procesarse (la acción post-validación — validar, contabilizar, emitir factura electrónica — la define la política api_invoice_validation_action de la compañía). Para lotes grandes use /integration/api/invoice/async.

Es el endpoint más completo de la API: además de la factura puede crear o actualizar el cliente (objeto customer), crear productos (objeto product en la línea), registrar recaudos inmediatos (statements), cruzar anticipos (advances), generar la salida de inventario automática (location + operation_type), aplicar AIU y construir el detalle clínico RIPS para facturación de salud. Cada factura del lote se procesa de forma independiente dentro de un savepoint: las válidas llegan en response y las fallidas en novelty; si al menos una falla, el status_code del lote es 99.

Mecanismos de idempotencia: transaction_id (si ya existe, devuelve la factura original sin duplicar), customer_ref según la política api_invoice_reference_control, y number manual (R005 si se repite).

Dentro de cada elemento de rips pueden enviarse además los arreglos clínicos del anexo técnico RIPS — consultations, procedures, emergencies, hospitalizations, newborns y medicines — con sus campos normativos (modalidad de atención, grupo de servicios, finalidad tecnológica, diagnósticos CIE-10/CIE-11 principal y relacionados, vía de ingreso, MIPRES, tipo y valor del pago moderador, profesional que atiende, etc.). Los campos omitidos toman los valores por defecto del CUPS y del paciente.

Parámetros

ParámetroTipoDescripción
invoices requerido array Lista de facturas a procesar. Cada elemento se procesa de forma independiente con los campos descritos abajo.
partner_vat requerido string Identificación del cliente (res.partner, campo vat). Requerido salvo que se envíe el objeto customer. Si el cliente no existe y la vertical salud está instalada, se intenta crear desde el maestro de pacientes; si no, responde R002.
customer object Alternativa a partner_vat: crea el cliente si no existe o actualiza sus datos de contacto (nunca los legales: nombre, identificación, tipo de documento) si ya existe.
vat requerido string Identificación del cliente.
name requerido string Razón social o nombre completo.
partner_type requerido string N = persona natural, J = jurídica.
Valores: N J
document_type requerido string Código interno o código DIAN del tipo de documento.
address string Dirección (actualiza street si el cliente existe).
city string Código DANE de la ciudad (res.country.city, campo code).
email string Correo electrónico.
phone string Teléfono (se asigna también como móvil al crear).
first_name string Primer nombre (solo creación de persona natural). Aplican también other_name, first_lastname y other_lastname.
journal_code requerido string Código del diario de ventas (account.journal, campo code). Solo tipologías sale, sale_add o sale_return; otro tipo responde R003.
type string Tipo de documento. Para out_refund (nota crédito) son obligatorios causal y refund_invoice.
Valores: out_invoice out_refund
Default: 'out_invoice'
date_invoice date Fecha de la factura (YYYY-MM-DD).
Default: fecha actual
number string Número manual de factura. Si ya existe responde R005.
transaction_id string Identificador de idempotencia. Si ya existe una factura con esta transacción, se devuelve esa factura con el mensaje 'La transaccion X ya existe' sin crear duplicados.
customer_oc string Orden de compra del cliente.
Default: 'NA'
customer_ref string Referencia externa. Según la política api_invoice_reference_control (unique/available), si ya existe una factura con esta referencia se devuelve la existente en lugar de crear otra.
Default: 'NA'
user_vat string Identificación del ejecutivo de ventas (res.users por vat del partner). Si se omite se usa el vendedor del cliente, o el del contrato de la primera línea según la política api_invoice_user_source. El ejecutivo debe tener parametrización analítica (R004).
Default: '00005'
create_uid string Identificación del usuario creador (res.users por vat del partner).
payment_term string Nombre del plazo de pago (account.payment.term). Default: plazo configurado en el cliente.
currency string Código de moneda (res.currency, campo name, ej. USD). Solo para facturas en moneda extranjera.
trm number Tasa de cambio para facturas en moneda extranjera.
comment string Observaciones de la factura.
ref2 string Referencia adicional 2.
ref3 string Referencia adicional 3.
company integer Id de compañía destino. Con valor distinto de 1 activa la reclasificación intercompañía de anticipos (requiere cuentas vinculadas 13/28 en políticas, R004 si faltan).
Default: 1
ei_payment_method array Métodos de pago DIAN para facturación electrónica. Cada código se valida contra los métodos habilitados de la compañía (R003).
Default: ['30']
note_type string Tipo de nota crédito según los tipos habilitados de facturación electrónica. Default '1' cuando se envía refund_invoice.
causal string Causal de devolución (invoice.return.causal, por nombre). Obligatorio para out_refund (R001).
refund_invoice string Número de la factura a acreditar (account.invoice, campo number). Obligatorio para out_refund (R001).
advances array Referencias de asientos de anticipo a cruzar (nombre o ref del account.move). Cada referencia debe existir en la cuenta de anticipos del cliente (R002).
advance_amount number Valor del anticipo a cruzar.
advance_cross boolean Cruza automáticamente los anticipos contra la factura vía diario de cruce (política api_advance_cross_journal, R004 si falta).
Default: según configuración de la compañía
aiu_type string Modalidad AIU. Al enviarlo aplican también tax_aiu_id (código de impuesto), rate_admin, rate_impre y rate_profi (porcentajes de administración, imprevistos y utilidad).
Valores: subtotal base_aiu utility
location string Código de ubicación origen (stock.location). Junto con operation_type y la política api_invoice_generate_picking, genera automáticamente la salida de inventario de los productos almacenables sin trazabilidad.
operation_type string Código del tipo de operación de inventario (stock.picking.type) para el picking automático.
analytic_dist boolean Activa distribución analítica por RIPS (el valor de cada RIPS distribuye el ingreso). También puede forzarse por política de compañía.
type_health string Facturación de salud: mono (un paciente, requiere patient_vat) o multi (paciente por RIPS). Con valor distinto de none son obligatorios date_start y date_stop, y cada línea debe traer sus rips.
Valores: none mono multi
Default: 'none'
patient_vat string Identificación del paciente (obligatorio si type_health = mono).
private boolean Facturación particular: si el paciente no existe se crea automáticamente desde los datos del tercero.
health_segment string Código del segmento de salud (health.partner.segment). Obligatorio si la política api_health_segment_required está activa; define la cuenta por cobrar.
copay number Valor de control: si es distinto de 0, el total de pagos compartidos recibidos en los RIPS (copagos, cuotas, recuperación, anticipos, voluntarios) debe coincidir con este valor (R003).
date_start date Inicio del periodo de atención (obligatorio si type_health ≠ none).
date_stop date Fin del periodo de atención (obligatorio si type_health ≠ none).
validate_qty boolean Exige que la cantidad de RIPS de cada línea coincida con la cantidad facturada (R003).
Default: true
capitation boolean Marca la factura como capitación. capitation_invoice permite asociar la factura de capitación origen (debe ser de capitación, R003).
service_order_number string Número de orden de servicio asociada.
health_advance_type string Tratamiento del anticipo en salud.
Valores: recaudo reporte
health_accreditation_type string Tipo de acreditación en salud.
Valores: pos snum
copayment_advance string Nombre del asiento de copago anticipado a cruzar. Incompatible con copayment_receipts (R003).
lines requerido array Líneas de la factura (R001 si está vacío).
product_ref requerido string Referencia interna del producto (product.product, campo default_code). Requerido salvo que se envíe el objeto product.
product object Alternativa a product_ref: si el producto existe (por default_code) se usa; si no, se crea. Campos: name*, default_code*, type_tax* (Gravado/Excluido/Exento — Gravado exige tax_iva), sale_ok, purchase_ok, asset_ok, product_type (product/consu/service), tracking, lst_price, barcode, category, line_analytic, uom (código EI, default 94), manufacturer y health_cups_code (homologación CUPS en salud). Categoría y línea analítica caen a las políticas api_product_* de la compañía (R004 si faltan).
quantity requerido integer Cantidad facturada.
price_unit requerido number Precio unitario antes de impuestos.
discount number Porcentaje de descuento de la línea.
description string Descripción de la línea. Default: nombre del producto (en salud, antecedido por el código CUPS).
uom_code string Código EI de la unidad de medida (uom.uom, campo ei_code; 'U' equivale a '94'). Default: UdM del producto.
contract string Número de contrato del cliente. Si no existe, el ERP lo crea con la parametrización comercial de la compañía; si se omite, usa (o crea) el contrato por defecto del cliente.
analytic string Código del centro analítico de la línea (account.analytic). Default: analítica del ejecutivo de ventas.
model string Modelo de contrato para homologación analítica (res.contract.model, por nombre). Con uen y sucursal resuelve la analítica vía account.analytic.homologation (R004 si no hay homologación).
uen string UEN para homologación analítica (res.contract.uen, por nombre).
sucursal string Código de sucursal analítica para homologación (account.analytic.sucursal).
analytic_location_id string Sede/ubicación analítica usada en la búsqueda de homologación.
taxes array Códigos de impuestos de venta (account.tax, campo code) para forzar el mapeo manual de la línea. Si se omite, aplican los impuestos configurados en el producto.
rips array Detalle RIPS por unidad facturada (obligatorio si type_health ≠ none; debe haber un RIPS por unidad salvo validate_qty=false).
cups requerido string Código CUPS del servicio (health.cups). Acepta códigos internos homologados vía health.cups.homologation.
patient_vat requerido string Identificación del paciente de la atención. Con private=true el paciente se crea si no existe; de lo contrario R002.
type_user string Tipo de usuario RIPS (selection health.rips).
Default: '01'
type_payment string Modalidad de pago (01 a 04).
Default: '01'
type_plan string Tipo de plan/cobertura (02 a 17).
Default: '01'
sucursal string Código analítico de la atención (requerido si analytic_dist).
date date Fecha de la atención.
amount number Valor del servicio (con analytic_dist=true y amount=0 toma el price_unit).
copay number Copago recibido. Aplican también health_fee (cuota moderadora), health_recovery (cuota de recuperación), health_advance (anticipo) y health_voluntary (pago voluntario).
health_num_contract string Número de contrato de salud. En modalidad mono puede resolverse automáticamente desde las líneas de pago del contrato.
health_num_authorization string Número de autorización. Aplican también health_num_policy, health_noinvoice_contract(+_reason), service_order y cpm_invoice (factura del pago moderador).
statements array Recaudos inmediatos contra la factura: por cada elemento se crea y contabiliza un pago. El valor no puede exceder el saldo de la factura (R003).
journal_code requerido string Código del diario de pago, tipo banco o efectivo (R002 si no existe).
amount requerido number Valor del recaudo (> 0).
ref_payment string Referencia del pago.
taxes array Impuestos globales manuales de la factura (adicionales a los de línea).
tax_code requerido string Código EI del impuesto de venta (account.tax, campo ei_code).
tax_base requerido number Base gravable.
tax_amount requerido number Valor del impuesto.
copayment_receipts array Copagos recibidos en la factura (solo salud, cuando la factura incluye el producto de copago). El total debe coincidir con el total de la factura (R003). Incompatible con copayment_advance.
payment_journal requerido string Código del diario de pago (debe tener cuenta débito configurada, R004).
payment_ref requerido string Referencia del recibo.
payment_amount requerido number Valor recibido.
Request
curl -X POST 'https://<instancia>/integration/api/invoice/create' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{
    "invoices": [
      {
        "partner_vat": "900123456",
        "journal_code": "FE",
        "date_invoice": "2026-07-01",
        "transaction_id": "TX-2026-000123",
        "customer_oc": "OC-4455",
        "payment_term": "30 días",
        "lines": [
          {
            "product_ref": "PROD-001",
            "quantity": 2,
            "price_unit": 50000,
            "discount": 0,
            "contract": "CT-001",
            "taxes": ["IVA19"]
          }
        ],
        "statements": [
          {"journal_code": "CAJA", "amount": 119000, "ref_payment": "REC-889"}
        ]
      }
    ]
  }'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {
        "id": 5678,
        "number": "FE12345",
        "transaction_id": "TX-2026-000123",
        "name": "OC-4455"
      }
    ]
  }
}

Crear facturas (asíncrono)

POST /integration/api/invoice/async
JWT · header X-Access-Token Requiere api_allow_invoice

Encola facturas para procesamiento asíncrono por colas de trabajo y responde de inmediato con los identificadores de los procesos encolados. Es la opción recomendada para lotes grandes o integraciones de alto volumen. El payload de cada factura es idéntico al del endpoint síncrono Crear facturas; internamente cada proceso encolado ejecuta el mismo motor de validación y contabilización.

El estado de cada proceso se consulta con /integration/api/async/read usando los async_id devueltos. Si la compañía tiene configurado un callback de facturación asíncrona, el ERP notificará el resultado a la URL parametrizada.

Parámetros

ParámetroTipoDescripción
invoices requerido array Lista de facturas a encolar. Cada factura usa exactamente la misma estructura del endpoint síncrono Crear facturas (cabecera, customer, lines con product/rips, statements, taxes, advances, copagos, etc.) — consulte esa referencia para el detalle completo de campos.
Request
curl -X POST 'https://<instancia>/integration/api/invoice/async' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{
    "invoices": [
      {
        "customer": "1020304050",
        "date_invoice": "2026-07-01",
        "lines": [
          {"product": "PROD-001", "quantity": 2, "price_unit": 50000}
        ]
      }
    ]
  }'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {"async_id": 91, "customer_ref": "REF-001", "async_state": "pending"}
    ]
  }
}

Obtener PDF de facturas

POST /integration/api/invoice/pdf
JWT · header X-Access-Token Requiere api_allow_invoice_read

Devuelve la representación gráfica (PDF) de las facturas indicadas, codificada en base64. Si alguna factura no puede generar su representación gráfica, responde R008 con el detalle.

Parámetros

ParámetroTipoDescripción
numbers requerido array Lista de números de factura (campo number).
Request
curl -X POST 'https://<instancia>/integration/api/invoice/pdf' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{"numbers": ["FE12345"]}'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {"id": 5678, "xml": "JVBERi0xLjQKJcOkw7zDtsOf..."}
    ]
  }
}

Consultar facturas

POST /integration/api/invoice/read
JWT · header X-Access-Token Requiere api_allow_invoice_read

Consulta facturas por número y devuelve su estado contable, estado de facturación electrónica y CUFE. Opcionalmente adjunta el XML y/o el PDF de la factura electrónica en base64.

Parámetros

ParámetroTipoDescripción
numbers requerido array Lista de números de factura a consultar (campo number).
xml boolean Si es true, incluye el XML de facturación electrónica en base64.
pdf boolean Si es true, incluye la representación gráfica (PDF) en base64.
Request
curl -X POST 'https://<instancia>/integration/api/invoice/read' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{"numbers": ["FE12345"], "xml": false, "pdf": false}'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {
        "id": 5678,
        "number": "FE12345",
        "state": "open",
        "ei_state": "accepted",
        "ei_uuid": "cufe-..."
      }
    ]
  }
}

Enviar factura por correo

POST /integration/api/invoice/send
JWT · header X-Access-Token Requiere api_allow_invoice_read

Envía por correo electrónico la factura indicada con sus adjuntos de facturación electrónica (XML y PDF), usando la plantilla de correo de facturación electrónica del ERP.

Parámetros

ParámetroTipoDescripción
number requerido string Número de la factura a enviar (campo number).
email requerido string Correo electrónico del destinatario.
Request
curl -X POST 'https://<instancia>/integration/api/invoice/send' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{"number": "FE12345", "email": "cliente@ejemplo.com"}'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": "Email sent for invoice FE12345"
  }
}

Obtener XML de facturas

POST /integration/api/invoice/xml
JWT · header X-Access-Token Requiere api_allow_invoice_read

Devuelve el XML de facturación electrónica de las facturas indicadas, codificado en base64.

Parámetros

ParámetroTipoDescripción
numbers requerido array Lista de números de factura (campo number).
Request
curl -X POST 'https://<instancia>/integration/api/invoice/xml' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{"numbers": ["FE12345"]}'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {"id": 5678, "xml": "PD94bWwgdmVyc2lvbj0iMS4wIi..."}
    ]
  }
}

Recaudos

Registrar recaudo de factura

POST /integration/api/account-payment
Alias: /integration/api/payment
JWT · header X-Access-Token Requiere api_allow_account_payment

Registra y contabiliza un recaudo (account.payment de tipo entrada) aplicado a una única factura de venta abierta. El pago se concilia contra la línea por cobrar de la factura; si esta no genera exactamente una línea de pago, la operación falla con R008. Con la política de compañía api_allow_bank_to_identified activa (y el módulo de conciliación bancaria instalado), el recaudo contabilizado crea además la partida bancaria por identificar con la referencia enviada en ref.

El endpoint es idempotente por transaction_id (máximo 12 caracteres): un valor repetido en un recaudo no cancelado responde R005. Validaciones de negocio con código R003: la factura debe ser de venta y estar abierta, la fecha debe estar dentro del mes en curso y no ser futura, el monto debe ser positivo sin superar el saldo de la factura y la moneda debe ser COP.

Para aplicar discount la compañía debe tener parametrizadas las políticas de descuentos financieros (api_payment_account_disc_id, api_payment_analytic_disc_id y api_payment_line_analytic_disc_id) y el cliente debe tener franjas de descuento configuradas (responde R004 si falta parametrización). El porcentaje debe coincidir con una franja vigente según los días de la factura — contados desde la fecha de la factura o hacia su vencimiento, según la política discount_receivable_date de la compañía — y no se admiten descuentos sobre facturas parcialmente conciliadas (R003). Consulte las franjas disponibles con /integration/api/partner/discount.

Requiere habilitación por compañía (responde R009 si no está activo). R001/R002 aplican para campos faltantes o registros inexistentes y R008 para errores internos durante la generación del recaudo.

Parámetros

ParámetroTipoDescripción
partner_vat requerido string Identificación del cliente que realiza el pago (res.partner, campo vat).
invoice requerido string Número de la factura de venta a recaudar (account.invoice, campo move_name). Debe ser una factura de venta en estado abierto (R003 en caso contrario).
journal_code requerido string Código del diario de banco o caja por donde ingresa el recaudo (account.journal, campo code).
date requerido date Fecha de consignación bancaria en formato YYYY-MM-DD. Debe pertenecer al mes en curso y no puede ser posterior a la fecha actual (R003).
ref string Referencia bancaria del recaudo. Con la política api_allow_bank_to_identified activa se registra como ref1 de la partida bancaria por identificar.
amount requerido number Valor recaudado en COP. Debe ser mayor que 0 y no puede superar el saldo pendiente de la factura (R003).
currency requerido string Nombre de la moneda (res.currency, campo name). Actualmente solo se acepta COP (R003 con cualquier otra).
trm_amount number Tasa representativa del mercado. Reservado para operaciones multimoneda; mientras solo se acepte COP el valor se fija internamente en 1.0.
discount number Porcentaje de descuento financiero por pronto pago a aplicar. Debe corresponder a una franja de descuento parametrizada para el cliente y cumplir su ventana de días.
transaction_id requerido string Identificador único de la transacción en el sistema externo, máximo 12 caracteres (R003 si es más largo). Un valor ya usado en un recaudo no cancelado responde R005.
Request
curl -X POST 'https://<instancia>/integration/api/account-payment' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{
    "partner_vat": "900123456",
    "invoice": "FE12345",
    "journal_code": "BB01",
    "date": "2026-07-06",
    "ref": "CONSIG-778899",
    "amount": 2380000,
    "currency": "COP",
    "discount": 0,
    "transaction_id": "TX20260706"
  }'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {"id": 4521, "name": "REC/2026/00789"}
    ]
  }
}

Registrar recaudo multifactura

POST /integration/api/multi-payment
JWT · header X-Access-Token Requiere api_allow_account_payment

Registra y publica un recaudo aplicado a varias facturas del mismo cliente en una sola operación. El body lleva los datos de cabecera y una lista lines; cada línea referencia una factura por su número (invoice) con el valor a aplicar (amount) y admite una lista opcional discounts con ajustes o descuentos por concepto de conciliación (concept, name, amount).

Cada factura se localiza como apunte por cobrar contabilizado, sin conciliar, con saldo pendiente y fecha menor o igual a date (responde R003 si no se encuentra). El valor de cada línea no puede superar el saldo de su factura ni diferir en moneda, y el total de cabecera debe cuadrar: suma de líneas menos suma de descuentos (R003 en caso contrario). Cuando la cuenta del concepto del descuento exige contabilidad analítica, o la compañía la requiere en pagos, esta se toma de la primera línea de la factura (R003 si la factura no se encuentra para extraerla).

El endpoint es idempotente por transaction_id: un valor ya registrado devuelve el recaudo existente con la marca The transaction_id already exists sin crear duplicados. Si la política de compañía api_allow_bank_to_identified está activa (y el módulo de conciliación bancaria instalado), el recaudo contabilizado genera además la partida bancaria por identificar con las referencias ref1/ref2/ref3.

Requiere habilitación por compañía (responde R009 si no está activo). R001/R002 aplican para campos faltantes o registros inexistentes y R008 para errores internos durante la generación del recaudo.

Parámetros

ParámetroTipoDescripción
partner_vat requerido string Identificación del cliente que realiza el pago (res.partner, campo vat).
journal_code requerido string Código del diario de banco o caja por donde ingresa el recaudo (account.journal, campo code).
date requerido date Fecha bancaria del recaudo en formato YYYY-MM-DD. Solo se aplican facturas con fecha contable menor o igual a este valor.
total requerido number Valor total del recaudo. Debe ser igual a la suma de los amount de las líneas menos la suma de los descuentos (R003 si no cuadra).
ref1 string Referencia 1 del recaudo; se registra como comunicación del pago.
ref2 string Referencia 2 del recaudo.
ref3 string Referencia 3 del recaudo.
currency string Nombre de la moneda (res.currency, campo name). Si se omite se usa la moneda de la compañía. Debe coincidir con la moneda de cada factura (R003).
transaction_id requerido string Identificador único de la transacción externa. Si ya existe un recaudo con el mismo valor, se devuelve ese recaudo con la marca 'The transaction_id already exists' sin crear duplicados (idempotencia).
lines requerido array Facturas a recaudar (responde R003 si viene vacía).
invoice requerido string Número de la factura a recaudar (name del apunte por cobrar). Debe estar contabilizada, sin conciliar, con saldo pendiente, a nombre del cliente y con fecha menor o igual a date (R003 si no se encuentra).
amount requerido number Valor a aplicar a la factura: mayor que 0 y no superior a su saldo pendiente (R003).
discounts array Descuentos o ajustes a registrar contra la factura de la línea, por concepto de conciliación.
concept requerido string Nombre del concepto de conciliación (account.payment.reconcile.concept) que define la cuenta contable del ajuste.
name requerido string Descripción de la línea de descuento.
amount requerido number Valor del ajuste o descuento.
Request
curl -X POST 'https://<instancia>/integration/api/multi-payment' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{
    "partner_vat": "900123456",
    "journal_code": "BB01",
    "date": "2026-07-06",
    "total": 4950000,
    "ref1": "CONSIG-778899",
    "ref2": "Pago facturas junio",
    "ref3": "900123456",
    "currency": "COP",
    "transaction_id": "TXM-2026-0706",
    "lines": [
      {"invoice": "FE12345", "amount": 2500000},
      {
        "invoice": "FE12360",
        "amount": 2500000,
        "discounts": [
          {
            "concept": "Pronto pago",
            "name": "Descuento pronto pago FE12360",
            "amount": 50000
          }
        ]
      }
    ]
  }'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {"id": 4522, "name": "REC/2026/00790", "state": "posted"}
    ]
  }
}

Recaudar orden de venta

POST /integration/api/order-payment
JWT · header X-Access-Token Requiere api_allow_sale

Ejecuta el ciclo completo de cierre de una orden de venta pagada: entrega el picking pendiente asociado, genera y valida la factura, crea el recaudo en el diario indicado, lo contabiliza y marca la orden como pagada (payment_integration_check). Al final intenta emitir la factura electrónica; si el envío a la DIAN falla, la operación contable ya quedó en firme y el campo message de la respuesta lo indica. Requiere habilitación por compañía (api_allow_sale); si no está activa responde R009.

La operación es transaccional: cualquier falla durante la entrega, la facturación o el recaudo revierte todo el proceso y responde R008. Otros códigos de error: R005 si la orden ya fue pagada por este canal, no está en estado "Pedido de venta" o ya tiene facturas asociadas; R003 si la fecha es anterior a hoy o el monto no coincide con el total de la orden; R002 si no existe un picking pendiente para la orden o hay más de uno; R001 si falta un campo requerido.

Parámetros

ParámetroTipoDescripción
order_name requerido reference sale.order por name Número de la orden de venta a recaudar (sale.order, campo name).
date requerido date (YYYY-MM-DD) Fecha del pago en formato YYYY-MM-DD. No puede ser anterior a la fecha actual.
Default: False
amount requerido number Monto pagado. Debe coincidir exactamente (2 decimales) con el total de la orden.
Default: 0
journal_code requerido reference account.journal por code Código del diario contable de recaudo (account.journal, campo code).
payment_ref string Referencia o memo del pago (número de transacción de la pasarela, consignación, etc.).
Request
curl -X POST 'https://<instancia>/integration/api/order-payment' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{
    "order_name": "SO2026-00187",
    "date": "2026-03-12",
    "amount": 297500.0,
    "journal_code": "BCO01",
    "payment_ref": "PSE-88412973"
  }'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "status": "success",
    "message": "Proceso de pago realizado con éxito -> Orden: SO2026-00187 -> Factura: FE12345 -> Recaudo: RC/2026/0451 y se generó la factura electrónica correctamente."
  }
}

Consultar descuentos financieros de cliente

POST /integration/api/partner/discount
JWT · header X-Access-Token Requiere api_allow_account_payment

Consulta la política de descuentos financieros por pronto pago configurada para un cliente. Devuelve el indicador apply_discount (si el cliente tiene activa la novedad de descuento en ventas) y la lista discount_ids con las franjas parametrizadas: porcentaje de descuento y ventana de días (from / to) en la que aplica. Es la consulta previa recomendada antes de enviar el parámetro discount en /integration/api/account-payment.

Requiere que el servicio de recaudos esté habilitado para la compañía (comparte la habilitación de account-payment; responde R009 si no está activo). Responde R001 si no se envía partner_vat y R002 si el cliente no existe.

Parámetros

ParámetroTipoDescripción
partner_vat requerido reference res.partner por vat Identificación (vat) del cliente a consultar.
Request
curl -X POST 'https://<instancia>/integration/api/partner/discount' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{"partner_vat": "900123456"}'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": {
      "apply_discount": true,
      "discount_ids": [
        {"discount": 3.0, "from": 0, "to": 10},
        {"discount": 1.5, "from": 11, "to": 20}
      ]
    }
  }
}

Consultar configuración de archivo bancario

POST /integration/api/payment-file-config/detail
JWT · header X-Access-Token

Devuelve el detalle completo de una configuración de archivo plano bancario de la central DrivErp, identificada por config_id o por bank_code (es obligatorio enviar al menos uno). Además de los datos generales (banco, código BIC, tipo de archivo, delimitador y codificación), retorna la estructura del archivo en tres secciones ordenadas por secuencia — header_lines, body_lines y footer_lines — donde cada campo define su contenido, tipo de contenido (plain, context o python), tamaño, ajuste a tamaño, alineación y carácter de relleno; y la lista variables con las variables auxiliares de la configuración.

No requiere habilitación por compañía; basta con un token válido. Códigos de error propios de este endpoint: E002 si no se envía ni config_id ni bank_code, E003 si no existe un banco con el BIC indicado, E004 si la configuración no se encuentra y E005 ante un error interno.

Parámetros

ParámetroTipoDescripción
config_id integer ID de la configuración a consultar. Alternativo a bank_code; tiene prioridad si se envían ambos.
bank_code string Código BIC del banco (res.bank, campo bic) cuya configuración se quiere consultar. Alternativo a config_id.
Request
curl -X POST 'https://<instancia>/integration/api/payment-file-config/detail' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{"bank_code": "COLOCOBM"}'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": {
      "id": 1,
      "bank_id": [123, "Bancolombia"],
      "bank_code": "COLOCOBM",
      "file_type": "txt",
      "delimiter": "coma",
      "encoding": "utf-8",
      "header_lines": [
        {
          "sequence": 1,
          "name": "Tipo de registro",
          "content": "1",
          "content_type": "plain",
          "size": 1,
          "adjust": true,
          "align": "left",
          "fill": "0"
        }
      ],
      "body_lines": [
        {
          "sequence": 1,
          "name": "Cuenta beneficiario",
          "content": "payment.partner_bank_account",
          "content_type": "context",
          "size": 17,
          "adjust": true,
          "align": "right",
          "fill": "0"
        }
      ],
      "footer_lines": [
        {
          "sequence": 1,
          "name": "Total registros",
          "content": "total_records",
          "content_type": "python",
          "size": 6,
          "adjust": true,
          "align": "right",
          "fill": "0"
        }
      ],
      "variables": [
        {
          "sequence": 1,
          "name": "total_records",
          "content": "len(payments)"
        }
      ]
    }
  }
}

Listar configuraciones de archivos bancarios

POST /integration/api/payment-file-config/list
JWT · header X-Access-Token

Devuelve la lista de configuraciones de archivos planos bancarios (payment.file.config) disponibles en la instancia central de DrivErp. Está pensado para que las instancias cliente sincronicen la parametrización de dispersión de pagos sin configurarla manualmente. Por cada configuración retorna el banco asociado (par [id, nombre]), su código BIC (bank_code), el tipo de archivo (txt o csv), el delimitador (coma o punto_coma) y la codificación (utf-8 o ANSI). Para obtener la estructura completa de un archivo use /integration/api/payment-file-config/detail.

No recibe parámetros en el body (enviar un objeto vacío) y no requiere habilitación por compañía; basta con un token válido. Un error interno al consultar las configuraciones responde código R009 con el detalle.

Request
curl -X POST 'https://<instancia>/integration/api/payment-file-config/list' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{}'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {
        "id": 1,
        "bank_id": [123, "Bancolombia"],
        "bank_code": "COLOCOBM",
        "file_type": "txt",
        "delimiter": "coma",
        "encoding": "utf-8"
      },
      {
        "id": 2,
        "bank_id": [124, "Banco de Bogotá"],
        "bank_code": "BBOGCOBB",
        "file_type": "csv",
        "delimiter": "punto_coma",
        "encoding": "ANSI"
      }
    ]
  }
}

Anticipos

Crear anticipos

POST /integration/api/advance
Alias: /integration/api/advance/create
JWT · header X-Access-Token Requiere api_allow_advance

Registra anticipos de clientes como asientos contables publicados. El body recibe una lista advances (responde R001 si viene vacía) y crea un asiento por cada elemento: debita la cuenta por defecto del diario de banco/efectivo y acredita la cuenta del cliente — la cuenta por cobrar o la cuenta de anticipos, según la política api_advance_account_source de la compañía. Un amount negativo invierte el sentido del asiento, lo que permite registrar la aplicación o devolución del anticipo.

El endpoint es idempotente por transaction_id: si algún elemento del lote trae un valor ya registrado, la respuesta devuelve el asiento existente con la marca The transaction_id already exists y ningún asiento del lote se crea (los demás elementos deben reenviarse con transacciones nuevas).

Requiere habilitación por compañía (responde R009 si no está activo). Otros códigos de error: R002 si el cliente, el diario o el usuario no existen; R003 si el diario no es de tipo banco/efectivo o maneja moneda extranjera; R004 si el diario no tiene cuenta débito por defecto o el cliente no tiene parametrizada la cuenta crédito correspondiente; y R008 si falla la creación o contabilización del asiento.

Parámetros

ParámetroTipoDescripción
advances requerido array Lista de anticipos a registrar (responde R001 si viene vacía). Se crea y contabiliza un asiento contable por cada elemento.
partner_vat requerido string Identificación del cliente que entrega el anticipo (res.partner, campo vat).
journal_code requerido string Código del diario por donde ingresa el dinero (account.journal, campo code). Solo se admiten diarios de tipo banco o efectivo y sin moneda extranjera (R003).
number requerido string Número o consecutivo del anticipo en el sistema externo. Se registra como nombre de las líneas y ref del asiento.
reference string Referencia adicional del anticipo (ref1 de las líneas).
ref2 string Referencia 2 de las líneas. Si se omite se usa la identificación del cliente.
transaction_id string Identificador único de la transacción externa. Si ya existe un asiento con el mismo valor, se devuelve ese asiento con la marca 'The transaction_id already exists' y no se crea ningún asiento del lote (idempotencia).
date date Fecha del anticipo en formato YYYY-MM-DD.
Default: fecha actual
ref_close string Referencia de cierre o cruce del anticipo (ref3 de las líneas).
notes string Notas del asiento; se registran en la narración.
create_uid string Identificación del usuario del ERP al que se atribuye la creación del asiento (res.users, por vat de su tercero asociado).
amount requerido number Valor del anticipo en COP. Un valor negativo invierte el sentido contable del asiento (intercambia débito y crédito).
Request
curl -X POST 'https://<instancia>/integration/api/advance' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{
    "advances": [
      {
        "partner_vat": "1020304050",
        "journal_code": "CJ01",
        "number": "ANT-2026-0455",
        "reference": "Anticipo pedido PED-8891",
        "ref2": "1020304050",
        "transaction_id": "TX-ANT-0455",
        "date": "2026-07-06",
        "ref_close": "PED-8891",
        "notes": "Anticipo 50% del pedido PED-8891",
        "create_uid": "79856231",
        "amount": 850000
      }
    ]
  }'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {"id": 99012, "name": "CJ01/2026/00455", "ref": "ANT-2026-0455"}
    ]
  }
}

Reversar anticipos

POST /integration/api/advance/reverse
JWT · header X-Access-Token Requiere api_allow_advance_reverse

Registra la reversión de anticipos de clientes creados con /integration/api/advance. El body recibe una lista advances (responde R001 si viene vacía) y genera un asiento contable publicado por cada elemento: debita la cuenta por defecto del diario y acredita la cuenta del cliente — la cuenta por cobrar o la cuenta de anticipos, según la política api_advance_account_source de la compañía. Las líneas del asiento conservan el número del anticipo como nombre y la identificación del cliente como referencia 2, de modo que la reversión quede cruzada con el anticipo original.

A diferencia de la creación de anticipos, este endpoint no valida el tipo del diario ni maneja transaction_id, por lo que reenvíos de la misma petición generan asientos adicionales. Requiere habilitación por compañía (responde R009 si no está activo). Otros códigos de error: R001 si falta un campo requerido, R002 si el cliente o el diario no existen, R004 si el cliente no tiene parametrizada la cuenta correspondiente y R008 si falla la creación o contabilización del asiento.

Parámetros

ParámetroTipoDescripción
advances requerido array Lista de reversiones a registrar (responde R001 si viene vacía). Se crea y contabiliza un asiento contable por cada elemento.
partner_vat requerido string Identificación del cliente del anticipo a reversar (res.partner, campo vat).
journal_code requerido string Código del diario con el que se registró el anticipo (account.journal, campo code). Su cuenta débito por defecto se usa en el asiento de reversión.
number requerido string Número del anticipo a reversar. Se registra como nombre de las líneas y ref del asiento.
reference requerido string Referencia de la reversión (ref1 de las líneas).
date date Fecha del asiento de reversión en formato YYYY-MM-DD. Se usa también como fecha de vencimiento de las líneas.
Default: fecha actual
ref_close string Referencia de cierre o cruce (ref3 de las líneas).
notes string Notas del asiento; se registran en la narración.
amount requerido number Valor a reversar en COP.
Request
curl -X POST 'https://<instancia>/integration/api/advance/reverse' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{
    "advances": [
      {
        "partner_vat": "1020304050",
        "journal_code": "CJ01",
        "number": "ANT-2026-0455",
        "reference": "Reversión anticipo ANT-2026-0455",
        "date": "2026-07-07",
        "ref_close": "PED-8891",
        "notes": "Reversión por cancelación del pedido PED-8891",
        "amount": 850000
      }
    ]
  }'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {"id": 99044, "name": "CJ01/2026/00466", "ref": "ANT-2026-0455"}
    ]
  }
}

Cartera

Consultar cartera

POST /integration/api/ar
JWT · header X-Access-Token Requiere api_allow_account_receivable

Consulta la cartera (cuentas por cobrar) de un tercero a partir de sus apuntes contables publicados en cuentas de tipo por cobrar. Los apuntes se agrupan por documento: cada elemento de la respuesta incluye el número del documento (invoice), el ID de la factura asociada (invoice_id), la fecha de vencimiento (exp_date), el detalle de saldos por cuenta contable (accounts, con account, code y residual) y el saldo total pendiente (total_residual, suma de los saldos por cuenta). Requiere habilitación por compañía: si el servicio no está activo responde R009.

Un partner_vat inexistente responde R002; invoices con un tipo distinto a lista responde R003. Los documentos con saldo en cero se incluyen salvo que se envíe ignore_zero en true.

Parámetros

ParámetroTipoDescripción
partner_vat requerido reference res.partner por vat Identificación del tercero cuya cartera se consulta (res.partner, campo vat).
invoices array Lista de números de documento para filtrar la consulta (nombre del apunte contable, ej. números de factura). Si se omite, se retorna toda la cartera del tercero.
ignore_zero boolean Si es true, excluye los apuntes con saldo pendiente en 0 (documentos ya pagados). Por defecto false.
Default: False
Request
curl -X POST 'https://<instancia>/integration/api/ar' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{
    "partner_vat": "900123456",
    "invoices": ["FE12345"],
    "ignore_zero": true
  }'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {
        "invoice": "FE12345",
        "invoice_id": 5678,
        "total_residual": 1190000.0,
        "exp_date": "2026-04-15",
        "accounts": [
          {
            "account": "Clientes Nacionales",
            "code": "13050501",
            "residual": 1190000.0
          }
        ]
      }
    ]
  }
}

Consultar cartera detallada

POST /integration/api/ar-detailed
JWT · header X-Access-Token Requiere api_allow_account_receivable_detailed

Consulta la cartera de un tercero con el detalle de cada factura y el cálculo del descuento financiero por pronto pago. Por cada apunte contable publicado en cuentas por cobrar asociado a una factura, la respuesta incluye número y ID de la factura, fechas de emisión y vencimiento, subtotal, impuestos y total, el saldo pendiente (total_residual) y los campos de descuento: discount_percent, discount_value y total_inc_discount (saldo a pagar aplicando el descuento). Requiere habilitación por compañía: si el servicio no está activo responde R009.

El descuento se toma de los acuerdos de descuento financiero del tercero según los días transcurridos: dependiendo de la política de la compañía se cuentan desde la fecha de la factura o los días restantes hasta el vencimiento, buscando el rango de días aplicable en el acuerdo. Solo aplica sobre facturas sin abonos parciales (saldo igual al total); si la factura ya tiene pagos parciales o el descuento supera el saldo, los tres campos de descuento retornan 0. Un partner_vat inexistente responde R002 e invoices con un tipo distinto a lista responde R003.

Parámetros

ParámetroTipoDescripción
partner_vat requerido reference res.partner por vat Identificación del tercero cuya cartera se consulta (res.partner, campo vat).
invoices array Lista de números de documento para filtrar la consulta (nombre del apunte contable, ej. números de factura). Si se omite, se retorna toda la cartera del tercero.
ignore_zero boolean Si es true, excluye los apuntes con saldo pendiente en 0 (documentos ya pagados). Por defecto false.
Default: False
Request
curl -X POST 'https://<instancia>/integration/api/ar-detailed' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{
    "partner_vat": "900123456",
    "invoices": ["FE12345"],
    "ignore_zero": true
  }'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {
        "invoice": "FE12345",
        "invoice_id": 5678,
        "date": "2026-03-15",
        "date_due": "2026-04-15",
        "amount_subtotal": 1000000.0,
        "amount_tax": 190000.0,
        "amount_total": 1190000.0,
        "discount_percent": 2.0,
        "discount_value": 20000.0,
        "total_residual": 1190000.0,
        "total_inc_discount": 1170000.0
      }
    ]
  }
}

Contabilidad

Crear asientos contables

POST /integration/api/account-move
Alias: /integration/api/account-move/create
JWT · header X-Access-Token Requiere api_allow_account_move

Crea y publica uno o varios asientos contables. El body recibe una lista moves; cada asiento lleva sus datos de cabecera (journal_code, date, ref, transaction_id) y una lista lines con las líneas contables. Los asientos quedan contabilizados de inmediato, omitiendo las validaciones de bloqueo estándar del ERP.

La contabilidad analítica (contract, uep, analytic) solo es exigida en líneas cuya cuenta sea de resultado (clase distinta de Activo, Pasivo o Patrimonio); en cuentas de balance estos campos se ignoran. Si la cuenta contable de la línea está marcada como cuenta de banco/efectivo, la fecha de consignación de la línea se fija automáticamente con la fecha del asiento.

El endpoint es idempotente por transaction_id: si algún asiento del lote trae un valor ya registrado, la respuesta devuelve el asiento existente con la marca The transaction_id already exists y ningún asiento del lote se crea (los demás elementos deben reenviarse con transacciones nuevas).

Requiere habilitación por compañía (responde R009 si no está activo). Otros códigos de error: R001 si moves viene vacío o falta un campo requerido, R002 si un registro relacionado no existe (diario, tercero, cuenta, contrato, analítica), R003 para valores inválidos o cuentas de tipo vista, y R008 si falla la creación o contabilización en el ERP.

Parámetros

ParámetroTipoDescripción
moves requerido array Lista de asientos contables a crear. Todos los asientos del lote se crean y contabilizan en una sola operación (responde R001 si viene vacía).
journal_code requerido string Código del diario contable (account.journal, campo code) donde se registra el asiento.
date date Fecha del asiento en formato YYYY-MM-DD.
Default: fecha actual
ref string Referencia libre del asiento.
transaction_id string Identificador único de la transacción en el sistema externo. Si ya existe un asiento con el mismo valor, se devuelve ese asiento con la marca 'The transaction_id already exists' y no se crea ningún asiento del lote (idempotencia).
lines requerido array Líneas contables del asiento. El asiento debe quedar balanceado (débitos = créditos).
partner_vat requerido string Identificación del tercero de la línea (res.partner, campo vat).
name requerido string Descripción de la línea del asiento.
ref1 string Referencia adicional 1 de la línea.
ref2 string Referencia adicional 2 de la línea.
ref3 string Referencia adicional 3 de la línea.
account requerido string Código de la cuenta contable (account.account, campo code). No puede ser una cuenta de tipo vista (R003).
debit number Valor débito de la línea.
Default: 0
credit number Valor crédito de la línea.
Default: 0
currency string Código de la moneda de la línea (res.currency, campo code). Enviar solo para líneas en moneda extranjera.
contract string Número del contrato (res.contract, campo number). Obligatorio cuando la cuenta de la línea es de resultado (clase distinta de Activo, Pasivo o Patrimonio).
uep string Nombre de la línea analítica / UEP (product.category.analytic, campo name). Obligatoria para cuentas de resultado.
analytic string Código de la cuenta analítica (account.analytic, campo code). Obligatoria para cuentas de resultado.
Request
curl -X POST 'https://<instancia>/integration/api/account-move' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{
    "moves": [
      {
        "journal_code": "CB01",
        "date": "2026-03-15",
        "ref": "Honorarios marzo 2026",
        "transaction_id": "TX-2026-0315",
        "lines": [
          {
            "partner_vat": "900123456",
            "name": "Honorarios asesoría contable",
            "ref1": "FACT-PROV-1102",
            "ref2": "900123456",
            "account": "51101501",
            "debit": 1500000,
            "credit": 0,
            "contract": "CT-2026-001",
            "uep": "Administrativa",
            "analytic": "GA01"
          },
          {
            "partner_vat": "900123456",
            "name": "Honorarios asesoría contable",
            "ref1": "FACT-PROV-1102",
            "account": "23352501",
            "debit": 0,
            "credit": 1500000
          }
        ]
      }
    ]
  }'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {"id": 98765, "name": "CB01/2026/00123", "ref": "Honorarios marzo 2026"}
    ]
  }
}

Cancelar asientos contables

POST /integration/api/account-move/cancel
JWT · header X-Access-Token Requiere api_allow_account_move_cancel

Cancela asientos contables identificados por su referencia (ref) o por su nombre (name). Todos los asientos que coincidan con la búsqueda pasan a estado cancelado, omitiendo las validaciones de bloqueo estándar del ERP. La respuesta lista los asientos afectados con su estado final; si ninguna referencia coincide, devuelve una lista vacía sin error.

Requiere habilitación por compañía (responde R009 si no está activo). Otros códigos de error: R001 si moves no se envía y R003 si el valor recibido no es una lista.

Parámetros

ParámetroTipoDescripción
moves requerido array Lista de referencias de los asientos a cancelar. Cada valor se compara contra el campo ref del asiento; también se acepta el nombre del asiento (name).
Request
curl -X POST 'https://<instancia>/integration/api/account-move/cancel' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{"moves": ["Honorarios marzo 2026", "ANT-2026-0455"]}'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {
        "id": 98765,
        "name": "CB01/2026/00123",
        "ref": "Honorarios marzo 2026",
        "state": "cancel"
      }
    ]
  }
}

Crear cuentas analíticas

POST /integration/api/analytic/create
JWT · header X-Access-Token Requiere api_allow_analytic

Crea una cuenta analítica (account.analytic, subcentro de costo) asociada a una categoría y a una sucursal analítica existentes. La cuenta creada queda disponible para ser referenciada por código en los demás endpoints que reciben el parámetro analytic (asientos, inventario, etc.).

Requiere habilitación por compañía (responde R009 si no está activo). Otros códigos de error: R001 si falta un campo requerido, R002 si la categoría o la sucursal no existen, R003 si analytic_type no es uno de los valores permitidos y R008 si falla la creación en el ERP.

Parámetros

ParámetroTipoDescripción
name requerido string Nombre de la cuenta analítica (subcentro de costo).
code requerido string Código de la cuenta analítica.
analytic_type requerido string Tipo de subcentro de costo. Valores permitidos: expense_a (gasto administrativo, 51), expense_s (gasto de venta, 52), expense_no (gasto no operacional, 53) y cost (costo, 62).
category requerido reference account.category.analytic por code Código de la categoría analítica a la que pertenece (account.category.analytic, campo code).
sucursal requerido reference account.analytic.sucursal por code Código de la sucursal analítica (account.analytic.sucursal, campo code).
Request
curl -X POST 'https://<instancia>/integration/api/analytic/create' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{
    "name": "Gastos Administración Bogotá",
    "code": "GA01",
    "analytic_type": "expense_a",
    "category": "ADM",
    "sucursal": "BOG"
  }'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {"id": 321, "name": "Gastos Administración Bogotá", "code": "GA01"}
    ]
  }
}

Consultar diarios contables

POST /integration/api/journal/read
JWT · header X-Access-Token Requiere api_allow_journal_read

Consulta los diarios contables de la compañía filtrando por tipo y, opcionalmente, por código. Por cada diario devuelve el nombre, el código, el tipo y las cuentas débito y crédito por defecto (como pares [id, nombre]). Es útil para descubrir los valores válidos de journal_code que exigen los endpoints de asientos, recaudos y anticipos.

Requiere habilitación por compañía (responde R009 si no está activo). Otros códigos de error: R001 si no se envía type y R002 si la búsqueda no arroja resultados.

Parámetros

ParámetroTipoDescripción
type requerido string Tipo de diario a consultar. Los más usados en integraciones: sale (factura de venta), sale_return (nota crédito venta), purchase (factura de compra), bank (bancos), cash (efectivo), cross (cruce de cuentas) y general.
Valores: sale sale_add sale_return sale_advance sale_income purchase purchase_return purchase_add purchase_advance cross bank cash stock close open close_account general
code string Código del diario para restringir la consulta a un diario específico.
Request
curl -X POST 'https://<instancia>/integration/api/journal/read' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{"type": "bank", "code": "BB01"}'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {
        "id": 12,
        "name": "Banco de Bogotá Cta 032456789",
        "code": "BB01",
        "type": "bank",
        "default_debit_account_id": [452, "11100501 Banco de Bogotá"],
        "default_credit_account_id": [452, "11100501 Banco de Bogotá"]
      }
    ]
  }
}

Inventario

Crear ajustes de inventario

POST /integration/api/inventory
JWT · header X-Access-Token Requiere api_allow_inventory

Crea un ajuste de inventario (stock.inventory) y lo procesa completo en una sola llamada: inicia el conteo, recalcula las cantidades teóricas, aprueba y valida el ajuste, dejando las existencias de la ubicación en las cantidades enviadas. Las líneas de conteo se envían en el array lines, cada una con product_ref y quantity. Todo el proceso corre dentro de una misma transacción: si algún paso falla, no queda ningún registro creado y se responde R008 con el detalle de la excepción. Requiere habilitación por compañía: si el servicio no está activo responde R009.

El campo transaction_id hace la operación idempotente: si ya existe un ajuste con ese identificador, se retorna con status_code 00 y el atributo adicional error: "The transaction_id already exists". Un contrato inexistente responde R002; parámetros faltantes o con formato inválido responden R001 o R003.

Parámetros

ParámetroTipoDescripción
ref requerido string Referencia o documento soporte del ajuste de inventario.
transaction_id requerido string Identificador único de la transacción en el sistema externo. Llave de idempotencia: si ya existe un ajuste con el mismo valor, se retorna ese ajuste sin crear uno nuevo.
transaction_type requerido string Código del tipo de transacción de inventario (inventory.transactions.types, campo code). Determina la contrapartida contable del ajuste. R002 si no existe.
location requerido string Código de la ubicación a ajustar (stock.location, campo code). R002 si no existe.
filter string Alcance del ajuste: none (toda la ubicación), partial (solo los productos enviados en lines), product, category, lot o lot_change. Un valor fuera de la lista responde R003.
Valores: none partial product category lot lot_change
Default: 'partial'
contract requerido string Número del contrato asociado al tercero de la compañía (res.contract). Si no existe responde R002.
analytic requerido string Código de la cuenta analítica del ajuste (account.analytic, campo code). R002 si no existe.
lines array Líneas de conteo físico. Con filter partial son los únicos productos que se ajustan; si se omite, el ajuste se crea sin conteos enviados.
product_ref requerido string Referencia interna del producto (product.product, campo default_code). R002 si no existe.
quantity requerido number Cantidad física contada; el ajuste lleva las existencias del producto en la ubicación a este valor.
Request
curl -X POST 'https://<instancia>/integration/api/inventory' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{
    "ref": "CONTEO-FISICO-2026-03",
    "transaction_id": "INV-2026-000112",
    "transaction_type": "AJU",
    "location": "BOD01",
    "filter": "partial",
    "contract": "CT-2026-001",
    "analytic": "110101",
    "lines": [
      {"product_ref": "MED001", "quantity": 95},
      {"product_ref": "MED002", "quantity": 40}
    ]
  }'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {
        "id": 341,
        "name": "INV/00341",
        "state": "done",
        "transaction_id": "INV-2026-000112"
      }
    ]
  }
}

Crear ubicaciones de inventario

POST /integration/api/location/create
JWT · header X-Access-Token Requiere api_allow_location

Crea una ubicación de inventario (stock.location). El campo code es la llave con la que el resto de endpoints de la API (stock, picking, inventory) referencian la ubicación, por lo que debe ser único: un código repetido responde R005. Para ubicaciones de uso interno es obligatorio indicar el almacén (warehouse); si falta responde R001. Requiere habilitación por compañía: si el servicio no está activo responde R009.

Un type fuera de la lista de usos válidos responde R003, y un parent o warehouse inexistente responde R002. Errores internos en la creación responden R008 con el detalle de la excepción.

Parámetros

ParámetroTipoDescripción
name requerido string Nombre visible de la ubicación.
parent reference stock.location por code Código de la ubicación padre (stock.location, campo code). Define la jerarquía de la nueva ubicación.
type requerido string Uso de la ubicación: supplier, view, internal, customer, inventory, procurement, production o asset.
warehouse reference stock.warehouse por code Código del almacén al que pertenece la ubicación (stock.warehouse, campo code). Obligatorio cuando type es internal (responde R001 si falta).
code requerido string Código único de la ubicación. Es el identificador que usan los demás endpoints de inventario; si ya existe una ubicación con ese código responde R005.
Request
curl -X POST 'https://<instancia>/integration/api/location/create' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{
    "name": "Bodega Principal - Estante A1",
    "parent": "BOD01",
    "type": "internal",
    "warehouse": "WH01",
    "code": "BOD01-A1"
  }'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {
        "id": 87,
        "name": "Bodega Principal - Estante A1",
        "code": "BOD01-A1"
      }
    ]
  }
}

Crear transferencias de inventario

POST /integration/api/picking
Alias: /integration/api/picking/create
JWT · header X-Access-Token Requiere api_allow_picking

Crea una transferencia de inventario (stock.picking) con sus líneas de movimiento, la confirma y la reserva. Si la compañía tiene activada la autovalidación de transferencias, la operación queda validada (done) en la misma llamada. Las líneas de producto se envían en el array products (obligatorio, responde R001 si está vacío). El endpoint requiere habilitación por compañía: si el servicio no está activo responde R009.

La cuenta analítica se resuelve en este orden: homologación analítica por model + uen + sucursal + analytic_location_id (cuando los módulos de homologación están instalados; combinación no encontrada responde R004), código enviado en analytic, o cuenta analítica de abastecimiento de la ubicación origen. En instalaciones con la extensión Cruz Roja (extended_cruzroja) la homologación es obligatoria para las operaciones que exigen analítica y, si el tercero no tiene contrato, se crea automáticamente a partir de model y uen. Si la compañía valida la fecha de la transacción, una fecha distinta a la actual (o fuera de los días de tolerancia) responde R003. Con assert_stock activo se verifican existencias disponibles del producto (y lote) en la ubicación origen; inventario insuficiente responde R008. Parametrizaciones faltantes (ubicaciones por defecto, UEP del producto, dirección de entrega del cliente en despachos outgoing) responden R004.

El campo transaction_id hace la operación idempotente: si ya existe una transferencia con ese identificador, se retorna con status_code 00 y el atributo adicional error: "The transaction_id already exists".

Parámetros

ParámetroTipoDescripción
picking_type requerido string Código del tipo de operación (stock.picking.type, campo picking_code). Determina las ubicaciones por defecto y si la operación exige analítica (procurement, return_procurement, outgoing, return_outgoing). R002 si no existe.
partner_vat requerido string Identificación del tercero asociado a la transferencia (res.partner, campo vat). R002 si no existe.
date date Fecha de la transferencia en formato YYYY-MM-DD. Sujeta a la validación de fecha configurada por compañía (R003 si difiere de la fecha actual o excede los días de tolerancia).
Default: fecha actual
origin requerido string Documento origen de la transferencia (remisión, pedido o referencia externa).
transaction_id string Identificador único de la transacción en el sistema externo. Llave de idempotencia: si ya existe una transferencia con el mismo valor, se retorna esa transferencia sin crear una nueva.
force_lot boolean Si es true, el lote es obligatorio en cada línea de producto; una línea sin lote responde R001.
Default: false
user_vat requerido string Identificación del usuario del ERP que registra la operación (res.users, vat del tercero asociado). R002 si no existe.
location_code string Código de la ubicación origen (stock.location, campo code). Si se omite, se usa la ubicación origen por defecto del tipo de operación (R004 si tampoco está configurada). Si se envía y no existe responde R002.
location_dest_code string Código de la ubicación destino (stock.location, campo code). Si se omite, se usa la ubicación destino por defecto del tipo de operación (R004 si tampoco está configurada). Si se envía y no existe responde R002.
contract string Número del contrato del cliente (res.contract). Si no se encuentra, se toma el primer contrato asociado al tercero. Del contrato se toman el modelo y la UEN de la transferencia y de sus líneas.
assert_stock boolean Si es true, valida existencias disponibles del producto (y lote) en la ubicación origen antes de crear la transferencia; inventario insuficiente responde R008. Solo aplica cuando la ubicación origen es de uso interno.
Default: true
note string Nota u observación interna de la transferencia.
model string Nombre de la modalidad del contrato (res.contract.model). Junto con uen y sucursal activa la homologación analítica cuando los módulos de homologación están instalados: los tres se validan contra sus catálogos (R002 si no existen) y la combinación debe existir en la tabla de homologación (R004 si no se encuentra).
uen string Nombre de la UEN (unidad estratégica de negocio, res.contract.uen) para la homologación analítica.
sucursal string Código de la sucursal analítica (account.analytic.sucursal) para la homologación analítica.
analytic_location_id string Código de ubicación analítica; cuarto criterio de búsqueda en la tabla de homologación analítica.
analytic string Código de la cuenta analítica (account.analytic, campo code). Si no se envía y la operación exige analítica, se toma la cuenta analítica de abastecimiento de la ubicación origen (R004 si no está configurada).
products requerido array Líneas de movimiento de la transferencia (responde R001 si se omite o está vacío).
default_code requerido string Referencia interna del producto (product.product, campo default_code). R002 si no existe. El producto debe tener UEP / línea analítica configurada (R004 si falta).
qty requerido number Cantidad a transferir; se registra como cantidad demandada y cantidad hecha del movimiento.
name string Descripción de la línea de movimiento. Si se omite, se usa el nombre del producto.
uom string Código DIAN de la unidad de medida (uom.uom, campo ei_code). Si se omite, se usa la unidad del producto (R004 si el producto no tiene unidad configurada).
lot string Nombre del lote del producto. Debe existir para el producto indicado (R002 si no existe). Obligatorio cuando force_lot es true (R001 si falta).
Request
curl -X POST 'https://<instancia>/integration/api/picking' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{
    "picking_type": "outgoing",
    "partner_vat": "900123456",
    "date": "2026-03-15",
    "origin": "REM-4521",
    "transaction_id": "WMS-2026-000451",
    "force_lot": true,
    "user_vat": "1020304050",
    "location_code": "BOD01",
    "contract": "CT-2026-001",
    "assert_stock": true,
    "note": "Despacho pedido cliente",
    "products": [
      {
        "default_code": "MED001",
        "qty": 10,
        "uom": "94",
        "lot": "L2026-045"
      }
    ]
  }'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {
        "id": 8912,
        "name": "WH/OUT/00451",
        "state": "assigned",
        "transaction_id": "WMS-2026-000451"
      }
    ]
  }
}

Validar transferencias de inventario

POST /integration/api/picking/validate
JWT · header X-Access-Token Requiere api_allow_picking_validate

Valida una transferencia de inventario existente registrando las cantidades realmente ejecutadas por línea. Para cada elemento del array products ubica la línea de operación que coincida con el producto y el move indicado, escribe la cantidad hecha y procesa la transferencia: si queda reservada (assigned) la valida de inmediato, generando automáticamente una entrega parcial (backorder) cuando las cantidades ejecutadas son menores a las demandadas. Una transferencia inexistente responde R002. Requiere habilitación por compañía: si el servicio no está activo responde R009.

La operación es idempotente sobre el estado final: si la transferencia ya está en estado done o cancel, no se modifica y se retorna su estado actual con status_code 00. Errores internos al escribir cantidades o al procesar la validación responden R008 con el detalle de la excepción.

Parámetros

ParámetroTipoDescripción
picking requerido string Nombre de la transferencia a validar (stock.picking, campo name), ej. WH/OUT/00451. R002 si no existe.
products requerido array Cantidades ejecutadas por línea de la transferencia (responde R001 si se omite o está vacío).
default_code requerido string Referencia interna del producto (product.product, campo default_code). R002 si no existe.
qty requerido number Cantidad realmente ejecutada (qty_done) para la línea.
move requerido integer ID del movimiento de inventario (stock.move) al que pertenece la línea. Junto con default_code identifica la línea de operación a actualizar; si no coincide ninguna responde R002.
Request
curl -X POST 'https://<instancia>/integration/api/picking/validate' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{
    "picking": "WH/OUT/00451",
    "products": [
      {
        "default_code": "MED001",
        "qty": 10,
        "move": 15234
      }
    ]
  }'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {
        "id": 8912,
        "name": "WH/OUT/00451",
        "state": "done",
        "transaction_id": "WMS-2026-000451"
      }
    ]
  }
}

Consultar existencias de inventario

POST /integration/api/stock
JWT · header X-Access-Token Requiere api_allow_stock

Consulta las existencias de una lista de productos en una ubicación interna, calculando por producto la cantidad total, la reservada y la disponible. Los productos a consultar se envían en el array products, cada uno con default_code y opcionalmente lot. Requiere habilitación por compañía: si el servicio no está activo responde R009.

Sin lot_detail, cada producto retorna un objeto con product, total_qty, reserved_qty y available_qty; si se filtró por lot, se agregan los campos lot y exp_date. Con lot_detail en true, cada producto retorna product y un array lots con las cantidades y fecha de vencimiento por lote, incluyendo los lotes sin existencias en la ubicación con cantidades en cero. Cada elemento de response es la lista de resultados de un producto consultado; los productos sin resultados se omiten. Errores internos en el cálculo responden R008.

Parámetros

ParámetroTipoDescripción
location requerido string Código de la ubicación a consultar (stock.location, campo code). Solo se consultan existencias de ubicaciones de uso interno. R002 si no existe.
lot_detail boolean Si es true, la respuesta desglosa las existencias por lote (incluyendo los lotes del producto sin existencias en la ubicación, con cantidades en 0) y agrega la fecha de vencimiento de cada lote.
Default: false
products array Productos a consultar. Si se omite o está vacío, la respuesta es un array vacío.
default_code requerido string Referencia interna del producto a consultar (product.product, campo default_code). R002 si no existe.
lot string Nombre del lote para filtrar la consulta. Debe existir para el producto (R002 si no existe).
Request
curl -X POST 'https://<instancia>/integration/api/stock' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{
    "location": "BOD01",
    "lot_detail": true,
    "products": [
      {"default_code": "MED001"}
    ]
  }'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      [
        {
          "product": "MED001",
          "lots": [
            {
              "lot": "L2026-045",
              "total_qty": 120.0,
              "reserved_qty": 20.0,
              "available_qty": 100.0,
              "exp_date": "2027-06-30 00:00:00"
            },
            {
              "lot": "L2025-112",
              "total_qty": 0,
              "reserved_qty": 0,
              "available_qty": 0,
              "exp_date": "2026-01-31 00:00:00"
            }
          ]
        }
      ]
    ]
  }
}

Productos

Crear productos desde plantilla

POST /integration/api/product/copy
JWT · header X-Access-Token

Crea un producto duplicando el producto plantilla configurado en las políticas API de la compañía. El nuevo producto hereda toda la parametrización de la plantilla (categoría, UEP, unidad de medida, cuentas, trazabilidad) y solo recibe el name y default_code enviados; el tratamiento de IVA se fija en Excluido. Es la alternativa ligera a product/create cuando todos los productos comparten la misma parametrización.

Si la compañía no tiene configurado el producto plantilla responde R004. Campos faltantes responden R001 y errores internos en la copia responden R008 con el detalle de la excepción.

Parámetros

ParámetroTipoDescripción
name requerido string Nombre del nuevo producto.
default_code requerido string Referencia interna que se asigna al nuevo producto.
Request
curl -X POST 'https://<instancia>/integration/api/product/copy' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{
    "name": "Ibuprofeno 400 mg Tableta",
    "default_code": "MED002"
  }'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {
        "id": 4522,
        "name": "Ibuprofeno 400 mg Tableta",
        "default_code": "MED002"
      }
    ]
  }
}

Crear productos

POST /integration/api/product/create
JWT · header X-Access-Token Requiere api_allow_product

Crea uno o varios productos (product.product). Los productos se envían en el array products (obligatorio, responde R001 si está vacío); cada elemento usa los campos descritos abajo. La clasificación health_type activa validaciones de la vertical salud: Medicamento exige health_cum_code, Procedimiento exige health_cups_code, Insumo exige risk y Reactivo exige risk y health_temperature (faltantes responden R001). Si type_tax es Gravado, tax_iva es obligatorio y debe ser un impuesto de tipo IVA (R003 en caso contrario). Requiere habilitación por compañía: si el servicio no está activo responde R009.

La referencia interna (default_code) y el código de barras deben ser únicos; un valor repetido responde R005. Cuando no se envían category o line_analytic, se toman de las políticas API de la compañía; si esa parametrización no existe responde R004. La creación es atómica: si algún producto del lote falla, no se crea ninguno y se responde el error correspondiente (R008 para excepciones internas del ERP).

Parámetros

ParámetroTipoDescripción
products requerido array Productos a crear (responde R001 si se omite o está vacío). La creación del lote es atómica: si un elemento falla, no se crea ninguno.
name requerido string Nombre del producto.
default_code requerido string Referencia interna única del producto. Si ya existe un producto con ese código responde R005.
sale_ok boolean Si es true, el producto puede venderse.
Default: false
purchase_ok boolean Si es true, el producto puede comprarse.
Default: false
asset_ok boolean Si es true, el producto se marca como activo fijo.
Default: false
product_type string Tipo de producto: product (almacenable), consu (consumible) o service (servicio).
Valores: product consu service
Default: 'product'
health_type string Clasificación de salud. Determina los campos de salud obligatorios: Medicamento exige health_cum_code, Procedimiento exige health_cups_code, Insumo exige risk y Reactivo exige risk y health_temperature (R001 si faltan).
Valores: Reactivo Insumo Medicamento Procedimiento Dispositivo Medico Otros
Default: 'Otros'
type_tax requerido string Tratamiento de IVA del producto. Si es Gravado, tax_iva es obligatorio (R001 si falta).
Valores: Gravado Excluido Exento
tax_iva string Nombre del impuesto IVA (account.tax). Debe ser un impuesto de tipo IVA (código DIAN 01-IVA); de lo contrario responde R003.
category string Nombre de la categoría del producto (product.category). Si se omite, se usa la categoría por defecto de las políticas API de la compañía (R004 si no está configurada).
line_analytic string Nombre de la UEP / línea analítica del producto (product.category.analytic). Si se omite, se usa la UEP por defecto de las políticas API de la compañía (R004 si no está configurada).
tracking string Trazabilidad del producto. Para productos almacenables (product_type product) sin trazabilidad se fuerza a lot.
Valores: serial lot none
Default: 'none'
lst_price number Precio de venta de lista en COP.
Default: 0
uom string Código DIAN de la unidad de medida (uom.uom, campo ei_code). Por defecto 94 (unidad). R002 si no existe.
Default: '94'
barcode string Código de barras único del producto. Si ya existe responde R005.
manufacturer string Nombre del fabricante (product.producer). R002 si no existe.
health_cum_code string Código CUM del medicamento (health.cums, campo code). Obligatorio cuando health_type es Medicamento (R001 si falta).
health_cups_code string Código CUPS del procedimiento (health.cups, campo code). Obligatorio cuando health_type es Procedimiento (R001 si falta).
risk string Nombre de la clasificación de riesgo (product.risk). Obligatorio cuando health_type es Insumo o Reactivo (R001 si falta).
health_temperature string Condición de almacenamiento. Obligatorio cuando health_type es Reactivo (R001 si falta).
Valores: refrigeration ambient freezing
pharmaceutical_form string Forma farmacéutica del medicamento (ej. Tableta, Jarabe).
product_concentration string Concentración del medicamento (ej. 500 mg).
Request
curl -X POST 'https://<instancia>/integration/api/product/create' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{
    "products": [
      {
        "name": "Acetaminofén 500 mg Tableta",
        "default_code": "MED001",
        "sale_ok": true,
        "purchase_ok": true,
        "asset_ok": false,
        "product_type": "product",
        "health_type": "Medicamento",
        "health_cum_code": "19938406-1",
        "type_tax": "Excluido",
        "tracking": "lot",
        "uom": "94",
        "lst_price": 350,
        "category": "Medicamentos",
        "line_analytic": "Farmacia",
        "manufacturer": "Genfar",
        "pharmaceutical_form": "Tableta",
        "product_concentration": "500 mg"
      }
    ]
  }'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {
        "id": 4521,
        "name": "Acetaminofén 500 mg Tableta",
        "default_code": "MED001"
      }
    ]
  }
}

Consultar precios de productos

POST /integration/api/product/price
JWT · header X-Access-Token Requiere api_allow_product_price

Consulta el precio de venta de una lista de productos según la lista de precios de integración configurada en las políticas API de la compañía (Lista de Precio Venta - Integración). Los productos se envían en el array products, cada uno con su default_code. Por cada producto se retorna la referencia, el precio final calculado por la lista de precios (0 si el producto no tiene regla aplicable) y su unidad de medida. Requiere habilitación por compañía: si el servicio no está activo responde R009.

Si la compañía no tiene configurada la lista de precios de integración responde R004. Un producto inexistente responde R002 y errores internos en el cálculo del precio responden R008.

Parámetros

ParámetroTipoDescripción
products array Productos a consultar. Si se omite o está vacío, la respuesta es un array vacío.
default_code requerido string Referencia interna del producto a consultar (product.product, campo default_code). R002 si no existe.
Request
curl -X POST 'https://<instancia>/integration/api/product/price' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{
    "products": [
      {"default_code": "MED001"},
      {"default_code": "MED002"}
    ]
  }'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {
        "product": "MED001",
        "price": 350.0,
        "uom": "Unidades"
      },
      {
        "product": "MED002",
        "price": 780.0,
        "uom": "Unidades"
      }
    ]
  }
}

Ventas

Consultar órdenes de venta

POST /integration/api/sale-order/read
JWT · header X-Access-Token Requiere api_allow_sale_read

Consulta las órdenes de venta confirmadas (estado "Pedido de venta") de un cliente identificado por su número de documento. Solo devuelve el detalle de las órdenes cuyas líneas son en su totalidad productos de tipo servicio; las órdenes que incluyen productos almacenables o consumibles aparecen en el arreglo response como objetos vacíos {} (el integrador debe ignorarlos). Requiere habilitación por compañía (api_allow_sale_read); si no está activa responde R009.

Códigos de error: R001 si no se envía vat, R002 si el cliente no existe, R003 si el cliente no tiene órdenes confirmadas, R005 si se intenta filtrar por órdenes ya facturadas (invoiced) y R008 ante una excepción interna del ERP.

Parámetros

ParámetroTipoDescripción
vat requerido string Número de identificación del cliente (res.partner, campo vat).
include_invoice_status string Filtra por estado de facturación de la orden: 'no' (No aplica) o 'to invoice' (Por facturar). El valor 'invoiced' no está permitido y responde R005.
Request
curl -X POST 'https://<instancia>/integration/api/sale-order/read' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{"vat": "900123456", "include_invoice_status": "to invoice"}'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {
        "name": "SO2026-00187",
        "date_order": "2026-03-12 09:41:00",
        "order_line": [
          {"description": "Consulta medicina especializada", "default_code": "SVC-0101"}
        ],
        "amount_untaxed": 250000.0,
        "amount_tax": 47500.0,
        "amount_total": 297500.0,
        "partner_id": {
          "name": "IPS SALUD TOTAL SAS",
          "vat": "900123456",
          "street": "Cra 15 # 93-60",
          "document_type_id": "NIT"
        }
      }
    ]
  }
}

Crear órdenes de servicio

POST /integration/api/service-order
JWT · header X-Access-Token Requiere api_allow_service_order

Crea órdenes de servicio (service.order) en lote. El payload envuelve las órdenes en la lista service_orders; cada orden lleva sus líneas en la lista lines con los campos product_ref, qty y price. El procesamiento es por orden: las que fallan no bloquean las demás y la respuesta separa successful_orders de failed_orders con el código de error de cada una. Requiere habilitación por compañía (api_allow_service_order); si no está activa responde R009.

La unicidad de name se valida por software integrador (usuario API que crea el registro), de modo que dos integradores distintos pueden usar la misma numeración. Códigos de error por orden: R001 campo requerido faltante, R002 registro no encontrado (cliente, paciente, contrato, sucursal u homologación de sucursal), R003 el total no corresponde a la sumatoria de las líneas, R005 la orden ya existe y R008 excepción interna. Si el body no incluye service_orders, responde R001 global.

En la respuesta, el objeto summary totaliza las órdenes procesadas; su clave de éxitos es literalmente succesful (con un solo "s" intermedio), tal como la emite el ERP.

Parámetros

ParámetroTipoDescripción
service_orders requerido array Lista de órdenes de servicio a crear. Cada elemento se procesa de forma independiente con los campos descritos abajo.
name requerido string Número de la orden de servicio en el sistema origen. Debe ser único por software integrador; si ya existe responde R005 para esa orden.
partner_vat requerido string Número de identificación del cliente (res.partner, campo vat).
patient_vat requerido string Número de identificación del paciente (health.patient, campo vat).
contract requerido string Número del contrato al que se asocia la orden (res.contract, campo number).
date date Fecha de la orden en formato YYYY-MM-DD. Si se omite se usa la fecha actual.
Default: fecha actual
sucursal requerido string Código de la sucursal analítica (account.analytic.sucursal, campo code). En instalaciones con el módulo extended_colcan el código se resuelve contra la homologación de sucursales (account.analytic.sucursal.homologation); si el código o su homologación no existen responde R002.
user_vat requerido string Número de identificación del ejecutivo comercial (usuario del ERP).
amount_total requerido number Total de la orden. Debe coincidir con la sumatoria de qty * price de las líneas; si no, responde R003.
lines array Líneas de la orden. El código no las exige, pero amount_total debe coincidir con la sumatoria de las líneas (0 si no se envían).
product_ref requerido string Referencia interna del producto de la línea (product.product, campo default_code).
qty requerido integer Cantidad de la línea (entero).
price requerido number Precio unitario de la línea.
Request
curl -X POST 'https://<instancia>/integration/api/service-order' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{
    "service_orders": [
      {
        "name": "OS-2026-00045",
        "partner_vat": "900123456",
        "patient_vat": "1020304050",
        "contract": "CT-2026-011",
        "date": "2026-04-08",
        "sucursal": "SUC01",
        "user_vat": "79845123",
        "amount_total": 180000.0,
        "lines": [
          {"product_ref": "LAB-0034", "qty": 2, "price": 90000.0}
        ]
      }
    ]
  }'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "summary": {"succesful": 1, "failed": 1, "processed": 2},
    "successful_orders": [
      {"id": 812, "name": "OS-2026-00045"}
    ],
    "failed_orders": [
      {"order": "OS-2026-00046", "error": "R002: No se encontró el registro de Paciente: '1020304051'"}
    ]
  }
}

Punto de Venta

Crear órdenes de punto de venta

POST /integration/api/pos-order
JWT · header X-Access-Token Requiere api_allow_pos_order

Crea órdenes de punto de venta (pos.order) en lote a partir de un POS externo. El payload envuelve las órdenes en la lista orders; cada orden lleva sus líneas en lines y sus pagos en statements. Las órdenes se procesan y se marcan como pagadas en el ERP dentro de la sesión POS correspondiente. Requiere habilitación por compañía (api_allow_pos_order); si no está activa responde R009.

El campo sequence_ref garantiza idempotencia: si ya existe una orden con esa transacción, la respuesta devuelve la orden existente y agrega en cada elemento el campo error con el texto "The transaction_id already exists", sin crear duplicados. Para devoluciones se envía is_return: true con los valores en positivo y el ERP invierte los signos. Si el cliente no tiene plazo de pago configurado, el ERP le asigna el plazo por defecto de la parametrización API de la compañía.

Códigos de error: R001 si falta orders o un campo requerido, R002 si el tercero no existe o está archivado, o si un código de impuesto no existe, R003 si un valor tiene tipo o formato inválido y R004 si el diario del método de pago no tiene cuenta débito configurada.

Parámetros

ParámetroTipoDescripción
orders requerido array Lista de órdenes POS a crear. Todas las órdenes del lote se validan primero; luego se procesan y se marcan como pagadas.
pos requerido string Nombre del punto de venta en el ERP (pos.config, campo name).
sequence_ref requerido string Secuencia/consecutivo de la orden en el POS externo. Actúa como identificador de transacción: si ya existe una orden con ese valor, se devuelve la orden existente en lugar de crear un duplicado.
pos_reference requerido string Referencia de la orden en el POS externo. Se usa como nombre de la orden en el ERP.
amount_total requerido number Total de la orden, impuestos incluidos.
amount_paid requerido number Total pagado.
amount_tax requerido number Total de impuestos.
pos_session string Nombre de la sesión POS a la que se asocia la orden. Si se omite, se usa la sesión abierta del punto de venta o se crea una nueva automáticamente.
partner_vat requerido string Número de identificación del cliente. Si el tercero no existe o está archivado responde R002.
pos_type string Tipo de documento POS: none, pos (documento POS DIAN) o electronic (factura electrónica).
Valores: none pos electronic
Default: 'none'
user_vat requerido string Número de identificación del vendedor (usuario del ERP). Aunque la validación de tipo lo trata como opcional, la creación de la orden lo exige: omitirlo produce un error interno.
lines requerido array Líneas de la orden (R001 si está vacío).
product_ref requerido string Referencia interna del producto (product.product, campo default_code).
quantity requerido integer Cantidad (entero). Admite valores negativos.
price_unit requerido number Precio unitario.
price_subtotal requerido number Subtotal de la línea sin impuestos.
price_subtotal_incl requerido number Subtotal de la línea con impuestos incluidos.
discount number Porcentaje de descuento de la línea.
description string Descripción de la línea. Si se omite se usa el nombre del producto.
taxes array Lista de códigos de impuestos de venta (account.tax, campo code). Un código inexistente responde R002.
statements requerido array Pagos de la orden (R001 si está vacío).
journal_code requerido string Código del diario del método de pago POS (pos.payment.method, vía journal_id.code). El diario debe tener cuenta débito configurada; si no, responde R004.
amount requerido number Monto del pago.
ref_payment string Referencia del pago (voucher, aprobación, etc.).
is_return boolean Si es true, la orden se registra como devolución: montos y cantidades se invierten automáticamente (enviarlos en positivo).
gift_bonus_number string Número de bono regalo asociado a la orden.
Request
curl -X POST 'https://<instancia>/integration/api/pos-order' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{
    "orders": [
      {
        "pos": "Tienda Chapinero",
        "sequence_ref": "TCH-2026-000981",
        "pos_reference": "Orden 00981-102-0004",
        "amount_total": 59500.0,
        "amount_paid": 59500.0,
        "amount_tax": 9500.0,
        "partner_vat": "1020304050",
        "pos_type": "pos",
        "user_vat": "79845123",
        "lines": [
          {
            "product_ref": "PRD-0210",
            "quantity": 2,
            "price_unit": 25000.0,
            "price_subtotal": 50000.0,
            "price_subtotal_incl": 59500.0,
            "discount": 0,
            "taxes": ["IVA19"]
          }
        ],
        "statements": [
          {"journal_code": "CAJA1", "amount": 59500.0, "ref_payment": "EFECTIVO"}
        ],
        "is_return": false
      }
    ]
  }'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {
        "id": 4521,
        "name": "Orden 00981-102-0004",
        "pos_reference": "Orden 00981-102-0004",
        "state": "paid",
        "sequence_ref": "TCH-2026-000981"
      }
    ]
  }
}

Salud

Consultar RIPS de facturas

POST /integration/api/invoice/rips
JWT · header X-Access-Token Requiere api_allow_rips_consultation

Devuelve el JSON RIPS (Registro Individual de Prestación de Servicios de Salud, el reporte que los prestadores presentan al Ministerio de Salud colombiano vía FEV-RIPS/SISPRO) generado por el ERP para cada factura consultada. El JSON se entrega sin el envoltorio rips del archivo radicado e incluye la identificación del obligado, el número de factura y los usuarios con sus servicios (consultas, procedimientos, urgencias, hospitalización, medicamentos, otros servicios, etc.). Requiere habilitación por compañía (api_allow_rips_consultation); si no está activa responde R009.

La consulta es parcialmente tolerante a fallos: si algunas facturas generan error, el resultado incluye las exitosas en response y las fallidas en la lista adicional errors; si todas fallan responde R008. Otros códigos de error: R001 si el body no es JSON válido o falta numbers y R002 si ninguno de los números corresponde a una factura.

Parámetros

ParámetroTipoDescripción
numbers requerido array Lista de números de factura (campo number) de las que se quiere obtener el JSON RIPS.
Request
curl -X POST 'https://<instancia>/integration/api/invoice/rips' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{"numbers": ["FE12345"]}'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {
        "number": "FE12345",
        "response": {
          "numDocumentoIdObligado": "900123456",
          "numFactura": "FE12345",
          "tipoNota": null,
          "numNota": null,
          "usuarios": [
            {
              "tipoDocumentoIdentificacion": "CC",
              "numDocumentoIdentificacion": "1020304050",
              "tipoUsuario": "01",
              "fechaNacimiento": "1992-05-14",
              "codSexo": "F",
              "codPaisResidencia": "170",
              "codMunicipioResidencia": "11001",
              "codZonaTerritorialResidencia": "02",
              "incapacidad": "NO",
              "consecutivo": 1,
              "codPaisOrigen": "170",
              "servicios": {
                "consultas": [
                  {
                    "codPrestador": "110010123456",
                    "fechaInicioAtencion": "2026-04-10 08:30",
                    "codConsulta": "890201",
                    "vrServicio": 250000
                  }
                ]
              }
            }
          ]
        }
      }
    ]
  }
}

Consultar CUV de facturas RIPS

POST /integration/api/invoice/rips/cuv
JWT · header X-Access-Token Requiere api_allow_cuv_consultation

Devuelve la respuesta de validación que SISPRO (Ministerio de Salud colombiano) emitió al radicar los RIPS de cada factura, incluido el CUV (Código Único de Validación) que certifica que el reporte fue aceptado. Todas las facturas consultadas deben estar en estado "Aceptado SISPRO"; si alguna no lo está, la consulta completa se rechaza con R003. Requiere habilitación por compañía (api_allow_cuv_consultation); si no está activa responde R009.

El objeto response de cada factura es la respuesta cruda de la aplicación FEV-RIPS: estado del resultado, CUV, fecha de radicación y el detalle de ResultadosValidacion cuando aplica. Códigos de error: R001 si el body no es JSON válido o falta numbers, R002 si ningún número corresponde a una factura o la factura no tiene respuesta SISPRO almacenada y R008 si la respuesta almacenada no es un JSON válido o hay un error interno.

Parámetros

ParámetroTipoDescripción
numbers requerido array Lista de números de factura (campo number) de las que se quiere obtener la respuesta de validación SISPRO.
Request
curl -X POST 'https://<instancia>/integration/api/invoice/rips/cuv' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{"numbers": ["FE12345"]}'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {
        "number": "FE12345",
        "response": {
          "ResultState": true,
          "CodigoUnicoValidacion": "a3f8c1e94b27d6051f8e2ac47b90d3125c6ef8a1b4d7c290e5f13a68d4b7c901",
          "FechaRadicacion": "2026-04-11T10:22:35Z",
          "NumFactura": "FE12345",
          "ResultadosValidacion": []
        }
      }
    ]
  }
}

Registrar eventos de cartera salud (radicación y glosas)

POST /integration/api/medical-claim
Alias: /integration/api/medical-claim/create
JWT · header X-Access-Token Requiere api_allow_medical_claim

Registra en lote eventos del ciclo de cartera del sector salud sobre facturas de venta: radicación ante el pagador, retiro, glosas (con sus subeventos de notificación, aceptación y rechazo) y notificación jurídica. El payload envuelve los eventos en la lista events. Los eventos se crean en una sola operación (si alguno falla no se crea ninguno) y cada uno se contabiliza de inmediato mediante la reclasificación entre las cuentas de radicación, glosa o jurídica parametrizadas en el tercero o en el segmento salud de la factura. Requiere habilitación por compañía (api_allow_medical_claim); si no está activa responde R009. Disponible también en el alias /integration/api/medical-claim/create.

Para glosas la factura debe estar validada, ser a crédito y el valor glosado no puede superar su total. El campo transaction_id da idempotencia: si ya existe un evento con esa transacción, la respuesta devuelve el registro existente con el campo error "The transaction_id already exists". Códigos de error: R001 campo requerido faltante (events, amount o claim_event en glosas, return_invoice en aceptaciones), R002 registro no encontrado, R003 factura no validada, valor de glosa superior al total o nota crédito inválida (tipo o tercero distintos), R004 cuentas de radicación/glosa/jurídica sin parametrizar y R008 factura ya pagada al radicar, factura de contado al glosar o error interno en la creación. Si el número enviado en invoice no existe ni como factura ni como asiento de saldo inicial, la petición falla con un error interno del ERP.

Parámetros

ParámetroTipoDescripción
events requerido array Lista de eventos de cartera a registrar. La validación es por lote completo: si algún evento falla, no se crea ninguno.
date date Fecha del evento en formato YYYY-MM-DD. Si se omite se usa la fecha actual.
Default: fecha actual
medical_event requerido string Tipo de evento: submission (radicación), withdrawal (retiro), claim (glosa) o legal (notificación jurídica).
Valores: submission withdrawal claim legal
name requerido string Nombre o consecutivo del evento en el sistema origen.
user_vat requerido string Número de identificación del usuario responsable (usuario del ERP).
invoice requerido string Número de la factura sobre la que se registra el evento (account.invoice, campo number). Si no existe como factura, se busca un asiento de saldo inicial por cobrar con ese número y el valor del evento se toma del débito del asiento.
amount number Valor del evento. Para radicación, retiro y jurídica se ignora y se toma el total de la factura; para glosa es obligatorio (R001 si es 0) y no puede superar el total de la factura (R003).
notes string Observaciones del evento.
claim_event string Subevento de glosa: none, notification (notificación de glosa), approval (aceptación) o rejection (rechazo). Obligatorio distinto de none cuando medical_event es claim; para los demás eventos se fuerza a none.
Valores: none notification approval rejection
Default: 'none'
claim_code string Código de la glosa según la codificación del pagador.
transaction_id string Identificador único de la transacción en el sistema origen. Si ya existe un evento con ese valor, se devuelve el registro existente sin crear duplicados.
return_invoice string Número de la nota crédito (account.invoice tipo out_refund) que soporta la aceptación de la glosa. Obligatorio cuando claim_event es approval; debe pertenecer al mismo tercero de la factura glosada.
Request
curl -X POST 'https://<instancia>/integration/api/medical-claim' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{
    "events": [
      {
        "date": "2026-04-15",
        "medical_event": "claim",
        "name": "GL-2026-0032",
        "user_vat": "79845123",
        "invoice": "FE12345",
        "amount": 350000.0,
        "claim_event": "notification",
        "claim_code": "FA1601",
        "notes": "Glosa por tarifa no pactada",
        "transaction_id": "GL-2026-0032-N1"
      }
    ]
  }'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {
        "id": 987,
        "name": "GL-2026-0032",
        "medical_event": "claim",
        "claim_event": "notification",
        "transaction_id": "GL-2026-0032-N1",
        "amount": 350000.0
      }
    ]
  }
}

Crear pacientes

POST /integration/api/patient/create
JWT · header X-Access-Token Requiere api_allow_patient

Crea uno o varios pacientes (health.patient) para la vertical salud. El payload envuelve los registros en la lista patients. Requiere habilitación por compañía (api_allow_patient); si no está activa responde R009.

La validación es por lote completo: si algún paciente falla, no se crea ninguno. Códigos de error: R001 si falta patients o un campo requerido, R002 si el tipo de documento, la ciudad o el país no existen, R003 si un valor tiene formato inválido (fechas, valores de selección) y R005 si ya existe un paciente con el mismo vat.

Parámetros

ParámetroTipoDescripción
patients requerido array Lista de pacientes a crear. La validación es por lote completo: si algún elemento falla, no se crea ninguno.
first_name requerido string Primer nombre del paciente.
other_name string Segundo nombre.
first_lastname requerido string Primer apellido.
other_lastname string Segundo apellido.
document_type requerido string Tipo de documento. Acepta el código interno o el código DIAN (ej. 13 = cédula de ciudadanía).
vat requerido string Número de identificación del paciente. Debe ser único; si ya existe un paciente con ese vat responde R005.
address requerido string Dirección de residencia.
city requerido string Código DANE de la ciudad de residencia (res.country.city, campo code).
email requerido string Correo electrónico.
address_zone string Zona territorial de residencia según RIPS: 01 = Rural, 02 = Urbana.
Valores: 01 02
Default: '02'
birthday date Fecha de nacimiento en formato YYYY-MM-DD.
phone string Teléfono de contacto.
gender string Género: f = Femenino, m = Masculino, i = Indeterminado.
Valores: f m i
Default: 'm'
birth_country string Código ISO del país de nacimiento (res.country, campo code).
Default: 'CO'
country_id string Código ISO del país de residencia (res.country, campo code).
Default: 'CO'
Request
curl -X POST 'https://<instancia>/integration/api/patient/create' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{
    "patients": [
      {
        "first_name": "Laura",
        "other_name": "Cristina",
        "first_lastname": "Gómez",
        "other_lastname": "Pérez",
        "document_type": "13",
        "vat": "1020304050",
        "address": "Cra 10 # 20-30",
        "city": "11001",
        "email": "laura@ejemplo.com",
        "address_zone": "02",
        "birthday": "1992-05-14",
        "phone": "3001234567",
        "gender": "f",
        "birth_country": "CO",
        "country_id": "CO"
      }
    ]
  }'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {"id": 3120, "vat": "1020304050", "name": "Laura Cristina Gómez Pérez"}
    ]
  }
}

Consultar pacientes

POST /integration/api/patient/read
JWT · header X-Access-Token Requiere api_allow_patient_read

Consulta un paciente por su número de identificación y devuelve sus datos básicos: nombres, apellidos, dirección, tipo de documento, ciudad y correo electrónico. Los campos relacionales (document_type_id, city_id) se devuelven como pares [id, nombre]. Requiere habilitación por compañía (api_allow_patient_read); si no está activa responde R009.

Códigos de error: R001 si no se envía vat y R002 si no existe un paciente con esa identificación.

Parámetros

ParámetroTipoDescripción
vat requerido reference health.patient por vat Número de identificación del paciente a consultar (health.patient, campo vat).
Request
curl -X POST 'https://<instancia>/integration/api/patient/read' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{"vat": "1020304050"}'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {
        "id": 3120,
        "vat": "1020304050",
        "first_name": "Laura",
        "other_name": "Cristina",
        "first_lastname": "Gómez",
        "other_lastname": "Pérez",
        "address": "Cra 10 # 20-30",
        "document_type_id": [4, "Cédula de Ciudadanía"],
        "city_id": [149, "Bogotá D.C."],
        "email": "laura@ejemplo.com"
      }
    ]
  }
}

Contratos

Crear contratos

POST /integration/api/contract/create
JWT · header X-Access-Token Requiere api_allow_contract

Crea un contrato comercial (res.contract) asociado a un cliente, con su modalidad, unidad estratégica de negocio y condiciones comerciales. Los campos comerciales opcionales (ejecutivo, ejecutivo de cartera, lista de precios y plazo de pago) toman por defecto la parametrización API de la compañía. Requiere habilitación por compañía (api_allow_contract); si no está activa responde R009.

La operación es idempotente por nombre: si ya existe un contrato con el mismo name, responde status_code 00 devolviendo el contrato existente sin crear duplicados. En instalaciones con el módulo extended_colcan el campo groupm es obligatorio y se crea adicionalmente la homologación contable del contrato con la cuenta por cobrar del cliente (o la de la configuración API de la compañía).

Códigos de error: R001 campo requerido faltante, R002 registro no encontrado (cliente, modalidad, UEN, ciudad, usuarios, lista de precios, plazo de pago o grupo de modalidad), R003 fecha con formato inválido y R008 error interno al crear el contacto de email, la homologación o el contrato.

Parámetros

ParámetroTipoDescripción
partner_vat requerido reference res.partner por vat Número de identificación del cliente titular del contrato (res.partner, campo vat).
number requerido string Número del contrato en el sistema origen.
model requerido reference res.contract.model por name Nombre de la modalidad de contrato (res.contract.model, campo name).
name string Nombre del contrato. Si se omite, el ERP lo compone como "[uen] modalidad".
uen requerido reference res.contract.uen por name Nombre de la unidad estratégica de negocio (res.contract.uen, campo name).
email string Correo para envío de la factura electrónica del contrato. Si se envía, el ERP crea un contacto hijo del cliente con ese correo y lo asocia al contrato.
user_vat reference res.users por partner_id.vat Número de identificación del ejecutivo comercial (usuario del ERP). Si se omite se usa el usuario por defecto de la configuración API de la compañía.
user_portfolio_vat reference res.users por partner_id.vat Número de identificación del ejecutivo de cartera (usuario del ERP). Si se omite se usa el de la configuración API de la compañía.
pricelist_name reference product.pricelist por name Nombre de la lista de precios (product.pricelist). Si se omite se usa la de la configuración API de la compañía.
payment_term reference account.payment.term por name Nombre del plazo de pago (account.payment.term). Si se omite se usa el de la configuración API de la compañía.
date_start date (YYYY-MM-DD) Fecha de inicio del contrato en formato YYYY-MM-DD.
date_end date (YYYY-MM-DD) Fecha de finalización del contrato en formato YYYY-MM-DD.
radication_address string Dirección de radicación de facturas (campo específico de instalaciones con módulo extendido).
city reference res.country.city por code Código DANE de la ciudad de radicación (res.country.city, campo code).
groupm requerido reference res.contract.groupm por name Nombre del grupo de modalidad (res.contract.groupm). Obligatorio solo en instalaciones con el módulo de homologación de contratos (extended_colcan); en ese caso también se crea la homologación contable del contrato.
Request
curl -X POST 'https://<instancia>/integration/api/contract/create' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{
    "partner_vat": "900123456",
    "number": "CT-2026-011",
    "model": "Evento",
    "name": "[Laboratorio] Evento",
    "uen": "Laboratorio",
    "email": "facturacion@ipssaludtotal.com",
    "user_vat": "79845123",
    "pricelist_name": "Tarifa Institucional 2026",
    "payment_term": "60 días",
    "date_start": "2026-01-01",
    "date_end": "2026-12-31"
  }'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {"id": 245, "name": "[Laboratorio] Evento", "number": "CT-2026-011"}
    ]
  }
}

Consultas

Consultar registros (ORM)

POST /integration/api/query
JWT · header X-Access-Token Requiere api_allow_query

Consulta registros de cualquier modelo del ERP a través del ORM y devuelve los campos solicitados. El campo opcional domain es un string con un dominio Odoo estándar (ej. "[('customer', '=', True)]") que se evalúa de forma segura para filtrar los registros; si se omite, se devuelven todos los registros del modelo (sujetos a limit/offset).

Requiere habilitación por compañía (política api_allow_query); si el servicio no está habilitado responde R009. Si el modelo no existe en el ERP responde R002; si falta model responde R001; si algún parámetro tiene un tipo inválido responde R003; y si el dominio o la lectura de campos produce una excepción interna responde R008 con el detalle del error.

Parámetros

ParámetroTipoDescripción
model requerido string Nombre técnico del modelo Odoo a consultar (ej. res.partner, account.move, product.product).
fields array Lista de campos a leer de cada registro. Si se omite, la respuesta incluye todos los campos del modelo.
limit integer Cantidad máxima de registros a devolver. Si se omite, devuelve todos los registros que coincidan.
offset integer Número de registros a omitir desde el inicio del resultado; combinado con limit permite paginar.
domain string Dominio Odoo estándar como string (ej. "[('customer', '=', True)]") que se evalúa de forma segura para filtrar los registros. Si se omite, se devuelven todos los registros del modelo (sujetos a limit/offset).
Request
curl -X POST 'https://<instancia>/integration/api/query' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{
    "model": "res.partner",
    "domain": "[(\"customer\", \"=\", True)]",
    "fields": ["id", "name", "vat", "email"],
    "limit": 2,
    "offset": 0
  }'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {
        "id": 1234,
        "name": "Comercializadora Andina S.A.S",
        "vat": "900123456",
        "email": "facturacion@andina.com.co"
      },
      {
        "id": 1235,
        "name": "Laura Gómez Pérez",
        "vat": "1020304050",
        "email": "laura.gomez@ejemplo.com"
      }
    ]
  }
}

Consultar por SQL

POST /integration/api/query/sql
JWT · header X-Access-Token Requiere api_allow_query

Ejecuta una consulta SQL directamente sobre la base de datos del ERP y devuelve las filas como objetos donde cada clave es el nombre de la columna del resultado. Está pensado exclusivamente para consultas de solo lectura (SELECT): antes de ejecutar, un filtro de palabras reservadas rechaza con R003 cualquier consulta que contenga delete, drop, insert, alter, truncate, execute, create, update, unlink, copy, write o referencias a la tabla ir_config_parameter, indicando en el mensaje las palabras detectadas.

Requiere habilitación por compañía (política api_allow_query); si el servicio no está habilitado responde R009. Si falta query responde R001, y si la consulta produce un error de SQL (sintaxis, tabla o columna inexistente) responde R008 con el mensaje del motor de base de datos.

Parámetros

ParámetroTipoDescripción
query requerido string Consulta SQL de solo lectura a ejecutar sobre la base de datos del ERP. Los nombres de tabla usan la convención de Odoo (res_partner, account_move, etc.).
Request
curl -X POST 'https://<instancia>/integration/api/query/sql' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{
    "query": "SELECT id, name, vat FROM res_partner WHERE vat = '\''900123456'\'' LIMIT 5"
  }'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {
        "id": 1234,
        "name": "Comercializadora Andina S.A.S",
        "vat": "900123456"
      }
    ]
  }
}

Actualización

Crear registros genéricos

POST /integration/api/create
JWT · header X-Access-Token Requiere api_allow_create

Crea uno o varios registros en un modelo del ERP de forma genérica. Los valores de data se pasan directamente al método create del modelo, por lo que las claves deben ser los nombres técnicos de los campos (pueden consultarse con el endpoint /integration/api/fields). La respuesta devuelve la lectura completa de los registros creados, con todos sus campos.

Requiere doble habilitación por compañía: la política api_allow_create debe estar activa (de lo contrario responde R009) y el modelo debe estar incluido en la lista "Modelos Autorizados API" de la configuración API de la compañía; si el modelo no está autorizado — o no se envía model, ya que la autorización se verifica primero — responde R006. Los modelos típicamente habilitados para escritura vía API son res.partner, res.contract, health.patient y product.product. Si falta data responde R001.

Parámetros

ParámetroTipoDescripción
model requerido string Nombre técnico del modelo Odoo en el que se crearán los registros. Debe estar autorizado en la política de compañía "Modelos Autorizados API".
data requerido array Lista de objetos, uno por registro a crear. Cada objeto usa los nombres técnicos de los campos del modelo como claves (los mismos que devuelve el endpoint /integration/api/fields).
Request
curl -X POST 'https://<instancia>/integration/api/create' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{
    "model": "res.partner",
    "data": [
      {
        "name": "Distribuciones El Dorado S.A.S",
        "vat": "901234567",
        "street": "Cl 26 # 68-35",
        "email": "contacto@eldorado.com.co",
        "phone": "6014567890"
      }
    ]
  }'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {
        "id": 2456,
        "name": "Distribuciones El Dorado S.A.S",
        "vat": "901234567",
        "street": "Cl 26 # 68-35",
        "email": "contacto@eldorado.com.co",
        "phone": "6014567890",
        "active": true
      }
    ]
  }
}

Actualizar registros

PUT /integration/api/update
JWT · header X-Access-Token Requiere api_allow_update

Actualiza registros existentes de los modelos permitidos por la API: res.partner, res.contract, health.patient y product.product (cualquier otro modelo responde R006). El body es un objeto con tres claves: model, ids y fields. Los campos que no existan en el modelo se descartan silenciosamente; si tras el filtrado no queda ningún valor por escribir, o no se encuentra ningún registro, responde R002. La respuesta devuelve la lectura de los campos efectivamente actualizados en cada registro.

Para res.partner aplican políticas de compañía adicionales: permisos por tipo de tercero (jurídico/natural) y por rol (cliente/tercero) que, de no estar habilitados, responden R008; y bloqueos por campo (email, dirección, teléfono, móvil, nombres, apellidos, ciudad) que descartan el campo sin generar error. Si se actualizan campos de nombre (first_name, first_lastname, etc.) el ERP recompone automáticamente el nombre completo. En compañías con el módulo extended_masterseries, los terceros marcados como proveedor o empleado no se actualizan: la respuesta llega con status_code 00 y el mensaje "No se permite actualizar el registro porque el partner es proveedor o empleado" en response.

Para product.product, en compañías con el módulo extended_cruzroja, no se permite inactivar productos cuyo tipo salud sea "Otros" (R007).

Requiere habilitación por compañía (política api_allow_update); si el servicio no está habilitado responde R009. Si falta model, ids o fields responde R001.

Parámetros

ParámetroTipoDescripción
model requerido string Nombre técnico del modelo a actualizar. Cualquier modelo fuera de la lista permitida responde R006.
Valores: res.partner res.contract health.patient product.product
ids requerido array Identificadores de los registros a actualizar. Para res.partner acepta números de identificación (vat) o IDs internos (si todos los valores son enteros se busca por ambos); para los demás modelos, solo IDs internos.
fields requerido object Objeto con los campos a escribir: cada clave es el nombre técnico de un campo del modelo y su valor el nuevo dato. Los campos que no existen en el modelo se descartan silenciosamente. Además de los campos directos, se aceptan las claves especiales descritas abajo, que el ERP traduce antes de escribir.
health_cum_code string Solo product.product: código CUM del medicamento (health.cums, campo code). El ERP lo resuelve y escribe health_cum_id. Si el código no existe responde R002.
health_cups_code string Solo product.product: código CUPS del procedimiento (health.cups, campo code). El ERP lo resuelve y escribe health_cup_id.
partner_type string Solo res.partner: J = persona jurídica, N = persona natural. Se traduce al campo interno type_partner.
Valores: J N
city string Solo res.partner: código DANE de la ciudad (res.country.city, campo code). El ERP lo resuelve y escribe city_id. Si el código no existe responde R002.
vat string Solo res.partner: si el valor enviado coincide con la identificación actual del registro, se descarta sin error.
Request
curl -X PUT 'https://<instancia>/integration/api/update' \
  -H 'Content-Type: application/json' \
  -H 'X-Access-Token: <token>' \
  -d '{
    "model": "res.partner",
    "ids": ["900123456"],
    "fields": {
      "email": "facturacion@andina.com.co",
      "phone": "6015551234",
      "city": "11001",
      "partner_type": "J"
    }
  }'
Response
{
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "status_code": "00",
    "response": [
      {
        "id": 1234,
        "email": "facturacion@andina.com.co",
        "phone": "6015551234",
        "city_id": [149, "Bogotá D.C."],
        "type_partner": "juridica"
      }
    ]
  }
}