Skip to main content
Canton items are Fireblocks transactions, not a separate resource tree. There are no Canton-specific read endpoints. You list and read Canton activity with the transactions endpoints you already use, and everything Canton-specific arrives in a cantonDetails object on the transaction. The webhook carries the identical cantonDetails object, so a client that handles one needs no second parser for the other. See Canton Transaction Webhooks.

Identify a Canton transaction

The presence of cantonDetails is the authoritative signal that a transaction is a Canton item. A transaction with no cantonDetails object is not one.

The three shapes of cantonDetails

At most one of these three keys is present on any transaction. The split is not inbound versus outgoing. Every response transaction you create is outgoing and carries offerResponse, and in the vault-to-vault transfer case a pre-existing outgoing transfer is stamped with a populated availableResponses. If cantonDetails is present but none of the three keys are, the transaction is Canton-related but outside these shapes. Skip it rather than treating it as an error.

Decide whether an offer can be responded to

This is the rule the rest of the page depends on.
A transaction is answerable if and only if cantonDetails.offerResponse.availableResponses is non-empty. Never decide answerability from subStatus == PENDING_RECEIVER_APPROVAL.
One offer can flag two transactions with PENDING_RECEIVER_APPROVAL. In the vault-to-one-time-address transfer case you see this:
A client that filters on the sub-status posts to both and gets a 409 on the second. A client that filters on availableResponses.length > 0 posts once. Transaction B is neither broken nor a duplicate. It is a linked leg whose only job is to point at where the answer goes.
An empty availableResponses means nothing is answerable here. It does not always mean the offer is closed: on a linked leg it means answer elsewhere, and originalTransactionId says where. The array going empty is also the terminal signal, covering answered, expired, and a response in flight. There is no separate resolved flag.

Fields on offerResponse

Not every offer has a deadline, so treat expiresAt as optional. Where it is present and passes, the transaction moves to sub-status RECEIVER_APPROVAL_TIMEOUT and availableResponses empties.
availableResponses carries identifiers, not argument shapes. What each value means, and which fields it requires, lives in the matching variant of the request schema on Answer an offer. Treat the enum as open: a new vendor flow adds a value, so tolerate values you do not recognize rather than failing to deserialize.

Answer an offer

Take id from the answerable transaction. That is the offerId path parameter of Answer an offer.
Copy cantonDetails.offerResponse.domain into the body’s domain, then pick a responseType from availableResponses.

Fields on call

Present on an outgoing transaction that carries a call you made with Make a Canton call. This makes GET /v1/transactions filterable into your Canton calls without a per-call-type collection endpoint. domain is derivable from type, but it is published so that filtering for all your onboarding activity is one filter across offers and calls rather than an eight-entry mapping each client reimplements.

Fields on settlement

Present on the settlement receipt, the transaction that appears when a venue executes an allocation you had locked. It is COMPLETED at creation and carries the cross leg: the asset and amount you receive, where the allocation transaction carried what you gave. Without originalTransactionId the credit side of a delivery-versus-payment is an unexplained incoming transfer, and the two halves of one trade cannot be reconciled through the API.

The ALLOCATED lifecycle

An accepted allocation is the one place a Canton transaction sits at CONFIRMING for an extended period rather than passing through it:
CONFIRMING with ALLOCATED is the only state in which ALLOCATION_WITHDRAW accepts the transaction, and that transaction’s id is what you pass as allocationTransactionId to Make a Canton call.

Amounts

amount is a decimal string, not a number. Token amounts exceed the precision of an IEEE 754 double, so a JSON number would round silently. Parse with a decimal library rather than parseFloat. Operations that move nothing, including onboarding, invites, and allow-list changes, carry "0".