Why tax calculation breaks without Koinly integration
Trades on an exchange are visible in the history, but the tax report is assembled manually — and by the second hundred operations it stops matching what actually happened in the account.
Export for the period, consolidation into a table, line-by-line manual reconciliation of operations — and at some point discrepancies appear in tax reporting, and it is unclear where the truth was lost: in the exchange data, in the table, or in the calculation rules.
The reason is that accounting for exchange trades is not only purchases and sales. It includes transfers between your own wallets, exchange of one asset for another, staking rewards, network fees, fractional remainders.
Each operation requires its own treatment: some things are a disposal, some are not. Manually, the rule is applied differently from line to line, and transaction matching errors accumulate by the end of the period.
The most common breakdown is double counting. A transfer from the exchange to your own wallet is read as a sale, the reverse transfer as a purchase, and income appears in the report that did not exist.
Or two parts of one trade end up in different lines and the operation is counted twice. Manual reconciliation finds this only after the figures have gone into reporting.
Koinly closes the problem at the source level: operations are pulled from the exchange directly, matched by addresses and timestamps, and disputed lines are flagged for human review. Below is how such an integration works and what remains on the side of the accountant or owner.
Measurable effect: reconciliation speed, accuracy, completeness of accounting
Direct export from the exchange to Koinly replaces manual transfer of statements: trades, staking rewards, and transfers between your own accounts enter accounting in the form in which they are recorded in the trading logs.
Then automatic categorization turns on — rules label operation types, and questionable items do not dissolve in the report but go into a review queue.
Measurements for the same portfolio before and after integration:
| Parameter | Before | After |
|---|---|---|
| Closing the reporting period | 2–3 weeks of manual statement review | 2–3 days together with discrepancy reconciliation |
| Completeness of trade accounting | some transfers between your own accounts were lost | every operation from exchange logs reaches accounting |
| Operation categorization | manually, errors on staking and internal transfers | by rules, disputed items go into a separate queue |
| Finding discrepancies | line-by-line comparison of tables | list of mismatches by account and date |
Speed of closing the reporting period
The period closes based on data readiness, not as manual reconciliation progresses: export runs on a schedule, discrepancies in transfers between accounts are highlighted immediately rather than surfacing on the last day. This removes the quarter-end rush and makes the closing deadline predictable.
Accuracy of categorization and completeness of accounting
Labeling rules are described explicitly and versioned — when the scheme changes, it is visible which operations were relabeled.
Disputed cases are not “adjusted” to fit the total: they remain in the queue with the account, date, and operation type indicated, so completeness of accounting is verifiable rather than declared in words.
Koinly integration: connection methods and their limitations
You can connect an exchange account to Koinly in three ways: direct connection to the exchange by key, import of operation files, and the service's API.
The choice is made not by convenience but by the volume of history and the number of platforms — each path has its own limits on the number of operations and its own cost of an accounting error.
| Option | When it fits | Limitations |
|---|---|---|
| Direct connection to the trading account | Active trading, hundreds of trades per month, one or two platforms | The service pulls history in batches, there is a cap on the number of operations, and some exchanges do not provide trades older than a certain period |
| Import of operation files | One-off calculations, unsupported platforms, archived accounts | Re-uploading creates duplicates, columns are matched manually, and a person performs reconciliation |
| Service API | Non-standard assets, accounts outside exchanges, regular calculation | You need your own exchange module and its maintenance, and there is a limit on request frequency |
Direct connection to the trading account
The key is issued read-only: you cannot trade or withdraw funds with it. Synchronization runs on a schedule, so recent trades enter the report with a delay, and the exchange often does not provide a deep archive at all — we cover that area with an export.
Import of exports and manual rules
The export fills in what is missing from the connection: transfers between your own accounts, staking rewards, network fees. Uploading is done with duplicate checks and asset matching rules; otherwise tax calculation diverges from actual account balances.
Implementation stages: from operation audit to handover of the regulation
The work proceeds in stages, and each ends with an artifact that can be checked: an operation map, a set of rules, a reconciliation protocol. The order is the same for exchange accounts, self-custody wallets, and on-chain addresses — only the method of obtaining data changes.
Operation audit and rule setup
- Inventory of sources. We collect exchanges, wallets, and networks, and clarify where a read-only key is sufficient and where exports are needed.
- Operation audit. We label movement types: trades, transfers between your own accounts, staking rewards, fees, fiat withdrawal. A transfer between your own wallets is not a sale, and most often the calculation breaks precisely on it.
- Setup of matching rules. We define the cost basis method for each asset pair, linking fees to trades, merging transfers, and handling positions for which there is no data.
- Import and normalization. We upload the history to Koinly and reconcile the final balances for each account with the actual ones — a discrepancy immediately shows the missed period.
- Labeling disputed operations. We record the decision on each ambiguous classification in writing so that in the next period the rule is applied automatically.
Check on a control period
Test reconciliation is performed on a closed period: we run the calculation, reconcile the result on a sample of trades manually, and check that a repeat import gives the same figure.
Discrepancies usually sit in three places — unclosed transfers, fees without linkage, and operations with incomplete data.
After convergence, we hand over the regulation: a map of sources and access rights, a set of rules with explanations, and the procedure for monthly import.
The calculation is launched according to the document without our involvement, and changing a rule is an edit of one line, not a rebuild of the entire history.
Handover package: matching rules, diagrams, reconciliation regulations
After implementation, the client is left not with a set of one-off scripts but with a working package: matching rules, flow diagrams, and reconciliation regulations. With them, the calculation is reproduced without the integration author — by in-house accounting or analyst staff.
Rules for matching and categorizing operations
- Matching rules table: how operations from exchange exports are linked to trades, transfers between your own accounts, and external addresses, what priority each rule has, and what exceptions were made manually.
- Category reference: fees, staking rewards, airdrop — with an indication of whether the operation goes into the taxable base or only into the acquisition cost.
- Rule change log: date, author, reason for the edit. It is visible how each change affected reports for past periods — the calculation remains reproducible.
- Set of reference exports: test data on which the rules are run after any edit.
Data flow diagrams and reconciliation regulations
- Data flow diagram from source to Koinly: where trade identifiers are normalized, where duplicates are filtered out, and at what boundary data is considered immutable.
- Reconciliation instructions: step-by-step month-end closing procedure, control sums for each account, and the procedure for investigation when there is a discrepancy.
- Maintenance regulation: run frequency, responsible person, and procedure for updating reference data when there are changes at the exchange.
Case study: how manual reconciliation and discrepancies in reports were removed
Initial situation and bottleneck
The client is an exchange with several thousand active accounts: accounting was kept via exports into spreadsheets, and reconciliation of operations was done manually.
Due to different formats for the same operation (trading, deposits/withdrawals, staking rewards), discrepancies appeared in reports, and month-end closing stretched over weeks, with part of the period spent finding the cause of the discrepancy rather than on the calculation itself.
We took over the export of operations via the exchange's API and passed it to Koinly with unambiguous type matching: each operation goes into its own category, not into “other”.
Trade pairs are reconciled automatically by identifiers, so duplicates and lost transfers between accounts do not reach accounting.
What changed in measurable metrics
- Manual operations when preparing the report: previously about 1,200 lines per export — now about 40, and only for handling exceptions.
- Discrepancies between exchange accounting and the report: from several dozen per period to a few, each closed with an indication of the cause.
- Month-end closing: from three weeks to two business days, including completeness checks.
- Check coverage: all deposits/withdrawals and trades; staking rewards and fees are labeled separately.
Reporting became reproducible: a repeat run for the same period gives the same result, and the change history is stored alongside the data.
How is automatic calculation different from exporting operations manually?
Manual export ends where operation matching begins. While there are dozens of trades, a file with history from the exchange's personal account and manual line labeling is enough: deposit, withdrawal, trade, accrual.
But as soon as there are several accounts and transfers move between them, the table stops balancing: each “in — out” pair is counted twice, and this is no longer a convenience issue but a direct error in the calculation base.
The main labor intensity of manual accounting is not in the export but in reconciliation. A transfer between your own wallets must be manually excluded from the calculation, staking rewards labeled as income, and fees linked to a specific trade.
One incorrectly labeled line changes the cost basis of the entire lot, and the discrepancy is discovered at reporting time, when there is nothing left to rebuild.
Automatic calculation begins with reading operations from exchanges and wallets and linking them by time, amount, and address.
The system itself distinguishes a transfer between your own accounts from a sale, applies the chosen cost basis method, and recalculates the result when a delayed transaction is loaded.
Integration with Koinly covers precisely this part: operations enter accounting without manual transfer, and reconciliation comes down to checking exceptions.
Short answer: manual export answers the question “what was in the account,” while automatic calculation answers “how much tax is due on it.” The boundary lies where a second account or a wallet outside the exchange appears.
Beyond that, manual transfer only becomes more expensive in labor and increases the probability of error with every new operation.
Common technical concerns before connecting
Before connecting, the client checks not the export itself but the risks around it: who sees the keys, what happens if synchronization fails, and how a rare asset is calculated. We have collected what most often comes up during technical review.
What permissions do exchange access keys need?
Read-only: trade history, balances, withdrawals. We do not request trading or withdrawal permissions — such a key physically cannot move funds, even if it ends up in the wrong place.
If the exchange cannot restrict permissions, we take the operation history as a file and import it on a schedule.
How are keys stored and what happens when they are revoked?
Keys are transmitted encrypted and stored in a secure secrets vault, not in configuration files or in messages; access to them is role-based, with an access log.
Revoking a key on the exchange side simply stops synchronization, while already loaded operations remain in Koinly — reporting does not collapse.
Several exchanges and wallets — in one report?
Yes, sources are combined into a single stream of operations: exchanges, hardware and software wallets, networks. Transfers between your own accounts are recognized as movements, not as sales — otherwise tax is charged on an asset that never went anywhere.
What if the export is interrupted or the asset is rare?
Synchronization proceeds page by page and resumes from the last confirmed operation; a repeat import does not create duplicates. For assets that are not in the reference, we add matching rules — wrapped and staking tokens.
Calculation rules are updated without rebuilding the integration: the configuration changes, and the history is recalculated on the same data.
Let's discuss the task: what data is needed for the work plan
To come back with an estimate of the scope of work and an implementation plan, full access to platforms and exports for all years are not needed. It is enough to describe the outline: where assets are stored, which services were in use, and how accounting is currently maintained. Below is the minimum that removes most of the uncertainty at the start.
- List of exchanges and wallets through which turnover actually went — this determines the set of connections and parsers for collecting history.
- Formats in which platforms provide data: operation export, API access, export from a blockchain explorer.
- Accounting policy: how the asset value at the time of receipt is determined and which cost basis method you apply on sale.
- Tax authority requirements for reporting: which forms and for which periods must be closed.
- Access scheme: whether you are ready to issue read-only keys or prefer to transfer export files.
- Volume of history: how many years and approximately how many operations need to be run through Koinly.
- Current accounting: spreadsheets, past reports, and manual reconciliations that are already maintained.
- Who on your side is responsible for reconciling discrepancies — this speeds up acceptance.
Based on these points, we describe the transaction matching scheme, the list of checks for duplicates and omissions, and the implementation stages with control points. Describe the task — we will come back with an estimate and a work plan.







