Authentication
The data API identifies a real user of the workspace. Not a "service account", not a technical identity: your program acts under someone's name, with their permissions, and its actions carry their signature in the history.
01The four pieces
| Piece | Example | Where to find it |
|---|---|---|
| Address | https://kouassi.madata.app | Your workspace address. |
| Database | prod_kouassi | prod_ followed by the subdomain. |
| Login | [email protected] | The user login email. |
| API key | a1b2c3… | Created in the workspace, shown once. |
02Create an API key
- Open your preferences. In the workspace, click your name at the top right, then Preferences.
- "My connectors" tab. Scroll down to the API keys card.
- "New API key". Give it a description that will still tell you, six months from now, which integration to unplug: "online shop sync", not "test".
- Confirm your password. The workspace asks again: creating a key means opening a door.
- Copy the key. It is shown only once. The workspace only stores a fingerprint and cannot show it again. A lost key is replaced, never recovered.
It grants everything its holder can see and do, with no password and no second factor. It belongs in a secret manager or an environment variable, never in a code repository, never in a screenshot sent to support.
One key per program, named. The day a contractor leaves or a server is replaced, you revoke one key instead of rotating everything.
03Getting the uid
The uid is the numeric identifier of the user inside the
workspace. Every execute_kw method asks for it.
common = xmlrpc.client.ServerProxy(f"{URL}/xmlrpc/2/common")
uid = common.authenticate(DB, LOGIN, KEY, {})
if not uid:
raise SystemExit("key refused: check the database, the login and the key")
authenticate returns false, not an error, when
credentials do not pass. The fourth argument is a dictionary of information
about the calling client: {} will do.
- The database is not
prod_<workspace>. - The login is not the user login email.
- The key was revoked, or a password was pasted while two factor authentication is enabled.
04Two factor authentication
As long as two factor authentication is not enabled on an account, its password also works on the API. As soon as it is, the password is refused by the API and only an API key gets through. That is on purpose: a second factor cannot be typed inside a script, and a key can be revoked with one click.
Use a key even without two factor authentication. Code that pastes a user password breaks the day that user changes it, and it grants your program far more than data access: the interface too.
05Web session (cookie)
The third channel, /web/dataset/call_kw, is the browser one.
It does not take a key in a header: it wants a session
cookie, obtained from /web/session/authenticate.
# 1. open the session and keep the cookie
curl -s -c cookies.txt https://<workspace>.madata.app/web/session/authenticate \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","params":{"db":"prod_<workspace>",
"login":"[email protected]","password":"your-api-key"}}'
# 2. call with the cookie
curl -s -b cookies.txt https://<workspace>.madata.app/web/dataset/call_kw \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"call","params":{
"model":"res.partner","method":"search_count",
"args":[[]],"kwargs":{}}}'
This channel mainly serves to replay exactly what the interface does, when a method depends on the session context. For everything else, XML-RPC and JSON-RPC are simpler: nothing to keep between two calls.
An idle session eventually expires and
the next call returns "Madata Session Expired" (code
100). Your program has to know how to reconnect. Being
stateless, XML-RPC does not have this problem.
06A key never raises permissions
Three barriers apply to every call, in this order.
| Barrier | What it controls |
|---|---|
| Access rights | The right to read, create, update or delete a model. A user without access to accounting reads no journal entry, whatever the key. |
| Record rules | Which rows of the model they see. A sales rep may only see their own opportunities: the API shows exactly as much. |
| Active company | Records of the current company. See multi company. |
In other words: your program never sees more than its holder sees on screen. When a call returns less than expected, it is almost always a permission question, not a code one.
Pick the user to match the job. A catalogue sync does not need accounting rights. A dedicated, properly limited user is safer than an administrator key, and the history will then say who did what.
07Revoking
In Preferences → My connectors → API keys, the list shows each key, its description and its creation date. The bin icon deletes it: the next call from that program fails immediately.
Revoke without hesitation when a key may have leaked, when the integration it served is retired, or when the person who held it leaves. Creating a new one takes thirty seconds.