Odoo ERP development services cover every change to Odoo that goes beyond switching on standard settings: Studio customizations, custom modules written in Python and XML, PDF reports, integrations with other systems, data migration scripts, and the work of keeping all of that running through each yearly Odoo upgrade. A good proposal names which of those layers each requirement sits in, because the layer decides what the change costs to build, who can maintain it, and whether Odoo's own upgrade service will carry it forward.
Most scope disputes in Odoo projects are not about code quality. They happen because the buyer asked for "a customization" and the provider quoted one layer while the requirement needed another. This guide breaks development into its layers, lists what each should deliver, and gives you a checklist for reading a development proposal before you sign it.
Configuration is not development — but it comes first
Before anything is built, a competent developer asks whether standard Odoo already does it. Odoo 19 ships a large amount of behaviour that is switched on in settings: approval rules, multi-step routes, fiscal positions, quotation templates, activity plans. A requirement that looks custom is often a setting nobody showed the team.
That is why the first deliverable of any development engagement should be a fit-gap list: every requirement, marked as standard, configuration, Studio, custom module or integration, with a one-line reason. If a provider skips this step and goes straight to an estimate for code, you will pay to rebuild things that already exist, and you will carry that code through every upgrade.
A useful test: for each item on the gap side, ask the provider to show you the standard screen that comes closest and explain what it cannot do. If they cannot show it, the gap has not been analysed.
The seven layers of Odoo development work
The table below is the map we use to scope work. Each layer has a different skill set, a different maintenance burden and a different answer to "what happens at upgrade time".
| Layer | Typical requirement | Built with | Who can maintain it | Upgrade path |
|---|---|---|---|---|
| 1. Studio customization | Extra field on a sales order, a new list view, a simple approval | Odoo Studio (no code) | A trained functional admin | Covered by Odoo's upgrade service while Studio and the subscription stay active |
| 2. Custom module | New business logic, computed fields, constraints, a new app | Python models + XML views, inheritance of standard modules | An Odoo developer | Your responsibility, unless covered by a maintenance-of-customizations subscription |
| 3. Reports and documents | Branded invoice, a picking list in a set layout, a management report | QWeb templates, report actions | An Odoo developer (simple ones: Studio) | Depends on how it was built (layer 1 or 2) |
| 4. Integrations | Sync with a web shop, marketplace, bank, 3PL or payroll system | External API, webhooks, connector modules | A developer who knows both systems | Custom code; the external API itself also changes |
| 5. Data migration | Move customers, products, open balances, history from the old system | Import templates, scripts | Developer + functional consultant | One-off, but scripts should be kept |
| 6. Automation | "When X happens, do Y" | Automation rules, server actions, scheduled actions | Admin (rules) or developer (code actions) | Rules via Studio are covered; code is yours |
| 7. Upgrade and maintenance | Keep custom work running on the next Odoo version | Upgrade scripts, retesting | An Odoo developer | Recurring, every version you move to |
The upgrade column is taken from Odoo's own rules. Odoo's upgrade service-level agreement covers standard applications, customizations created with Studio "as long as Studio is still installed and the respective subscription is still active", and developments covered by a maintenance of customizations subscription. It explicitly does not cover "additional modules not covered by a maintenance contract that are created in-house or by third parties, including Odoo partners" (Odoo 19 upgrade documentation). That single sentence is the most important scoping fact in Odoo development: custom code is a recurring commitment, not a one-off purchase.
Layer 1: Studio customizations
Odoo Studio is the no-code toolbox built into Odoo. According to the Odoo 19 Studio documentation, it lets you add or change fields and widgets, views, models and custom apps, automation rules and webhooks, PDF reports, approval rules and security rules.
What a development service should add here is judgement, not clicks: which changes belong in Studio, naming conventions so fields stay readable, and a record of every Studio change so the next person knows what exists. Two things to check before relying on Studio:
- Hosting and plan. The same documentation notes that installing Studio on a database on the Standard pricing plan automatically triggers an upsell to the Custom plan. Confirm the subscription impact with Odoo before anyone installs it.
- Where Studio stops. Complex computed logic, performance-sensitive batch processing and anything that must call an external system usually belong in a module. A Studio build that has grown into dozens of chained automation rules is harder to debug than the equivalent Python.
Layer 2: Custom modules
A custom module is a package of Python and XML that adds or changes behaviour. Odoo's own developer tutorial, Server framework 101, walks through the building blocks every module uses: models and fields, security, views, relations between models, computed fields and onchanges, actions, constraints, inheritance and interaction with other modules.
The word to listen for in a proposal is inheritance. Well-built Odoo modules extend standard models and views rather than copying or replacing them. A module that copies the standard sales order view to add two fields will break or silently diverge when Odoo changes that view in the next version. One that inherits the view and inserts its two fields at a named anchor usually survives.
A custom module engagement should deliver:
- the module source in your Git repository, not the provider's;
- a manifest with a clear version and dependency list;
- access-control rules for every new model (a model with no access rules is either unusable or open to everyone);
- automated tests for the business rules the module enforces;
- a short technical note: what the module changes, which standard models it touches, and how to disable it.
Layer 3: Reports and printed documents
Invoices, delivery slips and quotations are what customers see, so they are often the first development request. Simple layout changes can be done in Studio's PDF report editor; anything with conditional sections, extra data from related records, or several variants per company is usually a QWeb template in a module. Scope each document separately and include a sample output in the acceptance criteria — "branded invoice" is not a specification, a marked-up PDF is.
Layer 4: Integrations
Integration work connects Odoo to a shop, marketplace, payment provider, bank, warehouse or another ERP. It is usually the riskiest layer because two systems change independently. A proper integration scope states, for every data flow: the direction, the trigger (webhook, schedule, manual), the system of record, how duplicates are prevented, and what happens when one side is down.
One version fact matters now. Odoo's external API documentation states that the XML-RPC and JSON-RPC endpoints at /xmlrpc, /xmlrpc/2 and /jsonrpc are scheduled for removal in Odoo 22, and that all three services they expose are deprecated; Odoo 19 documents the newer External JSON-2 API alongside them (Odoo 19 external API reference). Any integration built today on the old endpoints has a known expiry date. Ask which API a provider will use and why.
If the integration is with a common platform, check whether a maintained connector already exists before commissioning one from scratch; see our integration services for the channels we cover.
Layer 5: Data migration
Migration is development because the old system's data never maps cleanly. Scripts clean, transform and load customers, products, open invoices and balances, and they must be re-runnable, since you will do at least one trial load before the real one. The deliverable is not "data imported"; it is a reconciliation report showing that totals in Odoo match totals in the old system. Our implementation checklist lists the balances to reconcile before go-live.
Layer 6: Automation
Automation rules (Studio) and scheduled or server actions (code) handle "when this happens, do that". The scoping question is ownership: rules built in Studio can be read and adjusted by an administrator, while code actions need a developer. Many small automations are better done as rules so the business can own them.
Layer 7: Upgrades and maintenance
Every custom module has to be adapted and retested for each Odoo version you move to. Odoo's upgrade process requires the update of custom modules to succeed before the production upgrade can complete, and it recommends testing on an upgraded test database first (Odoo 19 upgrade documentation). Budget time for this at every version change, and prefer providers who write modules with the next upgrade in mind.
Hosting decides what you are allowed to build
Before scoping any code, confirm where the database runs. The Odoo Online documentation is direct: "Odoo Online is incompatible with custom modules or modules from the Odoo Apps Store." On Odoo Online you are limited to configuration and Studio. Custom modules need Odoo.sh or an on-premise (self-hosted) deployment.
This is the most common reason a signed development scope has to be reworked: the buyer is on Odoo Online, the proposal is for custom modules, and nobody checked. If moving hosting is part of the plan, that move is its own line in the scope.
How to read an Odoo development proposal: a checklist
Use this list against any proposal, including ours. Every "no" is a question to ask before signing.
- Fit-gap first. Each requirement is marked standard, configuration, Studio, module or integration, with a reason.
- Version and edition stated. The proposal names the Odoo version (for example 19.0) and whether you run Community or Enterprise, because available standard features differ.
- Hosting confirmed. It states where the code will run and confirms custom modules are allowed there.
- Acceptance criteria per item. Each deliverable has a test you can perform: a document to print, a workflow to walk through, a record count to reconcile.
- Code ownership. Source is delivered to a repository you control, from the first commit.
- Inheritance, not copies. The provider confirms standard views and models are extended, not duplicated.
- Access rights. New models and menus come with defined user groups.
- Tests. Business rules in modules have automated tests, and you know how to run them.
- Staging. Development and your acceptance testing happen on a copy of production, not in the live database.
- Upgrade plan. The proposal says who adapts the custom code at the next Odoo version and how that is priced.
- Change handling. There is a written process for requirements that change mid-project.
- Documentation. A technical note per module and a short user note per changed workflow are included.
What goes wrong, and how to spot it early
"Customization" quoted as one line. If a proposal lists a single "customization" item with one estimate, the fit-gap analysis has not been done. Ask for the breakdown by layer before comparing prices between providers.
Code in the provider's account. If the provider hosts the only copy of your modules, changing provider later means asking for your own code. Symptom: nobody on your side can list the custom modules installed.
Rebuilding standard features. A custom approval module when Odoo's approval rules would have done it; a custom report when a filter and a saved view would have. Symptom: users find a standard menu that does the same thing as the custom one.
Overridden instead of inherited. Symptom: after a minor Odoo update, a standard field disappears from a form, or a standard fix does not show up in your database.
No test database. Changes deployed straight to production. Symptom: users report problems before the developer does.
Integrations without failure handling. Symptom: orders missing in Odoo after a short outage, or duplicated after a retry. Ask how the integration reprocesses a failed message and how it recognises one it has already handled.
Upgrade left out. Symptom: the project ends, and a year later you learn the custom modules block the move to the next version.
When to hire a developer, and when to buy a service
For one clearly specified module or report, a single experienced Odoo developer is often enough; our comparison of Odoo partners and freelancers covers that decision. When the work spans several layers — a module, two integrations, a migration and the upgrade path that ties them together — you need someone who owns the fit-gap analysis and the architecture, not only the code.
That is the work our Odoo customization service is built around: fit-gap first, Studio where it is enough, modules that inherit rather than replace, code in your repository, and a stated plan for the next upgrade. If you want a second opinion on a proposal you already have, send it through our contact page and we will mark each line by layer.
Frequently Asked Questions
What is the difference between Odoo customization and Odoo development?
In practice the terms overlap. "Customization" often means changes made in Studio or configuration, while "development" means writing custom modules, reports and integrations in code. The distinction that matters is the upgrade path: Odoo's upgrade service covers Studio customizations while Studio and the subscription remain active, but not custom modules unless they are under a maintenance-of-customizations subscription.
Can I install custom modules on Odoo Online?
No. Odoo's documentation states that Odoo Online is incompatible with custom modules and with modules from the Odoo Apps Store. On Odoo Online you can use configuration and Studio; custom modules require Odoo.sh or a self-hosted installation.
Who upgrades my custom Odoo modules to the next version?
Unless the modules are covered by a maintenance-of-customizations subscription with Odoo, adapting them is your responsibility — in practice, the provider you hire. Odoo's upgrade process requires custom modules to update successfully before a production upgrade completes, so plan and scope this work for every version change.
Should an Odoo developer build on the XML-RPC API?
Not for new integrations if it can be avoided. Odoo's external API documentation marks the XML-RPC and JSON-RPC endpoints as deprecated and scheduled for removal in Odoo 22. New work on Odoo 19 should consider the External JSON-2 API so the integration does not carry a known expiry date.
What should I receive at the end of an Odoo development project?
At minimum: the module source in a repository you control, automated tests for the business rules, access rights for every new model, a technical note per module, updated user instructions for changed workflows, and a written plan for adapting the code at the next Odoo upgrade.
Related Articles
Odoo Implementation Checklist: Tasks Before Go-Live
An Odoo 19 pre-go-live checklist ordered by how hard each setting is to undo: localization, taxes, valuation, sequences, access rights, email and cutover.
12 min readOdoo Community vs Enterprise in 2026: Which Edition Do You Actually Need?
An implementer's guide to choosing between free Odoo Community and paid Odoo Enterprise in 2026 — the real feature gaps, licensing costs, upgrade implications, and a decision matrix.
9 min readHow Much Does an Odoo Implementation Cost in 2026? Real Numbers by Company Size
A realistic 2026 breakdown of Odoo implementation costs — licenses, services, hosting, and hidden costs — with budget ranges for small businesses, mid-market companies, and enterprises.
8 min read