Skip to content

Troubleshooting

Symptoms are listed roughly in the order they tend to appear on a new installation.

The import succeeds but no data appears

The most common failure, and a misleading one: the ETL reports success because the marketplace returned a valid response, but that response was empty.

Work through these in order.

Check the token's permissions. A Wildberries token missing the Statistics scope returns an empty result set rather than an authorisation error. Reissue the token with every category listed in Connect your marketplace accounts and import again.

Check the token has not expired. Wildberries tokens last 180 days and expire silently. If the token predates that window, this is your answer.

Check the date range. The default import covers 7 days. If you had no sales in that period, an empty result is correct. Confirm with a wider window:

python run_etl.py --wb --days 60

Check the data actually landed. Query the database directly to distinguish an ETL problem from a dashboard problem:

SELECT source, COUNT(*), MIN(sale_date), MAX(sale_date)
FROM sales
GROUP BY source;

Rows here with an empty dashboard means the API or the frontend is at fault, not the import. No rows means the import is.

Profit figures look far too high

Cost prices are missing. Every SKU without one is treated as free, so profit collapses into net revenue.

Find the gaps:

SELECT source, sku, name
FROM products
WHERE cost_price IS NULL OR cost_price = 0
ORDER BY source, name;

Fill them in through the Products section of the dashboard or with PATCH /api/products/{source}/{sku}/cost.

The same product appears twice

If you sell an identical item on both marketplaces, it exists as two independent rows, one per platform. This is intentional. Commission structures, logistics costs and listing statistics differ between the two, and merging them would make any per-platform comparison meaningless.

It does mean cost prices are set separately for each. Setting the Wildberries cost does not populate the Ozon one.

The sync button does nothing

The API launches the import as a subprocess using an absolute interpreter path under /opt/analytics. On an installation that lives anywhere else, that path does not resolve and the job fails immediately.

Check the reported status:

curl http://localhost:8000/api/sync/status

A status of error with a message about a missing file confirms it. Either install to /opt/analytics, or edit the command in app.py to match your layout. Scheduled cron syncs are unaffected, because cron invokes the script directly.

A sync is stuck as running

The in-memory flag that prevents concurrent imports is only cleared when the job finishes. If the API process is restarted mid-import, the flag resets to idle, which is usually what you want. If the job is genuinely still going, wait: it is abandoned automatically after 15 minutes.

Sync state is not persisted. After a restart, the status endpoint reports idle even if an import was interrupted, and no partial-import record survives.

The dashboard loads but every request fails

Confirm the API is running and reachable:

sudo systemctl status mp-api
curl http://localhost:8000/api/kpis

If systemd reports the service as running but curl cannot connect, the service started before PostgreSQL was ready. Restart it.

If curl works from the server but the browser does not, the problem is in the Nginx proxy configuration rather than in the application.

Requesting the interactive API docs returns 404

There are none. The application disables FastAPI's generated /docs and /redoc endpoints. The API reference in this documentation set is the reference.

Cyrillic text is garbled in an exported CSV

Open the file through Excel's text import wizard and select UTF-8, rather than double-clicking it. Double-click works when the byte order mark is present, so if it is being stripped somewhere between the export and the file you opened, that is the thing to look at.

Telegram alerts never arrive

A bot cannot start a conversation. Send any message to your bot from the account that should receive alerts, then confirm the chat ID matches:

https://api.telegram.org/bot<TOKEN>/getUpdates

If the response contains no chat matching your configured ID, the ID is wrong.