Importing and exporting an agent
The aidoo-agent/v1 file format: what it contains, what it leaves out, a full example and the reference of every field, to write or adapt an agent by hand.
9 min readUpdated September 16, 2026
An Aidoo agent is fully described by a JSON file. You can export it from its page, read it, edit it in a text editor, version it with your code or hand it to a colleague, then import it into another workspace. The file follows the aidoo-agent/v1 format.
Three common uses:
- Duplicating across workspaces: an agent tuned on a first Odoo is reinstalled in a minute for another customer or another company.
- Keeping a history: one file per agent in a Git repository, and every change of mission or rule becomes a readable revision.
- Writing an agent outside the interface: an integrator, a script or an AI assistant can produce the file; Aidoo validates it on import and shows it in the creation wizard before anything is saved.
Exporting
Open the agent's page and click the JSON button (download icon) in the header. The browser downloads agent-<id>.json. Export is reserved to workspace owners and administrators.
Importing
In Agents > New agent, choose Import a JSON file (aidoo-agent/v1). Aidoo checks the file, then opens the creation wizard prefilled. Nothing is saved at that point: you designate the Odoo identity, review every step, and the agent is created as a draft like any other. An invalid file is rejected with the offending field.
The file
{
"schema": "aidoo-agent/v1",
"exportedAt": "2026-09-16T10:00:00.000Z",
"source": { "agentId": "64a1b2c3d4e5f6789012345a", "workspace": "ACME" },
"agent": { "...": "the configuration, detailed below" }
}| Key | Role |
|---|---|
schema | Required, always "aidoo-agent/v1". This is what identifies the format. |
exportedAt | ISO 8601 date of the export. Informative, ignored on import. |
source | Agent and workspace of origin. Informative, ignored on import. |
agent | The full configuration, described in the reference below. |
A hand-written file only needs schema and agent.
What the export never contains
The file is a portable configuration, not a vault. It contains:
- no Odoo identity: on import, you choose again the member whose rights the agent uses;
- no API key, token or connection credential;
- no skills and no knowledge sources: they belong to the workspace; reattach them after import;
- no execution state: mission history, learning-mode observations, error counters, event cursors.
Two fields deserve a look before sharing a file: notifications.email.recipients (e-mail addresses) and assignedOdooLogins (Odoo logins of the users who see the agent in the widget). Clear them if the file changes company. collaborators are agent ids from the original workspace: on import into another workspace, those that do not exist are simply ignored.
Full example
The "Overdue invoice follow-up" agent from the gallery, as it exports:
{
"schema": "aidoo-agent/v1",
"agent": {
"name": "Overdue invoice follow-up",
"avatar": { "seed": "finance-relance-impayes" },
"mode": "scheduled",
"instructions": "Every morning, list customer invoices (account.move, move_type='out_invoice') that are posted, unpaid and past their due date. For each one, add a chatter note summarising the delay (days, amount) and schedule a follow-up activity for the responsible salesperson. End with a summary: number of overdue invoices, total amount, top 5 customers concerned.",
"style": { "preset": "descriptive" },
"model": { "provider": "auto", "modelId": "auto" },
"environment": "production",
"timezone": "Europe/Paris",
"trigger": { "cron": "0 8 * * 1-5" },
"permissions": {
"workflowsOnly": false,
"webAccess": false,
"requireApproval": false,
"email": false,
"emailMode": "propose",
"document": false,
"rules": [
{ "scope": { "groupKey": "facturation" }, "operations": ["query", "read"] },
{ "scope": { "models": ["mail.activity"] }, "operations": ["query", "read", "create"] },
{
"scope": { "models": ["account.move"] },
"operations": ["query", "read", "write"],
"valueConditions": [{ "field": "move_type", "operator": "=", "value": "out_invoice" }]
}
]
},
"limits": { "timeoutSecondsPerRun": 300, "maxAutoEmailsPerRun": 10 },
"autoPause": { "enabled": true, "maxConsecutiveErrors": 3 },
"activeHours": { "enabled": false, "days": [1, 2, 3, 4, 5], "start": "08:00", "end": "18:00" },
"notifications": {
"email": { "enabled": false, "recipients": [], "frequency": "onlyOnError" },
"odooChatter": { "enabled": false },
"odooDiscuss": { "enabled": false }
},
"assignedOdooLogins": [],
"commands": [
{
"id": "follow-up-customer",
"label": "Follow up a customer",
"prompt": "Follow up every overdue invoice of this customer and summarise what you did.",
"variables": [{ "name": "Customer", "required": true }]
}
]
}
}Field reference
Values marked "default" can be omitted: Aidoo fills them in on import.
Identity and mission
| Field | Type | Description |
|---|---|---|
name | text, 1 to 80 characters | Displayed name. |
avatar.seed | text, 1 to 64 characters | Seed of the generated avatar. Default: random. |
mode | scheduled, event or conversational | Scheduled, triggered by an Odoo event, or only on demand in the chat. |
instructions | text, 1 to 20,000 characters | The mission. See Writing a good mission. |
style.preset | descriptive, concise, human, formal, technical | Style of the reports. Default: descriptive. |
style.humanTone | warm, direct, enthusiastic, casual | Nuance of the human style. |
style.language | fr, en, es, de, pt, ar, nl, fi | Language of the reports. Default: account language. |
Model and environment
| Field | Type | Description |
|---|---|---|
model.provider | auto, anthropic, openai, google, moonshot, deepseek, nvidia | Provider. auto lets Aidoo pick an up-to-date eco model; it is the recommended and most portable choice. |
model.modelId | text | Model id at the provider; auto with the auto provider. A model missing from the catalogue or not covered by the plan is reported at activation. |
environment | production or staging | Odoo connection used. Default: production. |
timezone | IANA time zone | Time zone of schedules and active hours. Default: Europe/Paris. |
Trigger (trigger)
| Field | Type | Description |
|---|---|---|
cron | cron expression, 5 fields | Main schedule (scheduled mode). Example: 0 8 * * 1-5, Monday to Friday at 8 am. |
extraCrons | list, at most 4 | Additional slots (5 slots in total). |
event.model | Odoo model | Watched model (event mode), for example crm.lead. |
event.on | create, update or date | React to creation, to modification, or to an approaching date. |
event.conditions | list of [field, operator, value] triples | Filter in Odoo domain format, for example ["stage_id", "=", 3]. |
event.points | list, 1 to 3 entries | For on: "date": { "dateField": "date_deadline", "offsetMinutes": -1440, "label": "D-1" }. Offset between -10080 and 10080 minutes (one week). |
Permissions (permissions)
| Field | Type | Description |
|---|---|---|
workflowsOnly | boolean | The agent can only run the listed workflows. Default: false. |
allowedWorkflowIds | list | Allowed workflows when workflowsOnly is true. Workspace-specific ids. |
webAccess | boolean | Web search and page reading. Default: false. |
requireApproval | boolean | Every write waits for your approval. Default: false. |
email | boolean | May propose Odoo e-mails. Default: false. |
emailMode | propose or auto | auto sends without approval, within limits.maxAutoEmailsPerRun. Default: propose. |
document | boolean | Reading of attachments (PDF, images) with a vision model. Default: false. |
rules | list | Access rules, see below. |
learning.active | boolean | Learning mode. true opens a 48-hour window at creation. See Rules and permissions. |
collaborators | list, at most 5 | Ids of agents this one may ask or delegate to. |
mcpApps | list, at most 5 | External apps: { "appSlug": "slack", "source": "composio", "enabledTools": [...], "allowWrites": false }. See Integrations. |
Unless in workflowsOnly mode, an agent needs at least one rule, one external app, web access or learning mode.
Each rule:
| Field | Type | Description |
|---|---|---|
scope.groupKey | group key | A whole functional group (facturation, ventes, crm, stock...). |
scope.models | list of Odoo models | Or an explicit list. One of the two is required. |
operations | query, read, create, write, workflow, execute, report, print | Allowed operations. Deletion does not exist: an agent never deletes. |
valueConditions | list | Conditions on values: { "field": "amount_total", "operator": "<", "value": 5000 }. Operators: =, !=, >, >=, <, <=, in, not in, ilike. |
Limits and automatic pause
| Field | Type | Description |
|---|---|---|
limits.maxToolCallsPerRun | integer, at least 1 | Maximum number of actions per run. |
limits.maxTokensPerRun | integer, 1,000 to 4,000,000 | Token budget per run. |
limits.timeoutSecondsPerRun | integer, 30 to 2,000 | Maximum duration of a run. Default: 300. |
limits.monthlyCreditBudget | positive integer | Credit ceiling per calendar month. |
limits.maxAutoEmailsPerRun | integer, 1 to 100 | E-mails sent automatically per run. Default: 10. |
autoPause.enabled | boolean | Automatic pause after consecutive errors. Default: true. |
autoPause.maxConsecutiveErrors | integer, 1 to 20 | Pause threshold. Default: 3. |
autoPause.maxWritesPerRun | integer, at least 1 | Beyond it, the run stops and the agent pauses. |
Active hours, notifications, visibility, commands
| Field | Type | Description |
|---|---|---|
activeHours.enabled | boolean | Restrict runs to a time range. Default: false. |
activeHours.days | list of 0 (Sunday) to 6 | Default: [1, 2, 3, 4, 5]. |
activeHours.start, activeHours.end | HH:MM | Default: 08:00 and 18:00. |
notifications.email.enabled | boolean | Report by e-mail. Default: false. |
notifications.email.recipients | list of addresses | Recipients. |
notifications.email.frequency | everyRun, onlyOnError, dailyDigest | Default: onlyOnError. |
notifications.odooChatter.enabled | boolean | Note in the chatter of processed records. |
notifications.odooDiscuss.enabled | boolean | Message in Discuss. |
assignedOdooLogins | list, at most 200 | Odoo users who see the agent in the widget. Empty: nobody in particular. |
commands | list, at most 6 | Quick command buttons of the chat: id, label (40 characters), prompt (2,000 characters), variables (at most 3, { "name", "required" }). |
Compatibility
- Unknown fields are ignored on import: a file produced by a newer Aidoo version imports, minus the settings it added.
- Missing fields take their default value.
- A file whose
schemais notaidoo-agent/v1is rejected. A new version number will only be introduced for an incompatible change, with a bridge fromv1files. - Export goes through the same validation as import: an exported file always imports back.
Next step
- Creating an agent: the other creation paths
- Rules and permissions: building safe rules