Features

Everything you need in front of Odoo.

ODXProxy gives your apps one safe, unified JSON-RPC API in front of any number of Odoo instances — with auth, a method allowlist, metrics, and clustering out of the box.

Function calling

Call methods, not just rows.

Reading and writing records is only half of it. The real power is call_method: invoke an Odoo model’s own public methods by name to run the ERP’s business logic — post an invoice, confirm an order, trigger a workflow.

Because the method runs inside Odoo, its validations, computed fields, and side-effects all happen — instead of being skipped by writing raw fields. It’s still authenticated and scoped to the Odoo user’s permissions, and it requires an explicit fn_name, so nothing runs by accident.

See call_method in the docs →
Post an invoice
POST /api/odoo/execute
x-api-key: <PROXY_API_KEY>

{
  "id": "01J9Z8K3QJ7Y5T2N6V4W8X0ABC",
  "action": "call_method",
  "model_id": "account.move",
  "fn_name": "action_post",
  "params": [[142]],
  "keyword": {},
  "odoo_instance": { "url": "…", "db": "…", "user_id": 2, "api_key": "…" }
}

One unified API surface

A single JSON-RPC 2.0 endpoint in front of Odoo. Callers send one request shape; the target Odoo instance is named in the body, and execute_kw is forwarded on their behalf.

Schema-agnostic by design

Add a model or field in Odoo and it just works — no proxy redeploy, no config, no schema regeneration. Callers name the model and fields in the request body, so the proxy adapts to your Odoo schema instead of mirroring it.

Security by allowlist

Odoo's execute_kw can call any model method. ODXProxy restricts callers to a curated allowlist of nine actions — search, read, create, write, and a few more — shrinking the blast radius of a leaked credential.

Two distinct secrets

The proxy's API key authenticates the caller to ODXProxy; each request also carries the Odoo user's own key. The two are never conflated, so the proxy's key never grants raw Odoo access.

Multi-instance routing

Because the Odoo instance is specified per request, one deployment can route to many backends — ideal for many databases and instances, agencies, and microservice fleets.

Observability built in

A Prometheus metrics endpoint, structured JSON logs, and a request id on every call you can trace end to end — so you can see exactly how your Odoo traffic behaves. The proxy never logs the API keys.

Tamper-resistant by design

Integrity is cryptographically signed (ECDSA P-256) and re-validated on every request against a trusted external time source — not the system clock — so a rolled-back clock can't slip past the check.

Hardened operations

Refuses to run as root, ships systemd / OpenRC hardening and a distroless nonroot image, and shuts down gracefully under load.

Clustering ready

An optional Redis-based heartbeat and upstream pools let you run a fleet of proxies behind one address.

High-performance Rust

Built on Rust with Tokio and an Axum + Hyper HTTP stack (HTTP/1.1 and HTTP/2), with built-in br / gzip / deflate response compression and a small runtime footprint under load.

The nine allowed actions

Every caller is limited to these. Anything else on a model goes through call_method, which requires a named function.

  • search_count
  • search
  • read
  • fields_get
  • search_read
  • create
  • write
  • unlink
  • call_method

See the actions reference and the error catalog for the full protocol.

See it in your stack.

Deploy the proxy, set one API key, and make your first request in minutes.