Transactions
Query, retrieve custody transaction history, initiate transactions from a custody account to internal or external destinations
A transaction moves assets from a custody account you own to an approved destination. The destination can be another custody account within your client (internal) or a whitelisted external address (external). Transactions enter the existing approval workflow — the status field reflects where the transaction is in that process.
List Transactions
Returns a paginated list of custody transactions for your organization.
View custody transactionQuery Parameters
pagePage number. Defaults to 1.
limitResults per page. Defaults to 20, maximum 100.
accountIdFilter by custody account ID. If no matching custody account is found within
your organization, the response is 200 with an empty items array.
assetTypeFilter by asset type such as BTC, ETH, or USDC.
statusFilter by transaction status. Defaults to all. Values are
case-insensitive, so failed and Failed are treated the same.
Example
curl -X GET "https://api.numis-trust.com/relay/v1/transactions?page=1&limit=20" \
-H "x-api-key: numis_abc123xyz789" \
-H "x-api-secret: your-api-secret"const params = new URLSearchParams({ page: '1', limit: '20' });
const response = await fetch(
`https://api.numis-trust.com/relay/v1/transactions?${params}`,
{
headers: {
'x-api-key': process.env.NUMIS_API_KEY,
'x-api-secret': process.env.NUMIS_API_SECRET,
},
},
);
const { items, total, totalPages } = await response.json();Response
{
"items": [
{
"id": "tx_abc123xyz789",
"sourceAccountId": "550e8400-e29b-41d4-a716-446655440000",
"destinationId": "660e8400-e29b-41d4-a716-446655440001",
"destinationType": "internal_wallet",
"amount": "1.25",
"assetType": "BTC",
"networkFee": "0.0002",
"status": "COMPLETED",
"direction": "OUT",
"createdAt": "2025-01-15T10:30:00.000Z",
"updatedAt": "2025-01-15T10:35:00.000Z"
}
],
"total": 42,
"page": 1,
"limit": 20,
"totalPages": 3
}Transactions retrieved successfully.
Credential lacks the View custody transaction permission.
Unexpected server error while retrieving transactions.
Get Transaction
Returns details for a single custody transaction.
View custody transaction detailPath Parameters
idrequiredUnique transaction identifier.
Example
curl -X GET "https://api.numis-trust.com/relay/v1/transactions/550e8400-e29b-41d4-a716-446655440000" \
-H "x-api-key: numis_abc123xyz789" \
-H "x-api-secret: your-api-secret"const id = '550e8400-e29b-41d4-a716-446655440000';
const response = await fetch(
`https://api.numis-trust.com/relay/v1/transactions/${id}`,
{
headers: {
'x-api-key': process.env.NUMIS_API_KEY,
'x-api-secret': process.env.NUMIS_API_SECRET,
},
},
);
const transaction = await response.json();Response
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"fbTransactionId": null,
"sourceAccountId": "660e8400-e29b-41d4-a716-446655440001",
"destinationId": "770e8400-e29b-41d4-a716-446655440002",
"destinationType": "external_wallet",
"amount": "0.5",
"assetType": "BTC",
"status": "COMPLETED",
"subStatus": null,
"approvals": {
"createdBy": "Relay Approver",
"createdAt": "2025-04-10T10:00:00.000Z",
"signedBy": "Relay Approver",
"signedAt": "2025-04-10T10:01:00.000Z",
"approvedBy": "Relay Approver",
"approvedAt": "2025-04-10T10:02:00.000Z",
"fbApprovedAt": "2025-04-10T10:03:00.000Z",
"rejectedBy": null,
"rejectedAt": null
},
"direction": "OUT",
"transactionType": "WITHDRAWAL",
"networkFee": "0.0001",
"createdAt": "2025-04-10T10:00:00.000Z",
"updatedAt": "2025-04-10T10:05:00.000Z"
}Transaction retrieved successfully.
id path parameter.Credential lacks the View custody transaction detail permission.
No transaction found for the given id within your client scope.
Unexpected server error while retrieving the transaction.
Calculate Transaction Fee
Returns an estimated network fee for a transaction before it is submitted. This endpoint validates the same source account, destination, asset, and amount constraints used for transaction initiation, but it does not create a transaction or enter the approval workflow.
Initiate account transactionsEstimate only
Fee estimates are calculated from the current custody provider response when available. The estimate can change before a transaction is actually submitted.
Request Body
sourceAccountIdrequiredThe account ID of the custody account to send from. Must belong to your
client, be active, and support assetType.
destinationIdrequiredIdentifier of the destination. For external, this is the ID of an approved
whitelisted address. For internal, this is the account ID of another
custody account owned by your client.
destinationTyperequiredWhether the destination is another custody account within your client
(internal) or a whitelisted external address (external).
amountrequiredAmount to estimate as a decimal string (e.g. "0.5"). Must be greater than
zero and must not exceed the maximum decimal precision supported by the
asset.
assetTyperequiredAsset symbol to transfer, for example BTC, ETH, or USDC. Must match
the asset held by the source account.
Example
curl -X POST "https://api.numis-trust.com/relay/v1/transactions/calculate-fee" \
-H "x-api-key: numis_abc123xyz789" \
-H "x-api-secret: your-api-secret" \
-H "Content-Type: application/json" \
-d '{
"sourceAccountId": "550e8400-e29b-41d4-a716-446655440000",
"destinationId": "7f3c1a2b-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
"destinationType": "external",
"amount": "0.5",
"assetType": "BTC"
}'const response = await fetch(
'https://api.numis-trust.com/relay/v1/transactions/calculate-fee',
{
method: 'POST',
headers: {
'x-api-key': process.env.NUMIS_API_KEY,
'x-api-secret': process.env.NUMIS_API_SECRET,
'Content-Type': 'application/json',
},
body: JSON.stringify({
sourceAccountId: '550e8400-e29b-41d4-a716-446655440000',
destinationId: '7f3c1a2b-4d5e-6f7a-8b9c-0d1e2f3a4b5c',
destinationType: 'external',
amount: '0.5',
assetType: 'BTC',
}),
},
);
const fee = await response.json();
console.log(fee.estimatedFee);Response
{
"assetType": "BTC",
"amount": "0.5",
"estimatedFee": 0.00031,
"feeAssetType": "BTC"
}Fee estimate calculated successfully.
Invalid request — missing or malformed field, assetType mismatch with
source account, amount is zero or negative, amount exceeds asset precision,
or the custody provider does not support fee estimation for the asset or
network.
Credential lacks the Initiate account transactions permission, is not client-scoped, or cannot access the source account.
The destination was not found, is not eligible, or does not belong to your client.
Unexpected server or custody provider error while calculating the fee estimate.
Initiate Transaction
Initiates a transaction from a source custody account to a destination. The transaction then moves through the approval workflow configured for the source account quorum.
Initiate account transactionsApproval workflow
Initiated transactions enter the existing quorum-based approval workflow. For
example, a transaction that requires an additional approval may start in
awaiting_signature.
Request Body
sourceAccountIdrequiredThe account ID of the custody account to send from. Must belong to your client and be active.
destinationIdrequiredIdentifier of the destination. For external, this is the ID of an approved
whitelisted address. For internal, this is the account ID of another
custody account owned by your client.
destinationTyperequiredWhether the destination is another custody account within your client
(internal) or a whitelisted external address (external).
amountrequiredAmount to send as a decimal string (e.g. "0.5"). Must be greater than zero
and must not exceed the maximum decimal precision supported by the asset.
assetTyperequiredAsset symbol to transfer — for example BTC, ETH, or USDC. Must match
the asset held by the source account.
Example
curl -X POST "https://api.numis-trust.com/relay/v1/transactions/initiate" \
-H "x-api-key: numis_abc123xyz789" \
-H "x-api-secret: your-api-secret" \
-H "Content-Type: application/json" \
-d '{
"sourceAccountId": "550e8400-e29b-41d4-a716-446655440000",
"destinationId": "7f3c1a2b-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
"destinationType": "external",
"amount": "0.5",
"assetType": "BTC"
}'const response = await fetch(
'https://api.numis-trust.com/relay/v1/transactions/initiate',
{
method: 'POST',
headers: {
'x-api-key': process.env.NUMIS_API_KEY,
'x-api-secret': process.env.NUMIS_API_SECRET,
'Content-Type': 'application/json',
},
body: JSON.stringify({
sourceAccountId: '550e8400-e29b-41d4-a716-446655440000',
destinationId: '7f3c1a2b-4d5e-6f7a-8b9c-0d1e2f3a4b5c',
destinationType: 'external',
amount: '0.5',
assetType: 'BTC',
}),
},
);
const tx = await response.json();
console.log(tx.id); // transaction ID
console.log(tx.status); // e.g. "awaiting_signature"Response
{
"id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"status": "awaiting_signature",
"sourceAccountId": "550e8400-e29b-41d4-a716-446655440000",
"destinationId": "7f3c1a2b-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
"destinationType": "external",
"amount": "0.5",
"assetType": "BTC",
"createdAt": "2024-01-15T10:30:00Z"
}Transaction submitted successfully and entered the approval workflow.
Invalid request — missing or malformed field, assetType mismatch with
source account, amount is zero or negative, amount exceeds asset precision,
or invalid destinationType.
Forbidden. If the credential is missing the required API scope, the response
message is Missing required API scope: Initiate account transactions.
The destination was not found, is not whitelisted (external), or does not belong to your client (internal).
Get Transaction Status
Returns the latest known status, sub-status, and update timestamp for a single custody transaction.
View custody transaction statusPath Parameters
idrequiredUnique transaction identifier.
Example
curl -X GET "https://api.numis-trust.com/relay/v1/transactions/550e8400-e29b-41d4-a716-446655440000/status" \
-H "x-api-key: numis_abc123xyz789" \
-H "x-api-secret: your-api-secret"const id = '550e8400-e29b-41d4-a716-446655440000';
const response = await fetch(
`https://api.numis-trust.com/relay/v1/transactions/${id}/status`,
{
headers: {
'x-api-key': process.env.NUMIS_API_KEY,
'x-api-secret': process.env.NUMIS_API_SECRET,
},
},
);
const status = await response.json();Response
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "COMPLETED",
"subStatus": "CONFIRMED",
"updatedAt": "2025-06-01T10:05:00.000Z"
}Transaction status retrieved successfully.
id path parameter.Credential lacks the View custody transaction status permission.
No transaction found for the given id within your client scope.
Unexpected server error while retrieving the transaction status.
Destination Types
The destinationType field determines how destinationId is resolved and what validation is applied before the transaction is submitted.
| Type | Destination | Validation |
|---|---|---|
external | Whitelisted address ID | Must be approved (APP status), active, and owned by your client |
internal | Custody account ID | Must be an active custody account owned by your client |
external — Sends to an address that has been added to your whitelist and has completed the approval process. Pending or rejected addresses are rejected with 404.
internal — Sends to another custody account within your client. Both source and destination must be active.
Amount Precision
The amount field must be a plain decimal string. Scientific notation (e.g. 1e-5) and values with more decimal places than the asset supports are rejected with 400.
| Asset | Max decimal places |
|---|---|
BTC | 8 |
ETH | 18 |
USDC | 6 |
For assets not listed above, the platform enforces the precision defined for that asset. Sending an amount like "0.000000001" for BTC (9 decimal places) returns a 400 error.