Numis TrustNumis Trust Docs

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.

GET/relay/v1/transactions
Required permission:View custody transaction

Query Parameters

Query Parameters
page
integer

Page number. Defaults to 1.

limit
integer

Results per page. Defaults to 20, maximum 100.

accountId
uuid

Filter by custody account ID. If no matching custody account is found within your organization, the response is 200 with an empty items array.

assetType
string

Filter by asset type such as BTC, ETH, or USDC.

status
'all' | 'completed' | 'pending' | 'failed'

Filter 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
}

Response Codes
200

Transactions retrieved successfully.

400Invalid request parameters.
401Missing or invalid credentials.
403

Credential lacks the View custody transaction permission.

429Rate limit exceeded.
500

Unexpected server error while retrieving transactions.


Get Transaction

Returns details for a single custody transaction.

GET/relay/v1/transactions/{id}
Required permission:View custody transaction detail

Path Parameters

Path Parameters
idrequired
uuid

Unique 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"
}

Response Codes
200

Transaction retrieved successfully.

400Invalid id path parameter.
401Missing or invalid credentials.
403

Credential lacks the View custody transaction detail permission.

404

No transaction found for the given id within your client scope.

429Rate limit exceeded.
500

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.

POST/relay/v1/transactions/calculate-fee
Required permission:Initiate account transactions

Estimate 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

Body Parameters
sourceAccountIdrequired
uuid

The account ID of the custody account to send from. Must belong to your client, be active, and support assetType.

destinationIdrequired
uuid

Identifier 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.

destinationTyperequired
'internal' | 'external'

Whether the destination is another custody account within your client (internal) or a whitelisted external address (external).

amountrequired
string

Amount 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.

assetTyperequired
string

Asset 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"
}

Response Codes
200

Fee estimate calculated successfully.

400

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.

401Missing or invalid credentials.
403

Credential lacks the Initiate account transactions permission, is not client-scoped, or cannot access the source account.

404

The destination was not found, is not eligible, or does not belong to your client.

429Rate limit exceeded.
500

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.

POST/relay/v1/transactions/initiate
Required permission:Initiate account transactions

Approval 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

Body Parameters
sourceAccountIdrequired
uuid

The account ID of the custody account to send from. Must belong to your client and be active.

destinationIdrequired
uuid

Identifier 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.

destinationTyperequired
'internal' | 'external'

Whether the destination is another custody account within your client (internal) or a whitelisted external address (external).

amountrequired
string

Amount 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.

assetTyperequired
string

Asset 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"
}

Response Codes
201

Transaction submitted successfully and entered the approval workflow.

400

Invalid request — missing or malformed field, assetType mismatch with source account, amount is zero or negative, amount exceeds asset precision, or invalid destinationType.

401Missing or invalid credentials.
403

Forbidden. If the credential is missing the required API scope, the response message is Missing required API scope: Initiate account transactions.

404

The destination was not found, is not whitelisted (external), or does not belong to your client (internal).

429Rate limit exceeded.

Get Transaction Status

Returns the latest known status, sub-status, and update timestamp for a single custody transaction.

GET/relay/v1/transactions/{id}/status
Required permission:View custody transaction status

Path Parameters

Path Parameters
idrequired
uuid

Unique 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"
}

Response Codes
200

Transaction status retrieved successfully.

400Invalid id path parameter.
401Missing or invalid credentials.
403

Credential lacks the View custody transaction status permission.

404

No transaction found for the given id within your client scope.

429Rate limit exceeded.
500

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.

TypeDestinationValidation
externalWhitelisted address IDMust be approved (APP status), active, and owned by your client
internalCustody account IDMust 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.

AssetMax decimal places
BTC8
ETH18
USDC6

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.

On this page