Sellbrite Store Management
Sellbrite Store Management connects an Odoo database to a Sellbrite account over Sellbrite's v1 REST API. Everything on this page describes the sellbrite_store_management module as it ships today; the behaviour below was read out of the released build.
Sellbrite holds your listings across the channels you sell on. The connector pulls that account's products, orders and customers into Odoo, pushes products and stock back out, and keeps a dashboard and a sync log over what it moved. It calls only the routes Sellbrite publishes, and authenticates the way Sellbrite documents.
| Technical name | sellbrite_store_management |
| Odoo versions | 17.0, 18.0, 19.0 (Community or Enterprise) |
| Current shipped version | 17.0 → 17.0.1.0.14, 18.0 → 18.0.1.0.14, 19.0 → 19.0.1.1.2 |
| Price | $349 USD — one-time, per Odoo version |
| Odoo module licence | OPL-1 |
| Category | Connector |
What the module does, and what it does not
It does:
- connect with the Account Token and Secret Key from Sellbrite's own settings, sent as HTTP Basic on every call;
- test that pair from Odoo by reading a real endpoint (
GET /channels), and set the instance status to Connected or Error; - import products (with images), orders, customers and warehouse locations, and export products, customers and stock;
- export order fulfilment and tracking back to Sellbrite;
- map each Sellbrite warehouse to Odoo warehouses, separately for orders, for stock import and for stock export;
- receive webhooks on four signed endpoints and turn each into a queue job;
- score order risk with configurable thresholds, and run optional automation rules (confirm, invoice, register payment, create delivery) that are off by default;
- keep a payout register, a refund list, period-based analytics, a dashboard and a sync log with 90-day retention;
- run 11 scheduled actions, with a queue that retries a failed job up to its retry limit.
It deliberately does not:
- import payouts or refunds from Sellbrite through the API. Sellbrite publishes no merchant endpoint for those, and the calls a previous build made have been withdrawn rather than left to fail. The payout register and the refund list work on records Odoo already holds.
- generate shipping labels or call a returns API. Neither route exists on Sellbrite's merchant API.
- use OAuth to connect an account. Sellbrite authenticates with a static token pair (HTTP Basic) and documents no OAuth and no scopes; one token is full-account.
- change your stock unless you ask it to. The stock import is off by default — see Import Stock Levels From Sellbrite.
If a capability is not on the first list, the module does not have it.
Requirements
| Requirement | Detail |
|---|---|
| Odoo | 17.0, 18.0 or 19.0, Community or Enterprise. Self-hosted or Odoo.sh — Odoo Online (SaaS) cannot install third-party modules |
| Odoo apps | base, sale_management, stock, account, delivery, mail, web, portal, product, contacts, digest — Odoo installs any that are missing |
| Python packages | requests |
| Sellbrite account | An account with API access, and the account token + secret key from Sellbrite → Settings → API |
| Network | Outbound HTTPS to api.sellbrite.com |
| Inbound (webhooks only) | Your Odoo instance reachable over HTTPS from Sellbrite, if you use the webhook intake |
Install requests into the same interpreter that runs Odoo:
sudo -u odoo pip install requests
Installation
The module is a single package; there is nothing else to install beside it.
- In Odoo, open Apps, turn on developer mode and click Update Apps List.
- Search for Sellbrite Store Management and click Install.
- Odoo installs the apps listed above automatically.
When the install finishes, a Sellbrite app appears in the main Odoo app switcher.
Configuration
Connect the account
Create a record under Sellbrite → Configuration → Instances. The fields the module defines for the connection are:
| Field | Technical name | Type | Required | What it is |
|---|---|---|---|---|
| Instance Name | name | Char | Yes | A label for this account |
| Company | company_id | Many2one | Yes | The Odoo company this account's records belong to |
| Account Token | api_key | Char | Yes in practice | Username half of the HTTP Basic pair, from Settings → API |
| Secret Key | api_secret | Char | Yes in practice | Password half of the HTTP Basic pair, from Settings → API |
| Store URL | shop_url | Char | No | Optional label for the account. It is also what webhook delivery matches on — see Webhooks |
| Webhook Secret | shared_secret | Char | Webhooks only | Verifies the signature on incoming webhooks. It is on the instance form, under Webhooks |
access_token, oauth_state, oauth_scope and the legacy password field were removed in 19.0.1.1.2: they belonged to an OAuth flow Sellbrite does not offer, and no code path read them.
The account token and the secret key are marked as credential fields: their values are masked on screen and only users in the Settings group can read them. The module does not store them anywhere else, and it does not print them in the log.
Sellbrite mints these under Settings → API inside your Sellbrite account. The pair travels as Authorization: Basic base64(account_token:secret_key) on every request.
Test the connection
Click Test Connection on the instance. The module calls GET /channels — a cheap, real endpoint — and reports the result in a notification, setting the record status to Connected or Error. A wrong token reads as a failed test, not as an error page.
The same record carries the settings the rest of the module reads:
| Setting | Effect |
|---|---|
| Default Warehouse | Warehouse used for imported orders |
| Pricelist / Salesperson | Applied to sales orders created from Sellbrite orders |
| Payout Journal | Journal used when a payout is reconciled into a bank statement |
| Currency | Currency for the instance's monetary KPIs |
| Risk thresholds (critical / high / medium) | Score bands for rule-based order risk |
| Monthly marketing cost / operating expenses | Inputs to the profit-margin view of the dashboard |
| Import Stock Levels From Sellbrite | Off by default; see below |
Import Stock Levels From Sellbrite
This switch is the only thing that lets the connector write Odoo stock, and it ships off, including on databases that upgrade from an earlier release.
When it is off:
- the scheduled inventory sync still reads Sellbrite, but it changes no Odoo quantity;
- the Import Stock Levels operation in the Operations Center asks you to tick the switch before it writes.
When it is on, each run of the inventory sync writes Sellbrite's on hand figure — the physical quantity — into the Odoo warehouse mapped as that location's Import Stock Warehouse. On hand is used deliberately: Sellbrite's available figure is on hand minus Sellbrite's own open-order reservations, so storing it would subtract those reservations in Odoo a second time and shrink the warehouse on every run.
Pushing stock the other way is unchanged: Export Stock Levels is an operation you run, and it sends each SKU's available quantity to every warehouse mapped for export.
Map the warehouses
Create one mapping record per Sellbrite location under Sellbrite → Configuration → Locations, filled from Sellbrite by Import Warehouses / Locations. Each mapping carries three separate warehouse links, and they are separate on purpose:
| Field | Used for |
|---|---|
| Warehouse for Orders | Where imported orders reserve stock |
| Export Stock Warehouses | Every Odoo warehouse whose stock is pushed to this Sellbrite location |
| Import Stock Warehouse | The single Odoo warehouse that this location's Sellbrite quantity is written into |
A location with no import warehouse is skipped by the stock import. A location with no export warehouses is skipped by the stock export. One location failing does not stop the others: each is processed inside its own savepoint.
Scheduled actions
The module installs 11 scheduled actions (Sellbrite → Configuration → Scheduled Actions, or Settings → Technical → Scheduled Actions):
| Scheduled action | Runs every |
|---|---|
| Sellbrite: Sync Products | 30 minutes |
| Sellbrite: Sync Orders | 15 minutes |
| Sellbrite: Sync Customers | 60 minutes |
| Sellbrite: Sync Inventory | 10 minutes |
| Sellbrite: Process Queue Jobs | 5 minutes |
| Sellbrite: Auto Risk Detection | 30 minutes |
| Sellbrite: Generate Analytics | 4 hours |
| Sellbrite: Webhook Health Check | 60 minutes |
| Sellbrite: Cleanup Old Logs | 24 hours |
| Sellbrite: Process Workflows | 10 minutes |
| Sellbrite: Daily Summary Report | 1 day |
All eleven are enabled on install. The intervals are defaults — shorten them to your volume, but Sellbrite meters the account, not the Odoo database, and shortening a sync interval is the usual cause of throttling.
Rate limits
The connector honours Sellbrite's published limits in the client itself: 40 requests per minute and 2 requests per second, with a token bucket enforcing both. Breaching either limit returns HTTP 403 with the body Rate Limit Exceeded — not 429, and with no retry-after header — so the client recognises that body as the throttle rather than as an authorisation failure, backs off, and retries within its budget. When the budget is spent the run stops with a clear error instead of hammering the endpoint.
Lists are read with page and limit. Sellbrite documents no pagination headers, so a short or empty page is the end signal, and GET /orders returns at most 100 records per page whatever the limit says.
Using the module
Menu
- Sellbrite → Dashboard
- Sellbrite → Orders
- Sellbrite → Refunds
- Sellbrite → Products
- Sellbrite → Customers
- Sellbrite → Payouts
- Sellbrite → Analytics
- Sellbrite → Operations — Run Operations, Queue Jobs, Logs
- Sellbrite → Configuration — Instances, Locations, Payment Gateways, Scheduled Actions, Webhooks
The dashboard is limited to the Sellbrite User group, payouts to Sellbrite Finance and analytics to Sellbrite Analytics. The other menus are visible to any user who can read the records behind them. Seven groups ship — User, Manager, Administrator, Analytics, Developer, Finance and Operations — and you assign them to users under Settings → Users.
Operations Center
Sellbrite → Operations → Run Operations runs one operation at a time against a chosen instance:
| Operation | What it does |
|---|---|
| Import Products | Reads the account's products into Odoo, with images |
| Import Orders | Reads orders for a date range (default: the last day) |
| Import Customers | Reads customers into Odoo partners |
| Import Stock Levels | Reads Sellbrite quantities into each mapped Import Stock Warehouse — requires the switch above |
| Import Warehouses / Locations | Reads Sellbrite's locations into mapping records |
| Export Products | Pushes Odoo products to Sellbrite |
| Export Customers | Pushes Odoo partners to Sellbrite |
| Export Stock Levels | Pushes available stock for every mapped export warehouse |
| Export Fulfillment / Tracking | Sends shipment and tracking details for an order |
The Specific SKUs / Order IDs box limits a run to the values you paste. The two stock operations report how many locations were processed and how many quantities changed; the other operations report their counts and write a log record.
Queue, risk and automation
Inbound webhooks and scheduled work are queued rather than executed in the request. Operations → Queue Jobs shows each job and its status; a failed job is retried up to its retry limit (3 by default) before it is left failed for you to inspect.
Risk scoring is rule-based, not a model: it scores an order from the order's own pattern, the customer's history and the products on it, and bands the result with the thresholds on the instance. Nothing leaves your database to score an order.
The module also carries two configuration models that have no menu of their own — order-processing workflow records (Sellbrite status to Odoo status, with steps, conditions and actions) and per-order automation rules. Both are edited in developer mode under Settings → Technical → Database Structure → Models. Every automation switch on them is off by default, and the connector never turns one on by itself.
Dashboard and analytics
The dashboard is an Odoo-side view of the records the connector holds, not a Sellbrite report: period filters (with an instance filter) drive the KPIs and the sales chart, so it is only as current as the last sync.
Sellbrite → Analytics keeps period summaries: new versus returning customers, acquisition cost, lifetime value, top products, revenue growth against the previous period, reorder recommendations and inventory turnover. They are computed from your Odoo records on load and refreshed by the 4-hour analytics action and the daily summary.
Webhooks
Webhooks let Sellbrite tell Odoo about a change immediately instead of waiting for the next sync. The module accepts four POST endpoints:
| Endpoint | Handles |
|---|---|
/sellbrite/webhook/product | Product created, updated or deleted |
/sellbrite/webhook/order | Order created, updated, fulfilled or cancelled |
/sellbrite/webhook/customer | Customer created, updated or deleted |
/sellbrite/webhook/refund | Refund created |
Each request must carry:
| Header | Meaning |
|---|---|
X-Sellbrite-Shop-Domain | Resolves which instance the event belongs to — the module matches it against the instance's Store URL, so set that field |
X-Sellbrite-Hmac-SHA256 | Base64 HMAC-SHA256 of the raw request body, keyed with the instance's Webhook Secret |
A request with a missing or wrong signature is rejected with {"status": "error"} and logged; a valid one creates a queue job and an information line in the sync log, and answers {"status": "ok"} without doing the import inside the request.
Webhook records live under Sellbrite → Configuration → Webhooks. Each one names its instance, its topic from the fourteen Sellbrite event names, and the delivery URL, which must be HTTPS. Sellbrite has no endpoint that registers a subscription for you, so add the delivery URL in the Sellbrite seller portal yourself; the Test Webhook button on the record sends a signed sample payload to that URL so you can prove the round trip before going live.
Troubleshooting
Connection
| Symptom | Cause and fix |
|---|---|
| Test Connection fails with 401 | The account token or secret key is wrong, or was regenerated in Sellbrite. Copy both again from Settings → API — the pair is read as a pair |
| Test Connection fails with a DNS or timeout error | The Odoo server cannot reach api.sellbrite.com over HTTPS. Check the outbound firewall or proxy |
| The status stays on Error after a good test | Re-run the test; the status is recorded when the call returns, so a failed call leaves the previous result |
The requests library is required | requests is missing from Odoo's Python environment. Install it into the interpreter that runs Odoo |
Sync
| Symptom | Cause and fix |
|---|---|
| Nothing syncs although the connection is fine | The scheduled actions are disabled, or Odoo's cron worker is not running. Check Settings → Technical → Scheduled Actions and that --max-cron-threads is greater than zero |
Runs fail with Rate Limit Exceeded | The account is being polled faster than 40 requests/minute or 2/second. Lengthen the sync intervals, or stop a manual run that overlaps a scheduled one |
| Orders stop halfway through a large range | Read the sync log for that run. A rejected record is contained and reported; re-run with a shorter date range to find it |
| Duplicated products or customers | Run the initial import once. If a first attempt half-finished, review the records before re-running; imports match on Sellbrite's own identifiers |
| Stock never changes in Odoo | Import Stock Levels From Sellbrite is off, the location has no Import Stock Warehouse, or the sync has not run since the mapping was set |
Webhooks
| Symptom | Cause and fix |
|---|---|
{"status": "error", "message": "Instance not found"} | The X-Sellbrite-Shop-Domain header does not match any instance's Store URL. Set the field to the domain Sellbrite sends |
{"status": "error", "message": "Invalid signature"} | The Webhook Secret on the instance does not match the one Sellbrite signs with, or a proxy rewrote the request body. The signature covers the raw body exactly |
| The Test Webhook button fails | The delivery URL must be HTTPS and reachable from the Odoo server. A private or self-signed host fails |
| Events arrive but nothing is imported | The queue job is waiting for Process Queue Jobs (5 minutes), or it failed and hit its retry limit — check Operations → Queue Jobs |
Version history
| Odoo version | Version you install today |
|---|---|
| 17.0 | 17.0.1.0.14 |
| 18.0 | 18.0.1.0.14 |
| 19.0 | 19.0.1.1.2 |
ECOSIRE module versions are <odoo major>.<module major>.<minor>.<patch>, so 19.0.1.1.2 is the Odoo 19 build of module version 1.1.2. Your installed version is shown in Apps.
19.0.1.1.2 — 2026-11-05. The package no longer ships another product's documentation or a sign-in flow Sellbrite does not offer. The bundled README was the Shopify clone's — its title, a Shopify partner setup, a support number and an LGPL-3.0 licence against an OPL-1 manifest — and is now this connector's own README. The Shopify-shaped OAuth routes (/sellbrite/install, /sellbrite/callback) and the Connect to Sellbrite button are deleted; Test Connection is the connection action. The unused access_token, oauth_state, oauth_scope and password fields are removed. The webhook secret is now Webhook Secret on the instance form, so webhook verification can be configured in the UI.
19.0.1.1.1 — 2026-11-05. Stock levels sync in both directions again: the inventory job and the two stock operations had been calling methods the location model no longer defined, so the job raised on every run and the operations did nothing. The import now writes Sellbrite's on hand quantity rather than its available quantity, which had been making every run shrink the warehouse by Sellbrite's own reservations. Stock import is now opt-in: Import Stock Levels From Sellbrite ships off, including on upgraded databases. The App Store page's contrast was raised, and the test suite no longer contacts the live API.
19.0.1.1.0 — 2026-09-17. Every route was rebuilt against Sellbrite's own API reference. The previous build addressed a Shopify-shaped API at a host that does not resolve in DNS, so the connection could not have worked; authentication is now HTTP Basic with the account token and secret key, the throttle is recognised as HTTP 403, and pagination follows page/limit.
18.0.1.0.14 — 2026-10-28. A failed Test Connection left the record reading Connected, because the failure status was written and then rolled back in the same transaction. The status now survives the rollback.
18.0.1.0.13 — 2026-08-04. Every per-record sync and action loop is wrapped in a savepoint with a flush, so one failed record cannot roll back the rest of the run.
Support
When you report a problem, include your Odoo version, the module version from Apps, and the relevant lines from Sellbrite → Operations → Logs — the log records the platform's own error text, which is what makes a report actionable.