Odoo Development
Publishing a Module on the Odoo Apps Store
Publishing on the Odoo Apps Store is less about the code than people expect. The technical bar is a module that installs cleanly on a fresh database. The real commitment is the one that starts afterwards, because every module you list is one you now maintain for every Odoo version you claimed to support.
Written by Tayyab RasheedOdoo 19 Certified, Technical Consultant
Part of our guide to Odoo Development
The manifest is the gate
Everything the store knows about your app comes from __manifest__.py and the contents of static/description/. The manifest is not paperwork, it is the gate, and the guidelines are blunt about the cost of an error: "A good manifest is essential as any error will unpublish all the modules from your repository."
Not the module with the bad manifest. Every module in the repository.
Everything below is Odoo's published vendor guidance, checked on 6 September 2026. That page carries no version marker, so re-check it before you rely on it.
| Key | Required | What Odoo requires | Failure mode |
|---|---|---|---|
name | Mandatory | Explicit, no more than 25 characters, no adjectives, no company name | Guideline breach on review |
version | Mandatory | Odoo version first, then major-minor-bugfix, e.g. 10.0.1.1.3. Beta below 1.0, new number every release | Your update is not detected |
license | Mandatory | Any licence that respects its dependencies' licences | Unset costs a listing-score point |
depends | Mandatory | Everything the module needs to run | A missing dependency errors the scan |
price | Optional | EUR or USD, one-shot. Unset or negative means free. Minimum 9 EUR | Below minimum is out of policy |
currency | Optional | EUR or USD only, EUR by default | Any other currency errors the scan |
support | Optional | Email for claims and support, shown only to buyers | Buyers cannot reach you |
summary | Optional | Summary of the main features | A thin listing |
live_test_url | Optional | URL of a demo instance | No live preview |
On the name limit: Odoo's current vendor guidelines specify a maximum of 25 characters for the manifest name. Treat that as the published requirement, even if enforcement may not always appear uniform in live listings.
What you may and may not put on the description page
The description is static/description/index.html, and it is sanitised. Three rules frame it: description and screenshots "must be in English, regardless of the originating country or language of the app"; neither description nor manifest may mention "promotions, advertisements or links to another app store or external platform"; and feature claims "must be accurate and cannot be misleading".
Links are whitelisted, not filtered. Allowed: resources inside your own static/description folder, canonical YouTube links, Microsoft Teams, and the mailto: and skype: prefixes. Everything else: "any other external link will be invalidated." Your documentation site does not survive, and neither does your own shop.
You cannot insert static tags, widgets or modals, and you cannot inject JavaScript. Styling is limited to Bootstrap 4 classes plus color, font-*, margin-*, padding-* and border-*. That list is narrower than it looks, and what happens to the properties outside it is the subject of the last section but one.
Price, commission and getting paid
The minimum price is 9 EUR, in EUR or USD, and currency accepts nothing else. Unset or negative price means the app is free.
The price-parity clause has teeth: if you sell the same app anywhere else, "the price on the Odoo Apps store should always be equal or lower than the one on other platforms", and a discount elsewhere must be mirrored on the store for the same period.
Odoo takes 30% commission. Sales accumulate against a purchase order, and Odoo closes only those that have "reached or exceeded 400 euros unredeemed sales" during the month, so a slow month does not pay out. Payment is by international SWIFT transfer, which the guidelines warn "can take days or weeks to be processed", longer outside Europe.
Support is an obligation, not a courtesy. For a paid app "the author is responsible for resolving the issue in a timely fashion" when a customer reports a bug, malfunction or configuration problem. "Support services are not required for free apps."
Licensing: what is required, and what is only recommended
This is the point most often stated wrongly, including in an earlier version of this page.
[Odoo policy] Any licence may be applied, provided it respects the licences of its dependencies, libraries and other derivative works. That is the requirement.
[Odoo recommendation] LGPL-3 for open source apps, OPL-1 for proprietary apps. Recommendations, not conditions of listing.
So "free means LGPL-3, paid means OPL-1" is a convention, not a rule. What is not optional is dependency compatibility: a module depending on AGPL code cannot be relicensed away from it by choosing a different string.
One detail from the Odoo source rather than the guidelines: omit license and the loader does not fail. It defaults to LGPL-3 and logs a warning (odoo/modules/module.py). The app installs, you have published under a licence you did not choose, and you have lost a listing-score point.
How the store decides where your listing appears
This is the section of the guidelines nobody quotes, and it decides whether anyone finds your app. Every app page is scored against five criteria, and "depending on the score received, the page will be displayed higher or lower in the default App listing".
The criteria are stated as faults, so each is a point you are losing:
| Odoo's criterion | How to satisfy it |
|---|---|
| "The module has no icon" | Ship an icon in static/description |
| "The module has no cover image (thumbnail)" | Ship a cover image as well as the icon |
| "License is not set in the module manifest" | Set license explicitly, never rely on the default |
| "The module has a rating that is quite poor (lower than 3)" | Downstream of the product and the support |
| "The module has a non-html description (like rst for example)" | Ship index.html, not a text or RST description |
Two things follow. The tie-break between apps on the same score "remains the best sellers", so a new app cannot outrank an established one on presentation alone. And the score is visible: open an app's description page from your App Store account, and below 5 out of 5 it shows what needs amending.
What gets an app unpublished
The enforcement ladder is explicit. A first breach brings temporary sanctions: an email listing the issues, the app unpublished until you fix it. Repeated breaches across multiple apps unpublish all of them, with account suppression for recurrent cases. No commissions are paid during a sanction, and Odoo "reserves the right to unpublish any App at any point without prior notice".
The substantive rules are worth knowing before you design rather than after:
- It must not break the Enterprise Subscription Agreement, alter the code verifying Enterprise validity, or alter the separation between portal and internal functionality
- It cannot be a clone "built with the clear intention to duplicate the functionalities of an Enterprise module"
- It must install by copying into the addons folder and satisfying dependencies. Unzipping or moving folders is out
- It cannot require an activation key, and the customer owns their data at all times
- Data sent to another service must be disclosed in the manifest, on the store page and in the app, with opt-in first
- It must be functional and "cannot serve as a simple advertisement"
Separate fair-use rules cover the store itself: no artificially altering rankings, no buying your own app to raise its rating or a competitor's to lower it, no advertising on another vendor's page.
One branch per Odoo version
There is no upload form. You connect a public repository to your Odoo account, the store scans it, and branch names correspond to Odoo versions. A module on branch 19.0 becomes the Odoo 19 listing, the same module on 18.0 becomes the Odoo 18 listing, and they are separate listings with separate prices and separate download counts.
The guidelines add a rule that only makes sense once you have seen this: "If you provide your module for different Odoo versions, use the same module name." The listings are separate, the identity is not.
Supporting three versions therefore means three branches carrying three ports of the same module. That is the shape of the ongoing work, and it is worth being sure about before the first listing rather than after the tenth.
Two things the guidelines do not tell you
Everything above is published policy. The two below are not. They are [CODEerts experience], observed while maintaining 114 apps in our current Odoo 19 catalogue, and both were re-verified against live listings on 6 September 2026 rather than recalled. Read them as results we measured on the listings we tested, not as documented Odoo rules.
| What happens | Why | What to do |
|---|---|---|
| A coloured pill rendered with no background on the live listing, and white text on it disappeared | In the three listings we tested, the background shorthand was stripped while background-color survived. 211 elements carried background: locally and none survived on the served page, on span, div and td alike. Every other property we checked came through, including color, border, padding and border-radius | Write background-color, never the shorthand, and never let text contrast depend on a background you have not seen survive live |
| An "In-App Purchases" tag appears although you enabled nothing | The tag follows the transitive depends tree, not a setting. base_automation depends on sms, which depends on iap_mail, which depends on iap | Resolve the full dependency closure before listing, not just direct depends |
The first contradicts the rule most publishers reach for. In what we measured it was not inline versus block: the shorthand went missing from every element type we saw it on, and the longhand came through. We have found no official Odoo statement on which properties the sanitiser keeps, so check your own listing after the scan rather than trusting either rule.
Before you publish: the checklist
- It installs on an empty database. Not your development database, which holds records your data files quietly depend on. A clean install is where load-order bugs surface, and it is what a buyer does
- It uninstalls cleanly. People uninstall while evaluating, and an override assuming its own tables exist can break the uninstall itself
- Every model has a line in
ir.model.access.csv. The most common "nothing happens" support ticket is a missing access rule, working fine for the administrator who tested it - The manifest is complete and honest. Explicit
license,versionin the full five-part form,dependslisting exactly what is used, and any Enterprise-only dependency declared in the listing rather than discovered after purchase - The description is English, self-contained and link-clean. Nothing outside the link whitelist, no JavaScript, no promotional copy
- Backgrounds use
background-color, and no text depends for contrast on a background you have not seen survive - All five scoring criteria are satisfied: icon, cover image, licence set, HTML description. The fifth, your rating, you earn
- You have looked at the live listing after the scan, not just the local render. The description you wrote and the description the store serves are not the same document
Version support is the real commitment
This is the decision that determines whether publishing is sustainable. Every new Odoo version means porting every module you maintain, whether or not it sold anything, and the cost is the product of your catalogue and your supported versions, not the size of either alone.
Two things follow. Support fewer versions than you think you should, because dropping one later disappoints existing buyers while never adding one costs nothing. And write modules that port easily, which means the ordinary discipline: inherit rather than replace, call super(), keep the surface narrow. The coding standards checklist is the same list that makes a module cheap to port. If the porting load is the part you would rather not own, it is the work we do as custom Odoo development.
Whether to publish at all
Publishing suits a module that solves a general problem and is worth maintaining regardless. It suits bespoke work poorly: client-specific modules carry assumptions that make no sense elsewhere, and generalising them is a rewrite rather than a cleanup.
The honest test is whether you would keep the module working for the next three Odoo versions even if it sold nothing. If the answer is no, publishing converts a finished project into an open-ended obligation.
FAQ
Questions, answered.
How do you publish a module on the Odoo Apps Store?
You connect a public repository to your Odoo account and the store scans it, taking each version branch as the module for that Odoo version. A module on a branch named 19.0 becomes the Odoo 19 listing. There is no upload step, so the repository layout is the publishing mechanism.
Do Odoo apps have to be free?
No. Paid apps are supported, priced per module and per version, with a minimum of 9 EUR and 30% commission to Odoo. On licensing, the vendor guidelines allow any licence provided it respects the licences of your dependencies. LGPL-3 for open source apps and OPL-1 for proprietary ones are recommendations, not conditions of listing, so a paid app on an open source licence is a choice rather than a contradiction. What is not optional is dependency compatibility, and leaving the licence unset costs you a listing-score point.
How much maintenance does a published Odoo app need?
One port per Odoo version per year, per module, plus support for anyone who bought it. The porting effort is what scales badly: ten modules across three supported versions is thirty listings to keep working, which is why publishers narrow their supported version range over time.
Keep reading
More on Odoo Development.
The full guide, plus the other articles in this cluster.
With CODEerts
Need something built properly?
We are certified Odoo partners. We build custom Odoo modules that extend the framework rather than fight it, and we publish our own apps on the Odoo Store.
See how we can helpBook a callReady to make Odoo work the way your business does?
Book a free callCODEerts is a team of certified Odoo partners and full-stack engineers. We implement, customise and support Odoo ERP, then build the software around it.