What Are System Parameters?
System parameters (ir.config_parameter) store key-value configuration settings in the database. They are used for: module settings, feature flags, API keys, URL configurations, and any value that should persist across restarts but be configurable without code changes.
Accessing Parameters
Get a Parameter
# In Python:
value = self.env['ir.config_parameter'].sudo().get_param('my_module.api_key')
# With default value:
value = self.env['ir.config_parameter'].sudo().get_param(
'my_module.max_retries', '3'
)
# Always returns a string (or False if not set)
# Convert types as needed:
max_retries = int(self.env['ir.config_parameter'].sudo().get_param(
'my_module.max_retries', '3'
))Set a Parameter
# In Python:
self.env['ir.config_parameter'].sudo().set_param(
'my_module.api_key', 'sk_live_xxx'
)
# In XML data:
<record id="config_api_url" model="ir.config_parameter">
<field name="key">my_module.api_url</field>
<field name="value">https://api.example.com</field>
</record>Via UI
# Settings → Technical → Parameters → System Parameters
# Here you can view, edit, and create parameters
# Useful for debugging and manual configurationCommon Odoo Parameters
| Key | Purpose | Example |
|---|---|---|
web.base.url | Base URL of Odoo instance | https://erp.company.com |
mail.catchall.domain | Email catchall domain | company.com |
mail.catchall.alias | Catchall email prefix | catchall |
mail.default.from | Default from email | notifications |
database.uuid | Unique database identifier | auto-generated UUID |
database.create_date | When database was created | 2026-01-15 |
report.url | URL for wkhtmltopdf | http://localhost:8069 |
Using Parameters in res.config.settings
# Expose parameters in the Settings UI:
class ResConfigSettings(models.TransientModel):
_inherit = 'res.config.settings'
my_api_key = fields.Char(
string='API Key',
config_parameter='my_module.api_key',
)
my_feature_enabled = fields.Boolean(
string='Enable Feature',
config_parameter='my_module.feature_enabled',
)
my_max_retries = fields.Integer(
string='Max Retries',
config_parameter='my_module.max_retries',
default=3,
)
# These automatically sync with ir.config_parameter
# Users can change them in Settings without touching codeSettings View
<record id="res_config_settings_view_form_inherit" model="ir.ui.view">
<field name="name">res.config.settings.inherit.my_module</field>
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
<field name="arch" type="xml">
<xpath expr="//div[@id='base_settings']" position="before">
<div class="app_settings_block" data-string="My Module">
<h2>My Module Settings</h2>
<div class="row mt16 o_settings_container">
<div class="col-12 o_setting_box">
<div class="o_setting_right_pane">
<label for="my_api_key"/>
<field name="my_api_key"/>
</div>
</div>
<div class="col-12 o_setting_box">
<div class="o_setting_left_pane">
<field name="my_feature_enabled"/>
</div>
<div class="o_setting_right_pane">
<label for="my_feature_enabled"/>
<div class="text-muted">
Enable the special feature
</div>
</div>
</div>
</div>
</div>
</xpath>
</field>
</record>Boolean Parameter Quirk
# IMPORTANT: Odoo DELETES the ir.config_parameter row
# when a Boolean field is unchecked in Settings!
# This means:
# - Checked: parameter exists with value 'True'
# - Unchecked: parameter DOES NOT EXIST (not 'False')
# Correct check:
is_enabled = self.env['ir.config_parameter'].sudo().get_param(
'my_module.feature_enabled'
)
# is_enabled is 'True' (string) or False (not found)
# To check if disabled:
if not self.env['ir.config_parameter'].sudo().get_param('my_module.feature_enabled'):
# Feature is disabled (parameter doesn't exist)
passCommon Patterns
Feature Flag
def _is_feature_enabled(self):
return bool(self.env['ir.config_parameter'].sudo().get_param(
'my_module.feature_x_enabled'
))API Configuration
def _get_api_client(self):
ICP = self.env['ir.config_parameter'].sudo()
return MyAPIClient(
url=ICP.get_param('my_module.api_url', 'https://api.default.com'),
key=ICP.get_param('my_module.api_key'),
timeout=int(ICP.get_param('my_module.api_timeout', '30')),
)Security Considerations
- Parameters are visible to admin users in the UI
- Always use
sudo()when reading parameters (they are global) - Do NOT store highly sensitive secrets (private keys, database passwords) — use environment variables or a secrets manager
- API keys are acceptable in parameters for convenience
DeployMonkey
DeployMonkey's AI agent manages system parameters — setting API keys, configuring URLs, and toggling feature flags. It understands the Boolean quirk and handles parameter types correctly.