Tax API

Download OpenAPI specification:

Introduction

The Tax API lets you create legislation- and standards-compliant tax reports for you and your customers.

API versions. The v3 report-calculation endpoints (/api/v3/...) are the current API. The v2 report-calculation and unrealized gains endpoints are deprecated and scheduled for removal on 2026-12-01 — please migrate to v3.

Creating a tax report (v3)

  1. POST transaction information to the /api/v3/requestReportCalculation endpoint, specifying the tax country, tax year and base currency.
  2. Poll the /api/v3/checkResult endpoint until the status is past NEW/PROCESSING. On completion the response carries the typed results (data), the downloadable report parts (reportParts, each with its own presigned URL), and any issues raised during the calculation.

This is the base URL of the Tax API:
https://api-test.cryptotax.io

Authentication

The Tax API is secured using JWT tokens. You must pass your individual token for each request using the HTTP header parameter Authorization.

Example:
Authorization: Bearer <token>

If you haven't requested your API token yet, please reach out to us at sales@blockpit.io for more details, or visit the Blockpit.io website.

White Labeling

There are three options for white labeling reports created through the Tax API:

  1. only use the Blockpit logo,
  2. co-label the report with your own logo
  3. only use your logo.

If you want to opt for option (2) or (3), please send us your logo image when requesting API access.

Also, please provide your address information to include on the report cover letter.

Reporting Base Currency

Tax report calculations are always based on a country's base (fiat) currency, identified by a basket id. For the fully-supported tax countries (Austria, Belgium, Switzerland, Germany, Spain, France, United Kingdom, Italy, Netherlands, United States) the base currency is fixed to the value shown. For the other listed countries it is the default and may be overridden via baseBasketId. For any tax country not listed below (e.g. the generic international report), you may choose any of the supported base currencies below via baseBasketId.

Base currency Code Basket id Tax countries
Euro EUR 203 Austria (AT)
Belgium (BE)
Bulgaria (BG)
Cyprus (CY)
Germany (DE)
Estonia (EE)
Spain (ES)
Finland (FI)
France (FR)
Greece (GR)
Croatia (HR)
Ireland (IE)
Italy (IT)
Lithuania (LT)
Luxembourg (LU)
Latvia (LV)
Malta (MT)
Netherlands (NL)
Portugal (PT)
Slovenia (SI)
Slovakia (SK)
Swiss Franc CHF 231 Switzerland (CH)
Liechtenstein (LI)
Pound Sterling GBP 205 United Kingdom (GB)
United States Dollar USD 227 United States (US)
Australian Dollar AUD 230 Australia (AU)
Canadian Dollar CAD 228 Canada (CA)
Czech Koruna CZK 208 Czech Republic (CZ)
Danish Krone DKK 206 Denmark (DK)
Hungarian Forint HUF 202 Hungary (HU)
Israeli New Shekel ILS 204 Israel (IL)
Norwegian Krone NOK 220 Norway (NO)
Polish Zloty PLN 216 Poland (PL)
Romanian Leu RON 162 Romania (RO)
Serbian Dinar RSD 143 Serbia (RS)
Swedish Krona SEK 215 Sweden (SE)
Ukrainian Hryvnia UAH 156 Ukraine (UA)

Country-specific vs. generic tax reports

The Tax API supports country-specific tax reports which comply with the countries' tax legislation and are approved by a Big 4 firm. Additionally, a generic tax report can be created for all other international tax countries.

Assets

Transactions reference assets by their numeric asset id (buyAsset, sellAsset, feeAsset). Resolve the ids for the tickers you use via GET /api/v3/assetsByTickers?tickers=BTC,ETH,… (up to 100 tickers). It returns a single asset per group of equal assets — the one with the smallest id — so you get one unambiguous id per ticker.

The v2 assets endpoints (GET /api/v2/assets and GET /api/v2/assetsByTickers) are deprecated and scheduled for removal on 2026-12-01 — please migrate to GET /api/v3/assetsByTickers.

Transaction types

Each trade carries a type label. Labels are grouped below; deposit/withdrawal are the unlabeled incoming/outgoing defaults.

Incoming

Type Label Description
deposit Unlabeled (In)
staking Staking You earned assets as a result of locking your tokens to support PoS consensus.
mining Mining You earned assets for actively running a mining node.
masternodes Masternode You earned assets for actively running a validator node.
income Income You received assets as income from various activities.
lending Interest You received interest for lending out your assets.
bounties Bounty You earned assets in exchange for specific minor tasks like marketing efforts.
cashback Cashback You earned assets in exchange for specific minor tasks like marketing efforts.
airdrop Airdrop You received assets for free without any particular actions.
security_token_distribution Security Token Income You received assets due to interest/dividend/revenue share distribution from a security token in which you invested.
nonTaxableIn Non-Taxable (In) You received a non-taxable deposit, e.g. a Fiat deposit.
receiveLoan Receive Loan (In) You received assets as a loan from a third party or protocol.
closeperp Close Perp You have fully or partially closed a perpetual futures position.

Outgoing

Type Label Description
withdrawal Unlabeled (Out)
spending Payment You paid for a good or service with assets.
lost Lost You lost assets due to errors, forgotten keys, theft, or other reasons.
fee Fee You paid a network or transaction fee.
nonTaxableOut Non-Taxable (Out) You have made a non-taxable withdrawal, e.g. a Fiat withdrawal.
repayLoan Repay Loan (Out) You repaid assets to settle a loan with a third party or protocol.
stockPurchase Stock Purchase You used cryptocurrencies to purchase real-world stocks.
stockSale Stock Sale You received cryptocurrencies from selling real-world stocks.
openperp Open Perp You have opened or added to a perpetual futures position.

Derivative / Margin

Type Label Description
margin_trading_profit Derivative Profit You realized profit from trading derivatives e.g. futures/options.
margin_trading_loss Derivative Loss You realized a loss from trading derivatives e.g. futures/margin.
margin_trading_fee Derivative Fee Fees paid or trading with derivatives, e.g. rollover fees.
marginProfit Margin Profit You realized profits from margin trading positions.
predictionProfit Prediction Profit You earned assets from a successful prediction or betting outcome.
marginLoss Margin Loss You realized a loss from margin trading positions.
predictionLoss Prediction Loss You lost assets due to an unsuccessful prediction or bet.
marginFee Margin Fee Fees paid for margin trading positions.

Complex (linked)

Type Label Description
trade Trade You sold an asset for another asset.
marginTrade Margin Trade You traded actual cryptocurrencies on the spot market using leverage.
transfer Transfer You transferred assets from one Integration to another.
tokenMigration Token Migration Token migration occurs when the same project switches from one token version to another. This is considered a non-taxable event.

Transaction mapping rules

  • transfer — Set transfer on both sides OR link an incoming linkedwithdrawal to any outgoing outflow.
  • tokenMigration — Set tokenMigration on both sides OR link an incoming swap to any outgoing outflow.
  • trade — Set trade on both sides OR use a single trade transaction with both in/out data.
  • Linking — For all dual-transaction cases, the incoming transaction must include a linkedTransactionId referencing the outgoing one.

The per-country availability of each type is served live by GET /api/v1/transaction_types.

Report calculation API endpoints (v3)

Load transaction data for tax calculation

Requests a new tax data calculation. The per-transaction fields exchangeOrderId, otcAmount, comment and all hardfork* fields are not accepted; the hardfork asset and date are resolved automatically. The trades list may be empty.

Request Body schema: application/json
required
required
Array of objects (ApiTradeV3Dto)

List of transactions

taxCountryCode
required
string
Enum: "AT" "AU" "BE" "BG" "CA" "CH" "CY" "CZ" "DE" "DK" "EE" "ES" "FI" "FR" "GB" "GR" "HR" "HU" "IE" "IL" "INT" "IT" "LI" "LT" "LU" "LV" "MT" "NL" "NO" "PL" "PT" "RO" "RS" "SE" "SI" "SK" "UA" "US"

Tax jurisdiction. AT, DE, CH, US, FR, ES, NL, BE, GB, IT produce country-specific reports. Any other supported country produces a parametric report based on that country's default tax settings. INT (and any unrecognised code) produces a parametric report based on the global default settings, using the fiat currency specified in baseBasketId.

Array of objects (ApiRateRequestDto)

Rates of assets, which can be used during calculation in the case when we do not have such rates (you got missing_rate error) or you want to use your own rates

taxYear
required
integer <int32> >= 2013

Year for which tax data should be calculated

object (ApiReportUserDataRequestDto)

Data that is used to form header for cover letter in reports. If 'null' then default value is provided.

baseBasketId
required
integer <int32>

Base basket id, only fiat is allowed

Responses

Request samples

Content type
application/json
{
  • "trades": [
    ],
  • "taxCountryCode": "DE",
  • "rates": [
    ],
  • "taxYear": 2018,
  • "reportUserData": {
    },
  • "baseBasketId": 870
}

Check for finished tax calculation results

Polls the status of a calculation request and returns the result.

status meaning
NEW the request has been received
PROCESSING the request is being processed
COMPLETED finished with no issues — results in data, files in reportParts
COMPLETED_WITH_FALLBACK finished, but one or more fallbacks were applied — see issues
ERROR the calculation failed — see issues

The issues field is a single typed list (ApiIssueV3Dto). Each item has a severity (ERROR or WARNING), a code, a message, the affected transactionIds, and an optional structured data payload.

code severity meaning / fallback applied
MISSING_RATE WARNING a rate could not be resolved; a rate of 0 was applied
MISSING_ASSET WARNING an asset was spent without a known acquisition; a synthetic previous incoming was created
EMPTY_REPORT WARNING there were no transactions to calculate
LINKED_WITHDRAWAL_LOOP WARNING a loop in linked withdrawals was detected and broken
MISSING_FORK_ASSET WARNING the forked asset was missing in the account at the fork date; the trade was treated as a deposit
WRONG_TRANSACTION_TYPE WARNING the transaction type was unknown/unsupported and was reassigned to deposit or withdrawal
MISSING_HARDFORK_ORIGIN_ASSET WARNING the hardfork origin asset could not be resolved; the transaction was treated as a deposit
UNKNOWN_ERROR ERROR an unexpected error aborted the calculation
query Parameters
request_id
required
string <uuid>

Request id which was fetched during tax data calculation request and should be used for fetching tax data

Responses

Response samples

Content type
application/json
{
  • "requestId": "d385ab22-0f51-4b97-9ecd-b8ff3fd4fcb6",
  • "status": "NEW",
  • "calculated": "2019-08-24T14:15:22Z",
  • "reportParts": [
    ],
  • "data": {
    },
  • "issues": [
    ]
}

Unrealized gains API endpoints

Load transaction data for unrealized gains calculation Deprecated

Deprecated — scheduled for removal on 2026-12-01. No replacement; the unrealized gains feature is being discontinued.

This API endpoint is used to request a new unrealized gains data calculation. In addition to information on all transactions (e.g. deposits, withdrawals, trades), you specify the country for which the unrealized gains should be calculated

Request Body schema: application/json
required
required
Array of objects (ApiTradeDto) [ 1 .. 2147483647 ] items

List of transactions

taxCountryCode
required
string
Enum: "AT" "AU" "BE" "BG" "CA" "CH" "CY" "CZ" "DE" "DK" "EE" "ES" "FI" "FR" "GB" "GR" "HR" "HU" "IE" "IL" "INT" "IT" "LI" "LT" "LU" "LV" "MT" "NL" "NO" "PL" "PT" "RO" "RS" "SE" "SI" "SK" "UA" "US"

Use the mentioned enums except for INT for country-specific calculations. Use INT for universal calculations that are based on the fiat currency specified in parameter baseBasketId.

Array of objects (ApiRateRequestDto)

Rates of assets, which can be used during calculation in the case when we do not have such rates (you got missing_rate error) or you want to use your own rates

baseBasketId
required
integer <int32>

Base basket id, only fiat is allowed

Responses

Request samples

Content type
application/json
{
  • "trades": [
    ],
  • "taxCountryCode": "DE",
  • "rates": [
    ],
  • "baseBasketId": 870
}

Check for finished unrealized gains calculation results Deprecated

Deprecated — scheduled for removal on 2026-12-01. No replacement; the unrealized gains feature is being discontinued.

This API endpoint is used to check on the status of a started unrealized gains calculation request. If the status property of the response shows the value COMPLETED, the calculation results can be found on the data property.

query Parameters
request_id
required
string <uuid>

Request id which was fetched during tax data calculation request and should be used for fetching tax data

Responses

Response samples

Content type
application/json
{
  • "requestId": "d385ab22-0f51-4b97-9ecd-b8ff3fd4fcb6",
  • "status": "EMPTY",
  • "calculated": "2019-08-24T14:15:22Z",
  • "baseAsset": {
    },
  • "data": {
    },
  • "errors": [
    ],
  • "warnings": [
    ],
  • "issues": {
    }
}

Report calculation API endpoints

Load transaction data for tax calculation Deprecated

Deprecated — scheduled for removal on 2026-12-01. Use the /api/v3 report-calculation endpoints instead.

This API endpoint is used to request a new tax data calculation. In addition to information on all transactions (e.g. deposits, withdrawals, trades), you specify the tax year and country for which the report should be generated, as well as the report format (e.g. PDF).

Request Body schema: application/json
required
required
Array of objects (ApiTradeDto) [ 1 .. 2147483647 ] items

List of transactions

taxCountryCode
required
string
Enum: "AT" "AU" "BE" "BG" "CA" "CH" "CY" "CZ" "DE" "DK" "EE" "ES" "FI" "FR" "GB" "GR" "HR" "HU" "IE" "IL" "INT" "IT" "LI" "LT" "LU" "LV" "MT" "NL" "NO" "PL" "PT" "RO" "RS" "SE" "SI" "SK" "UA" "US"

Use the mentioned enums except for INT for country-specific tax reports. Use INT for universal tax reports that are based on the fiat currency specified in parameter baseBasketId.

Array of objects (ApiRateRequestDto)

Rates of assets, which can be used during calculation in the case when we do not have such rates (you got missing_rate error) or you want to use your own rates

taxYear
required
integer <int32> >= 2013

Year for which tax data should be calculated

format
string
Enum: "json" "xlsx" "pdf"

Tax data format, default value json

object (ApiReportUserDataRequestDto)

Data that is used to form header for cover letter in reports. If 'null' then default value is provided.

baseBasketId
required
integer <int32>

Base basket id, only fiat is allowed

Responses

Request samples

Content type
application/json
{
  • "trades": [
    ],
  • "taxCountryCode": "DE",
  • "rates": [
    ],
  • "taxYear": 2018,
  • "format": "pdf",
  • "reportUserData": {
    },
  • "baseBasketId": 870
}

Check for finished tax calculation results Deprecated

Deprecated — scheduled for removal on 2026-12-01. Use the /api/v3 report-calculation endpoints instead.

This API endpoint is used to check on the status of a started calculation request.

Status property:

Value Description
NEW the request has been received
PROCESSING the request is being processed
COMPLETED the calculation results can be found in the data property
WARNING check the warnings property to get the details
ERROR the calculation is failed. Find the result in the errors property

Errors and warnings contain array of objects with properties type, message, and data:

type message data
ERROR missing_rate Amount of missing rates - {} Array of objects [1]
ERROR linkedwithdrawal_loop There is a loop detected in your linked withdrawal clarifications Array of objects [2]
ERROR missing_fork_asset Forked asset {} is missing in account {} at provided fork date ({}) transactionId
WARNING missing_asset Number of missing assets: {} Array of objects [3]
WARNING empty_report There is not any assets to calculate report null

Data property [1] object for ERROR status missing_rate type:

field type
assetId number
assetCode string
date string <date-time>
transactionIds Array of numbers

Data property [2] object for ERROR status linkedwithdrawal_loop type:

field type
id number
exchangeName string
accountName string
date string <date-time>
type Enum: 'deposit', 'withdrawal', 'trade'
amount number
asset string
depositAdjustmentType linkedwithdrawal \ null

Data property [3] object for WARNING status missing_asset type:

field type
transactionId number
assetId number
assetCode string
exchange string
account string
date string <date-time>
amount number
query Parameters
request_id
required
string <uuid>

Request id which was fetched during tax data calculation request and should be used for fetching tax data

Responses

Response samples

Content type
application/json
{
  • "requestId": "d385ab22-0f51-4b97-9ecd-b8ff3fd4fcb6",
  • "status": "EMPTY",
  • "calculated": "2019-08-24T14:15:22Z",
  • "format": "json",
  • "taxReportUrl": "string",
  • "data": null,
  • "errors": [
    ],
  • "warnings": [
    ],
  • "issues": {
    }
}

Assets API endpoints (v3)

Get supported assets for the provided tickers

Returns the currently available assets for the provided tickers (up to 1000 tickers), sorted by ticker then by basket id. For each group of equal assets only the one with the smallest id is returned, so each ticker maps to a single unambiguous asset. Requested tickers for which no asset exists are returned in notFoundTickers. You need this information when loading transaction data for tax calculation (i.e. the /api/v3/requestReportCalculation endpoint).

query Parameters
tickers
required
Array of strings

Responses

Response samples

Content type
application/json

Assets by tickers example

{
  • "assets": [
    ],
  • "notFoundTickers": [
    ]
}

Assets API endpoints

Get a paginated list of supported assets Deprecated

Deprecated — scheduled for removal on 2026-12-01. Use the /api/v3/assetsByTickers endpoint instead.

This API endpoint gives you information on all currently available assets and their ids. You need this information when loading transaction data for tax calculation (i.e. /requestReportCalculation API endpoint).

query Parameters
offset
integer <int32>
Default: 0

Optional offset of the paginated list of assets to return.

limit
integer <int32>
Default: 5000

Optionally specify the number of results to return. Use this parameter and the 'offset' parameter to determine your own pagination size.

Responses

Response samples

Content type
application/json

Asset example

[
  • {
    },
  • {
    }
]

Get a paginated list of supported assets with provided tickers, sorted by ticker then by basket_id then by asset_id Deprecated

Deprecated — scheduled for removal on 2026-12-01. Use the /api/v3/assetsByTickers endpoint instead.

This API endpoint gives you information on all currently available assets and their ids with provided tickers. You need this information when loading transaction data for tax calculation (i.e. /requestReportCalculation API endpoint).

query Parameters
tickers
required
Array of strings

Responses

Response samples

Content type
application/json

Asset example

[
  • {
    },
  • {
    }
]

Transaction types endpoints

Get a list of supported transaction types

This API endpoint gives you information about all currently supported transaction types.

Note that:

  • nonTaxableIn and nonTaxableOut will be reflected as Non-Taxable.
  • deposit and withdrawal will be reflected as Unlabeled.
  • linkedwithdrawal and withdrawal that are linked to each other will be reflected as Transfer.
  • Any transaction with a label of type Incoming linked to any transaction with a label of type Outgoing will also be reflected as Transfer.

Responses

Response samples

Content type
application/json
[
  • {
    }
]