OdooWebApps.com

Odoo API Keys: How to Create, Scope and Rotate Them

By Tal Oz, OdooWebApps. Published 22 September 2026.

How do you create an Odoo API key?

Log in as the user the integration should act as, then open Preferences (the menu under your avatar, also called My Profile), go to the Account Security tab and click New API Key. Odoo asks for a description and, on recent versions, a duration. Click Generate Key and copy the value immediately: it is shown once and cannot be retrieved afterwards. If you lose it, delete the key and make a new one.

The description is not decoration. It is the only thing that tells you later which system a key belongs to, so write "warehouse picking app, production" rather than "test".

Where does the key go in the call?

That depends on the API. On Odoo 19's JSON-2 the key is a bearer token in the Authorization header and there is no login step. On XML-RPC and JSON-RPC the key simply replaces the password: you still call authenticate with the database, the login and the key, and you still pass the key on every later call.

The same key, two APIs
# Odoo 19+, JSON-2: header, no login step
curl https://example.odoo.com/json/2/res.users/context_get \
  -H "Authorization: bearer $ODOO_API_KEY" \
  -H "Content-Type: application/json" -d '{}'

# Odoo 16 to 21, XML-RPC: the key is used in place of the password
uid = common.authenticate(DB, "api@example.com", ODOO_API_KEY, {})
models.execute_kw(DB, uid, ODOO_API_KEY, "res.partner", "search_read", [[]], {"limit": 1})

The login stays in use with the RPC protocols: a key is not a replacement for the user, it is a replacement for that user's password. It gives the same access to the account, so store it exactly as carefully, but it cannot be used to log in through the web interface.

How long does a key last?

On Odoo 19, at most three months. Odoo will not create a longer key, so every production integration needs a rotation routine. Shorter is recommended for interactive or externally exposed use, typically a day. Earlier versions did not enforce a maximum, which is why many older integrations hold keys that never expire; those keep working until the database moves to 19.

Keys can be rotated programmatically too, which is how a long-running integration stays alive without someone diarising it. The part worth planning is not the code: it is deciding who owns the rotation, where the new key is stored, and how you find out that a key is about to expire rather than when the app stops.

Which user should hold the key?

A dedicated integration user, never a person and never an administrator. Every API call runs with that user's access rights and record rules, so a key on an admin account turns a small bug into an unbounded one, and a key on a real employee breaks the day they leave and their account is archived.

A sane integration user
SettingWhat to doWhy
TypeInternal user (or portal, if the app only serves customers)External API access needs an internal user for most models
GroupsOnly the apps the integration touches, at User levelA picking app needs Inventory, not Accounting
Read-only where possibleAccounting: read access rather than full rightsMost dashboards only read
CompaniesOnly the companies it should seePrevents cross-company data leaking into results
NameSomething recognisable, like API picking appIt shows in the chatter of every record it touches

A useful side effect of a named integration user: every record it creates or updates shows that name in Odoo's tracking, so an accountant can see at a glance which changes came from the app and which from a person.

Why is my API key not working?

In rough order of how often we see each one. The first two are configuration, not code, and account for most cases:

  • The plan does not include API access. On Odoo Online the external API is only on the Custom plan, not One App Free or Standard. The code is fine; the subscription is the blocker.
  • Wrong database name. On Odoo Online it is usually the subdomain, but not always. A quick common.version() or GET /web/version proves the URL before you debug the credentials.
  • The key expired. Three months maximum on Odoo 19. Check the Account Security tab for the key's duration.
  • Login and key belong to different users. With the RPC protocols both must match; a key generated for one user will not authenticate another's login.
  • Access rights, not authentication. If authenticate returns a uid but a call raises an access error, the key is fine and the user's groups are the problem. Test as that user in the web interface to see the same error.
  • Two-factor authentication. It does not block API keys; that is exactly what keys are for. If a script broke when 2FA was enabled, it is still sending the password.

How should the key be stored?

As a secret, in the environment or a secrets manager, never in source control and never in anything that reaches a browser or a mobile app. An Odoo API key carries the full access of its user, so a key shipped in client-side code is the same as publishing that user's password. In the apps we build, Odoo calls only ever run on the server, and the key exists as one environment variable on the host.

Rotate deliberately: create the new key, deploy it, confirm traffic is using it, then delete the old one. Because Odoo shows a key value only once, the rotation should be a documented routine rather than a scramble when a key silently expires. If you want that, plus the integration itself, built and maintained for a specific workflow, that is what we do.

Want this looked at for your setup?

Every Odoo instance is configured a little differently. Tell us what you're working with and we'll give you a straight answer.