Batch Trade and Allocations

Overview

Bakkt provides a service for clients to collectively request digital asset allocations for investor accounts in bulk. Bakkt collects the allocation requests, aggregates them into a single order submitted to the market, and — once filled — processes the allocations at the average fill price of that order back out to the identified investor accounts.

The overall process:

  1. Open a batch of allocations, specifying the symbol and batch type (notional or quantity based).
  2. Submit allocation requests to the batch for each investor account (side, amount, symbol; optional custom fee in BPS or fixed).
  3. Close the batch, indicating the number of allocations that belong to it.
  4. Bakkt runs validations across the requested allocations and adjusts the aggregate order size based on any allocations that fail validation.
  5. Bakkt sends trade details for bookkeeping/tax reporting and issues a trading email confirmation to notify each investor of the allocation.

Core Concepts

Allocations

Digital asset allocation involves identifying the percentage of digital assets in the investor's overall investments, then choosing the blend of digital assets that match the investor's desired portfolio balances. Bakkt provides a Firm Allocation Account in order to submit batch trades for investors.

Event Notifications

Bakkt provides a durable event queue so clients can receive updates on digital asset orders, transfers, allocations, and gifting rewards. See the Webhooks guide for event queue and SQS integration details.

Notifications

Bakkt provides an end-of-day summary of investor digital asset transactions. Bakkt Support helps configure notices during onboarding.

Workflow

1. Create the Firm Allocation Account

Contact Bakkt at [email protected] to begin submitting batch trades. Bakkt must create a Firm Allocation Account before this flow can be used.

2. Submit Batched Trade Allocation Requests and Close the Batch

Use the Open Batch Trade Allocation, Request for Allocation, and Request to Close Allocation endpoints to create a batch, specify its allocations, and submit it:

  • The Open and Close endpoints are used once per batch.
  • The Allocate endpoint is used for each allocation within the batch.

Required fields are documented in the OpenAPI specification.

3. Validate the Batch and Allocations

Each allocation request validates the request data. If any validation fails, the response has a REJECTED status and a reason string explaining why.

After the batch is closed, Bakkt runs a series of validations across all allocations and processes them. Terminal-state messages are sent via the event queue:

  • COMPLETE — the allocation processed successfully; the event payload contains allocation details.
  • REJECTED — the allocation failed validation.

Common errors and reject reasons:

  • Customer account does not exist.
  • Firm Allocation Account does not exist.
  • The same clientTransactionId was submitted more than once.
  • The allocation symbol does not match the batch symbol.
  • The batch ID does not exist (when allocating to or retrieving from a batch).
  • Allocation count mismatch (when closing the batch).
  • Investor account does not hold enough digital assets to sell.
  • The clientTransactionId does not exist (when retrieving allocation details).
  • Symbol does not exist.
  • Allocation amount (notional or quantity) is negative.

4. Settle Funds

Batched orders carry the same markup/commission as investor trading. After processing the allocations, funds settle via Third-Party Journals (TPJs) from investor accounts.

Sample Events

Bakkt uses a durable event queue for messaging; payloads are delivered in the body of SQS messages. See Webhooks for event queue details.

Batch opened:

{
  "event_type": "allocation/batch/1",
  "message_id": "6f6ab118-5c02-41e1...",
  "payload": {
    "allocations": 0,
    "createdAt": "2026-01-03T06:02:13.417Z",
    "id": "5c394ed8-b7a3-48d8-b793-7ee6...",
    "request": {
      "batchTransactionId": "49136c79-3ce9-4f8d-8794...",
      "symbol": "BTCUSD",
      "type": "NOTIONAL"
    },
    "status": "OPEN"
  },
  "timestamp": "2026-01-03T06:02:13.424552751Z"
}

Batch closed:

{
  "event_type": "allocation/batch/1",
  "message_id": "b8b55e4a-3637-42fd-80e5-e2311...",
  "payload": {
    "allocations": 1,
    "createdAt": "2026-01-03T06:02:16.121Z",
    "id": "3ac9077f-d7a6-4200-bc1f-669d567...",
    "request": {
      "batchTransactionId": "95875dd9-c380-4cb5...",
      "symbol": "BTCUSD",
      "type": "NOTIONAL"
    },
    "status": "CLOSED"
  },
  "timestamp": "2026-01-03T06:02:16.190980550Z"
}

Allocation complete:

{
  "event_type": "allocation/batch/1",
  "message_id": "0c61649a-25db-424c-904e-5568b...",
  "payload": {
    "createdAt": "2026-06-24T14:33:31.605Z",
    "id": "458b1182-6449-48e1-b2c0-3c942c...",
    "netMoney": "200",
    "price": "21440.92",
    "quantity": "0.00932796",
    "request": {
      "account": "6a605008...",
      "amount": "200",
      "batchTransactionId": "d26q8619-7uc1-4fcf-99b6-...",
      "clientTransactionId": "69d4c791-4db3-486b-b4a8-d5fb...",
      "side": "BUY",
      "symbol": "BTCUSD"
    },
    "status": "COMPLETE"
  },
  "timestamp": "2026-06-24T14:34:16.749988161Z"
}

Allocation rejected:

{
  "event_type": "allocation/batch/1",
  "message_id": "6f61118-5c02-41e1...",
  "payload": {
    "createdAt": "2026-01-03T06:02:13.417Z",
    "id": "5c394ed8-b7a3-1118-b793-7ee6...",
    "rejectReason": "Insufficient BCH available to allocate",
    "request": {
      "account": "AT00000",
      "symbol": "BCHUSD",
      "quantity": 0.0001,
      "type": "QUANTITY"
    },
    "batchTransactionId": "49136c79-3ce9-4f8d-8794...",
    "clientTransactionId": "94c28222-1111-1111-1111-a359913c4c4d",
    "side": "SELL",
    "status": "REJECTED"
  },
  "timestamp": "2026-01-03T06:02:13.424552751Z"
}

Reporting

Tax Reporting

Bakkt treats all allocations as trade transactions and posts them to its bookkeeping department for cost-basis purposes, noting the transaction type as Buy or Sell. Allocation details are included in each investor's year-end profit/loss statement.