Odoo da a tu integración una llamada por segundo. Todo lo demás se deduce de ahí.
Si buscas consejos sobre integración con Odoo encuentras dos tipos de página: un folleto de partner o un tutorial que enseña a llamar a search_read desde Python. Ninguno menciona lo que de verdad decide tu arquitectura. Odoo publica límites firmes sobre lo que puede hacer una integración externa, y dos de ellos tienen fecha.
Esto está escrito desde el lado de la construcción, para el equipo que tiene que conectar un producto, un portal de clientes, una tienda, un motor de precios o una herramienta interna a una base de datos Odoo y mantenerlo vivo a través del tren de releases de Odoo. Da por hecho que Odoo se queda. Nada de lo que sigue es un argumento para reemplazar un ERP que ya lleva tu contabilidad. La única pregunta que merece respuesta es dónde está la frontera entre Odoo y el software que es tuyo, y la propia documentación de Odoo responde casi todo si lees las cinco páginas correctas.
Los cinco límites en una tabla
| Límite | Qué dice Odoo | Qué impone a tu diseño |
|---|---|---|
| Puerta del plan | El acceso a la API externa existe en los planes Custom y no en One App Free ni Standard | La API es una línea del contrato del ERP, no una capacidad gratuita. Confírmalo antes de dimensionar la integración |
| Presupuesto de llamadas | En torno a una llamada por segundo, de forma no sostenida y sin llamadas paralelas, es lo que la política de uso aceptable considera aceptable en Odoo Cloud | Agrupa lecturas, agrega en el servidor y deja que Odoo te empuje eventos en lugar de sondearlo |
| Límite transaccional | Cada llamada al endpoint JSON-2 corre en su propia transacción SQL y no se pueden encadenar varias en una | Toda operación de varios pasos que deba ser todo o nada pertenece a un único método dentro de un módulo propio |
| Reloj del protocolo | /xmlrpc, /xmlrpc/2 y /jsonrpc están previstos para retirarse en Odoo 22 (otoño de 2028) y Odoo Online 21.1 (invierno de 2027) | Lo nuevo apunta a /json/2. Los clientes RPC existentes necesitan un plan con fechas, no un ticket de backlog |
| Reloj de actualización | Cada versión mayor tiene tres años de soporte, las actualizaciones de Odoo Online son obligatorias según calendario, y una base de datos con módulos propios no puede actualizarse hasta que sean compatibles | El código propio es una obligación de mantenimiento recurrente con un nombre detrás, y tus pruebas de integración forman parte de la puerta de actualización |
Lee las dos últimas filas juntas, porque ahí es donde duele. Tu cliente RPC debe haber desaparecido antes de que Odoo Online llegue a 21.1, y la actualización que te lleva allí no la controlas del todo.
Límite 1: la API externa es una función del plan
La primera sorpresa es comercial, no técnica. La referencia de la API JSON-2 de Odoo indica que el acceso a datos mediante la API externa solo está disponible en los planes Custom, y que no lo está en los planes One App Free ni Standard.
Esa nota reordena muchos proyectos. Una empresa que eligió el plan Standard porque parecía la opción intermedia sensata ha comprado un ERP con el que su propio software no puede hablar. El presupuesto de integración tiene entonces que absorber un cambio de plan por cada usuario, cada mes, para siempre. Es lo más barato de comprobar y lo más caro de descubrir en la semana seis.
Dos notas prácticas. Primera: Odoo Community autoalojado no tiene ninguna puerta de plan, porque no hay plan, y eso es uno de los pocos argumentos reales para gestionarlo tú. Segunda: los nombres y niveles de plan son superficie de marketing y se mueven, así que trata la nota de la documentación como el motivo para revisar tu contrato, no como una cita para pegar en un memorándum.
Límite 2: una llamada por segundo y sin paralelismo
Odoo no publica una cuota por endpoint con un umbral 429 documentado. Lo que publica es una política. La política de uso aceptable de Odoo Cloud enumera las llamadas RPC y de API sin limitar como abuso de red prohibido, recuerda que existen APIs de lote para importaciones, y dice que las llamadas limitadas suelen ser aceptables en uso no sostenido a un ritmo de una llamada por segundo, sin llamadas paralelas. También nombra la salida: en Odoo.sh, el alojamiento dedicado puede considerarse una alternativa para levantar esa restricción.
Un techo de política es más difícil de diseñar que una cuota documentada, porque no puedes medir tu camino hacia la seguridad. Hay que asumir que el número es el número. Una llamada por segundo, en serie, son unas 86.000 llamadas al día si usas cada segundo, cosa que ninguna integración real hace. El diseño pasa entonces de "cuán rápido podemos ir" a "cuántas llamadas necesita esto como mínimo".
Qué te ahorra eso, en llamadas
- Un viaje de ida y vuelta en lugar de dos.
search_readsustituye a unsearchseguido de unread. Cada método ORM combinado es una llamada que no gastaste. - Agrega dentro de Odoo.
read_groupdevuelve sumas agrupadas desde la base de datos. Traer 40.000 líneas de pedido para sumarlas en tu código es la misma respuesta a cien veces el coste. - Escribe en lotes. Pasar una lista de ids a una escritura es una llamada. Un bucle sobre ids es una llamada por registro, y un bucle de 3.000 registros es una caída que has provocado tú.
- Pide solo los campos que necesitas. Una lista
fieldsmantiene la respuesta pequeña y evita que tu cliente dependa de columnas que nunca quisiste, algo que vuelve a importar al actualizar. - Nunca sondees para detectar cambios. El sondeo es el mayor consumidor de un presupuesto de una llamada por segundo, y escala con tu número de clientes en lugar de con tu volumen de datos.
El sustituto del sondeo ya está en el producto. Las reglas de automatización de Odoo incluyen una acción Send Webhook Notification que publica los campos seleccionados de un registro en la URL que indiques, con vista previa del payload, y también pueden activarse mediante un webhook entrante de un sistema externo. La propia documentación de Odoo añade una advertencia: implica a desarrollo o a arquitectura de soluciones, porque un webhook mal configurado puede perturbar la base de datos. La advertencia es correcta y es la razón por la que los webhooks van detrás de una cola en tu lado, no cableados directamente a la lógica de negocio.
La forma que sobrevive es aburrida. Odoo empuja un evento. Tu servicio lo acepta, lo escribe en tu propio almacén, responde 200 rápido y hace el trabajo real de forma asíncrona, con política de reintentos y un limitador que respeta una llamada por segundo. Tu producto lee de tu almacén, no de Odoo. Odoo sigue siendo el sistema de registro de lo que le corresponde.
¿Una base de datos Odoo en el centro del roadmap y nadie es dueño de la frontera?
Dimensionar la integraciónLímite 3: cada llamada es su propia transacción
Este es el límite que produce la clase de error caro, y está dicho con claridad en la sección de transacciones de la referencia JSON-2: todas las llamadas al endpoint JSON-2 corren en su propia transacción SQL, se confirman al tener éxito y se descartan al fallar, y no es posible encadenar varias llamadas dentro de una transacción. La documentación va más allá y dice que la base de datos puede ser modificada por otras transacciones concurrentes entre tus llamadas, y que eso es especialmente peligroso en operaciones relacionadas con reservas y pagos.
Léelo como una instrucción de arquitectura, porque lo es. La solución que recomienda Odoo está en el mismo párrafo: llama siempre a un único método que realice todas las operaciones relacionadas en una sola transacción y, cuando no exista tal método, créalo en un módulo dedicado.
Lo que significa que la respuesta honesta a "¿podemos hacerlo sin tocar código de Odoo?" suele ser no. Una secuencia de tres llamadas que comprueba stock, lo reserva y confirma un pedido no es una transacción. Son tres transacciones con dos ventanas en las que otro usuario, otra integración o una acción programada puede cambiar el mundo bajo tus pies. El fallo no es una caída. Es una reserva duplicada, un pago contra un precio caducado o una línea de pedido sin cabecera, descubierta por contabilidad un mes después.
Tres reglas que aplicamos a todo camino de escritura en Odoo
- Una operación de negocio, una llamada. Si la operación tiene una invariante, recibe un método en un módulo propio y tu servicio llama a ese único método. La invariante vive en la transacción de base de datos, no en tu código de orquestación.
- Claves de idempotencia en todo lo que crea. Tu política de reintentos reenviará una llamada cuya respuesta nunca viste. Guarda tu propia clave en el registro de Odoo, compruébala antes de crear, y un reintento se vuelve inocuo en lugar de una factura duplicada.
- Reconcilia, no confíes. Un proceso nocturno que compara tu almacén con Odoo mediante unas pocas lecturas agregadas detecta la deriva que se le escapa al manejo de errores por llamada. Barato en llamadas, y lo único que encuentra los fallos que nadie registró.
Límite 4: el protocolo RPC tiene fecha de retirada
Casi toda integración con Odoo que existe habla XML-RPC, porque durante años esa fue la respuesta. La referencia de la API RPC externa abre ahora con un aviso de retirada: tanto la API XML-RPC como la JSON-RPC en /xmlrpc, /xmlrpc/2 y /jsonrpc están previstas para retirarse en Odoo 22 (otoño de 2028) y en Odoo Online 21.1 (invierno de 2027), con la API External JSON-2 como sustituto. Los tres servicios expuestos, common, db y object, están obsoletos. Los controladores internos declarados con @route(type='jsonrpc') quedan explícitamente fuera del aviso.
Dos fechas, y la que te obliga depende de dónde viva tu base de datos. Odoo Online llega antes al corte, en el invierno de 2027, porque publica versiones menores y se mueve más rápido que la línea mayor. Las bases autoalojadas y las de Odoo.sh tienen hasta Odoo 22 en el otoño de 2028, más el tiempo que estés dispuesto a quedarte en una versión sin soporte.
La migración es pequeña si tu capa de llamadas es un módulo, y dolorosa si las llamadas RPC están repartidas por el código. Qué cambia:
| Aspecto | XML-RPC y JSON-RPC | External JSON-2 |
|---|---|---|
| Endpoint | /xmlrpc/2/common y luego /xmlrpc/2/object | POST /json/2/<modelo>/<método> |
| Autenticación | Iniciar sesión primero y arrastrar el id de usuario devuelto en cada llamada | Una clave de API como bearer token en la cabecera Authorization, sin viaje de login |
| Selección de base de datos | Un argumento posicional en cada llamada | La cabecera opcional X-Odoo-Database, necesaria cuando un servidor aloja varias bases |
| Payload | Argumentos posicionales en orden fijo | Un objeto JSON con ids, context y parámetros con nombre |
| Descubrimiento | Leer el código del modelo que invocas | Una ruta de documentación /doc por base de datos, generada desde sus propios modelos |
El cambio de autenticación es el que conviene planificar en lugar de portar mecánicamente. Las claves JSON-2 se pueden crear, revocar y rotar de forma programática mediante res.users.apikeys, con una fecha de expiración que se valida contra la duración máxima permitida por los roles del usuario. La recomendación de Odoo es ejecutar las integraciones automatizadas bajo un usuario bot dedicado, con permisos mínimos y contraseña vacía, para cerrar la vía de login y que el registro de acceso nombre al bot en lugar de suplantar a una persona. Hazlo una vez por integración y la rotación de claves pasa a ser una tarea de operaciones en lugar de una migración.
Límite 5: el reloj de actualización es de Odoo
La documentación de actualización es la página que la mayoría de los planes de integración se salta, y contiene la restricción de cola más larga. Cada versión mayor tiene tres años de soporte. En Odoo Online, la actualización es obligatoria cada dos años para una versión mayor, y unas semanas después del siguiente lanzamiento para una versión menor, y las menores llegan aproximadamente cada dos meses. El equipo de actualización de Odoo ejecuta una actualización de prueba silenciosa de cada base que toca, y si esa prueba tiene éxito y dura menos de veinte minutos, la actualización automática sigue adelante salvo que actúes antes de la fecha límite.
Y luego las dos frases que deciden quién paga. Una base de datos con módulos propios no puede actualizarse hasta que exista una versión de esos módulos para la versión objetivo. Y si un cambio de una versión nueva rompe una personalización, hacerla compatible es responsabilidad del mantenedor de ese módulo. La propia lista de pruebas de Odoo pone las integraciones con software externo, APIs y EDI en primer lugar.
No es una queja sobre Odoo. Es el acuerdo, y es razonable. Pero significa que cada módulo propio y cada integración que construyas tienen un coste recurrente con un nombre detrás, y ese nombre debe ser una persona real o un contrato real. La versión 19 lo hace concreto: res.users.groups_id pasó a ser group_ids en el código de 19.0, y el modelo de contrato separado se movió al núcleo de RRHH como hr.version. Cualquier cliente externo que nombrase esos campos devuelve un 200 limpio con la forma equivocada, o un error, según la llamada. Ninguno de los dos lo detecta una suite de pruebas que simula Odoo.
La defensa barata es una prueba de contrato: una suite pequeña que ejecuta tus caminos reales de lectura y escritura contra una copia actualizada de la base de datos y verifica los campos de los que realmente dependes. Es la misma disciplina que con cualquier otra API que no controlas, y convierte la ventana de actualización obligatoria en una mañana en lugar de un simulacro de incendio.
Donde el alojamiento decide la discusión
Tres de los cinco límites los fija el lugar donde corre la base de datos, lo que convierte el alojamiento en una decisión de arquitectura y no de compras.
| Opción | Presupuesto de llamadas y acceso a la API | Control de actualizaciones | Encaja cuando |
|---|---|---|---|
| Odoo Online | Se aplica el techo de uso aceptable, API externa ligada al nivel de plan | Rolling Release, actualizaciones obligatorias según el calendario de Odoo, endpoints RPC fuera con 21.1 en el invierno de 2027 | Procesos estándar, integración ligera, sin ganas de infraestructura |
| Odoo.sh | La misma política, con alojamiento dedicado como vía documentada para levantar la limitación | Ramas escalonadas y builds de prueba, actualizaciones cuando tú las lanzas dentro de la ventana de soporte | Módulos propios de verdad, hábito de CI, tráfico de integración que un techo compartido estrangularía |
| Community autoalojado | Sin puerta de plan ni techo de política, la capacidad y el proxy inverso son tuyos | Enteramente tuyo, incluida la decisión de quedarte sin soporte | Integración intensa, requisitos de residencia de datos, operaciones internas que ya existen |
Aquí importa un hecho de licencia que se adivina a menudo. El código de Odoo Community se publica bajo la LGPL versión 3, y por eso un módulo propietario sobre Community es una práctica normal y no un argumento legal. Las ediciones Enterprise y los planes alojados de Odoo tienen condiciones comerciales separadas, así que léelas contra tu caso en lugar de heredar una opinión de un hilo de foro.
Autoalojar no es gratis. Compras la eliminación de un techo de llamadas añadiendo copias de seguridad, actualizaciones, monitorización, un proxy inverso que ahora limitas tú y alguien de guardia. Ese intercambio es el mismo que describe nuestra guía de software a medida frente a software estándar: paga por aquello que tu lógica de negocio toca de verdad y configura el resto.
La forma de referencia que construimos
Toda integración con Odoo que hemos revisado converge en la misma arquitectura una vez que los cinco límites están sobre la mesa. Es un servicio, propiedad de tu equipo, situado entre Odoo y todo lo demás.
- Una capa anticorrupción. Un módulo de tu código conoce los nombres de modelo, los campos y las rarezas de Odoo. Nada más en tu producto lo importa. Cuando
groups_idse convierte engroup_ids, cambias un archivo. - Tu propio almacén de lectura. Lo que tu producto lee en el camino caliente vive en tu base de datos, alimentado por eventos y reconciliado por calendario. La latencia del producto deja de depender de un ERP con techo de llamadas.
- Un endpoint de webhook con cola. Aceptar, persistir, responder 200, procesar en asíncrono, reintentar con espera creciente. La regla de automatización de Odoo es el productor y tu cola absorbe picos que un manejador sincrónico descartaría.
- Un escritor con un solo carril. Un único trabajador serializado impone el presupuesto de llamadas en un solo sitio, transporta las claves de idempotencia y te da un panel para todo el volumen de llamadas de la integración.
- Métodos de módulo propio para las invariantes. Métodos pequeños, con nombre y acotados a una transacción para las operaciones que no pueden romperse a medias. Revisados y versionados como código de producto, porque al actualizar son tu responsabilidad.
- Pruebas de contrato contra una base de datos realmente actualizada. La puerta que hace soportable el calendario de Odoo.
El análogo más cercano en nuestro propio trabajo no es un ERP. En el proyecto de automatización de procesos de MyMerch el cliente tenía una operación de comercio que funcionaba en muchas tiendas y perdía margen en dos puntos concretos. La propuesta tentadora era una reescritura. Lo que funcionó fue nombrar los traspasos manuales, automatizarlos y dejar la plataforma en paz. El mismo instinto sirve para un ERP: el valor está en la frontera de integración y la plataforma de debajo suele estar bien. La versión general de ese argumento la escribimos en saneamiento de arquitectura sin reescritura.
Cuatro cosas que no haríamos
- No replicar Odoo en tiempo real. Una sincronización bidireccional de estado mutable compartido sobre un enlace de una llamada por segundo es un proyecto de sistemas distribuidos disfrazado de integración. Elige un escritor por campo y mantenlo.
- No mover la contabilidad principal a tu producto. En el momento en que las facturas, la lógica fiscal o el plan de cuentas viven en dos sistemas, la reconciliación es tuya para siempre. Si una obligación legal te empuja allí, la respuesta suele ser una capa al lado del ERP y no dentro de tu aplicación, que es la misma conclusión a la que llegamos sobre la factura electrónica estructurada alrededor de un procesador de pagos.
- No poner lógica de negocio en reglas de automatización. Las acciones de servidor y los bloques de código en la interfaz son invisibles para la revisión de código, no están probados y no están versionados. Son un pegamento excelente y un lugar terrible para reglas de las que depende el dinero.
- No dejar que la integración no sea el módulo de nadie. Las personalizaciones de Odoo sin documentar y sin dueño son el motivo más común de que una actualización se atasque, y lo más habitual que un nuevo proveedor hereda a ciegas. Nuestra lista para esa situación de traspaso está en asumir un proyecto de software de otro proveedor.
Un plan de 30 días para pasar de la incógnita a la seguridad
- Días 1 a 3, fijar los hechos. Tipo de alojamiento, versión exacta, nivel de plan y si la API externa está disponible por contrato. Después, listar cada integración existente y qué protocolo habla. La mayoría de los equipos no puede responder a lo último el primer día.
- Días 4 a 10, medir el volumen de llamadas. Registrar cada llamada saliente durante una semana, agrupada por origen y propósito. Los trabajos de sondeo estarán arriba en esa lista y serán lo primero en desaparecer.
- Días 11 a 18, nombrar las invariantes. Escribir cada operación que deba ser todo o nada. Cada una se convierte en un método de módulo propio con prueba, o en un riesgo aceptado con un proceso de reconciliación detrás.
- Días 19 a 25, construir la frontera. Un módulo anticorrupción, un escritor serializado con claves de idempotencia, un endpoint de webhook con cola. Sin funciones nuevas en esa ventana.
- Días 26 a 30, planificar el paso a JSON-2. Un plan con fechas atado a tu propia ventana de actualización y no a 2027. Un usuario bot dedicado, claves de API por integración con caducidad y un runbook de rotación.
Treinta días asumen que alguien es dueño de las decisiones. Cuando ese dueño no existe, el trabajo se atasca en el paso dos, y ese es un motivo habitual por el que las empresas incorporan un CTO fraccional para un programa de integración acotado en lugar de contratar para ello.
FAQ de integración con Odoo
¿Está obsoleto XML-RPC en Odoo?
¿Cuál es el límite de peticiones de la API de Odoo?
¿Necesito un plan de pago de Odoo para usar la API externa?
¿Puedo ejecutar varias llamadas a la API de Odoo en una transacción?
¿Webhooks o sondeo con Odoo?
¿Los módulos propios bloquean una actualización de Odoo?
¿Con qué frecuencia hay que actualizar una base de datos en Odoo Online?
¿Qué se rompió para las integraciones en Odoo 19?
¿Puedo mantener un módulo propietario sobre Odoo Community?
Reflexiones finales
Odoo es un buen ERP con un contrato externo deliberadamente estrecho, y documenta ese contrato con honestidad. Los equipos que sufren son los que lo tratan como una base de datos abierta con una API REST atornillada. Lee los cinco límites como entradas de diseño: presupuesta tus llamadas, mete las invariantes en una transacción, pasa a JSON-2 en tu propio calendario en lugar de en 2027, y da a cada módulo propio un dueño que siga ahí en la próxima actualización. Construye un servicio frontera que controles y el ERP pasa a ser una dependencia que gestionas en lugar de una fecha límite a la que reaccionas.
Fuentes primarias
- Documentación de Odoo 19, External JSON-2 API, incluida la restricción de plan, la gestión de claves de API y la sección de transacciones
- Documentación de Odoo 19, External RPC API, con el aviso de retirada de los endpoints XML-RPC y JSON-RPC
- Política de uso aceptable de Odoo, abuso de red y de servicios, sobre el ritmo de llamadas limitadas
- Documentación de Odoo 19, actualización, sobre duración del soporte, actualizaciones obligatorias, Rolling Release y responsabilidad de los módulos propios
- Documentación de Odoo 19, reglas de automatización, incluida la acción Send Webhook Notification
- Código de Odoo 19.0, res.users, con el campo group_ids
- Código de Odoo 19.0, el modelo hr.version en el núcleo de RRHH
- Archivo LICENSE de Odoo 19.0, LGPL versión 3 para el código de Community
