Sales Tracking
The money part of the business. After a book launches, your sales come in through retailer dashboards — KDP for Amazon, Apple for iBooks, Kobo’s Writing Life for Kobo, Draft2Digital if you’re aggregating, each with its own reports in its own format. The typical indie author downloads the reports to their computer, opens them in Excel or Google Sheets, tries to understand the columns, maybe builds a personal tracking spreadsheet that works for a while and then breaks when the retailer changes their report format. Six months later you have an incomplete financial picture of your own business and your tax prep is a panic. The Sales Tracking subtab exists to replace the spreadsheet with something designed specifically for author sales reporting, so that once you import a report, it’s structured, queryable, visualizable, and exportable without ever losing data to format drift.
It’s distinct from the rest of the Marketing module in that it’s purely retrospective. You can’t forecast sales, you can’t schedule campaigns, you can’t make decisions that affect future sales from this subtab. What you can do is look at what’s already happened — sales by marketplace, royalties by period, payment records, and the deltas between them — so you can make informed decisions elsewhere.
Importing reports
Section titled “Importing reports”Two kinds of file import:
KDP sales reports
Section titled “KDP sales reports”The xlsx or csv reports you download from KDP’s dashboard. KDP’s report format has specific columns (Title, ASIN, Marketplace, Date, Units Sold, Royalty Type, Royalty, Currency) and the subtab’s importer recognizes the columns via a regex-driven mapping. That means if KDP changes their column labels slightly in a future update, the importer can usually still read the file — the mapping is defensive.
Import a file, and the subtab:
- Reads the file (xlsx via openpyxl, csv via Python’s csv module).
- Maps columns to internal fields.
- Normalizes dates to YYYY-MM-DD.
- Strips currency symbols and commas from royalty values.
- Deduplicates against existing records (by title, marketplace, date, units, royalty — a record that matches all five is considered a duplicate and skipped).
- Inserts the new rows as a batch tagged with the import timestamp and filename.
The dedup matters because re-importing the same file — or overlapping monthly reports — is common, and you don’t want duplicates silently doubling your numbers.
Payment records
Section titled “Payment records”KDP (and most other retailers) issue monthly or bi-monthly payments separately from the sales reports. Payment reports have their own format — amount, currency, method, status, retailer. The subtab has a separate payments import flow that reads payment files and stores them in a dedicated payments table.
Payment records matter because your sales total doesn’t equal your disbursement total. Amazon holds earnings for 60 days before paying out. You might have $500 in sales for a month but only $300 in actual bank deposits during that month. Tracking payments separately from sales gives you both views — what you earned and what’s actually landed in your account.
The dashboard
Section titled “The dashboard”When you open Sales Tracking, the default view is the dashboard: a time-series chart of units sold and royalties earned across the date range you’re filtering, with stacked breakdowns by retailer, marketplace, and title.
Toggleable time granularity:
- Daily. Day-by-day view. Useful for launch weeks where you want to see the velocity of the launch.
- Weekly. The default. Smooths out day-of-week noise and shows actual trends.
- Monthly. Long-term view. Best for “how am I doing this year?”
Filter options:
- Date range. Last 7 days, last 30 days, last 90 days, last year, all time, or custom range.
- Retailer. KDP (the only one supported in the current version), or “all retailers.” Future versions will add more retailers.
- Marketplace. Amazon.com, Amazon.co.uk, Amazon.de, and so on. Each Amazon marketplace is a separate filter.
- Title. A specific book, or “all books.”
All filters compose. You can view “Book One on Amazon.com for the last 30 days, daily granularity” and the chart updates to exactly that slice.
What the dashboard shows
Section titled “What the dashboard shows”- Units sold. Total count, broken down by retailer/marketplace/title/period.
- Royalties earned. In your primary currency (converted from non-primary currencies using the exchange rate at the date of sale).
- Average price per sale. Units sold divided by royalties earned.
- Top-performing titles. Ranked list of which books are driving the most revenue in the current filter.
- Top-performing marketplaces. Which marketplaces are contributing the most.
- Trend indicators. Week-over-week or month-over-month changes, flagged as up / down / flat.
For payment tracking specifically, the subtab has a separate Payments view that shows disbursements over time — which payments have been issued, which are pending, and which have failed. The payments view is simpler than the sales dashboard because payments are simpler events than sales.
Deduplication and data integrity
Section titled “Deduplication and data integrity”Re-importing the same file should not produce duplicate records. The subtab uses a composite key for dedup — (title, marketplace, report_date, units_sold, royalty) — and any row that matches all five fields in an existing row is skipped on re-import.
This policy catches:
- Re-importing the same file. Same rows, all five fields match, all skipped.
- Overlapping monthly reports. KDP’s monthly reports sometimes overlap at the boundaries. Dedup handles it.
- Corrected reports. If KDP re-issues a report with a correction (say, they fixed a royalty rate), and the new row differs from the old row in the royalty field, dedup treats it as a new record. You’d then have both the old and new records, which is usually what you want — you can see the correction as a new row rather than silently overwriting the old one.
There’s also a batch concept. Every import creates a batch record with a timestamp, filename, and row count. You can see your import history as a list of batches, and you can delete a batch to undo an import if you imported the wrong file. Deleting a batch removes all its rows from the sales table, which is the escape hatch for mistaken imports.
CSV export
Section titled “CSV export”The subtab can export any filtered view as a CSV file. Apply your filters, click Export, download a CSV. The export includes every row in the current filter, with the same column structure whether you’re exporting KDP-specific fields or a general summary.
CSV export is most useful for:
- Tax prep. At the end of the year, export your full sales data as a CSV and hand it to your tax preparer.
- External analysis. If you want to run analysis that the subtab doesn’t support (say, you want to run a specific regression on price versus conversion), export and load into your preferred tool.
- Backup. Periodic exports as a backup of your financial data. The subtab stores the data in SQLite within the Ishvana project folder, but an external CSV gives you an extra layer of safety.
What the subtab doesn’t do
Section titled “What the subtab doesn’t do”A few deliberate limits:
- It doesn’t handle non-KDP retailers yet. Apple Books, Google Play Books, Kobo, Draft2Digital — each has its own report format, and the subtab currently only supports KDP. Future versions will add other retailers. For now, if you’re publishing wide, you’ll need to track non-KDP sales elsewhere and merge the numbers manually.
- It doesn’t forecast. There’s no “what will my next month’s sales look like” prediction. Forecasting requires assumptions about future marketing, seasonality, and launch cadence that the subtab doesn’t try to model.
- It doesn’t track ad ROI. Sales data is here. Ad spend is in Amazon Ads and Facebook Ads. The subtab doesn’t connect the two, so you can’t see “$200 in ad spend produced $450 in royalties” directly — you’d compute that manually by comparing the sales dashboard against your ad platform’s reports.
- It doesn’t handle subscription reads. Kindle Unlimited pages read (KENP) earnings are technically different from unit sales and have their own schema. KDP reports include KENP data, and the subtab imports it, but the display is simplified — KENP earnings show up as a separate line in the royalty column rather than being modeled as a distinct read-based revenue stream.
- It doesn’t sync with bank accounts. Payment records track what KDP says it paid you. Whether the money actually landed in your bank account is a separate question that involves your bank, your tax jurisdiction, and sometimes international transfer delays. The subtab shows the KDP side.
What it is good for
Section titled “What it is good for”- Launch week. You import daily KDP reports throughout the week and watch the units-per-day chart show the velocity of the launch. When the velocity drops off, you know it’s time to start running ads or social media promotion.
- Monthly business review. Once a month, import the latest reports and look at the monthly view. Is the series growing? Is Book One still selling after two years, or is the backlist decaying? Answering these questions takes a few minutes with the dashboard instead of an afternoon with a spreadsheet.
- Tax prep season. Export the full year’s data as a CSV, hand it to your accountant, done.
- Long-term career tracking. Two years of sales history gives you a real sense of your baseline, your launch bumps, and your series sell-through rate. The subtab makes the history queryable so the tracking compounds instead of being scattered across annual spreadsheets.