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.
11 min readUpdated October 10, 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-<agent-name>.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, choose the Odoo users who will see the agent in the widget, review every step, then Create the agent creates and activates it, like any other agent. An invalid file is rejected with the offending field.
If the file does not specify permissions.learning (and the agent is not in workflowsOnly mode), it starts in learning mode and the file's rules serve as starting rules.
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, no knowledge sources, no Drive files: they belong to the workspace; reattach them after import;
- no agent group: groups are specific to a workspace; put the agent in a group after import;
- no connection to external apps: the file keeps each app's name and the selected tools, not the connected account; connect the app under Integrations in the destination workspace;
- 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. allowedWorkflowIds also point to workflows of the original workspace: select them again at the Permissions step. drive.folders paths are kept as is: check that those folders exist in the destination Drive.
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,
"askUser": 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" }]
}
],
"learning": { "active": true }
},
"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 },
"questions": { "widget": true, "email": 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. |
avatar.character | integer, 1 to 20 | Illustrated character of the agent. Absent: assigned automatically. |
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, to be approved before sending. 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. |
askUser | boolean | In autonomous runs, the agent may ask a human a question and resume with the answer. Default: false. |
drive.enabled | boolean | Access to the Aidoo Drive: its private folder in write mode, the shared folder in read mode. Default: false. |
drive.folders | list, at most 10 | Additional allowed folders: { "path": "accounting/exports", "access": "read" } (read or write). Workspace-specific paths. |
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": [...] }. source is composio (app catalogue, default), custom (one of your own MCP servers) or native (connector provided by Aidoo). enabledTools (at most 100) restricts the agent to those tools; absent: every tool of the app. See Integrations. |
Unless in workflowsOnly mode, an agent needs at least one rule, one external app, web access, Drive 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. Absent: unlimited (default). |
limits.maxTokensPerRun | integer, 1,000 to 4,000,000 | Token budget per run. Absent: the equivalent of 100 credits for the chosen model, which is also the minimum. |
limits.timeoutSecondsPerRun | integer, 30 to 4,500 | Maximum duration of a run, in seconds. 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. Absent: unlimited (default). |
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. |
notifications.questions.widget | boolean | The agent's questions are shown in the Odoo widget of assigned users. Default: true. |
notifications.questions.email | boolean | Questions are e-mailed to the recipients, with an answer link. Default: false. The dashboard always shows them. |
assignedOdooLogins | list, at most 200 | Odoo users who see the agent in the widget. Empty: the agent appears in nobody's widget. |
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