Numis TrustNumis Trust Docs

Accounts

Create and manage custody accounts

Custody accounts hold assets in a secure vault. Each account is tied to a single asset type and workspace. After creation, an account moves through an approval workflow before a deposit address is assigned.


List Accounts

Returns a paginated list of custody accounts your API user is authorized to access. Use these accounts for transaction initiation, reporting, and reconciliation workflows.

GET/relay/v1/accounts
Required permission:View custody account

Query Parameters

Query Parameters
page
integer

Page number. Defaults to 1.

limit
integer

Results per page. Defaults to 20, maximum 100.

search
string

Search by account name, asset ID, or deposit address.

assetId
string

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

workspace
'custody' | 'transactional'

Filter by workspace.

role
'custody' | 'staking'

Filter by account role. Accepts multiple values.

status
'active' | 'inactive' | 'pending_approval'

Filter by account status.

Example

curl -X GET "https://api.numis-trust.com/relay/v1/accounts?page=1&limit=20&search=main&assetId=BTC" \
  -H "x-api-key: numis_abc123xyz789" \
  -H "x-api-secret: your-api-secret"
const params = new URLSearchParams({
  page: '1',
  limit: '20',
  search: 'main',
  assetId: 'BTC',
});
const response = await fetch(
  `https://api.numis-trust.com/relay/v1/accounts?${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": "550e8400-e29b-41d4-a716-446655440000",
      "name": "BTC Custody Account",
      "description": "Main Bitcoin holdings",
      "workspace": "custody",
      "role": "custody",
      "assetId": "BTC",
      "chainType": "BTC",
      "address": "bc1qrelayaccountaddress",
      "status": "active",
      "availableBalance": "0.5",
      "availableBalanceCad": "48750.25",
      "createdAt": "2025-01-15T10:30:00.000Z",
      "updatedAt": "2025-01-15T10:35:00.000Z"
    }
  ],
  "total": 1,
  "page": 1,
  "limit": 20,
  "totalPages": 1
}

Response Codes
200Accounts retrieved successfully.
400Invalid request parameters.
401Missing or invalid credentials.
403

Credential lacks the View custody account permission.

429Rate limit exceeded.

Get Account

Returns details for a single custody account.

GET/relay/v1/accounts/{id}
Required permission:View custody account

Path Parameters

Path Parameters
idrequired
uuid

The custody account ID to retrieve.

Example

curl -X GET "https://api.numis-trust.com/relay/v1/accounts/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/accounts/${id}`,
  {
    headers: {
      'x-api-key': process.env.NUMIS_API_KEY,
      'x-api-secret': process.env.NUMIS_API_SECRET,
    },
  },
);
const account = await response.json();

Response

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "BTC Custody Account",
  "description": "Main Bitcoin holdings",
  "workspace": "custody",
  "role": "custody",
  "assetId": "BTC",
  "chainType": "BTC",
  "address": "bc1qrelayaccountaddress",
  "status": "active",
  "availableBalance": "0.5",
  "availableBalanceCad": "48750.25",
  "createdAt": "2025-01-15T10:30:00.000Z",
  "updatedAt": "2025-01-15T10:35:00.000Z"
}

Response Codes
200Account retrieved successfully.
400Invalid id path parameter.
401Missing or invalid credentials.
403

Credential lacks the View custody account permission.

404

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

429Rate limit exceeded.

Create Account

Creates a new custody account. The account starts in pending_approval status — a deposit address is assigned only after the account clears the approval workflow.

POST/relay/v1/accounts
Required permission:Initiate new custody account

Approval workflow

Newly created accounts require approval before they become active. Poll the Get Account endpoint using the returned id.

Request Body

Body Parameters
namerequired
string

Display name for the account. Must be between 3 and 50 characters.

workspacerequired
'custody' | 'transactional'

Vault operating mode. See Workspace Types below.

assetIdrequired
string

Asset symbol to hold in this account — for example BTC, ETH, or USDC. Unsupported symbols are rejected with 400.

description
string

Optional free-text label. Maximum 255 characters.

role
'custody' | 'staking'

Optional account role. Defaults to custody. Use staking to create a staking-designated account.

Example

curl -X POST "https://api.numis-trust.com/relay/v1/accounts" \
  -H "x-api-key: numis_abc123xyz789" \
  -H "x-api-secret: your-api-secret" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "BTC Custody Account",
    "workspace": "custody",
    "assetId": "BTC",
    "description": "Main Bitcoin holdings",
    "role": "custody"
  }'
const response = await fetch('https://api.numis-trust.com/relay/v1/accounts', {
  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({
    name: 'BTC Custody Account',
    workspace: 'custody',
    assetId: 'BTC',
    description: 'Main Bitcoin holdings',
    role: 'custody',
  }),
});

const account = await response.json();
console.log(account.id); // use when polling for approval status

Response

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "BTC Custody Account",
  "workspace": "custody",
  "assetId": "BTC",
  "role": "custody",
  "address": null,
  "description": "Main Bitcoin holdings",
  "status": "pending_approval",
  "createdAt": "2024-01-15T10:30:00Z"
}

Response Codes
201

Account created. Use the returned id to poll for status updates.

400

Invalid request — missing required field, unsupported assetId, or invalid workspace value.

401Missing or invalid credentials.
403

Credential lacks the Initiate new custody account permission.

409

Conflict — an account with identical parameters already exists.

429Rate limit exceeded.

Workspace Types

The workspace field controls the security and throughput characteristics of the underlying vault.

WorkspaceTemperatureBest For
custodyColdLong-term storage, compliance holdings, reserves
transactionalHotSettlement accounts, payment processing, trading desks

custody (cold storage) — Enhanced security protocols, lower operational speed, higher compliance controls. Use for assets you intend to store long-term with minimal transaction frequency.

transactional (hot account) — Optimized for throughput and low latency. Use for accounts that require frequent or real-time transactions.


Role Types

The role field classifies the functional purpose of an account within its workspace. It is returned by read endpoints and can be used as a filter on the List Accounts endpoint.

RoleDefaultPurpose
custodyYesStandard asset holding account
stakingNoDedicated account for staking assets and earning rewards

custody (default) — A standard account for holding assets. Used for all general-purpose accounts.

staking — A dedicated account role for participating in staking protocols. Requires a staking provider to be connected before staking operations can begin. Use the role filter on the List Accounts endpoint to retrieve only staking accounts.

Approve Account

Approve a new custody account by account ID.

POST/relay/v1/accounts/approve
Required permission:Approve new custody account

Request Body

Body Parameters
accountIdrequired
uuid

Unique account identifier to approve.

Example

curl -X POST "https://api.numis-trust.com/relay/v1/accounts/approve" \
  -H "x-api-key: numis_abc123xyz789" \
  -H "x-api-secret: your-api-secret" \
  -H "Content-Type: application/json" \
  -d '{
    "accountId": "550e8400-e29b-41d4-a716-446655440000"
  }'
const response = await fetch('https://api.numis-trust.com/relay/v1/accounts/approve', {
  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({
    accountId: '550e8400-e29b-41d4-a716-446655440000',
  }),
});

const { accountId, status } = await response.json();
console.log(status); // "approved"

Response

{
  "accountId": "550e8400-e29b-41d4-a716-446655440000",
  "status": "approved"
}

Response Codes
200Account approved successfully.
400

Account cannot be approved, including when it has already been processed.

401

Missing or invalid API credentials.

403

Forbidden. If the credential is missing the required API scope, the response message is Missing required API scope: Approve new custody account.

404Account was not found.
409

Account approval conflicts with the current state.

500

Internal error during account approval.


Reject Account

Reject a custody account by account ID.

POST/relay/v1/accounts/reject
Required permission:Approve new custody account

Request Body

Body Parameters
accountIdrequired
uuid

Unique account identifier to reject.

Example

curl -X POST "https://api.numis-trust.com/relay/v1/accounts/reject" \
  -H "x-api-key: numis_abc123xyz789" \
  -H "x-api-secret: your-api-secret" \
  -H "Content-Type: application/json" \
  -d '{
    "accountId": "550e8400-e29b-41d4-a716-446655440000"
  }'
const response = await fetch('https://api.numis-trust.com/relay/v1/accounts/reject', {
  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({
    accountId: '550e8400-e29b-41d4-a716-446655440000',
  }),
});

const { accountId, status } = await response.json();
console.log(status); // "rejected"

Response

{
  "accountId": "550e8400-e29b-41d4-a716-446655440000",
  "status": "rejected"
}

Response Codes
200Account rejected successfully.
400

Account cannot be rejected, including when it has already been processed.

401

Missing or invalid API credentials.

403

Forbidden. If the credential is missing the required API scope, the response message is Missing required API scope: Approve new custody account.

404Account was not found.
409

Account rejection conflicts with the current state.

500

Internal error during account rejection.

On this page