Devest · Odoo REST API

REST API for Odoo

Accounting, Sales, Purchase and Inventory through clean, versioned endpoints under /api/v1, running with each user's own Odoo permissions. Available for Odoo 18 and Odoo 19.

Get started in three steps

  1. Install the module devest_rest_api from Apps in Odoo.
  2. Grant access: Settings → Users → add the group REST API / User. Use a dedicated user per integration, with only the app rights it needs.
  3. Create a key: REST API menu → My API key. The key works only for this API, expires, and can be revoked in My Profile → Account Security.
curl -H "Authorization: Bearer $ODOO_API_KEY" \
  "https://your-company.odoo.com/api/v1/sale-orders?state=sale&limit=20&fields=name,partner_id,amount_total"

What it covers

Accounting

Customer invoices, vendor bills, journal entries and items, payments, accounts, journals, taxes, analytic accounts. Post, reset to draft, cancel.

invoices · bills · journal-entries · journal-items · payments · accounts · journals · taxes · analytic-accounts

Sales

Quotations, sales orders and lines, sales teams, pricelists. Confirm, cancel, create invoices.

sale-orders · sale-order-lines · sales-teams · pricelists

Purchase

Requests for quotation, purchase orders and lines. Confirm, approve, create vendor bills.

purchase-orders · purchase-order-lines

Inventory

Receipts, deliveries and internal transfers, stock levels, moves, locations, warehouses, lots and serial numbers. Reserve and validate.

transfers · stock-levels · stock-moves · locations · warehouses · lots

Common data

Contacts, products, categories, units of measure, currencies, countries.

partners · products · product-categories · uoms · currencies · countries

Your own models

Administrators expose any other model (for example custom construction models) from the Endpoints screen, choosing its fields and actions, without code.

Security and best practices

AuthenticationOdoo's own API keys: stored hashed, expiring, revocable. Sent as Authorization: Bearer <key>.
AuthorizationEvery call runs as the key's user: access rights, record rules and companies apply. Records the user cannot see answer 404.
Least exposureEach endpoint whitelists readable fields, writable fields and actions. Passwords, tokens and secrets are never exposed.
ScopeThe invoices endpoint can never reach vendor bills, and refuses changes that would turn an invoice into another document type.
TransactionsOne database transaction per call: any error rolls everything back.
Rate limitingPer user per minute (300 by default), then 429 with Retry-After.
Safe retriesSend Idempotency-Key with any POST; a retried request never creates a duplicate.
Audit logEvery call is recorded: user, key, records, fields changed, result, duration and IP address.

Quick reference

ListGET /api/v1/{resource}?fields=&limit=&offset=&order=&filter=&search=&updated_since=
ReadGET /api/v1/{resource}/{id}?fields=name,partner_id(email),order_line(product_id,price_unit)
CreatePOST /api/v1/{resource} → 201 + Location
UpdatePATCH /api/v1/{resource}/{id}; lines: {"id": 12, "price_unit": 9}, {"id": 12, "_delete": true}
DeleteDELETE /api/v1/{resource}/{id} → 204
WorkflowPOST /api/v1/{resource}/{id}/actions/{action} (e.g. action_confirm, action_post, button_validate)
Filtersstate=sale&partner_id=7 or filter=[["amount_total",">",1000]]
CompaniesX-Company-Id: 1,3 · language: Accept-Language: en
Errors{"error": {"code", "message", "request_id", "details"}} · every response has X-Request-Id
POST /api/v1/sale-orders
Authorization: Bearer <key>
Idempotency-Key: order-2026-0001
Content-Type: application/json

{"partner_id": 7, "client_order_ref": "PO-778",
 "order_line": [{"product_id": 5, "product_uom_qty": 3, "price_unit": 50}]}

Each Odoo database also serves its own live reference at /api/v1/docs, built from its installed apps and the signed-in user's rights. Field names follow the Odoo version: on Odoo 19, order lines use product_uom_id and tax_ids.