Start with the event, not the row count
Two imported rows can describe one underlying event, but two similar rows can also be genuine separate fills. A reconciliation process asks what happened, which source recorded it and how that source represented it. Deleting everything with the same amount can remove real activity.
Koinly documents exact-duplicate detection, while warning that API and CSV data or differently formatted exports may not match exactly. A tool skipping a file does not prove that all other overlapping imports are clean. Keep the original exports and import reports before making corrections.
Map the coverage of each source
Create a small inventory: account, file or API source, covered dates, event types and import status. Note whether an export contains orders, individual trade fills, deposits, withdrawals or fees. Do not assume two files complement each other just because their filenames differ.
For a fictional example, an API connection covers November and a CSV covers the same account for the same month. Importing both may overlap. Another CSV might contain only withdrawals that the first source omitted. Check that actual coverage before removing a source or importing it again.
Normalize the timestamps before comparing
The same instant can be written as 2026-11-01 00:15 at UTC+02:00 and 2026-10-31 22:15 at UTC. It crosses a date boundary without becoming a different event. Treating both raw timestamps as UTC could make one activity appear twice at different times.
Koinly says it assumes UTC when a file does not specify a timezone, and provides an import setting for files recorded in another zone. Choose the source file's actual timezone; do not choose a convenient zone merely to make rows line up. Preserve the raw timestamp and document the interpretation.
Match candidates using several fields
Compare account, normalized time, asset, quantity, available transaction or trade identifier, direction and fee representation. Treat a match as a candidate for review rather than a universal deduplication rule. A blockchain transaction can involve several movements, and an exchange order can contain several fills.
In our fictional worksheet, API row A and CSV row B share event label DEMO-001 after time normalization. That label is not a real transaction hash. Row C has a different event label despite an identical amount, so the worksheet keeps it separate pending evidence. The download is a teaching file, not a provider import template.
Correct a small, evidenced sample first
Read the software's current correction and restore instructions. Start with a small group you can reconcile to the original statement. Record which representation you retain and why; review fees and resulting balances afterward. Avoid permanently deleting a whole account history to resolve one uncertain duplicate.
Preserve a correction log with the source filename, original row or event reference, observed issue and decision. If you contact support, share only the required records through its official channel. Financial exports can reveal balances and counterparties, so keep real files out of public forum posts.
Review the import outcome, not just the success banner
Check imported, skipped and rejected rows, date coverage and the balance changes you expected. A completed upload is not proof of complete history. If an import overlaps an existing integration, reconcile that overlap before adding another file in an attempt to repair the result.
This workflow is data hygiene, not a tax classification or a promise that a generated report is correct. Local rules and individual circumstances still matter. Keep the original evidence so a provider or qualified adviser can inspect the decisions behind the final records.
In the worksheet, the two normalized DEMO-001 timestamps are identical while DEMO-002 remains a separate candidate. Keep both source rows as evidence until the overlap is understood; do not turn a matching timestamp into a deletion command.


