Download OpenAPI specification:
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.
/api/v3/requestReportCalculation endpoint, specifying the tax country, tax year and base currency./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
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.
There are three options for white labeling reports created through the Tax API:
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.
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) |
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.
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.
Each trade carries a type label. Labels are grouped below; deposit/withdrawal are the unlabeled incoming/outgoing defaults.
| 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. |
| 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. |
| 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. |
| 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. |
transfer on both sides OR link an incoming linkedwithdrawal to any outgoing outflow.tokenMigration on both sides OR link an incoming swap to any outgoing outflow.trade on both sides OR use a single trade transaction with both in/out data.linkedTransactionId referencing the outgoing one.The per-country availability of each type is served live by GET /api/v1/transaction_types.
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.
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. |
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 |
{- "trades": [
- {
- "transactionId": 1,
- "accountName": "string",
- "exchangeName": "string",
- "tradeDate": "2015-09-13T23:29:52.123Z",
- "type": "trade",
- "linkedType": "transfer",
- "buyAmount": 0,
- "buyAssetId": 0,
- "sellAmount": 0,
- "sellAssetId": 0,
- "feeAmount": 0,
- "feeAssetId": 0,
- "linkedTransactionId": 0
}
], - "taxCountryCode": "DE",
- "rates": [
- {
- "assetId": 23,
- "date": "2015-09-13",
- "price": 12.05,
- "transactionId": 23
}
], - "taxYear": 2018,
- "reportUserData": {
- "name": "John Doe",
- "address": "Khreshchatyk str",
- "addressSupplement": "apt. 10",
- "postcode": "01001",
- "city": "Kyiv",
- "state": "Kyiv district",
- "country": "Ukraine"
}, - "baseBasketId": 870
}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 |
| request_id required | string <uuid> Request id which was fetched during tax data calculation request and should be used for fetching tax data |
{- "requestId": "d385ab22-0f51-4b97-9ecd-b8ff3fd4fcb6",
- "status": "NEW",
- "calculated": "2019-08-24T14:15:22Z",
- "reportParts": [
- {
- "downloadUrl": "string",
- "title": "string",
- "reportPartType": "REPORT",
- "extension": "pdf"
}
], - "data": {
- "taxYear": 0,
- "taxCountry": "string",
- "baseAsset": "string",
- "taxCategorySummaries": [
- {
- "title": "string",
- "totalGain": 0,
- "labelSummary": [
- {
- "label": "deposit",
- "costBasis": 0,
- "proceed": 0,
- "gain": 0
}
]
}
]
}, - "issues": [
- {
- "severity": "ERROR",
- "code": "MISSING_RATE",
- "message": "string",
- "transactionIds": [
- 0
], - "data": [
- null
]
}
]
}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
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 |
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 |
{- "trades": [
- {
- "transactionId": 0,
- "accountName": "string",
- "exchangeName": "string",
- "tradeDate": "2015-09-13T23:29:52.123Z",
- "type": "trade",
- "linkedType": "transfer",
- "buyAmount": 0,
- "buyAssetId": 0,
- "sellAmount": 0,
- "sellAssetId": 0,
- "feeAmount": 0,
- "feeAssetId": 0,
- "exchangeOrderId": "string",
- "otcAmount": 0,
- "hardforkAssetId": 0,
- "hardforkExchangeName": "Binance",
- "hardforkAccountName": "string",
- "hardforkDate": "2015-09-13T23:29:52.123Z",
- "linkedTransactionId": 0,
- "comment": "string"
}
], - "taxCountryCode": "DE",
- "rates": [
- {
- "assetId": 23,
- "date": "2015-09-13",
- "price": 12.05,
- "transactionId": 23
}
], - "baseBasketId": 870
}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.
| request_id required | string <uuid> Request id which was fetched during tax data calculation request and should be used for fetching tax data |
{- "requestId": "d385ab22-0f51-4b97-9ecd-b8ff3fd4fcb6",
- "status": "EMPTY",
- "calculated": "2019-08-24T14:15:22Z",
- "baseAsset": {
- "id": 343,
- "basketId": 343,
- "name": "Bitcoin",
- "ticker": "BTC",
- "taxConfig": {
- "property1": {
- "type": "CRYPTO"
}, - "property2": {
- "type": "CRYPTO"
}
}
}, - "data": {
- "unrealisedGains": [
- {
- "id": 0,
- "assetId": 0,
- "basketId": 0,
- "accountName": "string",
- "exchangeName": "string",
- "widgetId": 0,
- "holdingsAcquisitionPart": 0,
- "holdingsAcquisitionDate": "2019-08-24T14:15:22Z",
- "holdingsAcquisitionTimeRange": {
- "min": "2019-08-24T14:15:22Z",
- "max": "2019-08-24T14:15:22Z"
}, - "holdingsAcquisitionPrice": 0,
- "salesProceed": 0,
- "holdingsGains": 0,
- "holdingsTaxRelevance": "string",
- "taxationStatementType": {
- "title": "string",
- "shortTitle": "string",
- "taxFree": true
}, - "transactionId": 0
}
], - "totalGainsPerStatementType": {
- "property1": 0,
- "property2": 0
}
}, - "errors": [
- null
], - "warnings": [
- null
], - "issues": {
- "validationIssues": [
- {
- "errorCode": "string",
- "message": "string",
- "transactionId": 0
}
], - "fallbackIssues": [
- {
- "issueType": "missing_rate",
- "message": "string",
- "transactionId": 0,
- "data": null
}
]
}
}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).
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 |
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 |
{- "trades": [
- {
- "transactionId": 0,
- "accountName": "string",
- "exchangeName": "string",
- "tradeDate": "2015-09-13T23:29:52.123Z",
- "type": "trade",
- "linkedType": "transfer",
- "buyAmount": 0,
- "buyAssetId": 0,
- "sellAmount": 0,
- "sellAssetId": 0,
- "feeAmount": 0,
- "feeAssetId": 0,
- "exchangeOrderId": "string",
- "otcAmount": 0,
- "hardforkAssetId": 0,
- "hardforkExchangeName": "Binance",
- "hardforkAccountName": "string",
- "hardforkDate": "2015-09-13T23:29:52.123Z",
- "linkedTransactionId": 0,
- "comment": "string"
}
], - "taxCountryCode": "DE",
- "rates": [
- {
- "assetId": 23,
- "date": "2015-09-13",
- "price": 12.05,
- "transactionId": 23
}
], - "taxYear": 2018,
- "format": "pdf",
- "reportUserData": {
- "name": "John Doe",
- "address": "Khreshchatyk str",
- "addressSupplement": "apt. 10",
- "postcode": "01001",
- "city": "Kyiv",
- "state": "Kyiv district",
- "country": "Ukraine"
}, - "baseBasketId": 870
}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 |
| request_id required | string <uuid> Request id which was fetched during tax data calculation request and should be used for fetching tax data |
{- "requestId": "d385ab22-0f51-4b97-9ecd-b8ff3fd4fcb6",
- "status": "EMPTY",
- "calculated": "2019-08-24T14:15:22Z",
- "format": "json",
- "taxReportUrl": "string",
- "data": null,
- "errors": [
- null
], - "warnings": [
- null
], - "issues": {
- "validationIssues": [
- {
- "errorCode": "string",
- "message": "string",
- "transactionId": 0
}
], - "fallbackIssues": [
- {
- "issueType": "missing_rate",
- "message": "string",
- "transactionId": 0,
- "data": null
}
]
}
}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).
| tickers required | Array of strings |
Assets by tickers example
{- "assets": [
- {
- "id": 7847,
- "basketId": 58485,
- "name": "HT 3x Long",
- "ticker": "HT3L",
- "taxConfig": {
- "DE": {
- "type": "DERIVATIVE"
}, - "AT": {
- "type": "DERIVATIVE"
}, - "DEFAULT": {
- "type": "CRYPTO"
}
}
}, - {
- "id": 7848,
- "basketId": 7893,
- "name": "ASD",
- "ticker": "ASD",
- "taxConfig": {
- "DEFAULT": {
- "type": "CRYPTO"
}
}
}
], - "notFoundTickers": [
- "FOO",
- "BAR"
]
}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).
| 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. |
Asset example
[- {
- "id": 7847,
- "basketId": 58485,
- "name": "HT 3x Long",
- "ticker": "HT3L",
- "taxConfig": {
- "DE": {
- "type": "DERIVATIVE"
}, - "AT": {
- "type": "DERIVATIVE"
}, - "DEFAULT": {
- "type": "CRYPTO"
}
}
}, - {
- "id": 7848,
- "basketId": 7893,
- "name": "ASD",
- "ticker": "ASD",
- "taxConfig": {
- "DEFAULT": {
- "type": "CRYPTO"
}
}
}
]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).
| tickers required | Array of strings |
Asset example
[- {
- "id": 7847,
- "basketId": 58485,
- "name": "HT 3x Long",
- "ticker": "HT3L",
- "taxConfig": {
- "DE": {
- "type": "DERIVATIVE"
}, - "AT": {
- "type": "DERIVATIVE"
}, - "DEFAULT": {
- "type": "CRYPTO"
}
}
}, - {
- "id": 7848,
- "basketId": 7893,
- "name": "ASD",
- "ticker": "ASD",
- "taxConfig": {
- "DEFAULT": {
- "type": "CRYPTO"
}
}
}
]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.[- {
- "type": "security_token_distribution",
- "countrySpecificData": {
- "allowedCountries": [
- "AT"
]
}
}
]