WhaleBooks API for third party access

WhaleBooks API for third party access

The API is ideal for third-party applications that aim to record their clients' transactions in WhaleBooks while also retrieving their portfolio results.

Comprehensive API documentation can be found at: https://whalebooks.com/open-api .

  • First, contact WhaleBooks Support to acquire the necessary API key.

  • Next, authenticate using this API key by including it in the "X-Api-Key" header.

  • Requests rate limit: 160 req / sec


Examples:

1. Create a User

Using: POST /api/v2/users

  • If successful, you will receive a response containing the user and their ID.

  • If an HTTP 409 error is returned, the user already exists in our system, and you must first obtain their permission to write data to their account. To do this, redirect the user to:

    • https://whalebooks.com/allow-api?user=<USER_EMAIL>&subject-id=<YOUR_ID>.

    • Once the user grants you access, you can resend the POST request and receive a user response that includes the userId.

Example body:

{ "email": "john.doe@example.com" }

2. Create Organization

Under an existing or new user, you’ll need to create an organization for which you will have write access.

Use: POST /api/v2/organizations and pass userId in request:

Example body:

{ "userId": 1,     "orgName": "fromAPI",     "displayName": "fromAPI",     "email": "fromAPI@api.com",     "taxResidency": "CZ",     "taxSubject": "NATURAL_PERSON" }

3. Get the Organization vault-id 

Use: GET /api/v2/organizations/{organization-id}/vaults

  • You will need vault-id in subsequent API calls.

Get user organizations

Returns the list of organizations the user is a member of, including membership/plan info and portfolios. The result is sorted by organization name
GET /api/v2/users/{user-id}/organizations

4. Create portfolio

Under Organization create Portfolio. A Portfolio is required to obtain meaningful computation results.

Use: POST /api/v2/organizations/{organization-id}/vaults/{vault-id}/portfolios

Example body:

{    "name": "fromAPI1",    "currency": "USD",    "computationType": "FIFO",    "experimentalComputation": true,      "feeApplicationType": "AT_PROFIT_REALIZATION",    "initialState": null }

5. Create/Update/Delete transaction container

Transactions are grouped into transaction containers. 1 (per client) should suffice.

Create Transaction Container

Use: POST /api/v2/organizations/{organization-id}/vaults/{vault-id}/containers

Example body:

{    "name": "fromAPI1",    "portfolioId": 1,    "type": "MANUAL"  # you should always use type manual in this usecase }

Update Transaction Container

@PUT /api/v2/organizations/{organization-id}/vaults/{vault-id}/containers/{container-id}

Updates an existing Transaction Container’s name, source

Request Body

Field

Type

Description

Field

Type

Description

name

String

New name of the transaction container.

source

String

New source identifier or description for the container.

Example

{ "name": "January Transactions", "source": "Whalebooks" }

Delete Transaction Container

@DELETE /api/v2/organizations/{organization-id}/vaults/{vault-id}/containers/{container-id}

Deletes a Transaction Container from the given vault.

  • Removes the container from all linked portfolios

  • Removes all transactions linked to the container

Response

HTTP 204 No Content

6. Create transactions

Use: POST /api/v2/organizations/{org-id}/vaults/{vault-id}/containers/{container-id}/transactions

Example body:

{    "baseCurrency":"BTC",    "quoteCurrency":"USD",    "type":"BUY",    "timestamp":1675209600698,    "note":"",   "addresses":[],   "baseQuantity":"10",    "quoteQuantity":"", "unitPrice":"25000", "transaction_container_id": 57000 }

Bulk create portfolio transactions

POST /api/v2/organizations/{organization-id}/vaults/{vault-id}/containers/{container-id}/transactions/bulk

Request body:

Array of transactions objects.

Rules

  • Minimum: 1 item

  • Maximum: 100 items

    • If more than 100 → 400 Bad Request with message: "Max 100 transactions per request."

  • If empty/null array → 400 Bad Request with message: "Request must contain at least 1 transaction."

Example

[ { "type": "BUY", "timestamp": "2024-09-01T10:00:00Z", "exchangeName": "Binance", "baseCurrency": "BTC", "quoteCurrency": "USD", "baseQuantity": 1, "quoteQuantity": 2, "status": { "code": "COMPLETED" }, "note": "BTC buy", "transactionLabels": [ { "name": "investment" } ] }, { "type": "DEPOSIT", "timestamp": "2024-09-02T08:00:00Z", "exchangeName": "Kraken", "baseCurrency": "ETH", "status": { "code": "COMPLETED" }, "addresses": ["0xabcdef1234567890"], "note": "ETH deposit" } ]

Response

  • 200 OK

  • Body: JSON array of created PortfolioTransactionDetailDto objects (same order as input).

7. Get portfolio calculations

Use: GET /api/v2/organizations/{organization-id}/vaults/{vault-id}/portfolios/{portfolio-id}/computation/dashboard

8. Download Reports

@GET /organizations/{organization-id}/vaults/{vault-id}/portfolios/{portfolio-id}/report/computation

Generates and downloads a portfolio report for the given organization, vault, and portfolio.

The report format depends on the type parameter (see ReportType list below).

The date range is automatically determined by the first transaction date and the portfolio’s reporting interval

Query parameters:

type - The type of report to generate (see Report Types below).

locale - The language/locale for the report (e.g., en, cs, de).

Supported ReportType values

Enum

File Extension

Content-Type

Enum

File Extension

Content-Type

TAX_TRADING_STATEMENT

.pdf

application/pdf

TRADE_CONFIRMATION

.pdf

application/pdf

ACTIVITY_STATEMENT

.pdf

application/pdf

Response

  • Returns the report file as a downloadable attachment.

Example

curl -X GET \ "http://whalebooks.com/api/v2/organizations/10/vaults/10/portfolios/5/report/computation?locale=cs-CZ&type=TAX_TRADING_STATEMENT" \ -H "X-Api-Key: YOUR_API_KEY_HERE" \ -o tax_trading_statement.pdf

9. Set or Delete Portfolio Initial State

@POST /api/v2/organizations/{organization-id}/vaults/{vault-id}/portfolios/{portfolio-id}/initial-state

Sets or deletes the initial state of a portfolio. The initial state defines the starting balance for cost basis calculations (e.g., AVCO, FIFO, etc.) based on another source portfolio.

Query parameters:

long sourcePortfolioId (required unless delete=true) - ID of the source portfolio to copy initial state from

boolean delete (not required) - If true, deletes the initial state of the portfolio (ignores body params)

Request Body:

{ "currency": "CZK", "computationType": "AVCO" }

Field

Type

Required

Description

Field

Type

Required

Description

currency

string

✅ Yes

Portfolio currency

computationType

ComputationType

✅ Yes

Cost basis method: AVCO, FIFO, LIFO, or HIFO

  • If delete=true: The portfolio’s initial state is removed.

  • If sourcePortfolioId is provided and body contains valid currency and computationType, the initial state is copied from the source portfolio.

  • Supports both ordered (FIFO, LIFO, HIFO) and unordered (AVCO) computation types.

Example (set initial state):

curl -X POST "http://whalebooks.com/api/v2/organizations/123/vaults/456/portfolios/789/initial-state?sourcePortfolioId=999" \ -H "Content-Type: application/json" \ -H "X-Api-Key: YOUR_API_KEY" \ -d '{ "currency": "CZK", "computationType": "AVCO" }'

Example (delete initial state)

curl -X POST "http://whalebooks.com/api/v2/organizations/123/vaults/456/portfolios/789/initial-state?delete=true" \ -H "X-Api-Key: YOUR_API_KEY"

10. Get Initial State Info for a Portfolio

@GET /api/v2/organizations/{organization-id}/vaults/{vault-id}/portfolios/{portfolio-id}/initial-state

Retrieves summary information about the initial state of a given portfolio. This includes whether the initial state is set, which source portfolio it was copied from, and the effective date.

Response:

Returns a JSON object with metadata about the portfolio’s initial state.

Example (initial state is set):

{ "isSet": true, "sourcePortfolioId": 22799, "sourcePortfolioName": "Initial Reference Portfolio", "fromDate": "2024-07-31" }

Example (no initial state):

{ "isSet": false, "sourcePortfolioId": null, "sourcePortfolioName": null, "fromDate": null }

Example

curl -X GET "http://whalebooks.com/api/v2/organizations/123/vaults/456/portfolios/789/initial-state" \ -H "X-Api-Key: YOUR_API_KEY"

 

Copyright © 2020-2025 General Bytes USA LLC