技術ログ

When was an Odoo API key last used? Find unused keys and limit API calls (Odoo 20)

公開: 2026-10-10 · 著者: GRAMSHIFT

What Odoo stores about a key, what Latest Login and the server log can tell you, and how to cap the calls of an AI agent

When was an Odoo API key last used? Find unused keys and limit API calls (Odoo 20)

Odoo 20 does not record when an API key was last used. A key stores its description, its user, its scope, its creation date and its expiration date, and nothing about its use: no last call, no IP address, no number of calls. Odoo also has no limit on how many calls a key may make. Below: what you can still find out with standard Odoo, free ways to keep keys under control, and how to see the use of every key, checked against the Odoo 20 source.

  • The key record (res.users.apikeys) has a description, a user, a scope, a creation date and an expiration date. There is no "last used" field.
  • Latest Login, a column of the Users list, changes when someone logs in to the web client, and when an XML-RPC or JSON-RPC script calls authenticate. It does not change for JSON-2 calls, and it belongs to the user, not to the key.
  • The server log has one line per call with the time, the IP address, the model and the method, but not the key.
  • Expiration dates make old keys stop working on their own, and administrators can cap how long a key may live.

What Odoo stores about an API key

In Odoo 20 an API key is a row of res.users.apikeys with five things you can see: the description you typed ("Claude Desktop", "n8n sync"), the user it belongs to, its scope, its creation date and its expiration date. The secret itself is stored hashed. When a call arrives, Odoo checks the key and runs the call as that user. Nothing is written to the key: you cannot tell from it whether it was used this morning or never.

Users see their own keys under My Preferences, Security, where the button is Create API Key. Administrators see every key, with its user and creation date, and can delete it, under Settings, Permissions, Manage API Keys.

Latest Login: only some clients update it

The Users list has a Latest Login column (hidden by default: switch it on from the optional columns), taken from res.users.log. Odoo adds a row there when a login goes through its login method: a person signing in to the web client, or a script calling XML-RPC common.authenticate (or login) with the key as password, which many XML-RPC clients do once before their calls.

Calls signed with the key directly do not go through that method. A JSON-2 call with Authorization: Bearer, and an execute_kw call that passes the key, are checked without adding a login row. So an AI tool that only uses JSON-2 can work all day and leave Latest Login unchanged. And because the field belongs to the user, three keys of one user share it.

The server log: calls, but not keys

If you run Odoo yourself, its log has one line per HTTP request, with the time, the database, the client IP address and, for API calls, the model and method (for example POST /json/2/res.partner/search_read, or /xmlrpc/2/object#res.partner.write for XML-RPC). The request lines do not name the key or the user (only authenticate calls write a line with the login name). You can see that something read contacts at 03:00 from a given IP address; you cannot see which of your keys it was. Behind a reverse proxy, turn on Odoo's proxy mode so that the address is the client's and not the proxy's.

Free ways to keep keys under control

  • One user per tool. Create the key of each AI tool or integration under its own user. Latest Login, Last Updated by and the chatter then name the tool, and you can limit what it may do with access rights (see Read-only Odoo API key for ChatGPT, Claude or an MCP server).
  • Expiration dates. In Odoo 20 every key can get an expiration date, and each user group has an API Keys maximum duration days setting that caps how far in the future it may be for users of that group. Keys that nobody renews stop working on their own. Keys created by an administrator can have no expiration date at all.
  • A list of keys with owners. Keep, outside Odoo, which key belongs to which tool and who set it up. When a tool is retired, remove its key.

Limiting how many calls a key can make

Odoo has no rate limit. An AI agent that retries a failing call in a loop can send thousands of requests in a few minutes, and Odoo serves them all.

With nginx in front of Odoo, limit_req can cap requests. It is usually keyed on the client IP address, so every tool running on the same server shares one limit. For JSON-2 you can key it on the Authorization header instead (limit_req_zone $http_authorization ...), which gives each key its own limit; requests without that header are then not limited by that zone, so keep an IP-based limit as well. For XML-RPC and JSON-RPC the key travels inside the request body, where nginx cannot see it.

What each option gives you

Key recordLatest LoginServer lognginx limit_req
Last use of each keyNoPer user, some clientsNo (no key)No
IP addressNoNoYes, per callNo
Calls per keyNoNoNoNo
Limit per keyNoNoNoJSON-2 only, with the Authorization header

Last use, IP and calls of every key, with a limit per key

For Odoo 20 we built AI API Key Usage & Rate Limit (paid, by GRAMSHIFT, which publishes this site). It lists every API key of the database with the time of its last call, the IP address and channel of that call (JSON-2, XML-RPC or JSON-RPC), and its calls today, in 7 days and in 30 days, with filters for keys that made no call for 30 days. Give any key a limit in calls per minute, or set a default for every key: calls above it get HTTP 429 with Retry-After on JSON-2, and an error with the same message on XML-RPC and JSON-RPC, while every other key keeps working. It counts from the day it is installed, works with the keys you already have, and its page lists exactly what is covered.

To see what a key changed, see How to see what ChatGPT, Claude or an MCP server changed in Odoo.

How this was checked: the key fields, the login log, the maximum key duration and the way calls are authenticated were read in the Odoo 20 source (as of 2026-10-06); the log lines come from a local Odoo 20 Community server. The module's behaviour was tested on a local Odoo 20 Community server on 2026-10-10. This page is not affiliated with Odoo S.A. On the use of AI: this article and the module were written by Claude, an AI model, working for GRAMSHIFT; the quoted code paths were compared against the source.

よくある質問