Odoo automation · runs monthly
Create Odoo invoices from a client list
At month end you have a list of retainer clients and amounts, and every line becomes an invoice typed into Odoo by hand: customer, lines, due date, Confirm, Send.
Cotlet does it in your own Odoo account with list_contacts, create_contact, create_draft_invoice, post_invoice and send_invoice, called by your AI agent, an n8n workflow or a script.
Hosted · nothing to install or maintain
Can Odoo do this on its own?
Odoo creates invoices in the app through the Customer Invoices journal (checked 14 Oct 2026), and there is no bulk import of invoice lines from a list in the pages we read. From outside the app the external API is Custom-plan only on Odoo Online, and the development-version MCP server has Create Records but no tool that posts or sends an invoice.
How you do it in Odoo today
- Open the Customer Invoices journal from the Accounting Dashboard, or create the draft from a sales order.
- Set the customer, then the due date or payment terms, then add lines on the Invoice Lines tab with Add a line. Odoo pulls default payment terms from the customer record.
- Click Confirm. The status changes from Draft to Posted, Odoo assigns the invoice number, and a journal entry is created.
- Click Send, choose Email or Download in the Send window, and repeat for the next client.
- A posted invoice can no longer be updated; Reset to draft is the way back when a line is wrong.
How to create Odoo invoices from a client list
Create a draft customer invoice in Odoo for each client in this list with the retainer amount next to their name. Add missing clients as contacts first. Show me the drafts, and post and send them only after I say so. - 01
Resolve every client
list_contacts looks each name up. A client with two matching contacts is stopped and listed for you; a name with no match goes to create_contact, which only adds a contact and reaches nobody.
- 02
Create drafts only
create_draft_invoice makes one draft per client with the lines from your list. A draft has no accounting impact until it is confirmed, so the agent can create all of them before you look.
- 03
Show the batch
The agent returns each draft with its customer, lines and total, and flags any client who already has a draft for the same period so you do not bill twice.
- 04
Post after your OK
post_invoice confirms an invoice, which locks it and gives it its number, so each call waits for your OK. The agent posts only the drafts you approved.
- 05
Send what is posted
send_invoice emails the posted invoice to the customer, again with your OK per call. Invoices whose contact has no email are posted but not sent, and are listed.
What you get back
Clients in the list: 3
New contacts created: 1 (Harbor Print)
Draft invoices: 3, total 7,000.00 EUR
- Northwind Studio 2,400.00 EUR
- Harbor Print 2,150.00 EUR
- Atlas Dental 2,450.00 EUR
Posted and sent: 0, waiting for your OK Other ways to ask
- Invoice every contact tagged Retainer for 1,500.00 EUR with the line "Monthly retainer", due in 14 days.
- Create the drafts only and send me the totals; I will post them in Odoo.
- Create one draft per row in this sheet, with the description in column C as the invoice line.
What Odoo allows, and what to know first
- Odoo creates invoices in Draft status, and a draft has no accounting impact until you click Confirm.
- On confirmation Odoo assigns each invoice a unique number from a defined sequence and creates a journal entry.
- Once confirmed, an invoice can no longer be updated; Odoo's Reset to draft button is how you change it.
- Odoo takes default payment terms from the customer record when you set the customer on an invoice.
post_invoice and send_invoice ask for your OK by default. To run it monthly without you, switch confirmation off for those tools in your dashboard.
Sources: Odoo documentation: Customer invoices · Odoo documentation: External API · Odoo documentation: Available MCP tools
Call create_draft_invoice from a script
curl -X POST https://cotlet.dev/api/v1/odoo/contacts/931/draft-invoices \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"invoice_date":"2026-10-31","due_date":"2026-11-14","lines":[{"description":"Monthly retainer, October","quantity":1,"unit_price":2400}]}' {
"invoice_id": 4201,
"number": null,
"contact": "Northwind Studio",
"status": "draft",
"payment_status": "not_paid",
"invoice_date": "2026-10-31",
"due_date": "2026-11-14",
"lines": [
{
"description": "Monthly retainer, October",
"quantity": 1,
"unit_price": 2400,
"subtotal": 2400
}
],
"amount_untaxed": 2400,
"amount_tax": 0,
"amount_total": 2400,
"currency": "EUR"
} MCP: add https://cotlet.dev/mcp/v1 with the same key; the call is odoo_write → create_draft_invoice. Example data.
Schedule it in n8n, Make, Zapier or cronOdoo tools this automation uses
| Tool | Parameters |
|---|---|
| list_contacts | query, is_company, limit, offset |
| create_contact | name, email, phone, is_company |
| create_draft_invoice | contact_id, lines, invoice_date, due_date, reference |
| post_invoice | invoice_id |
| send_invoice | invoice_id, method |
Frequently asked questions
Is it safe to connect Odoo to Cotlet?
Yes. You sign in to Odoo yourself, in your own Cloud Browser in the EU, and we never save your password. Your agents only get Odoo once you enable it, every background request is listed, and the browser profile is stored encrypted with AES-256-GCM, the cipher 1Password uses for its vaults. The AI model never sees a login, posts and messages wait for your OK, and Disable for agents cuts access in one click. Independent scanners grade cotlet.dev A+ on Qualys SSL Labs, securityheaders.com and Mozilla Observatory; live results are on https://cotlet.dev/security.
Give your agent access to Odoo.
Free 7-day trial with 2,000 credits, no card needed. Cotlet is independent and not affiliated with Odoo.