Odoo
Let hires look up customers and invoices, see who owes what, draft, confirm and send invoices, record payments and keep notes in Odoo, online or on your own servers.
Explore 10 actions and their permissionsExact inputs, sign-in scopes, access limits and approval rules.
With Odoo, a hire can:
- find customers and see what each one owes,
- list customer invoices by status (draft, unpaid, overdue, paid, cancelled), customer and date,
- read an invoice with its lines and its latest messages and notes,
- see who owes what and how late (current, 1–30, 31–60, 61–90 and over 90 days),
- list payments received,
- draft an invoice, confirm it, send it by email, register a payment, and add a note to an invoice's chatter.
It works with Odoo Online, Odoo.sh and an Odoo you run yourself, from Odoo 17 on.
Odoo Online plans
On Odoo Online, connecting other apps needs the Custom plan. The One App Free and Standard plans don't allow it. Odoo.sh and your own Odoo always do.
1. Make an API key in Odoo
Hires act as the Odoo user whose key you use, so use an accountant's user or one made for Roster with Invoicing rights (Billing or Accountant).
- In Odoo, click your picture at the top right and choose Preferences (or My Profile). Once you've typed your Odoo's address in Roster, the form links straight to this page.
- Open Account Security and click New API Key.
- Confirm your password, name the key
Roster, choose how long it lasts, and click Generate key. - Copy the key. Odoo shows it only once.
In Odoo 19, keys last at most three months. When one runs out, make a new one and paste it on the connection.
2. Connect it in Roster
- Open Integrations → Tools → Add a tool, search for Odoo and choose it.
- API key: paste the key.
- Odoo address: the address you open Odoo at, like
https://mycompany.odoo.com. - Odoo version: Odoo 19 or later for current Odoo Online and new installs; Odoo 17 or 18 for older ones. Not sure? In Odoo, open Settings and scroll to the bottom: the version is shown there.
- Database: for Odoo 17 or 18, the database name (on Odoo Online it's usually the first part
of the address,
mycompany). For Odoo 19 only needed if your Odoo server has several databases. - Login (Odoo 17 or 18 only): the login of the user who made the key.
- Click Connect. Roster signs in to Odoo with the key, and the connection shows Connected as your company's name. If Odoo refuses the key (or, for 17 and 18, the login), Roster says so and saves nothing.
3. Give hires access
On the hire's Tools tab, click Give access on Odoo:
- Read only: it can look up customers, invoices and payments and see who owes what. It can't change anything.
- Read and write: it can also draft invoices, confirm them, send them, register payments and add notes.
Drafting, confirming and sending are separate. A draft isn't owed and nobody sees it until someone confirms or sends it, so a hire can prepare invoices for you to check first. Confirming gives the invoice its number without emailing anyone; sending emails it with Odoo's own invoice email and PDF.
Hires refer to invoices by their number, like INV/2026/00012 (drafts don't have one yet, so
they use the id), and to customers by name or email. Products and income accounts on a line are
given by their Odoo id.
Watching invoices
A hire's responsibility can watch Odoo: it's woken when customer invoices change (confirmed, paid, edited, cancelled) or fall overdue, with the list. Checking costs nothing when nothing changed.
If something goes wrong
- "Invalid apikey" or "didn't accept the login and API key": the key ran out or was deleted, or the login doesn't match the user who made it. Make a new key.
- "Set the Odoo database": add the database name on the connection.
- Odoo Online refuses every request: check the plan allows connecting other apps (Custom).
- "Access denied" on one thing: the Odoo user behind the key lacks that right. Give it Invoicing rights in Odoo.
Tools and permissions reference
This reference is built from the same definitions Roster uses to connect Odoo and give hires access. It updates with each release.
Authentication and requested permissions
The account or app you connect sets the outer limit. Each hire's access can narrow it further. Connecting a tool gives it to no hire until you give access on that hire's Tools tab.
API key or access token
In Odoo: your picture → Preferences → Account Security → New API Key.
No fixed permission list is declared for this connection. Review the sign-in consent screen, the account's roles, and the service's own documentation before connecting.
Connection fields
| Field | What to provide |
|---|---|
API keyapiKeyRequired · sealed secret | In Odoo: your picture → Preferences → Account Security → New API Key. |
Odoo addressurlRequired | The address you open Odoo at, without /odoo or /web. |
Odoo versionapiOptional | Use the value for your account or connection. Choices: Odoo 19 or later (JSON-2) (json2); Odoo 17 or 18 (JSON-RPC) (jsonrpc). Starts with: |
DatabasedatabaseOptional | For Odoo 17 or 18, and for an Odoo server with several databases. On Odoo Online it's usually the first part of the address. |
LoginusernameOptional | The login of the user who made the key. Shown when |
Per-hire limits
Read-only hires receive only actions that read. Read-and-write access also allows actions that change things, where the connection itself permits them. An empty resource allowlist usually means everything the connected account can reach; each field below explains its meaning.
No additional fields.
Actions
10 actions: 5 only read and 5 change something. A read action may still need approval when your workspace or hire is set to ask. A locked approval requirement always applies.
10 of 10 actions. Open an action for its arguments and full input schema.
list_customersRead only
Customers in Odoo with what each owes, optionally matching words in their name or email, or only those owing or overdue.
Approval: Uses your workspace and hire approval settings.
| Argument | Type | Details |
|---|---|---|
searchOptional | string | words in the name or email |
owingOptional | "any" | "unpaid" | "overdue" | See input schema below.Default: "any" |
limitOptional | integer | See input schema below.Default: 30 |
Full input schema (JSON)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"search": {
"description": "words in the name or email",
"type": "string"
},
"owing": {
"default": "any",
"type": "string",
"enum": [
"any",
"unpaid",
"overdue"
]
},
"limit": {
"default": 30,
"type": "integer",
"minimum": 1,
"maximum": 200
}
}
}list_invoicesRead only
Customer invoices, newest first, filtered by status (draft, unpaid, overdue, paid, void), customer, invoice date and words in the number or reference.
Approval: Uses your workspace and hire approval settings.
| Argument | Type | Details |
|---|---|---|
statusOptional | "any" | "draft" | "unpaid" | "overdue" | "paid" | "void" | unpaid: sent and not fully paid; overdue: unpaid and past its due dateDefault: "any" |
customerOptional | string | a customer's name or id |
fromOptional | string | invoice date on or after, yyyy-mm-dd |
toOptional | string | invoice date on or before, yyyy-mm-dd |
searchOptional | string | words in the invoice number or reference |
limitOptional | integer | See input schema below.Default: 30 |
Full input schema (JSON)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"status": {
"default": "any",
"description": "unpaid: sent and not fully paid; overdue: unpaid and past its due date",
"type": "string",
"enum": [
"any",
"draft",
"unpaid",
"overdue",
"paid",
"void"
]
},
"customer": {
"description": "a customer's name or id",
"type": "string"
},
"from": {
"description": "invoice date on or after, yyyy-mm-dd",
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$"
},
"to": {
"description": "invoice date on or before, yyyy-mm-dd",
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$"
},
"search": {
"description": "words in the invoice number or reference",
"type": "string"
},
"limit": {
"default": 30,
"type": "integer",
"minimum": 1,
"maximum": 200
}
}
}get_invoiceRead only
One customer invoice in full: customer, dates, lines, totals, what's owed and its latest messages and notes.
Approval: Uses your workspace and hire approval settings.
| Argument | Type | Details |
|---|---|---|
invoiceRequired | string | the invoice number, e.g. INV/2026/00012, or its id |
Full input schema (JSON)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"invoice": {
"type": "string",
"minLength": 1,
"description": "the invoice number, e.g. INV/2026/00012, or its id"
}
},
"required": [
"invoice"
]
}receivables_summaryRead only
Who owes what and how late: open customer invoices totalled by age (current, 1-30, 31-60, 61-90, over 90 days) and the customers most overdue.
Approval: Uses your workspace and hire approval settings.
This action takes no arguments.
Full input schema (JSON)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {}
}list_paymentsRead only
Payments received from customers, newest first, optionally from one customer.
Approval: Uses your workspace and hire approval settings.
| Argument | Type | Details |
|---|---|---|
customerOptional | string | a customer's name, email or id |
limitOptional | integer | See input schema below.Default: 30 |
Full input schema (JSON)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"customer": {
"description": "a customer's name, email or id",
"type": "string"
},
"limit": {
"default": 30,
"type": "integer",
"minimum": 1,
"maximum": 200
}
}
}create_draft_invoiceRead and write
Create a draft customer invoice. Nothing is sent and it isn't owed yet: it stays a draft until someone confirms or sends it.
Approval: Uses your workspace and hire approval settings.
| Argument | Type | Details |
|---|---|---|
customerRequired | string | the customer's name, email or id |
linesRequired | object[] | See input schema below. |
dateOptional | string | invoice date, yyyy-mm-dd; default: set when it's confirmed |
due_dateOptional | string | due date, yyyy-mm-dd; default: the customer's payment terms |
referenceOptional | string | the customer's reference, e.g. a PO number |
notesOptional | string | terms and conditions shown on the invoice |
Full input schema (JSON)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"customer": {
"type": "string",
"minLength": 1,
"description": "the customer's name, email or id"
},
"lines": {
"minItems": 1,
"maxItems": 100,
"type": "array",
"items": {
"type": "object",
"properties": {
"description": {
"type": "string",
"minLength": 1,
"description": "what was sold, as it should read on the invoice"
},
"quantity": {
"default": 1,
"type": "number",
"exclusiveMinimum": 0
},
"rate": {
"type": "number",
"minimum": 0,
"description": "price per unit, before tax"
},
"item": {
"description": "a product or service id or code from the accounting system",
"type": "string"
},
"account": {
"description": "an income account code, where the system needs one",
"type": "string"
}
},
"required": [
"description",
"rate"
]
}
},
"date": {
"description": "invoice date, yyyy-mm-dd; default: set when it's confirmed",
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$"
},
"due_date": {
"description": "due date, yyyy-mm-dd; default: the customer's payment terms",
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$"
},
"reference": {
"description": "the customer's reference, e.g. a PO number",
"type": "string",
"maxLength": 100
},
"notes": {
"description": "terms and conditions shown on the invoice",
"type": "string",
"maxLength": 5000
}
},
"required": [
"customer",
"lines"
]
}confirm_invoiceRead and write
Confirm a draft invoice: it gets its number and counts as owed. Nothing is emailed to the customer.
Approval: Uses your workspace and hire approval settings.
| Argument | Type | Details |
|---|---|---|
invoiceRequired | string | the invoice number, e.g. INV/2026/00012, or its id |
Full input schema (JSON)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"invoice": {
"type": "string",
"minLength": 1,
"description": "the invoice number, e.g. INV/2026/00012, or its id"
}
},
"required": [
"invoice"
]
}send_invoiceRead and write
Email an invoice to the customer with Odoo's invoice email (and its PDF), confirming it first if it's a draft.
Approval: Uses your workspace and hire approval settings.
| Argument | Type | Details |
|---|---|---|
invoiceRequired | string | the invoice number, e.g. INV/2026/00012, or its id |
Full input schema (JSON)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"invoice": {
"type": "string",
"minLength": 1,
"description": "the invoice number, e.g. INV/2026/00012, or its id"
}
},
"required": [
"invoice"
]
}record_paymentRead and write
Record a payment the customer made against a confirmed invoice (Odoo's Register payment).
Approval: Uses your workspace and hire approval settings.
| Argument | Type | Details |
|---|---|---|
invoiceRequired | string | the invoice number or id |
amountRequired | number | See input schema below. |
dateOptional | string | when it was paid; default today |
referenceOptional | string | the bank or cheque reference |
Full input schema (JSON)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"invoice": {
"type": "string",
"minLength": 1,
"description": "the invoice number or id"
},
"amount": {
"type": "number",
"exclusiveMinimum": 0
},
"date": {
"description": "when it was paid; default today",
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$"
},
"reference": {
"description": "the bank or cheque reference",
"type": "string",
"maxLength": 100
}
},
"required": [
"invoice",
"amount"
]
}add_noteRead and write
Add an internal note to an invoice's chatter in Odoo, e.g. what the customer said when chased. Never emailed to the customer.
Approval: Uses your workspace and hire approval settings.
| Argument | Type | Details |
|---|---|---|
invoiceRequired | string | the invoice number, e.g. INV/2026/00012, or its id |
noteRequired | string | See input schema below. |
Full input schema (JSON)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"invoice": {
"type": "string",
"minLength": 1,
"description": "the invoice number, e.g. INV/2026/00012, or its id"
},
"note": {
"type": "string",
"minLength": 1,
"maxLength": 2000
}
},
"required": [
"invoice",
"note"
]
}Watches and incoming events
- This integration supports a responsibility that watches for changes. The guide above explains what it checks and how to limit it.
- No incoming webhook handler is declared for this integration.
Limits and troubleshooting
- Permission errors: check both the connected account's rights and the hire's resource and read/write limits.
- Expired or revoked access: reconnect or replace the key on the connection.
- Rate limits and unavailable services can interrupt work. The hire's timecard records the outcome.
- The action schema describes accepted inputs. It does not grant additional access or bypass approvals.