KEY_LINK_TX_SIGN_REQUEST message to your Fireblocks Agent, the request carries transaction details produced by Fireblocks’ Policy Service, mainly in the metadata field. Fireblocks Agent forwards this message to your customer server (the /messagesToSign endpoint you implement) exactly as received, so your server can inspect these details — for example, to confirm the amount and destination match what you expect — before authorizing your HSM or key management system to sign.
This structure is internal and can change without notice
metadata is not a stable, versioned part of the customer server API — the OpenAPI spec for /messagesToSign types it as a bare object with no defined shape, and userAccessToken (below) isn’t in the spec at all. The fields on this page were captured from a real request and cross-checked against Fireblocks’ source; they aren’t a committed contract. The same field name can even carry different values at different nesting levels of the same request (called out below where observed) — this is genuinely internal, organically-grown data, not a designed schema.If your integration reads these fields, parse them defensively:- Ignore fields you don’t recognize instead of failing.
- Don’t assume a field that’s present today will always be present, or that its type/casing stays the same.
- Don’t hard-fail your signing flow solely because a field is missing, unless you’ve deliberately decided to require it.
Where this appears
AKEY_LINK_TX_SIGN_REQUEST you receive at /messagesToSign is a MessageEnvelope, where message.payload is a stringified JSON object. Parsing it gives you a MessagePayload:
timestamp (and version, not shown above) are already part of the official OpenAPI spec for MessagePayload — they’re not internal/undocumented, just omitted from earlier examples on this page. userAccessToken, by contrast, isn’t in the OpenAPI spec at all, and Fireblocks Agent itself never reads it — it’s a JWT representing the initiating user’s session, relayed to your server untouched.
metadata
A flat object mixing a transaction summary with lower-level signing details:
string
A JSON-encoded string. Parse it to get the TxMetaData object described below.
array
Signatures over the
txMetaData string. Each entry:array
The raw payload(s) to be signed, prior to their appearance in
messagesToSign.number
The number of signature operations Fireblocks expects back for this request.
string
The Fireblocks asset ID, e.g.
SOL_TEST. A flattened copy of the same value inside txMetaData — kept in sync with it.string
(Optional) The transaction’s operation type, e.g.
TRANSFER. A flattened copy of txMetaData.transactionType.string
The primary destination address. A flattened copy of
txMetaData.dstAddress.string
(Optional) Destination tag/memo, for chains that support one. A flattened copy of
txMetaData.dstTag.number
The transaction amount.
string
The transaction amount as a string, for precision.
string
The amount in the asset’s smallest unit (e.g. lamports for SOL), as a string.
number
The USD value of the transfer.
number
The network fee, in the asset’s smallest unit.
string
The network fee as a decimal string, in base asset units.
string
Hex-encoded HD wallet chaincode used to derive the signing key for this operation.
string
The source ID. This is a string, but legacy transaction flows can send it as a JSON number instead — parse it as a string either way.
string
The source type, e.g.
VAULT.string
The destination ID.
string
The destination type, e.g.
ONE_TIME. Note this uses a shorter form than txMetaData.dstType below (which was ONE_TIME_ADDRESS for the same destination) — they aren’t guaranteed to match.Signature verification
Fireblocks Agent verifies thepolicy_service entry in txMetaDataSignatures against Fireblocks’ Policy Service certificate before it ever calls your /messagesToSign endpoint — if that signature doesn’t validate, Fireblocks Agent discards the message and never forwards it to your server. By the time your server receives a request, this check has already passed. Fireblocks Agent’s current verification logic only checks the policy_service entry; it doesn’t verify USER_AUTHORIZER entries when present.
Fireblocks Agent obtains the Policy Service certificate through its own paired-device credentials, which aren’t exposed to your customer server. If you need to re-verify the signature independently (for example, running a modified Fireblocks Agent or a defense-in-depth check), the algorithm is RSA with SHA-256 over the raw txMetaData string, and the signature is hex-encoded.
TxMetaData
The object you get from parsing txMetaData. This is Policy Service’s own transaction/destination representation — the same underlying data model used in the API Co-signer callback handler’s transaction payload, though field values aren’t guaranteed to line up between the two (see the callouts below).
Identifiers
string
The transaction’s ID.
string
The workspace (tenant) ID.
string
The transaction’s operation type, e.g.
TRANSFER.string
The Fireblocks asset ID.
Initiator
string
The ID of the user or API user who created the transaction.
string
Observed identical to
userId.string
(Optional) Display name of the initiating user.
Source
string
The source type, e.g.
VAULT.string
(Optional) The specific source subtype. Observed as an empty string when not applicable.
string
The source ID. Always a string here, unlike
metadata.srcId (above), which can also appear as a JSON number in legacy flows.string
(Optional) Display name of the source, e.g. the vault account’s name. Can carry human-identifiable information — handle it accordingly.
string
(Optional) Set for end-user-wallet sources. Observed as an empty string otherwise.
Destination
boolean
Whether this transaction uses the multi-destination
destinations array. Note the all-caps wire key — unusual among the otherwise camelCase fields here.string
The primary destination’s type, e.g.
ONE_TIME_ADDRESS. This value doesn’t necessarily match the dstType enum documented for the API Co-signer callback handler (ONE_TIME_ADDRESS here vs. ONE_TIME there, for what’s otherwise the same kind of destination).string
(Optional) The specific destination subtype. Observed as an empty string when not applicable.
string
ONE_TIME or WHITELISTED.string
(Optional) The destination’s ID. Empty for one-time addresses.
string
(Optional) Display name of the destination, e.g. an exchange account or vault account name. Can carry human-identifiable information — handle it accordingly.
string
The primary destination’s address.
string
The display form of
dstAddress.string
(Optional) Destination tag/memo, for chains that support one. Not present for this Solana example.
string
(Optional) The display form of
dstTag.Amounts and fees
number
The transfer amount.
string
The transfer amount as a string, for precision.
number
The USD value of the transfer.
string
(Optional) The USD exchange rate used to compute
amountUSD. Not present in every real payload seen — don’t treat it as required.string
The fee level used, e.g.
MEDIUM.string
The asset the fee is paid in.
string
(Optional) The USD exchange rate used for the fee asset. Not present in every real payload seen — don’t treat it as required.
boolean
(Optional) Whether the fee is deducted from the requested amount. Not present in every real payload seen — don’t treat it as required.
boolean
(Optional) Whether cash-out is enabled for this transfer.
Blockchain details
string
The blockchain/network asset ID, e.g.
SOL_TEST.string
The network protocol, e.g.
SOL.boolean
Whether this is a testnet transaction.
string
(Optional) Chain-specific. Observed for Solana as the blockhash used to build the transaction.
string
(Optional) Chain-specific. Observed for Solana as the nonce account address.
Policy verdict
string
The policy verdict for the primary destination, e.g.
ALLOW.object
Details about the policy rule that produced the verdict. Same shape as
actionInfo in the API Co-signer callback handler payload — ruleType, byGlobalPolicy, byRule, capturedRuleV2, capturedRuleNumV2, rulesSnapshotId, etc.object
(Optional) Present when two-tier authorization applies. Same shape as
authorizationGroups in the API Co-signer callback handler payload — the exact shape varies by policy version. Observed as {"groups": []} when not applicable.string
The overall policy verdict for the transaction, e.g.
ALLOW. Observed identical to action for a single-destination transfer.string
The Fireblocks API/console user ID designated to sign, per the matched policy rule.
array
The full list of designated signer IDs. Observed as a single-element array matching
signerId for a SINGLE designation.Other fields
boolean
(Optional) Related to
HAS_DESTINATIONS; whether the multi-destination format is in use.object
(Optional) Internal instrumentation. Observed containing only
sendToCoreStartTime (a Unix timestamp in milliseconds).object
(Optional) Enrichment data. Shares its wire key with
enrichmentJson in the API Co-signer callback handler payload, but the fields actually present vary by context — this is a loosely-typed bag, not a fixed schema. Observed here containing only templateMessageName (a string), which isn’t part of the schema documented on that page.object
(Optional) Additional context about how the transfer was initiated. Same wire key as
txAdditionalDetails in the API Co-signer callback handler payload, but again a loosely-typed bag — the fields observed here (availableBalance, isAutoCalculatedGasLimit, useBroadcastingService, useBroadcastOrchestrator, psv2MultiInstanceFlow) don’t match the fields documented on that page.object
(Optional) Observed as an empty object (
{}) in every sample seen so far.object
(Optional) Internal request-tracing context.
object
(Optional) Internal policy-engine debugging data.
destinations
Present when HAS_DESTINATIONS is true. Each entry:
string
Same value as the top-level
dstType for a single-destination transfer.string
(Optional) Observed as an empty string when not applicable.
string
ONE_TIME or WHITELISTED.string
This destination’s address.
string
(Optional) This destination’s ID. Empty for one-time addresses.
string
The display form of
dstAddress.number
The amount sent to this destination.
string
Same amount, as a string.
number
The USD value of the amount sent to this destination.
string
The policy verdict for this specific destination.
object
Same shape as the top-level
actionInfo above, scoped to this destination.object
(Optional) Same wire key as the top-level field above, scoped to this destination. Observed as an empty object (
{}) here.object
(Optional) Same wire key as the top-level field above, scoped to this destination.
Example
A sanitized version of a real capturedmetadata field (JWT, signatures, and the raw signing payload truncated/redacted; everything else structurally faithful):