DTCC Digital Assets

Digital Assets API Reference Guide

An integration guide for DTCC Digital Assets APIs organized around four core implementation journeys: account management, wallet management, conversion order processing, and corporate action handling. Each section presents the workflow sequence, key endpoints, request and response patterns, business rules, and operational considerations required to implement and operate integrations with the platform.

Getting Started
One integration guide across the DTCC Digital Assets journey

This reference organizes DTCC Digital Assets APIs by implementation journey rather than by internal service boundary. The guide covers four core journeys: account management, wallet management, conversion order processing, and corporate action handling. Each tab presents a compact workflow summary, a searchable endpoint reference, representative payloads, business rules, status handling, and retry guidance.

Base URLs:
EnvironmentIdentity (Authentication)Services
PSE (Pre-Production)https://api.pse.lds.dtcc-da.com/identityhttps://api.pse.lds.dtcc-da.com/services
Productionhttps://api.ledgerscan.dtcc-da.com/identity/https://api.ledgerscan.dtcc-da.com/services/
Authentication pattern: These workflows use the Service Account Credentials grant. The token request is sent to /connect/token with grant_type=urn:dtcc:params:oauth:grant-type:service-account-credentials, type=conveyance, entity context, tenant context via acr_values=tenant:{tenantId}, and service-account credentials. Downstream API calls use Authorization: Bearer {access_token}.
Account ManagementAccount detail, hierarchy summary, access control metadata, locked operation handling, and on-chain account activities through the DTCC APIs.
Wallet ManagementWallet inventory, ledger/account reference data, and status tracking for wallet administration workflows.
Conversion OrdersRegistered securities, issue and ledger reference data, active security selection, idle wallet selection, order submission, and order lifecycle tracking.
Corporate ActionsEvent discovery, event type taxonomy, securities filtering, event detail, core dates by category, DTC mandatory classification, and status handling.
Guide Structure

Workflow-first organization

Each tab starts with a compact flow showing call ordering, parallel-load opportunities, branch behavior, and service dependencies before endpoint-level detail.

Integration Pattern

Service-account authentication

Workflows begin with a service account token request using the conveyance model and tenant/entity context. The resulting access token is passed as a bearer token to each API.

Operational Readiness

Rules, status, and error handling

Each journey includes business rules, retry guidance, permission considerations, idempotency, async state tracking, and graceful degradation for reference-data failures.

Primary API Journeys

JourneyPrimary APIsPurpose
Account Management/connect/token, /v1/accounts/{accountId}, /v1/accounts/{accountId}/summary, /v1/accounts/{accountId}/activities, /v1/conversion/accounts/{accountId}/balancesRetrieve account detail, hierarchy, access control information, on-chain activity, and security-level balances.
Wallet Management/connect/token, /v1/conversion/wallets, /v1/conversion/clientsLoad wallet inventory and supporting account reference data for administration and status tracking.
Conversion Orders/connect/token, /v1/conversion/securities, /v1/conversion/securities/issue-types, /v1/conversion/securities/issue-subtypes, /v1/conversion/securities, /v1/conversion/wallets, /v1/conversion/orders, /v1/conversion/async-operations/query, /v1/conversion/orders/{orderId}Discover eligible securities, retrieve order inputs, submit conversion orders, resolve the order identifier from the async operation, and retrieve order detail.
Corporate Actions/connect/token, /v2/corporate-actions, /v2/corporate-actions/event-types, /v1/conversion/securities, /v2/corporate-actions/{id}Discover, filter, and inspect corporate action events and lifecycle context.
How to use this guide: Start with the relevant tab for the implementation journey, review the compact flow, then use the searchable endpoint cards for request parameters, sample calls, response models, retry guidance, and service dependencies.
Certification

Workflow Certification Framework

CERT
Tokenization Service Workflow Certification Guide
Production Readiness Validation Framework
›

This framework defines the Workflow Certification Program for Tokenization Service integrations. The intent of these certifications is not to validate individual API endpoints. Endpoint behavior, request formats, and response structures are already covered by API specifications and implementation guides. Instead, this framework validates that a customer or integration partner can correctly execute the complete business workflows required for production operation.

Certification Focus

Focus Area

Workflow Execution

Complete the ordered sequence of steps that compose each production workflow.

Focus Area

Business-Rule Compliance

Apply the platform business rules that govern eligibility, direction, and validation.

Focus Area

Error Handling

Handle invalid credentials, expired credentials, access denials, and service failures.

Focus Area

Operational Readiness

Demonstrate production supportability across the certified workflows.

Focus Area

Production Supportability

Sustain and monitor operations after go-live without introducing risk.

Focus Area

Evidence Collection

Produce request logs, response payloads, and execution output as audit evidence.

Certification Philosophy

Each workflow document follows the same seven-step structure. The objective is to verify that customers can correctly implement the platform's intended workflow patterns rather than simply execute API calls successfully.

Authenticate

Establish a valid session.

Retrieve Required Data

Load inputs for the workflow.

Apply Business Rules

Enforce platform constraints.

Execute Workflow Actions

Perform the operation.

Validate Outcomes

Confirm expected results.

Handle Failures

Manage error conditions.

Produce Evidence

Capture supporting audit artifacts.

AuthenticationData RetrievalBusiness RulesAction ExecutionOutcome ValidationFailure HandlingEvidence

Certification Portfolio

The following workflow certifications are currently included within the Tokenization Service certification framework.

Account ManagementSupports account discovery, hierarchy inspection, sub-account visibility, wallet visibility, activity retrieval, balance retrieval, and operational monitoring.
Wallet ManagementSupports wallet discovery, wallet inventory review, status monitoring, ledger lookup, and client reference lookup.
Conversion OrdersSupports security discovery, reference-data retrieval, wallet discovery, eligibility determination, conversion-order creation, and lifecycle monitoring.
Corporate ActionsSupports corporate-action discovery, event filtering, event inspection, event classification, lifecycle-date interpretation, and corporate-action monitoring.

Common Certification Requirements

All workflow certifications require demonstration of the following.

RequirementDetail
AuthenticationValid service account authentication.
Error HandlingInvalid credentials, expired credentials, access denied, invalid requests, not found conditions, and service failures.
Workflow CompletionAll required steps executed successfully.
AuditabilityRequest logs, response payloads, execution output, workflow results, and negative-test results.

Common Error Types

HTTPConditionExpected integration behavior
400Malformed request, invalid parameter, or invalid credentialsCorrect the request. Do not retry as-is.
401JWT access credential missing, expired, or invalidRequest a new JWT access credential, then retry once.
403Service account lacks the required permission, or the account is lockedSurface access denied. Do not retry.
404Resource not foundSurface not found. Do not retry.
500, 503Service failureRetry with exponential backoff, maximum three attempts.

Conversion order submission adds two codes: 409 for a duplicate X-Idempotency-Key, and 422 for a business rule violation such as invalid conversion direction, quantity of zero, or submission outside operational hours.

Certification Framework Summary

Account Management→Wallet Management→Conversion Orders→Corporate Actions

These workflow certifications serve as the formal production-readiness gate for Tokenization Service integrations.

Pre-Implementation
Participant Setup & Onboarding

Participant onboarding establishes the DTCC entity, account hierarchy, wallet structure, administrative access, and service-account readiness required before a participant can begin using Tokenization Services.

Workflow Summary

Collect Onboarding Inputs

Capture participant name, DTC account information, technical contact, entity administrator, and go-live inputs.

Initiate Onboarding

The Integration team uses the Operations Portal to initiate participant onboarding, validate onboarding inputs, and launch the provisioning workflow.

Provision Participant

Create the participant entity, DTCC standard account structure, provision wallets, assign controller permissions, create the participant administrator, send onboarding notifications, and activate the participant.

Readiness rule: to access APIs participants must provision and configure service accounts
Onboarding Setup: Service accounts and Wallet Registration can only be set up by the participant through the UI. API-based service account and wallet registration setup is not available.
Category 1
Account Management

Account Management provides service-account based workflows for retrieving account detail, viewing sub-accounts and linked wallets, interpreting access control metadata, and querying on-chain account activities. Accounts give participants the ability to organize their wallets, and each account is made up of a group of subaccounts or wallets. Two accounts are configured by default: Internal, for wallets a participant uses for its own proprietary purposes, and Clients, for wallets registered on behalf of a participant's clients. Balance, on-chain activity, and the list of wallets mapped to an account are available to view for each account. Account Entity and Activity data are served by the DTCC APIs.

Authentication pattern: These workflows use the Service Account Credentials grant. The token request is sent to /connect/token with grant_type=urn:dtcc:params:oauth:grant-type:service-account-credentials, type=conveyance, entity context, tenant context via acr_values=tenant:{tenantId}, and service-account credentials. Downstream API calls use Authorization: Bearer {access_token}.

Workflow Summary

A condensed view of the API call sequence, dependencies, and branch rules.

Authenticate

POST /connect/token
Obtain a service-account bearer token.

Fetch account

GET /v1/accounts/{accountId}
Retrieve account and optional access control metadata.

Fetch hierarchy

GET /v1/accounts/{accountId}/summary
Retrieve child accounts and linked wallets.

Query activities

GET /v1/accounts/{accountId}/activities
Retrieve filtered on-chain activity from the DTCC APIs.

Degrade gracefully

Show partial account data if downstream hierarchy or activity services are unavailable.

Locked operation rule: When locked operations such as Updating or ChangeLinking are present, link/unlink and mutation actions should be treated as unavailable regardless of permission metadata.
Service AccountDTCC APIsAccess ControlDTCC APIs
GET
Get Account Detail
/v1/accounts/{accountId}
›

Retrieves account data and optional page-level access control permissions. This call confirms that the account exists and that the caller has access.

Request Parameters

ParameterLocationTypeRequiredDescription
accountIdpathstringYesThe account identifier
includeObacquerybooleanOptionalWhen true, includes access-control information

Sample Request

typescript
const accountResponse = await fetch(
  `${baseUrl}/v1/accounts/${accountId}?includeObac=true`,
  { headers: { 'Authorization': `Bearer ${access_token}` } }
);
if (!accountResponse.ok) throw new Error(`Account fetch failed: ${accountResponse.status}`);
const account = await accountResponse.json();

Response Template

json
{
  "accountId": "account-id",
  "name": "Example Account",
  "externalId": null,
  "itemId": null,
  "accessControl": { "isController": true, "isShared": false, "hasShareRequest": false }
}

TypeScript Interface

typescript
interface AccountWithAccessControlResponse {
  accountId: string;
  name: string;
  externalId: string | null;
  itemId: string | null;
  accessControl: AccessControlInfo | null;
}
interface AccessControlInfo {
  isController: boolean;
  isShared: boolean;
  hasShareRequest: boolean;
}

Error Handling

Handle 401 by requesting a new JWT access credential and retrying once; handle 403 as account lockout or access denied; handle 404 as account not found; validate bad requests client-side before submission.

Common Error Types

HTTPConditionExpected integration behavior
400Malformed request or invalid query parameterCorrect the request. Do not retry as-is.
401JWT access credential missing, expired, or invalidRequest a new JWT access credential, then retry once.
403Service account lacks the required permission, or the account is lockedSurface access denied. Do not retry.
404Resource not foundSurface not found. Do not retry.
500, 503Service failureRetry with exponential backoff, maximum three attempts.

Retry Guidance

Read-only GET; safe to retry on 5xx or network timeout. Do not retry credential requests on 4xx.

Permissions & Scopes

Auth PatternService Account Credentials grant
Credential DeliveryAuthorization: Bearer {access_token}

GET
Get Account Hierarchy Summary
/v1/accounts/{accountId}/summary
›

Returns child accounts and linked wallets below a parent account for display and access-control interpretation.

Request Parameters

ParameterLocationTypeRequiredDescription
accountIdpathstringYesThe parent account identifier
includeObacquerybooleanOptionalWhen true, the response includes access control metadata per item
countqueryintegerOptionalPagination page size
offsetqueryintegerOptionalPagination offset
sortOrderquerystringOptionalSort order: Ascending or Descending
orderByquerystringOptionalAccount order field: Name
typequerystringOptionalFilter: Account or Wallet
searchForquerystringOptionalSearch for filter

Enumerations

Enumeration values must be provided exactly as they are defined; they are case-sensitive.

GET /v1/accounts/{accountId}/summary

DirectionParameter / FieldEnum NameValues
Input (query)sortOrderSortOrderAscending, Descending
Input (query)orderByAccountHierarchyFieldsName
Input (query)typeAccountHierarchyEntityTypeWallet, Account
Output (response)entityTypeAccountHierarchyEntityTypeWallet, Account
Output (response)trackingStatusTrackingStatusNone, Enabled, Disabled, Enabling, Disabling
Output (response)linkageStatusLinkageStatusLinking, Unlinking, Linked

Sample Request

typescript
const summaryResponse = await fetch(
  `${baseUrl}/v1/accounts/${accountId}/summary?includeObac=true`,
  { headers: { 'Authorization': `Bearer ${access_token}` } }
);
const summaryItems = await summaryResponse.json();
const accountIds = summaryItems.filter(i => i.type === 'Account').map(i => i.id);
const walletIds = summaryItems.filter(i => i.type === 'Wallet').map(i => i.id);

Response Template

json
[
  { "id": "account-1", "name": "Sub Account", "type": "Account", "lockedOperations": ["Updating"] },
  { "id": "wallet-1", "name": "Wallet A", "type": "Wallet", "walletDetails": { "address": "0x..." } }
]

TypeScript Interface

typescript
interface AccountSummary {
  id: string;
  name: string;
  type: 'Account' | 'Wallet';
  externalId?: string;
  lockedOperations?: string[];
  walletDetails?: { address: string };
  accessControl?: { isShared: boolean };
}

Error Handling

If the summary fetch fails, account data may still be shown while hierarchy detail is unavailable; present a partial state and a retry option.

Common Error Types

HTTPConditionExpected integration behavior
400Malformed request or invalid query parameterCorrect the request. Do not retry as-is.
401JWT access credential missing, expired, or invalidRequest a new JWT access credential, then retry once.
403Service account lacks the required permission, or the account is lockedSurface access denied. Do not retry.
404Resource not foundSurface not found. Do not retry.
500, 503Service failureRetry with exponential backoff, maximum three attempts.

Retry Guidance

Read-only GET; safe to retry on 5xx or network timeout.

Permissions & Scopes

Auth PatternService Account Credentials grant
Credential DeliveryAuthorization: Bearer {access_token}

GET
Get Account Activities
/v1/accounts/{accountId}/activities
›

Retrieves paginated on-chain activities with date range, activity type, network, source wallet, destination wallet, pagination, and sorting filters.

Request Parameters

ParameterLocationTypeRequiredDescription
accountIdpathstringYesParent or sub-account identifier
startDatequeryISO 8601 stringOptionalFilter activities from this date; defaults to the current week if omitted
endDatequeryISO 8601 stringOptionalFilter activities until this date; clamp future values to now
activityTypequerystringOptionalFilter by activity type
networkquerystringOptionalLedger network filter
fromWalletIdquerystringOptionalSource wallet filter
toWalletIdquerystringOptionalDestination wallet filter
limit / offsetqueryintegerOptionalPagination controls
sortBy / sortOrderquerystringOptionalSorting controls

Enumerations

Enumeration values must be provided exactly as they are defined; they are case-sensitive.

GET /v1/accounts/{accountId}/activities

DirectionParameter / FieldEnum NameValues
Input (query)sortOrderSortOrderAscending, Descending
Input (query)activityTypeActivityTypePayment, PaymentReceived, Fee, Mint, Burn, Pause, Unpause, Freeze, Unfreeze, Revoked, Clawedback, Clawback

Sample Request

typescript
const params = new URLSearchParams();
params.set('startDate', startDate.toISOString());
params.set('endDate', endDate.toISOString());
if (activityType) params.set('activityType', activityType);
if (network) params.set('network', network);
if (fromWalletId) params.set('fromWalletId', fromWalletId);
if (toWalletId) params.set('toWalletId', toWalletId);
const activitiesResponse = await fetch(
  `${baseUrl}/v1/accounts/${accountId}/activities?${params.toString()}`,
  { headers: { 'Authorization': `Bearer ${access_token}` } }
);
const activities = await activitiesResponse.json();

Response Template

json
{
  "items": [{
    "ledger": "Ethereum",
    "wallet": { "id": "wallet-1", "name": "Source Wallet", "walletId": "0x..." },
    "primaryCounterWallet": { "id": "wallet-2", "name": "Destination Wallet", "walletId": "0x..." },
    "createdAt": "2026-01-01T00:00:00Z",
    "totalValue": 500,
    "pricedInItem": "TOKEN",
    "status": "Completed",
    "operations": [{ "amount": 500, "token": { "symbol": "TOK" } }]
  }],
  "metadata": { "asOfDate": "2026-01-01T00:00:00Z" }
}

TypeScript Interface

typescript
interface AccountActivitiesWithMetaDataApiModel {
  items: AccountActivitiesApiModel[];
  metadata: { asOfDate: string };
}

Activity Types

These are the definitions for the activityType input filter and output values.

ValueDescription
PaymentA token or native asset transfer sent from a tracked wallet to another address.
PaymentReceivedA token or native asset transfer received by a tracked wallet from another address.
FeeA gas/transaction fee deducted from a tracked wallet, with the fee amount debited from the sender and credited to the miner/burn address.
MintA token issuance where new tokens are created and credited to a wallet, with no originating holder.
BurnA token destruction where tokens are permanently removed from circulation, with no receiving holder.
PauseA token contract administrative event indicating the token was paused (transfers disabled) by a contract administrator.
UnpauseA token contract administrative event indicating the token was unpaused (transfers re-enabled) by a contract administrator.
FreezeAn administrative event indicating a specific wallet address was frozen on a token contract, preventing it from transacting.
UnfreezeAn administrative event indicating a specific wallet address was unfrozen on a token contract, restoring its ability to transact.
RevokedApplied to the source wallet in a clawback operation — tokens were forcibly removed from this wallet by a contract administrator.
ClawedbackApplied to the destination wallet in a clawback operation — tokens were forcibly transferred into this wallet as the recipient of a clawback.
ClawbackApplied to the token perspective in a clawback operation — represents the overall forced transfer event at the token contract level, combining both the revocation and receipt.

Response Metadata

The response includes metadata with asOfDate, indicating the point-in-time represented by the activity data.

Error Handling

Handle invalid filters as 400; expired credentials as 401; access restrictions as 403; service failures as error states with retry. Activity retrieval fails independently of account retrieval, so account detail remains displayable when activity retrieval fails.

Common Error Types

HTTPConditionExpected integration behavior
400Malformed request or invalid query parameterCorrect the request. Do not retry as-is.
401JWT access credential missing, expired, or invalidRequest a new JWT access credential, then retry once.
403Service account lacks the required permission, or the account is lockedSurface access denied. Do not retry.
404Resource not foundSurface not found. Do not retry.
500, 503Service failureRetry with exponential backoff, maximum three attempts. Continue to display account detail without activities.

Retry Guidance

Read-only GET; safe to retry on 5xx or network timeout. If the activity service is unavailable, show account details without activities rather than failing the whole view.

Permissions & Scopes

Auth PatternService Account Credentials grant
Credential DeliveryAuthorization: Bearer {access_token}

GET
Get Account Balances
/v1/conversion/accounts/{accountId}/balances
›

Retrieves balance records for an account.

Request Parameters

ParameterLocationTypeRequiredDescription
accountIdpathstringYesIdentifier of the account whose balances are being queried; the same identifier used by /v1/accounts/{accountId}, and it must be accessible under the calling service account's permissions.

Enumerations

Enumeration values must be provided exactly as they are defined; they are case-sensitive.

GET /v1/conversion/accounts/{accountId}/balances

DirectionParameter / FieldEnum NameValues
Output (response)statusFinancialSecurityStatusOnboarding, Active, Pause, Failed
Output (response)typeWalletTypesInternal, Client

Sample Request

typescript
const balancesResponse = await fetch(
  `${baseUrl}/v1/conversion/accounts/${accountId}/balances`,
  { headers: { 'Authorization': `Bearer ${access_token}` } }
);
if (!balancesResponse.ok) throw new Error(`Balance retrieval failed: ${balancesResponse.status}`);
const balances = await balancesResponse.json();

Response Template

json
{
  "items": [
    {
      "cusip": "037833100",
      "security": "Apple Inc. Common Stock",
      "issueSubType": {
        "id": "1",
        "code": "CS",
        "description": "Common Stock"
      },
      "totalQuantity": 131,
      "walletsCount": 2,
      "ledgersCount": 2,
      "holders": [
        {
          "quantity": 101,
          "wallet": {
            "id": "06572a05-8033-4088-8b0a-01faa6ed74df",
            "name": "First Bank EVM Wallet",
            "walletAddress": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e"
          },
          "ledger": {
            "name": "Ethereum",
            "network": "Ethereum_Mainnet"
          }
        },
        {
          "quantity": 30,
          "wallet": {
            "id": "1b6e961b-6c6a-4726-8f4c-f2330a5782fa",
            "name": "American Bank Besu Wallet",
            "walletAddress": "0x4bDb16A35fc5fdc4A8701Bc5B688D254E99027c0"
          },
          "ledger": {
            "name": "Besu private",
            "network": "Besu"
          }
        }
      ]
    }
  ],
  "metadata": {
    "asOfDate": "2026-05-18T00:00:00Z"
  }
}

TypeScript Interface

typescript
interface AccountBalancesResponse {
  items: AccountSecurityBalancesResponse[];
  metadata: AccountBalancesMetadataResponse;
}
interface AccountSecurityBalancesResponse {
  cusip: string;
  security: string;
  issueSubType: { id: string; code: string; description: string };
  totalQuantity: number;
  walletsCount: number;
  ledgersCount: number;
  holders: SecurityBalanceHolder[];
}
interface SecurityBalanceHolder {
  quantity: number;
  wallet: { id: string; name: string; walletAddress: string };
  ledger: { name: string; network: string };
}
interface AccountBalancesMetadataResponse {
  asOfDate: string;
}

Response Metadata

The response includes metadata with asOfDate, indicating the point-in-time represented by the balance data.

Error Handling

Handle 401 by requesting a new JWT access credential and retrying once; handle 403 as either an insufficient permission scope or an account the service account is not authorized for; handle 404 as an unknown or inaccessible account identifier and correct the value rather than retrying.

Common Error Types

HTTPConditionExpected integration behavior
400Malformed request or invalid query parameterCorrect the request. Do not retry as-is.
401JWT access credential missing, expired, or invalidRequest a new JWT access credential, then retry once.
403Service account lacks the required permission, or the account is lockedSurface access denied. Do not retry.
404Resource not foundSurface not found. Do not retry.
500, 503Service failureRetry with exponential backoff, maximum three attempts.

Retry Guidance

Read-only GET; safe to retry on 5xx or network timeout using exponential backoff with a bounded retry limit. Because this call is expected to run frequently as part of pre-conversion checks and scheduled reconciliation, refresh the JWT access credential proactively ahead of its expiry rather than re-authenticating reactively after a 401.

Permissions & Scopes

Auth PatternService Account Credentials grant
Credential DeliveryAuthorization: Bearer {access_token}

This endpoint uses the Service Account Credentials grant, consistent with the rest of this guide. Request the credential from /connect/token with grant_type=urn:dtcc:params:oauth:grant-type:service-account-credentials, type=conveyance, entity context, tenant context via acr_values=tenant:{tenantId}, and service-account credentials before calling this endpoint.

Under Construction: Service Account management APIs (create, update, delete service accounts) are under development and will be documented in a future version of this guide. Wallet registration is not available through APIs; wallet registration is performed through the UI.
Certification

Account Management Workflow Certification Test

CERT
Account Management Workflow Certification Test
Certification · v1 · Authenticate → Retrieve Account → Retrieve Hierarchy → Query Activity → Query Balances
›

Demonstrate that a customer integration can authenticate using a service account, retrieve an account, retrieve account hierarchy information, retrieve account activities, retrieve and reconcile account balances, and correctly handle expected errors and service failures. The purpose of this test is to certify that the integration correctly implements the Account Management workflow before production access is granted.

Certification Workflow

Five sequential stages. Stages two through five depend on the JWT access credential issued in stage one using the Service Account Credentials grant.

Authenticate

Obtain a JWT access credential using SA-AccountBot.

Retrieve Account

Confirm the account identifier matches the request.

Retrieve Hierarchy

Retrieve child accounts and linked wallets.

Query Activity

Retrieve paginated activities with asOfDate.

Query Balances

Retrieve, reconcile, and interpret security-level balances.

Independent service failure: Account retrieval and activity retrieval fail independently. If activity retrieval fails, account data remains available and the integration must fail gracefully with a clear error message.
Single grant for all steps: All five steps use the Service Account Credentials grant. The JWT access credential issued in step one is reused for every subsequent call, including the balances retrieval in step five.
AuthenticationAccount RetrievalHierarchyActivityBalances

Prerequisites

Provisioned service account, service account password, tenant ID, and a valid account ID. Service accounts and permissions are provisioned by DTCC. The service account must be granted the permission required to access the balances endpoint used in step five.

Test Data

typescript
const tenantId = "<tenant-id>";
const accountId = "<account-id>";
const baseUrl = "<base-url>";
const username = "SA-AccountBot";
const password = process.env.SERVICE_ACCOUNT_PASSWORD!;

POST
Step 1 — Authentication
${baseUrl}/connect/token
›

Goal

This step validates that the integration can obtain a JWT access credential from the Identity Server using service account credentials. The JWT access credential proves the caller's identity and must be supplied as a bearer credential on every subsequent API call in this workflow.

Procedure

typescript
async function authenticate() {
  const response = await fetch(`${baseUrl}/connect/token`, {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body: new URLSearchParams({
      grant_type: "urn:dtcc:params:oauth:grant-type:service-account-credentials",
      type: "conveyance",
      entity: ENTITY_ID_OF_WHICH_SA_IS_MEMBER_OF,
      acr_values: `tenant:${tenantId}`,
      username,
      password
    })
  });
  if (!response.ok) {
    throw new Error(`Authentication failed: ${response.status}`);
  }
  const data = await response.json();
  return data.access_token;
}

Expected Result

HTTP 200; JWT access credential returned; credential accepted by downstream APIs.

Common Error Types

HTTPConditionExpected integration behavior
400Invalid credentials; invalid_clientSurface authentication rejected. Do not retry with the same credentials.
500, 503Identity Server failureRetry with exponential backoff, maximum three attempts.

GET
Step 2 — Retrieve Account
${baseUrl}/v1/accounts/${accountId}
›

Goal

Verify the integration can retrieve account information.

Procedure

typescript
async function getAccount(accessToken: string, accountId: string) {
  const response = await fetch(
    `${baseUrl}/v1/accounts/${accountId}?includeObac=true`,
    { headers: { Authorization: `Bearer ${accessToken}` } }
  );
  if (!response.ok) {
    throw new Error(`Account retrieval failed: ${response.status}`);
  }
  return response.json();
}

Validation

typescript
{
  accountId: string,
  name: string
}

Expected Result

HTTP 200; account returned; account identifier matches request; response successfully parsed. The workflow requires account resolution before subsequent operations.

Common Error Types

HTTPConditionExpected integration behavior
401Expired or invalid JWT access credentialRe-authenticate, then retry once.
403Insufficient permissionsSurface access denied. Do not retry.
404Account not foundSurface account not found. Do not retry.

GET
Step 3 — Retrieve Hierarchy
${baseUrl}/v1/accounts/${accountId}/summary
›

Goal

Verify the integration can retrieve child accounts and linked wallets.

Procedure

typescript
async function getHierarchy(accessToken: string, accountId: string) {
  const response = await fetch(
    `${baseUrl}/v1/accounts/${accountId}/summary?includeObac=true`,
    { headers: { Authorization: `Bearer ${accessToken}` } }
  );
  if (!response.ok) {
    throw new Error(`Summary retrieval failed: ${response.status}`);
  }
  return response.json();
}

Validation

typescript
[
  {
    id: string,
    name: string,
    type: "Account" | "Wallet"
  }
]

The summary endpoint returns a combined hierarchy view of child accounts and linked wallets.

Expected Result

HTTP 200; hierarchy returned; child entities visible; wallets visible; no parsing errors.

Common Error Types

HTTPConditionExpected integration behavior
401Expired or invalid JWT access credentialRe-authenticate, then retry once.
403Insufficient permissionsSurface access denied. Do not retry.
500, 503Service failureDisplay account detail without hierarchy and offer retry.

GET
Step 4 — Query Activities
${baseUrl}/v1/accounts/${accountId}/activities
›

Goal

Verify the integration can retrieve activities.

Procedure

typescript
async function getActivities(accessToken: string, accountId: string) {
  const response = await fetch(
    `${baseUrl}/v1/accounts/${accountId}/activities`,
    { headers: { Authorization: `Bearer ${accessToken}` } }
  );
  if (!response.ok) {
    throw new Error(`Activity retrieval failed: ${response.status}`);
  }
  return response.json();
}

Validation

typescript
{
  items: [],
  metadata: {
    asOfDate: string
  }
}

The activities workflow retrieves paginated activity data and includes metadata such as asOfDate.

Expected Result

HTTP 200; activities returned; metadata returned; data successfully parsed.

Common Error Types

HTTPConditionExpected integration behavior
400Invalid filter or query parameterCorrect the filter values. Do not retry as-is.
401Expired or invalid JWT access credentialRe-authenticate, then retry once.
500, 503Activity service failureAccount data remains available; fail activity retrieval gracefully with a clear error message.

GET
Step 5 — Query Balances
${baseUrl}/v1/conversion/accounts/${accountId}/balances
›

Goal

Verify the integration can retrieve security-level account balances, interpret the balance payload, reconcile aggregate totals against holder allocations, and process the response metadata.

Procedure

This endpoint uses the same Service Account Credentials grant as the rest of the workflow, so it reuses the JWT access credential issued in Step 1 rather than obtaining a separate credential.

typescript
async function getBalances(accessToken: string, accountId: string) {
  const response = await fetch(
    `${baseUrl}/v1/conversion/accounts/${accountId}/balances`,
    { headers: { Authorization: `Bearer ${accessToken}` } }
  );
  if (!response.ok) throw new Error(`Balance request failed: ${response.status}`);
  return response.json();
}

const balances = await getBalances(accessToken, accountId);

Validation

Confirm the balance response returns an items collection and a metadata object.

typescript
{
  cusip: string,
  security: string,
  issueSubType: { id: string, code: string, description: string },
  totalQuantity: number,
  walletsCount: number,
  ledgersCount: number,
  holders: []
}

Every balance record must carry a CUSIP, security name, issue sub-type, total quantity, wallet count, ledger count, and holder records. Total quantity, wallet count, and ledger count must each be zero or greater, and holder records must be present wherever balances exist.

typescript
for (const item of balances.items) {
  const holderTotal = item.holders.reduce(
    (sum, holder) => sum + holder.quantity,
    0
  );
  if (holderTotal !== item.totalQuantity) {
    throw new Error("Balance reconciliation failed");
  }
}

Aggregate balances must reconcile with holder-level allocations, so the sum of holder quantities equals totalQuantity. Using the sample response, holders of 101 and 30 reconcile to a total of 131.

Expected Result

HTTP 200; balance data retrieved; payload interpreted; aggregate totals reconcile with holder allocations; balance snapshot date available.

Common Error Types

This endpoint returns distinct error envelope shapes depending on which layer rejects the request.

HTTPConditionResponse bodyExpected integration behavior
400Malformed authentication requesterrorCode, message, requestId, tracingUrlCorrect the request encoding and verify all required fields are present. Do not retry as-is.
401Invalid service account credentialserrorCode, message, requestId, tracingUrlAuthentication rejected. Verify credentials before retrying.
401Expired or missing access token; GATEWAY__UNAUTHENTICATEDErrorCode, ErrorMessageRe-authenticate, then retry once.
403Service account lacks the required permission for this accounterrorCode, message, requestId, tracingUrlConfirm the service account was granted the balances permission. Do not retry.
403Token does not grant access to this account; GATEWAY__ACCESSDENIEDErrorCode, ErrorMessageSurface access denied. Do not retry.
403User locked out; AUTHORIZATION_ENGINE__USER_LOCKED_OUT_EXCEPTIONErrorCode, ErrorMessageSurface the lockout. Do not retry until the lockout is cleared.
404Account identifier does not exist or is not accessibleerrorCode, message, requestId, tracingUrlValidate the account identifier before calling. Do not retry without correcting it.
500, 503Service failureerrorCode, errorMessageRetry with exponential backoff and a bounded retry count. Surface the failure once retries are exhausted and terminate the workflow safely.

Token Lifecycle and Resilience

Access tokens are time-limited. Cache the credential, refresh it proactively ahead of expiry rather than reacting to a 401, and never reuse an expired token.


E2E
Step 6 — End-to-End Workflow Execution
authenticate → getAccount → getHierarchy → getActivities → getBalances
›

Goal

Execute the complete workflow in a single transaction.

Procedure

typescript
async function runWorkflow() {
  const token = await authenticate();
  const account = await getAccount(token, accountId);
  const hierarchy = await getHierarchy(token, accountId);
  const activities = await getActivities(token, accountId);
  const balances = await getBalances(token, accountId);
  return { account, hierarchy, activities, balances };
}

Expected Result

log
Authenticate          PASS
Retrieve Account      PASS
Retrieve Hierarchy    PASS
Query Activity        PASS
Query Balances        PASS
Workflow Complete     PASS

Each constituent call returns its expected success code.

Negative Test Cases

IDScenarioHTTPExpected result
NT-1Invalid Credentials400Authentication rejected with invalid_client. Invalid service account credentials are an expected authentication failure scenario.
NT-2Expired Credential401Re-authentication required.
NT-3Invalid Account404Account Not Found.
NT-4Access Denied403Access Denied for insufficient permissions.
NT-5Activity Service Failure500, 503Account data remains available, activity retrieval fails gracefully, and the user receives a clear error message.
NT-6Invalid Service Account Credentials (Step 5)401Authentication rejected. Verify credentials before retrying.
NT-7Insufficient Permission (Step 5)403Access denied. Confirm the service account was granted the balances permission.
NT-8Expired Balance Token (Step 5)401Re-authentication required; GATEWAY__UNAUTHENTICATED.
NT-9Unauthorized Account Access (Step 5)403Access denied; GATEWAY__ACCESSDENIED.
NT-10Locked Out User (Step 5)403Lockout detected; AUTHORIZATION_ENGINE__USER_LOCKED_OUT_EXCEPTION.
NT-11Malformed Authentication Request (Step 5)400Bad request. Correct the request encoding and confirm all required fields are present.
NT-12Balance Service Failure (Step 5)500, 503Retry logic executed, failure reported, and the workflow terminated safely.

Production Certification Criteria

A customer is certified only on successful authentication, account retrieval, hierarchy retrieval, activity retrieval, and balance retrieval with payload validation, reconciliation, and metadata processing, plus token lifecycle management and a bounded retry strategy, plus proper error handling for invalid credentials, expired credentials, invalid account, insufficient permission, access denied, user lockout, malformed authentication requests, and service failures, plus evidence collection showing each stage completed successfully.

Category 2
Wallet Management

Wallet Management covers wallet inventory and ledger/account reference data used to support wallet administration and status tracking. This guide version focuses on wallet discovery and reference-data retrieval APIs.

Wallet registration: Wallet registration is performed through the UI and is not available through the API.
Authentication pattern: These workflows use the Service Account Credentials grant. The token request is sent to /connect/token with grant_type=urn:dtcc:params:oauth:grant-type:service-account-credentials, type=conveyance, entity context, tenant context via acr_values=tenant:{tenantId}, and service-account credentials. Downstream API calls use Authorization: Bearer {access_token}.

Workflow Summary

A condensed view of the API call sequence, dependencies, and branch rules.

Authenticate

POST /connect/token
Obtain service-account token.

Load wallets

GET /v1/conversion/wallets
Display current wallet inventory.

Load reference data

GET /v1/conversion/clients
Load account reference data.

Track status

Use wallet inventory views to monitor wallet state and status changes.

Service AccountWallet InventoryReference DataStatus Tracking
GET
List Registered Wallets
/v1/conversion/wallets
›

Loads existing wallets for inventory display and status review.

Request Parameters

ParameterLocationTypeRequiredDescription
CountqueryintegerOptionalPage size
OffsetqueryintegerOptionalPagination offset
searchquerystringOptionalSearch by wallet name
networksquerystring[]OptionalFilter by network name
typequerystringOptionalinternal or client
sortBy / sortOrderquerystringOptionalSorting controls

Enumerations

Enumeration values must be provided exactly as they are defined; they are case-sensitive.

GET /v1/conversion/wallets

DirectionParameter / FieldEnum NameValues
Input (query)orderByWalletFieldsName, Network, CreatedAt
Input (query)sortOrderSortOrderAscending, Descending
Output (response)typeWalletTypesInternal, Client
Output (response)stateProcessingStatesIdle, Registering, FailedCompliance, Failed

Sample Request

typescript
const walletsResponse = await fetch(`${baseUrl}/v1/conversion/wallets`, {
  headers: { 'Authorization': `Bearer ${access_token}` }
});
const wallets = await walletsResponse.json();

Response Template

json
[
  { "id": "wallet-1", "name": "Example Wallet", "type": "CLIENT", "network": "Ethereum", "walletAddress": "0x...", "state": "Idle" }
]

TypeScript Interface

typescript
interface WalletSummary {
  id: string;
  name: string;
  type: string;
  network: string;
  walletAddress: string;
  account: AccountDetails;
  state: string;
  participant?: Participant;
}

Error Handling

Handle 401 by requesting a new JWT access credential and retrying once; handle 5xx with retry and a visible error state. Wallet registration is not available through this API, so no create or update failure paths apply.

Common Error Types

HTTPConditionExpected integration behavior
400Malformed request or invalid query parameterCorrect the request. Do not retry as-is.
401JWT access credential missing, expired, or invalidRequest a new JWT access credential, then retry once.
403Service account lacks the required permission, or the account is lockedSurface access denied. Do not retry.
404Resource not foundSurface not found. Do not retry.
500, 503Service failureRetry with exponential backoff, maximum three attempts. Terminate the inventory view safely if the failure persists.

Retry Guidance

Read-only GET; safe to retry on 5xx or network timeout.

Permissions & Scopes

Auth PatternService Account Credentials grant
Credential DeliveryAuthorization: Bearer {access_token}

GET
Load Account Reference Data
/v1/conversion/clients
›

Fetches existing accounts from the DTCC APIs.

Enumerations

Enumeration values must be provided exactly as they are defined; they are case-sensitive.

GET /v1/conversion/clients

DirectionParameter / FieldEnum NameValues
Input (query)sortOrderSortOrderAscending, Descending

Sample Request

typescript
const accountsResponse = await fetch(`${baseUrl}/v1/conversion/clients`, {
  headers: { 'Authorization': `Bearer ${access_token}` }
});
const accounts = await accountsResponse.json();

Response Template

json · /v1/conversion/clients
[
  { "name": "Example Account", "externalId": "external-id", "id": "account-id" }
]

TypeScript Interface

typescript
interface AccountDetails { name: string; externalId: string; id?: string; entityId?: string; }

Error Handling

If client reference data fails, wallet context may be incomplete; present a retry path and keep the wallet inventory visible. The reference-data call fails independently of the wallet inventory call.

Common Error Types

HTTPConditionExpected integration behavior
400Malformed request or invalid query parameterCorrect the request. Do not retry as-is.
401JWT access credential missing, expired, or invalidRequest a new JWT access credential, then retry once.
403Service account lacks the required permission, or the account is lockedSurface access denied. Do not retry.
404Resource not foundSurface not found. Do not retry.
500, 503Service failureRetry with exponential backoff, maximum three attempts. Keep wallet inventory available and present a meaningful error rather than terminating the workflow.

Retry Guidance

Reference data GETs are read-only and safe to retry. The call must resolve before inventory review begins.

Permissions & Scopes

Auth PatternService Account Credentials grant
Credential DeliveryAuthorization: Bearer {access_token}
Cross-service dependency: the DTCC APIs provides wallet and account reference data used by wallet administration views.
Certification

Wallet Management Workflow Certification Test

CERT
Wallet Management Workflow Certification Test
Certification · v1 · Authenticate → Load Wallets → Load Clients → Review → Track Status
›

Demonstrate that a customer integration can authenticate with a service account, load wallet inventory, load account and client reference data, review wallet inventory, and track wallet status. This certification verifies that the customer can correctly consume wallet-related APIs and construct an operational view of wallet inventory and status. The workflow is read-only and intended to support wallet administration and operational monitoring.

Certification Workflow

Authenticate once, load wallet inventory, then retrieve client reference data before reviewing inventory and tracking status.

Authenticate

Obtain a JWT access credential using SA-WalletReader.

Load Wallet Inventory

GET /v1/conversion/wallets

Load Reference Data

/v1/conversion/clients

Review Inventory

Correlate wallets with client and account data.

Track Status

Extract and review wallet status values.

Sequence: Client retrieval runs after wallet inventory loads and must resolve before inventory review begins.
AuthenticationWallet InventoryReference DataStatus Tracking

Prerequisites

Tenant ID, service account, service account password, base URL, and known wallet data. Required access: /connect/token, /v1/conversion/wallets, /v1/conversion/clients.

Test Data

typescript
const tenantId = "<tenant-id>";
const baseUrl = "<base-url>";
const username = "SA-WalletReader";
const password = process.env.SERVICE_ACCOUNT_PASSWORD!;

Shared Helper Functions

typescript
async function authenticate() {
  const response = await fetch(`${baseUrl}/connect/token`, {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body: new URLSearchParams({
      grant_type: "urn:dtcc:params:oauth:grant-type:service-account-credentials",
      type: "conveyance",
      entity: ENTITY_ID_OF_WHICH_SA_IS_MEMBER_OF,
      acr_values: `tenant:${tenantId}`,
      username,
      password
    })
  });
  if (!response.ok) throw new Error(`Authentication failed: ${response.status}`);
  const data = await response.json();
  return data.access_token;
}

async function getWallets(accessToken: string) {
  const response = await fetch(`${baseUrl}/v1/conversion/wallets`, {
    headers: { Authorization: `Bearer ${accessToken}` }
  });
  if (!response.ok) throw new Error(`Wallet retrieval failed: ${response.status}`);
  return response.json();
}

async function getClients(accessToken: string) {
  const response = await fetch(`${baseUrl}/v1/conversion/clients`, {
    headers: { Authorization: `Bearer ${accessToken}` }
  });
  if (!response.ok) throw new Error(`Client retrieval failed: ${response.status}`);
  return response.json();
}

POST
Step 1 — Authentication
${baseUrl}/connect/token
›

Goal

This step validates that the integration can obtain a JWT access credential from the Identity Server using service account credentials. The JWT access credential proves the caller's identity and must be supplied as a bearer credential on every subsequent API call in this workflow.

Procedure

typescript
const accessToken = await authenticate();

Expected Result

HTTP 200; JWT access credential returned; credential accepted by downstream APIs. Evidence: authentication successful, credential received.

Common Error Types

HTTPConditionExpected integration behavior
400Invalid credentials; invalid clientSurface authentication rejected. Do not retry with the same credentials.
500, 503Identity Server failureRetry with exponential backoff, maximum three attempts.

GET
Step 2 — Load Wallet Inventory
${baseUrl}/v1/conversion/wallets
›

Goal

Verify wallet inventory can be retrieved.

Procedure

typescript
const wallets = await getWallets(accessToken);

Validation

Wallet data returned; response is non-empty; wallet identifiers present.

Expected Result

HTTP 200; wallet inventory successfully loaded. Evidence: wallet inventory response, wallet count.

Common Error Types

HTTPConditionExpected integration behavior
400Invalid query parameters such as an invalid sort field or malformed filterCorrect the request. Do not retry as-is.
401Expired or invalid JWT access credentialRe-authenticate, then retry once.
403Missing permissionSurface access denied. Do not retry.
500, 503Wallet endpoint failureInventory unavailable; surface the failure and terminate the workflow safely.

GET
Step 3 — Load Reference Data
${baseUrl}/v1/conversion/clients
›

Goal

Verify client reference data can be loaded.

Procedure

typescript
const clients = await getClients(accessToken);

Validation

Available client records returned.

Expected Result

HTTP 200; reference data available and usable. Evidence: client response.

Common Error Types

HTTPConditionExpected integration behavior
401Expired or invalid JWT access credentialRe-authenticate, then retry once.
403Missing permissionSurface access denied. Do not retry.
500, 503Reference data failureDetect the failure, present a meaningful error, and keep the workflow running with wallet inventory still available.

GET
Step 4 — Review Wallet Inventory
correlate wallets with client and account data
›

Goal

Verify wallet inventory can be correlated with reference data.

Procedure

typescript
const inventoryView = wallets.map(wallet => ({
  wallet,
  client: clients.find(c => c.id === wallet.clientId)
}));

Validation

Wallets visible; wallets associated with client and account data; inventory records complete.

Expected Result

Inventory review completed. Evidence: sample wallet records, reference-data mapping.

Common Error Types

This step performs no additional API calls. If reference data was unavailable in Step 3, the integration must present the inventory without client correlation rather than failing the review.


GET
Step 5 — Track Wallet Status
extract wallet status values
›

Goal

Verify wallet status data is visible and reviewable.

Procedure

typescript
const walletStatuses = wallets.map(wallet => ({
  walletId: wallet.id,
  status: wallet.status
}));

Validation

Status field available; status values populated; statuses can be reported.

Expected Result

Wallet state visible; wallet status review completed. Evidence: status report, sample wallet statuses.

Common Error Types

This step performs no additional API calls. If the status field is absent from the wallet inventory response, treat the step as failed rather than defaulting to an assumed status.


E2E
Step 6 — End-to-End Workflow Execution
executeWalletWorkflow()
›

Goal

Execute the complete wallet management workflow in a single run to confirm every stage succeeds in sequence.

Procedure

typescript
async function executeWalletWorkflow() {
  const token = await authenticate();
  const wallets = await getWallets(token);
  const clients = await getClients(token);
  return { wallets, clients };
}

Expected Result

log
Authenticate      PASS
Load Wallets      PASS
Load Clients      PASS
Review Inventory  PASS
Track Status      PASS
Workflow Complete PASS

Each constituent call returns its expected success code.

Negative Test Cases

IDScenarioHTTPExpected result
NT-1Invalid Credentials400Authentication rejected; invalid client.
NT-2Expired Credential401Re-authentication required.
NT-3Missing Permission403Access denied.
NT-4Invalid Query Parameters400Validation error, for example an invalid sort field or malformed filter.
NT-5Reference Data Failure500, 503Failure detected; meaningful error presented; workflow does not crash.
NT-6Wallet Endpoint Failure500, 503Inventory unavailable; failure surfaced; workflow terminated safely.

Production Certification Criteria

A customer is certified only on successful authentication, wallet inventory retrieval, client retrieval, inventory review, and wallet-status review, plus proper handling of all negative tests.

Category 3
Conversion Orders

Conversion Operations covers discovery of registered securities, filter reference data, active securities for order entry, eligible idle wallets, and conversion order submission. Conversions are the mechanism for clients to convert securities between electronic book entry and digital tokenized forms. When submitting a conversion order, the participant selects the source wallet and the destination wallet. The process for converting securities from electronic to digital and back to electronic is identical; the only difference is what is assigned as the source and destination of the securities. Submission is asynchronous and returns no response body, so the integration polls the async operation with its idempotency key to obtain the order identifier before retrieving the order. Submitted orders are processed straight through, moving from Processing to Completed.

Authentication pattern: These workflows use the Service Account Credentials grant. The token request is sent to /connect/token with grant_type=urn:dtcc:params:oauth:grant-type:service-account-credentials, type=conveyance, entity context, tenant context via acr_values=tenant:{tenantId}, and service-account credentials. Downstream API calls use Authorization: Bearer {access_token}.

Workflow Summary

A condensed view of the API call sequence, dependencies, and branch rules.

Authenticate

POST /connect/token
Obtain service-account token.

Load securities and filters

GET /v1/conversion/securities
GET /v1/conversion/securities/issue-types
GET /v1/conversion/securities/issue-subtypes in parallel.

Load order inputs

GET /v1/conversion/securities?status=Active
GET /v1/conversion/wallets in parallel.

Filter eligibility

Use Active securities and wallets that are Idle and conversion eligible.

Submit order

POST /v1/conversion/orders
Returns 202 Accepted with no body. Retain the idempotency key.

Poll async operation

POST /v1/conversion/async-operations/query
Poll with the idempotency key until resourceId is populated.

Retrieve order detail

GET /v1/conversion/orders/{orderId}
Use resourceId as the order identifier.

Track lifecycle

Orders are processed straight through from Processing to Completed. Failed is terminal.

Order rule: Submission requires an idempotency key, an Active security, wallets that are Idle and conversion eligible, valid conversion direction, quantity greater than zero, and server-side operational-hours compliance. Because submission returns no body, the idempotency key is the only handle on the order until the async operation exposes resourceId.
Service AccountParallel LoadingEligibilityIdempotencyAsync Polling
GET
List Registered Securities and Filter Data
/v1/conversion/securities · /v1/conversion/securities/issue-types · /v1/conversion/securities/issue-subtypes
›

Fetches a paginated securities list alongside issue type and issue sub-type reference data.

Request Parameters

ParameterLocationTypeRequiredDescription
Offset / CountqueryintegerOptionalControls which slice of the securities list is returned, where offset sets the starting position and limit sets the number of records per page.
searchquerystringOptionalFree-text term matched against issuer name, security name, or CUSIP to narrow the securities list.
networkquerystringOptionalRestricts results to securities tokenized on a single ledger network, specified by network name.
issueTypeIdquerystringOptionalRestricts results to a high-level security classification such as equity or debt, referenced by an identifier from the issue types endpoint.
issueSubTypeIdquerystringOptionalRestricts results to a finer classification nested beneath the high-level type, such as common stock, referenced by an identifier from the issue sub-types endpoint.
statusquerystringOptionalRestricts results to securities in a single lifecycle status. Accepts one FinancialSecurityStatus value: Onboarding, Active, Pause, or Failed.
sortBy / sortOrderquerystringOptionalDetermines which field the securities list is ordered on and whether that order runs ascending or descending.

Enumerations

Enumeration values must be provided exactly as they are defined; they are case-sensitive.

GET /v1/conversion/securities

DirectionParameter / FieldEnum NameValues
Input (query)orderByFinancialSecurityFieldsCUSIP, Description, Issuer
Input (query)sortOrderSortOrderAscending, Descending
Input (query)statusFinancialSecurityStatusOnboarding, Active, Pause, Failed
Output (response)statusFinancialSecurityStatusOnboarding, Active, Pause, Failed
Output (response)processingStateProcessingStatesIdle, Registering, FailedCompliance, Failed

GET /v1/conversion/securities/issue-types

DirectionParameter / FieldEnum NameValues
Input (query)sortOrderSortOrderAscending, Descending

GET /v1/conversion/securities/issue-subtypes

DirectionParameter / FieldEnum NameValues
Input (query)sortOrderSortOrderAscending, Descending

Sample Request

typescript
const [securitiesResponse, issueTypesResponse, issueSubTypesResponse] = await Promise.all([
  fetch(`${baseUrl}/v1/conversion/securities?offset=0&limit=25`, { headers: { 'Authorization': `Bearer ${access_token}` } }),
  fetch(`${baseUrl}/v1/conversion/securities/issue-types`, { headers: { 'Authorization': `Bearer ${access_token}` } }),
  fetch(`${baseUrl}/v1/conversion/securities/issue-subtypes`, { headers: { 'Authorization': `Bearer ${access_token}` } })
]);
const securities = await securitiesResponse.json();

Response Template

json
[
  {
    "id": "security-id",
    "cusip": "123456789",
    "issuerName": "Example Issuer",
    "security": "Example Security",
    "securitySymbol": "EX",
    "status": "Active",
    "tokens": [{ "ledgerId": "ledger-id", "name": "Token", "ledger": { "name": "Ethereum", "network": "Ethereum" } }],
    "restrictions": {
      "dOChill":        { "enabled": false, "updatedAt": null },
      "complianceLock": { "enabled": false, "updatedAt": null },
      "globalLock":     { "enabled": false, "updatedAt": null }
    }
  }
]

TypeScript Interface

typescript
interface EligibleSecurityApiModel {
  id: string;
  cusip: string;
  issuerName: string;
  security: string;
  securitySymbol: string;
  issueType: IssueType;
  issueSubType: IssueType;
  tokens: EligibleSecurityToken[];
  status: string;
  trackingTrancheId: string;
  restrictions: SecurityRestrictions;
}
interface IssueType { id: string; code: string; description: string; }
interface SecurityRestrictions {
  dOChill: RestrictionState;
  globalLock: RestrictionState;
  complianceLock: RestrictionState;
}
interface RestrictionState { enabled: boolean; updatedAt: string | null; }

Business Rules

The securities response includes embedded token and ledger network associations, reducing the need for per-security lookup calls. Issue type, issue sub-type, and network are independent filter dimensions.

Status and Restrictions Are Separate Signals

All eligible securities carry an Active status, but a security can be Active and still have a chill or lock in place. A chill or lock is a transfer restriction: while it is in effect, transfers of the security's tokens are blocked across the entire security (all of its tokens), not just a single account or wallet. When the restriction is lifted, transfers are allowed again. Confirming that status is Active is not enough to know a security is usable right now; you must also read the restrictions object on the same response.

The restrictions object is always present and always reports all three restriction types. Each type is an object with an enabled flag (true when the restriction is currently in effect) and an updatedAt timestamp (UTC) recording when it last changed, or null if it has never applied. Because every type is always present, always test the enabled flag rather than checking whether a field exists.

FieldRestrictionWhat it means
dOChillDelivery Order (DO) ChillA temporary restriction on transfers, typically while a settlement or verification is pending.
globalLockGlobal LockA block on all transfers of the token, typically during a corporate action or a regulatory investigation.
complianceLockCompliance LockA block on transfers imposed for regulatory or compliance reasons, for example a sanctions concern.
How to tell if a security is restricted: Read the security, then inspect its restrictions object and check each type for "enabled": true. If any of the three is enabled, the security's token transfers are currently restricted even when status is Active. Use the updatedAt value on the enabled restriction to see when that chill or lock was last applied. Restriction state can change at any time as upstream events are processed, so poll the endpoint and re-read restrictions when you need a current view.
json · restrictions block
"status": "Active",
"restrictions": {
  "dOChill":        { "enabled": false, "updatedAt": null },
  "complianceLock": { "enabled": false, "updatedAt": null },
  "globalLock":     { "enabled": true,  "updatedAt": "2026-09-25T14:03:00Z" }
}
typescript · checking for a restriction
function isRestricted(security) {
  const r = security.restrictions;
  return r.dOChill.enabled || r.globalLock.enabled || r.complianceLock.enabled;
}

// Active status alone is not sufficient; also confirm no restriction is enabled.
const usable = security.status === 'Active' && !isRestricted(security);

Error Handling

If securities fail to load, show an error state. If issue type, issue sub-type, or ledger reference data fails, disable the corresponding filter while still rendering the securities list.

Common Error Types

HTTPConditionExpected integration behavior
400Malformed request or invalid query parameterCorrect the request. Do not retry as-is.
401JWT access credential missing, expired, or invalidRequest a new JWT access credential, then retry once.
403Service account lacks the required permission, or the account is lockedSurface access denied. Do not retry.
404Resource not foundSurface not found. Do not retry.
500, 503Service failureRetry with exponential backoff, maximum three attempts. Disable only the affected filter rather than the whole view.

Retry Guidance

All four endpoints are read-only GETs and safe to retry on 5xx or network timeout.

Permissions & Scopes

Auth PatternService Account Credentials grant
Credential DeliveryAuthorization: Bearer {access_token}

GET
Load Active Securities and Registered Wallets
/v1/conversion/securities · /v1/conversion/wallets
›

Loads order-entry inputs in parallel and filters wallets to Idle state.

Request Parameters

ParameterLocationTypeRequiredDescription
statusquerystringYesActive
Offset / CountqueryintegerOptionalPagination controls
participantIdquerystringOptionalThe 8-digit DTC participant number that identifies the member firm whose wallets are being retrieved, for example 00002667. This is the same identifier used across all DTC and DTCC services to uniquely identify a participant.

Enumerations

Enumeration values must be provided exactly as they are defined; they are case-sensitive.

GET /v1/conversion/securities

DirectionParameter / FieldEnum NameValues
Input (query)orderByFinancialSecurityFieldsCUSIP, Description, Issuer
Input (query)sortOrderSortOrderAscending, Descending
Output (response)statusFinancialSecurityStatusOnboarding, Active, Pause, Failed
Output (response)processingStateProcessingStatesIdle, Registering, FailedCompliance, Failed

GET /v1/conversion/wallets

DirectionParameter / FieldEnum NameValues
Input (query)orderByWalletFieldsName, Network, CreatedAt
Input (query)sortOrderSortOrderAscending, Descending
Output (response)typeWalletTypesInternal, Client
Output (response)stateProcessingStatesIdle, Registering, FailedCompliance, Failed

Sample Request

typescript
const [securitiesResponse, walletsResponse] = await Promise.all([
  fetch(`${baseUrl}/v1/conversion/securities?status=Active`, { headers: { 'Authorization': `Bearer ${access_token}` } }),
  fetch(`${baseUrl}/v1/conversion/wallets`, { headers: { 'Authorization': `Bearer ${access_token}` } })
]);
const securities = await securitiesResponse.json();
const wallets = await walletsResponse.json();
const eligibleWallets = wallets.filter(w => w.state === 'Idle');

Response Template

json
{
  "securities": [
    { "id": "security-id", "cusip": "123456789", "issuerName": "Example Issuer", "security": "Example Security", "status": "Active" }
  ],
  "wallets": [
    { "id": "wallet-id", "name": "Example Wallet", "type": "INTERNAL", "network": "DTC_Classic", "walletAddress": "0x...", "state": "Idle" }
  ]
}

TypeScript Interface

typescript
interface Security {
  id: string;
  cusip: string;
  issuerName: string;
  security: string;
  securitySymbol?: string;
  issueType: IssueType;
  issueSubType: IssueType;
  status: string;
  trackingTrancheId: string;
}
interface WalletSummary {
  id: string;
  name: string;
  type: string;
  network: string;
  walletAddress: string;
  account: AccountDetails;
  state: string;
  participant?: Participant;
}

Eligibility Rules

Only Active securities are eligible for orders. A wallet is eligible as a source or destination candidate only when its processing state is Idle and conversionEligible is true. Both conditions must hold; an Idle wallet that is not conversion eligible must be excluded.

An Active status is necessary but not sufficient. A security can be Active and still carry a chill or lock, which blocks transfers of its tokens while the restriction is in effect. Before treating an Active security as usable, read its restrictions object and confirm that dOChill, globalLock, and complianceLock all report "enabled": false. See the List Registered Securities and Filter Data card for the full restriction model.

Error Handling

Handle 401 by requesting a new JWT access credential and retrying once; handle 5xx with retry and an error state. If no Active security or no Idle wallet is returned, block order submission rather than submitting an ineligible order.

Common Error Types

HTTPConditionExpected integration behavior
400Malformed request or invalid query parameterCorrect the request. Do not retry as-is.
401JWT access credential missing, expired, or invalidRequest a new JWT access credential, then retry once.
403Service account lacks the required permission, or the account is lockedSurface access denied. Do not retry.
404Resource not foundSurface not found. Do not retry.
500, 503Service failureRetry with exponential backoff, maximum three attempts. Block order submission until inputs load successfully.

Retry Guidance

Both calls are read-only GETs and safe to retry on 5xx or network timeout.

Permissions & Scopes

Auth PatternService Account Credentials grant
Credential DeliveryAuthorization: Bearer {access_token}

POST
Submit and Track Conversion Orders
/v1/conversion/orders · /v1/conversion/async-operations/query · /v1/conversion/orders/{orderId}
›

Prior to submitting a conversion order, we recommend to retrieve and check the wallet and securities from the appropriate endpoints.

Submission is asynchronous. POST /v1/conversion/orders returns 202 Accepted with no response body, so the order identifier is not available on the submission response. Retain the X-Idempotency-Key supplied at submission, poll POST /v1/conversion/async-operations/query with that key until resourceId is populated, then retrieve the order from GET /v1/conversion/orders/{orderId}. Orders are processed straight through, entering Processing and settling at Completed.

Request Parameters

GET /v1/conversion/orders

ParameterLocationTypeRequiredDescription
searchForquerystringOptionalFree-text search key filter
fromWalletquerystringOptionalSource wallet identifier filter
toWalletquerystringOptionalDestination wallet identifier filter
updateFrom / updateToquerystringOptionalLower and upper bounds of the update date range
idsqueryarrayOptionalFilter by specific order identifiers
financialSecurityIdsqueryarrayOptionalFilter by security identifiers
statusqueryarrayOptionalFilter by order status
originqueryarrayOptionalFilter by how the order was originated
includeObacquerybooleanOptionalInclude access control metadata when true
orderBy / sortOrderquerystringOptionalSorting controls
Offset / CountqueryintegerOptionalPagination controls

POST /v1/conversion/orders

ParameterLocationTypeRequiredDescription
X-Idempotency-KeyheaderstringYesMax 255 characters; prevents duplicate submissions. Retain this value for the async operation query.
financialSecurityIdbodystringYesSecurity being converted
fromWalletIdbodystringYesThe source account or wallet from which the position will be debited. For Classic accounts, the format is {participantId}-10 (Free NA) or {participantId}-11 (Free MA), for example 00002667-10. These are auto-generated at onboarding and retrievable via GET /v1/conversion/wallets. For digital wallets, this is the registered blockchain wallet address.
toWalletIdbodystringYesThe destination account or wallet to which the converted position will be credited. For Classic accounts, the format is {participantId}-10 (Free NA) or {participantId}-11 (Free MA), for example 00002667-10. These are auto-generated at onboarding and retrievable via GET /v1/conversion/wallets. For digital wallets, this is the registered blockchain wallet address.
activityTypebodystringYesMemoSeg reduction reason code indicating how the conversion affects the participant's segregated position. Code 040 reduces (debits) the MemoSeg quantity; code 098 leaves the MemoSeg position unchanged.
quantitybodystringYesAmount to convert; must be greater than zero
participantIdbodystringOptionalThe 8-digit DTC participant number that identifies the member firm on whose behalf the conversion order is submitted, for example 00002667. This is the same identifier used across all DTC and DTCC services to uniquely identify a participant.
notebodystringOptionalOptional order note

POST /v1/conversion/async-operations/query

ParameterLocationTypeRequiredDescription
idempotencyKeysbodyarrayYesOne or more idempotency keys retained from prior submissions. The field accepts an array and the server processes all keys supplied in a single query. As a best practice, submit no more than 100 keys per request. See the Batch Query Behavior section below.
Offset / CountbodyintegerOptionalPagination controls

GET /v1/conversion/orders/{orderId}

ParameterLocationTypeRequiredDescription
orderIdpathstringYesOrder identifier, taken from resourceId on the async operation response

Batch Query Behavior

The idempotencyKeys field on POST /v1/conversion/async-operations/query accepts an array, and the server processes all keys supplied in a single query. As a best practice, submit no more than 100 idempotency keys per request; submitting very large arrays in a single request may impact performance.

BehaviorDetail
Unmatched keysSubmitting keys for operations that do not exist does not return an error; the response contains only the records that matched. For example, submitting 10 keys where only 5 have corresponding operations returns a list of 5 results, with no indication of which keys were unmatched.
PaginationThe response is paginated. Even for a large number of submitted keys, the number of records returned per page is controlled by the Count and Offset parameters. When the number of matching results exceeds the Count value, page through the results to retrieve them all.
Recommended batch sizeSubmit no more than 100 keys per request to avoid the performance impact of very large arrays.

Enumerations

Enumeration values must be provided exactly as they are defined; they are case-sensitive.

GET /v1/conversion/orders

DirectionParameter / FieldEnum NameValues
Input (query)orderByOrderFieldsCreatedAt, UpdatedAt
Input (query)sortOrderSortOrderAscending, Descending
Input (query)statusOrderStatusProcessing, Completed, Failed
Input (query)originOrderOriginParticipant, Admin, ForcedReconversion
Output (response)statusOrderStatusProcessing, Completed, Failed
Output (response)originOrderOriginParticipant, Admin, ForcedReconversion

POST /v1/conversion/async-operations/query

DirectionParameter / FieldEnum NameValues
Output (response)objectKindObjectKindUndefined, Order, Wallet, FinancialSecurity
Output (response)statusAsyncOperationStatusNew, Processing, Completed, Failed
Output (response)operationNameOperationNameUndefined, Register, Submit, Import

GET /v1/conversion/orders/{orderId}

DirectionParameter / FieldEnum NameValues
Output (response)statusOrderStatusProcessing, Completed, Failed
Output (response)originOrderOriginParticipant, Admin, ForcedReconversion

The submission endpoint POST /v1/conversion/orders returns no response body, so it publishes no response enumerations. The tables above cover the three calls that read order state.

Sample Request

GET /v1/conversion/orders

typescript
const query = new URLSearchParams({
  fromWallet: sourceWallet.id,
  toWallet: destinationWallet.id,
  financialSecurityIds: selectedSecurity.id,
  status: 'Processing',
  offset: '0',
  count: '20'
});

const ordersResponse = await fetch(`${baseUrl}/v1/conversion/orders?${query}`, {
  headers: { 'Authorization': `Bearer ${access_token}` }
});
const existingOrders: OrderResponse[] = await ordersResponse.json();

POST /v1/conversion/orders

typescript
const idempotencyKey = generateIdempotencyKey();

const orderResponse = await fetch(`${baseUrl}/v1/conversion/orders`, {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${access_token}`,
    'Content-Type': 'application/json',
    'X-Idempotency-Key': idempotencyKey
  },
  body: JSON.stringify({
    financialSecurityId: selectedSecurity.id,
    fromWalletId: sourceWallet.id,
    toWalletId: destinationWallet.id,
    activityType: '040',
    quantity: '500'
  })
});

// 202 Accepted with no response body. Retain idempotencyKey for the async query.
if (orderResponse.status !== 202) {
  throw new Error('Conversion order was not accepted');
}

POST /v1/conversion/async-operations/query

typescript
const asyncResponse = await fetch(`${baseUrl}/v1/conversion/async-operations/query`, {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${access_token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    idempotencyKeys: [idempotencyKey],
    offset: 0,
    count: 10
  })
});

const operations: AsyncOperationResponse[] = await asyncResponse.json();
const orderId = operations[0]?.resourceId;

GET /v1/conversion/orders/{orderId}

typescript
const detailResponse = await fetch(`${baseUrl}/v1/conversion/orders/${orderId}`, {
  headers: { 'Authorization': `Bearer ${access_token}` }
});
const orderDetail: OrderDetailResponse = await detailResponse.json();
// orderDetail.status === 'Processing'

Response Template

GET /v1/conversion/orders

json
[
  {
    "id": "order-id",
    "symbol": "EXMPL",
    "cusip": "037833100",
    "fromWallet": { "id": "source-wallet-id", "name": "Participant Classic Account", "walletAddress": "00002667-10" },
    "toWallet": { "id": "destination-wallet-id", "name": "First Bank EVM Wallet", "walletAddress": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e" },
    "quantity": 500,
    "status": "Processing",
    "errorMessage": null,
    "createdAt": "2026-01-01T00:00:00Z",
    "updatedAt": "2026-01-01T00:00:00Z",
    "activityType": "040",
    "origin": "Participant"
  }
]

POST /v1/conversion/orders returns 202 Accepted with an empty body.

POST /v1/conversion/async-operations/query

json
[
  {
    "id": "async-operation-id",
    "idempotencyKey": "3f2504e0-4f89-41d3-9a0c-0305e82c3301",
    "objectKind": "Order",
    "status": "Completed",
    "operationName": "Submit",
    "resourceId": "order-id",
    "resourceUrl": "/v1/conversion/orders/order-id",
    "errorCode": null,
    "errorMessage": null,
    "asOfDate": "2026-01-01T00:00:00Z"
  }
]

GET /v1/conversion/orders/{orderId}

json
{
  "orderId": "order-id",
  "participant": { "id": "participant-id", "participantNumber": "00002667" },
  "financialSecurityInfo": { "cusip": "037833100", "security": "Example Security" },
  "fromWallet": { "id": "source-wallet-id", "name": "Participant Classic Account", "walletAddress": "00002667-10" },
  "toWallet": { "id": "destination-wallet-id", "name": "First Bank EVM Wallet", "walletAddress": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e" },
  "quantity": 500,
  "submittedBy": "SA-ConversionBot",
  "status": "Completed",
  "errorMessage": null,
  "createdAt": "2026-01-01T00:00:00Z",
  "updatedAt": "2026-01-01T00:05:00Z",
  "activityType": "040",
  "fromTransactionId": "0x639dc5a1b2c3d4e5f60718293a4b5c6d7e8f90a1b2c3d4e5f60718293a4b5c6d",
  "toTransactionId": "12200cc6f1e2d3c4b5a69788796a5b4c3d2e1f00998877665544332211aabbccdd",
  "check": { "status": "Passed" },
  "origin": "Participant"
}

While an order is in Processing, both fromTransactionId and toTransactionId are null. They are populated with the on-chain ledger transaction hashes once the order reaches Completed and the underlying ledger events settle. See the Transaction Identifiers section below for field-level semantics.

Transaction Identifiers

The order detail response (GET /v1/conversion/orders/{orderId}) is the only endpoint that exposes the on-chain transaction identifiers for a conversion. The orders list endpoint (GET /v1/conversion/orders) does not return these fields.

FieldContains
fromTransactionIdThe on-chain ledger transaction hash for the source (debit) leg of the conversion — for example, a Burn on Besu such as 0x639dc5....
toTransactionIdThe on-chain ledger transaction hash for the destination (credit) leg of the conversion — for example, a Mint on Canton such as 12200cc6....

Both fields are null until the order settles, then carry the ledger-native transaction hash for their respective leg. The hash format follows the convention of the underlying network (for example, a 0x-prefixed 32-byte hex string on Besu/EVM networks). Because a conversion moves between a DTC Classic account and a digital wallet, only the digital-wallet leg corresponds to a blockchain transaction; the DTC Classic leg (identifiers in the {participantId}-10 / {participantId}-11 format) is not an on-chain event, so the transaction identifier that carries an on-chain hash depends on the conversion direction.

Relationship to external custody or validator providers (for example, Fireblocks): The transaction hash originates from the underlying ledger (Besu or Canton), not from the Conversion Service. When an external custody or validator provider surfaces the on-chain transaction hash for the same settled ledger event, that value matches the corresponding fromTransactionId or toTransactionId returned here, because both systems independently report the same underlying chain data. Providers that expose an internal reference rather than the raw on-chain hash will not match directly; compare against the on-chain hash surfaced by the provider.

TypeScript Interface

typescript
interface OrderResponse {
  id: string;
  symbol?: string;
  cusip?: string;
  fromWallet: WalletRefResponse;
  toWallet: WalletRefResponse;
  quantity: number;
  status: string;
  errorMessage?: string;
  createdAt: string;
  obac?: AccessControlInfoResponse;
  activityType?: string;
  updatedAt?: string;
  origin?: string;
}

interface AsyncOperationResponse {
  id: string;
  idempotencyKey: string;
  objectKind: string;
  status: string;
  operationName: string;
  resourceId?: string;
  resourceUrl?: string;
  errorCode?: string;
  errorMessage?: string;
  asOfDate: string;
}

interface OrderDetailResponse {
  orderId: string;
  participant: ParticipantResponse;
  financialSecurityInfo?: OrderFinancialSecurityInfo;
  fromWallet: WalletRefResponse;
  toWallet: WalletRefResponse;
  quantity: number;
  submittedBy?: string;
  submitterEmail?: string;
  submitterComment?: string;
  status: string;
  errorMessage?: string;
  createdAt: string;
  updatedAt?: string;
  activityType?: string;
  fromTransactionId?: string;
  toTransactionId?: string;
  check: CheckInfoResponse;
  origin?: string;
}

Business Rules

Conversion direction must move between DTC_Classic and non-Classic wallets. Orders can be submitted Monday-Friday, 02:00-18:15 ET, with operational-hours enforcement server-side. Query the orders list before submitting to detect whether a prior submission with the same intent already exists, filtering on fromWallet, toWallet, financialSecurityIds, or status.

Error Handling

Handle 400 validation errors, 403 permission or lockout failures, 409 duplicate idempotency key, 422 business rule violations, and 5xx server errors. Submission does not execute the conversion synchronously; a 202 Accepted response confirms only that the order was queued for processing. Treat an async operation status of Failed as a submission failure and surface errorCode and errorMessage.

Common Error Types

HTTPConditionExpected integration behavior
400Malformed request, missing X-Idempotency-Key, quantity of zero, or wallet identifier not found see Error Code Reference belowCorrect the request. Do not retry as-is.
401JWT access credential missing, expired, or invalidRequest a new JWT access credential, then retry once.
403Service account lacks the required permission, or the account is lockedSurface access denied. Do not retry.
404Security or order identifier not found see Error Code Reference belowSurface not found. Do not create a replacement order.
409Duplicate X-Idempotency-Key, or a conflicting wallet already exists see Error Code Reference belowTreat the order as already submitted. Query the async operation with the same key to resolve the existing order identifier.
422Business rule violation such as invalid conversion direction, ineligible security, ineligible wallet, or submission outside operational hoursSurface the specific rule violation. Do not retry until the input is corrected.
500Unhandled or infrastructure failure see Error Code Reference belowNot retryable without platform investigation. Surface the failure and escalate.
503Service failureRetry with the same X-Idempotency-Key, maximum three attempts.
Reference

Error Code Reference

Some error responses include a machine-readable errorCode that pinpoints the specific cause beyond the HTTP status. The tables below enumerate the codes returned for HTTP 400, 404, 409, and 500. Not every error response carries a specific code — responses without one are fully described by the summary table above.

Each entry lists the returned errorCode, the condition that triggers it, and the recommended correction.

HTTP 400 — Bad Request

Error CodeCauseCorrection
ConversionOperationsEngine__InvalidQuantityquantity ≤ 0.Submit with a positive quantity.
ConversionOperationsEngine__SameOrderWalletsfromWalletId and toWalletId are identical.Use two distinct wallet IDs.
ConversionOperationsEngine__SameWalletLedgersBoth wallets are on the same network.Use wallets on different networks.
ConversionOperationsEngine__WalletIsNotConversionEligibleThe wallet has conversionEligible = false.Use a wallet that has completed registration and is marked eligible.
ConversionOperationsEngine__OperationCannotBePerformedThe wallet's processingState is not Idle.Wait for wallet registration to complete before submitting.
ConversionOperationsEngine__OrderFinancialInstrumentRequiredNeither assetId nor financialSecurityId was provided.Include exactly one of assetId or financialSecurityId.
ConversionOperationsEngine__MultipleOrderFinancialInstrumentsProvidedBoth assetId and financialSecurityId were provided.Remove one of the two fields.
ConversionOperationsEngine__InactiveFinancialSecurityOrderCreatingExceptionThe referenced security is not in Active status.Use an active security.
ConversionOperationsEngine__OutsideAllowedTimeWindowRequest submitted outside operational hours or on a holiday.Resubmit during the operational window.
ConversionOperationsEngine__InvalidOrderActivityTypeactivityType is not a supported value.Use a supported activity type code.
ConversionOperationsEngine__InvalidWalletAddressThe wallet address is not valid for the specified network.Correct the address format.
ConversionOperationsEngine__WalletNotFoundThe wallet ID does not exist or is not accessible to your tenant.Verify the wallet ID.

HTTP 404 — Not Found

Error CodeCauseCorrection
ConversionOperationsEngine__OrderNotFoundThe order ID does not exist or is not accessible.Verify the order ID.
ConversionOperationsEngine__AssetNotFoundThe assetId does not exist.Verify the asset ID.
ConversionOperationsEngine__FinancialSecurityNotFoundThe financialSecurityId does not exist.Verify the financial security ID.

HTTP 409 — Conflict

Error CodeCauseCorrection
AsyncOperation__AsyncOperationAlreadyExistsThe idempotency key was already used and the original request succeeded.Query async operations with the key to retrieve the existing order ID. Do not resubmit.
ConversionOperationsEngine__WalletAlreadyExistsA wallet with the same address and network already exists in your tenant.Use the existing wallet or register with a different address.
ConversionOperationsEngine__WalletWithSameNameAlreadyExistA wallet with the same name already exists in your tenant.Choose a different wallet name.

HTTP 500 — Internal Server Error

Unhandled or infrastructure failures. The errorCode value is "500". Not retryable without platform investigation.

Retry Guidance

The submission POST is protected by X-Idempotency-Key. Retrying with the same key is safe and will not create duplicate orders. Do not generate a new key on retry, because the key is also the lookup value for the async operation query. The async operation query and the order detail retrieval are read-only and safe to retry.

Permissions & Scopes

Auth PatternService Account Credentials grant
Credential DeliveryAuthorization: Bearer {access_token}
Operational WindowMonday to Friday, 02:00 to 18:15 ET
Business RuleConversion direction must be DTC_Classic to non-Classic or vice versa
Cross-service dependency: the DTCC APIs provides securities, wallets, and order management. the DTCC APIs provides ledger/network reference data for filtering.
Certification

Conversion Order Certification Tests

CERT
Conversion Order Certification Tests
Certification · v2 · Auth → Reference Data → Eligibility → Submit → Async → Retrieve → Lifecycle → Audit
›

Demonstrate that a customer integration can execute the complete conversion order lifecycle: authenticate with the Service Account Credentials grant, load order, security, and wallet reference data, validate security and wallet eligibility, submit a conversion order, enforce idempotency controls, track asynchronous processing, correlate the async operation to the resulting order, retrieve final order detail, monitor lifecycle progression, and reconstruct the transaction audit trail. Unlike Account Management and Wallet Management, this certification validates both retrieval operations and transactional business processes.

Certification Workflow

Authenticate, load reference data in parallel, validate eligibility, submit, then track the order asynchronously to a terminal state.

Authenticate

Service Account Credentials grant against /connect/token.

Load Reference Data

Orders, securities, and wallets in parallel, plus issue type, issue sub-type, and ledger filters.

Validate Security

Security status equals Active.

Validate Wallet

Wallet state equals Idle and conversionEligible is true.

Submit Order

POST /v1/conversion/orders returns 202 Accepted with no body.

Track Async Operation

Query by X-Idempotency-Key until a terminal status.

Correlate To Order

resourceId resolves the order identifier.

Retrieve Order Detail

GET /v1/conversion/orders/{orderId}.

Validate Lifecycle And Audit

Processing to Completed, then reconstruct the audit trail.

Order submission rule: Submission does not execute the conversion and returns no response body. Completion must be determined through async operation tracking rather than assumed from the submission response. Enforcement of operational hours, idempotency, direction, and eligibility occurs server side at submission time.
Service AccountParallel LoadingEligibilityIdempotencyAsync TrackingAudit

Key Business Rules

RuleRequirement
Security EligibilityKnown security states are Onboarding, Active, Pause, and Failed. Only Active securities are eligible for conversion-order creation.
Wallet EligibilityKnown wallet states are Idle, Registering, FailedCompliance, and Failed. Only wallets that are Idle and conversion eligible may be used.
Conversion DirectionConversion must occur between DTC Classic and digital wallets.
Quantity ValidationQuantity must be greater than zero.
IdempotencyEvery submission must include X-Idempotency-Key. The same key must remain traceable throughout asynchronous processing.
Asynchronous ProcessingOrder creation returns HTTP 202 Accepted. Completion is determined through async operation tracking, not from the submission response.
Operational HoursMonday to Friday, 02:00 ET to 18:15 ET. Enforcement is server-side.

Test Data

typescript
const tenantId = "<tenant-id>";
const baseUrl = "<base-url>";
const username = "SA-ConversionBot";
const password = process.env.SERVICE_ACCOUNT_PASSWORD!;

Shared Helper Functions

typescript
async function authenticate() {
  const response = await fetch(`${baseUrl}/connect/token`, {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body: new URLSearchParams({
      grant_type: "urn:dtcc:params:oauth:grant-type:service-account-credentials",
      type: "conveyance",
      entity: ENTITY_ID_OF_WHICH_SA_IS_MEMBER_OF,
      acr_values: `tenant:${tenantId}`,
      username,
      password
    })
  });
  if (!response.ok) {
    throw new Error(`Authentication failed: ${response.status}`);
  }
  const data = await response.json();
  return data.access_token;
}

async function loadReferenceData(accessToken: string) {
  const [ordersResponse, securitiesResponse, walletsResponse] = await Promise.all([
    fetch(`${baseUrl}/v1/conversion/orders`, { headers: { Authorization: `Bearer ${accessToken}` } }),
    fetch(`${baseUrl}/v1/conversion/securities`, { headers: { Authorization: `Bearer ${accessToken}` } }),
    fetch(`${baseUrl}/v1/conversion/wallets`, { headers: { Authorization: `Bearer ${accessToken}` } })
  ]);
  return {
    orders: await ordersResponse.json(),
    securities: await securitiesResponse.json(),
    wallets: await walletsResponse.json()
  };
}

async function loadFilterData(accessToken: string) {
  const [issueTypesResponse, issueSubTypesResponse] = await Promise.all([
    fetch(`${baseUrl}/v1/conversion/securities/issue-types`, { headers: { Authorization: `Bearer ${accessToken}` } }),
    fetch(`${baseUrl}/v1/conversion/securities/issue-subtypes`, { headers: { Authorization: `Bearer ${accessToken}` } })
  ]);
  return {
    issueTypes: await issueTypesResponse.json(),
    issueSubTypes: await issueSubTypesResponse.json()
  };
}

function generateIdempotencyKey() {
  return crypto.randomUUID();
}

async function queryOperation(accessToken: string, idempotencyKey: string) {
  const response = await fetch(`${baseUrl}/v1/conversion/async-operations/query`, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${accessToken}`,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({ idempotencyKeys: [idempotencyKey], offset: 0, count: 10 })
  });
  const [operation] = await response.json();
  return operation;
}

async function getOrder(accessToken: string, orderId: string) {
  const response = await fetch(`${baseUrl}/v1/conversion/orders/${orderId}`, {
    headers: { Authorization: `Bearer ${accessToken}` }
  });
  if (!response.ok) {
    throw new Error(`Order retrieval failed with status ${response.status}`);
  }
  return response.json();
}

POST
Step 1 — Authentication
${baseUrl}/connect/token
›

Goal

Verify that the integration can obtain an access credential using the Service Account Credentials grant. The credential proves the caller's identity and must be supplied as a bearer credential on every subsequent call in this workflow.

Procedure

typescript
const accessToken = await authenticate();

Validation

The token response returns access_token, token_type, and expires_in; the helper returns the access_token value, which is usable on a subsequent API call.

Expected Result

HTTP 200; credential issued and usable.

Common Error Types

HTTPConditionExpected integration behavior
400Invalid service account credentials or malformed grant requestCorrect the credentials. Do not retry with the same values.
403Service account lacks the required permissionSurface the permission failure. Do not retry.
500, 503Identity service failureRetry with exponential backoff, maximum three attempts.

GET
Step 2 — Reference Data Retrieval
loadReferenceData() · loadFilterData()
›

Goal

Verify that all prerequisite data loads successfully. Order, security, and wallet inventories supply the order inputs; issue type, issue sub-type, and ledger reference data supply the filter context.

Procedure

typescript
const { orders, securities, wallets } = await loadReferenceData(accessToken);
const { issueTypes, issueSubTypes } = await loadFilterData(accessToken);

Validation

Order inventory returned. Security inventory returned. Wallet inventory returned. Issue type reference data returned. Issue sub-type reference data returned. Ledger network data returned.

Expected Result

HTTP 200 on each call; all six data sets available for downstream steps.

Common Error Types

HTTPConditionExpected integration behavior
401Expired or invalid access credentialRe-authenticate, then retry once.
403Service account lacks the required permissionSurface access denied. Do not retry.
500, 503Service failureRetry with exponential backoff. Each call fails independently, so present a partial state rather than blocking the whole load.

GET
Step 3 — Security Validation
status equals Active
›

Goal

Verify that a valid conversion security can be identified from the security inventory loaded in Step 2.

Procedure

typescript
const security = securities.find(security => security.status === "Active");

Validation

The security exists and carries CUSIP, issuer, issue type, issue sub-type, restrictions, and token network information. Status equals Active. Securities in Onboarding, Pause, or Failed status are not eligible.

Expected Result

Eligible security identified.

Common Error Types

This step performs no API calls. If no Active security is found, the integration must block order submission rather than proceeding with an ineligible security.


GET
Step 4 — Wallet Validation
state equals Idle and conversionEligible is true
›

Goal

Verify that suitable source and destination wallets can be selected from the wallet inventory loaded in Step 2.

Procedure

typescript
const eligibleWallets = wallets.filter(
  wallet => wallet.state === "Idle" && wallet.conversionEligible === true
);

Validation

The wallet exists, state equals Idle, conversionEligible equals true, network information is present, and no failure state is set. A wallet that satisfies only one of the two eligibility conditions is not a valid candidate. Wallets in Registering, FailedCompliance, or Failed state are not eligible.

Expected Result

Eligible wallets identified.

Common Error Types

This step performs no API calls. If no wallet is both Idle and conversion eligible, the integration must block order submission rather than proceeding with an ineligible wallet.


POST
Step 5 — Order Submission
${baseUrl}/v1/conversion/orders
›

Goal

Verify that a conversion order can be submitted with a valid idempotency key and accepted for asynchronous processing.

Procedure

typescript
const idempotencyKey = generateIdempotencyKey();

const response = await fetch(`${baseUrl}/v1/conversion/orders`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${accessToken}`,
    "Content-Type": "application/json",
    "X-Idempotency-Key": idempotencyKey
  },
  body: JSON.stringify({
    financialSecurityId: security.id,
    fromWalletId: sourceWallet.id,
    toWalletId: destinationWallet.id,
    quantity: "100",
    activityType: "040"
  })
});

Validation

HTTP 202 returned. The request is accepted and no validation error is returned. No response body is expected, so the order identifier is not available at this point. Retain idempotencyKey for the async operation query.

Expected Result

HTTP 202 Accepted with no response body.

Common Error Types

HTTPConditionExpected integration behavior
400Malformed request, missing X-Idempotency-Key, or quantity of zeroCorrect the request. Do not retry as-is.
403Service account lacks the required permission, or the account is lockedSurface access denied. Do not retry.
409Duplicate X-Idempotency-KeyTreat the order as already submitted. Query the async operation with the same key to resolve the existing order.
422Business rule violation such as invalid direction, ineligible security, ineligible wallet, or submission outside operational hoursSurface the specific rule violation. Do not retry until the input is corrected.
500, 503Service failureRetry with the same X-Idempotency-Key, maximum three attempts.

POST
Step 6 — Idempotency Validation
duplicate submission with same X-Idempotency-Key
›

Goal

Verify that resubmitting an identical request with the same idempotency key does not create a duplicate order.

Procedure

Submit the same order request twice using the same X-Idempotency-Key.

Validation

A duplicate order is not created, idempotency is maintained, and the operation remains traceable under the original key.

Expected Result

Duplicate processing prevented.

Common Error Types

HTTPConditionExpected integration behavior
409Duplicate X-Idempotency-KeyTreat as already submitted. Reconcile against the existing order rather than resubmitting.
400X-Idempotency-Key omitted entirelySubmission rejected. Add the header before retrying.

POST
Step 7 — Async Operation Validation
${baseUrl}/v1/conversion/async-operations/query
›

Goal

Verify that asynchronous operations can be monitored using the idempotency key retained at submission.

Procedure

typescript
const operation = await queryOperation(accessToken, idempotencyKey);

Validation

The operation returns id, idempotencyKey echoing the submitted key, objectKind, status, operationName, and asOfDate. Known status values are New, Processing, Completed, and Failed. resourceId populates once processing begins.

Expected Result

HTTP 200; async operation successfully tracked.

Common Error Types

HTTPConditionExpected integration behavior
401Expired or invalid access credentialRe-authenticate, then retry once.
500, 503Service failureRetry with exponential backoff. The query is read-only and safe to repeat.

GET
Step 8 — Async-to-Order Correlation
resourceId resolves the order identifier
›

Goal

Verify that an async operation can be correlated to the order it produced.

Procedure

typescript
const operation = await queryOperation(accessToken, idempotencyKey);
const order = await getOrder(accessToken, operation.resourceId);

Validation

resourceId is populated, resourceUrl is populated, the referenced order exists, and the order is retrievable.

Expected Result

HTTP 200; async operation successfully correlated to an order.

Common Error Types

HTTPConditionExpected integration behavior
404resourceId references an order that cannot be retrievedSurface not found. Do not create a replacement order.
500, 503Service failureRetry with exponential backoff, maximum three attempts.

GET
Step 9 — Retrieve Final Order
${baseUrl}/v1/conversion/orders/{orderId}
›

Goal

Verify that final order detail can be accessed once the order identifier is known.

Procedure

typescript
const orderDetail = await getOrder(accessToken, operation.resourceId);

Validation

The response carries order identifier, status, participant information, transaction information, and audit timestamps.

Expected Result

HTTP 200; order detail successfully retrieved.

Common Error Types

HTTPConditionExpected integration behavior
401Expired or invalid access credentialRe-authenticate, then retry once.
404Order identifier not foundSurface not found. Do not create a replacement order.
500, 503Service failureRetry with exponential backoff, maximum three attempts.

GET
Step 10 — Lifecycle Validation
order status transitions
›

Goal

Verify that lifecycle transitions can be monitored through to a terminal state.

Validation

Valid states are Processing, Completed, and Failed. Status progression is visible, a terminal state is reached, and the final state is recorded. Failed is terminal and must be surfaced with errorMessage rather than resubmitted.

Expected Result

HTTP 200; current order status returned and reportable.

Common Error Types

HTTPConditionExpected integration behavior
401Expired or invalid access credentialRe-authenticate, then retry once.
404Order identifier not foundSurface not found. Do not create a replacement order.
500, 503Service failureRetry with exponential backoff, maximum three attempts.

GET
Step 11 — Audit Validation
end-to-end transaction trace
›

Goal

Verify that the complete transaction history can be reconstructed from the artifacts produced across the workflow.

Validation

The order identifier is traceable, the idempotency key is traceable, the async operation is traceable, audit timestamps are available, and transaction identifiers are available.

Expected Result

End-to-end audit trace established.

Common Error Types

This step performs no additional API calls. It relies on the artifacts captured in Steps 5 through 10. If any link in the chain cannot be reconstructed, the audit trace is incomplete and the workflow must be treated as unverified.


E2E
Step 12 — End-to-End Workflow Execution
complete conversion order lifecycle
›

Goal

Execute the complete workflow from authentication through audit validation in a single uninterrupted run.

Validation

text
Authentication      PASS
Reference Data      PASS
Security Validation PASS
Wallet Validation   PASS
Order Submission    PASS
Idempotency         PASS
Async Tracking      PASS
Correlation         PASS
Order Retrieval     PASS
Lifecycle           PASS
Audit               PASS

Each constituent call returns its expected success code.

Expected Result

Complete workflow executed and every stage verified.

Negative Test Cases

IDScenarioHTTPExpected result
NT-1Invalid service account credentials400Authentication rejected.
NT-2Invalid security422Order rejected.
NT-3Ineligible wallet422Order rejected.
NT-4Missing idempotency key400Request rejected.
NT-5Expired access credential401Authorization failure; re-authentication required.
NT-6Async processing failure—Async operation returns Failed status with errorCode and errorMessage present. Not an HTTP error condition.
NT-7Invalid order retrieval404Order not found; error handled without creating a replacement order.
NT-8Service unavailable503Retry attempted, failure reported, workflow stops safely.

Production Certification Criteria

The customer must demonstrate authentication, reference-data retrieval, active-security validation, wallet eligibility validation covering both idle state and the conversion-eligible flag, conversion-order submission, idempotency compliance, async-operation monitoring, async-to-order correlation, final-order retrieval, lifecycle monitoring, audit validation, required negative-test handling, and end-to-end workflow execution.

Category 4
Corporate Actions

Corporate Actions workflows support discovery, filtering, and detail inspection of corporate action events. The initial load retrieves events, event type taxonomy, and securities filters in parallel. Event detail is retrieved from a single endpoint and includes classification, security, date, DTC mandatory, and support context.

The information provided by corporate action notification API endpoints leverages DTCC's ISO CANO messages. For a data dictionary on these data points, please refer to DTCC's ISO 20022 Messaging Specifications, located here.

Authentication pattern: These workflows use the Service Account Credentials grant. The token request is sent to /connect/token with grant_type=urn:dtcc:params:oauth:grant-type:service-account-credentials, type=conveyance, entity context, tenant context via acr_values=tenant:{tenantId}, and service-account credentials. Downstream API calls use Authorization: Bearer {access_token}.

Workflow Summary

A condensed view of the API call sequence, dependencies, and branch rules.

Authenticate

POST /connect/token
Obtain service-account token.

Load events

POST /v2/corporate-actions
Retrieve paginated events with a JSON body; offset and count are required, filters are optional.

Load filter data

GET /v2/corporate-actions/event-types
GET /v1/conversion/securities
Load in parallel.

Inspect event

GET /v2/corporate-actions/{id}
Retrieve full event detail.

Apply context

Interpret status, category, DTC mandatory classification, support flag, and relevant core dates.

Detail rule: Full corporate action detail is returned from GET /v2/corporate-actions/{id}, including security data, event classification, core dates, DTC mandatory classification, support status, and payout-related metadata.
Service AccountParallel LoadingEvent FiltersEvent Detail
POST
List Corporate Action Events and Reference Data
POST /v2/corporate-actions · GET /v2/corporate-actions/event-types · GET /v1/conversion/securities
›

Fetches the events list alongside event taxonomy and securities filter options. The events list is retrieved with POST /v2/corporate-actions, which carries the pagination and filter fields in a JSON body; offset and count are required and the filter fields are optional. The event taxonomy and securities calls remain GET requests.

Endpoint migration: The corporate action events list has moved from GET /v1/corporate-actions (query-string parameters) to POST /v2/corporate-actions (JSON request body). GET /v1/corporate-actions is deprecated. The filter fields that were previously query parameters are now supplied in the request body, which must include the required offset and count fields.

Request Parameters

POST /v2/corporate-actions — all filter and pagination fields are supplied in the JSON request body (EventFilterRequest). The body is required and must include offset and count; the remaining filter fields are optional. A request with no body, or one that omits offset or count, is rejected with HTTP 400.

ParameterLocationTypeRequiredDescription
offsetbodyinteger (int32)YesZero-based index of the first record to return. Minimum 0.
countbodyinteger (int32)YesMaximum number of records to return per page. Minimum 1.
idsbodystring[]OptionalFilter by internal event identifiers (GUID format). Up to 50 values.
eventIdsbodystring[]OptionalFilter by external (DTC) event identifiers. Up to 50 values.
eventTypesbodyEventTypeFilterItem[]OptionalFilter by event types and subtypes. Each item is an object with a required type (EventTypeEnumeration) and an optional subType (SubEventTypeEnumeration). Up to 50 values.
securityIdsbodystring[]OptionalFilter by event security identifier. Up to 50 values.
securityCusipsbodystring[]OptionalFilter by security CUSIP. Up to 50 values.
statusbodyEventStatusEnumeration[]OptionalFilter by event status. Up to 5 values.
searchForbodystringOptionalFree-text search key filter. Maximum length 50 characters.
orderBybodyEventFields enumOptionalField the results are sorted on.
sortOrderbodySortOrder enumOptionalSort direction: Ascending or Descending.

Enumerations

Enumeration values must be provided exactly as they are defined; they are case-sensitive.

POST /v2/corporate-actions

DirectionParameter / FieldEnum NameReference
Input (body)eventTypes[].typeEventTypeEnumerationEvent Type ▾
Input (body)eventTypes[].subTypeSubEventTypeEnumerationSub-Event Type ▾
Input (body)statusEventStatusEnumerationEvent Status ▾
Input (body)orderByEventFieldsEvent Fields ▾
Input (body)sortOrderSortOrderSort Order ▾
Output (response)subTypeSubEventTypeEnumerationSub-Event Type ▾
Output (response)statusEventStatusEnumerationEvent Status ▾

The POST /v2/corporate-actions response (CorporateActionEventResponse) returns type, subType, and status; dtcMandatory and category are returned only by the event detail endpoint GET /v2/corporate-actions/{id}. Enumeration values are defined once in the Corporate Action Enumerations reference at the end of this section.

GET /v2/corporate-actions/event-types

DirectionParameter / FieldEnum NameReference
Output (response)eventTypeEventTypeEnumerationEvent Type ▾
Output (response)subEventTypeSubEventTypeEnumerationSub-Event Type ▾

This endpoint returns the authoritative list of valid event type / sub-event type pairs, including the numeric codes used by the service. See the Event Type and Sub-Event Type references.

GET /v1/conversion/securities

DirectionParameter / FieldEnum NameValues
Input (query)orderByFinancialSecurityFieldsCUSIP, Description, Issuer
Input (query)sortOrderSortOrderAscending, Descending
Output (response)statusFinancialSecurityStatusOnboarding, Active, Pause, Failed
Output (response)processingStateProcessingStatesIdle, Registering, FailedCompliance, Failed

Sample Request

typescript
const [eventsResponse, eventTypesResponse, securitiesResponse] = await Promise.all([
  fetch(`${baseUrl}/v2/corporate-actions`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${access_token}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ orderBy: 'UpdatedAt', sortOrder: 'Descending', count: 25, offset: 0 })
  }),
  fetch(`${baseUrl}/v2/corporate-actions/event-types`, {
    headers: { 'Authorization': `Bearer ${access_token}` }
  }),
  fetch(`${baseUrl}/v1/conversion/securities`, {
    headers: { 'Authorization': `Bearer ${access_token}` }
  })
]);
const events = await eventsResponse.json();

Response Template

json
[
  {
    "id": "9149E44A-CAB4-4CB4-8656-A01BDA2B18EC",
    "eventId": "0000006",
    "typeDescription": "Cash Dividend",
    "type": "CashDividend",
    "subTypeDescription": "DRIP (DTC Only)",
    "subType": "DRIPDTCOnly",
    "status": "Approved",
    "positionCaptureDate": "2025-03-12T00:00:00Z",
    "declaredPayableDate": "2025-03-12T00:00:00",
    "earliestDTCAnticipatedPaymentDate": null,
    "earliestDTCInstructionExpirationDate": null,
    "digitalAllocationDate": "2025-05-05T19:00:00Z",
    "updatedAt": "2025-05-05T19:00:00Z",
    "security": { "id": "E6789C8C-2CA4-446C-AE93-0A9AFFCC457A", "externalId": "E6789C8C-2CA4-446C-AE93-0A9AFFCC457A", "cusip": "46090E103", "name": "Invesco QQQ Trust", "onboardedDate": "2024-01-15T00:00:00Z" },
    "dtcProcessingIndicator": true
  }
]

TypeScript Interface

typescript
interface CorporateActionEventResponse {
  id: string;
  eventId: string;
  typeDescription: string;
  type: string;
  subTypeDescription: string;
  subType: string;
  status: string;
  positionCaptureDate: string | null;
  declaredPayableDate: string | null;
  earliestDTCAnticipatedPaymentDate: string | null;
  earliestDTCInstructionExpirationDate: string | null;
  digitalAllocationDate: string | null;
  updatedAt: string | null;
  security: SecurityListResponse;
  dtcProcessingIndicator: boolean;
}
interface SecurityListResponse {
  id: string;
  externalId: string;
  cusip: string;
  name: string;
  onboardedDate: string;
}
interface EventTypePairResponse {
  eventType: number;
  eventTypeCode: string;
  eventTypeDescription: string;
  subEventType: number;
  subEventTypeCode: string;
  subEventTypeDescription: string;
}

Status Values

Approved, ConditionallyApproved, Incomplete, Cancelled, and Deleted.

Error Handling

Handle 401 by requesting a new JWT access credential and retrying once, 403 as lockout or missing permission, 400 as invalid filters, and 5xx with retry. If the event-type or securities call fails, disable the affected filter while keeping the events list usable.

Common Error Types

HTTPConditionExpected integration behavior
400Malformed request or invalid filter parameterCorrect the request. Do not retry as-is.
401JWT access credential missing, expired, or invalidRequest a new JWT access credential, then retry once.
403Service account lacks the required permission, or the account is lockedSurface access denied. Do not retry.
404Resource not foundSurface not found. Do not retry.
500, 503Service failureRetry with exponential backoff, maximum three attempts. Keep the workflow stable and disable only the affected filter.

Retry Guidance

All three calls are read-only queries and safe to retry on 5xx or network timeout. The events list is a POST /v2/corporate-actions that performs a read with no side effects, so retrying it is safe; the event-types and securities calls are GET requests.

Permissions & Scopes

Auth PatternService Account Credentials grant
Credential DeliveryAuthorization: Bearer {access_token}

GET
Get Corporate Action Event Detail
/v2/corporate-actions/{id}
›

Retrieves full detail for a specific corporate action event.

Request Parameters

ParameterLocationTypeRequiredDescription
idpathstringYesUnique key of a single corporate action event, taken from the results of the event list call.

Enumerations

Enumeration values must be provided exactly as they are defined; they are case-sensitive.

GET /v2/corporate-actions/{id}

DirectionParameter / FieldEnum NameReference
Output (response)typeEventTypeEnumerationEvent Type ▾
Output (response)subTypeSubEventTypeEnumerationSub-Event Type ▾
Output (response)statusEventStatusEnumerationEvent Status ▾
Output (response)dtcMandatoryDtcMandatoryDTC Mandatory ▾
Output (response)categoryEventCategoryEvent Category ▾

Enumeration values are defined once in the Corporate Action Enumerations reference at the end of this section.

Sample Request

typescript
const eventDetailResponse = await fetch(
  `${baseUrl}/v2/corporate-actions/${eventId}`,
  { headers: { 'Authorization': `Bearer ${access_token}` } }
);
if (!eventDetailResponse.ok) {
  const error = await eventDetailResponse.json();
  throw new Error(`Event detail request failed: ${error.ErrorCode} - ${error.ErrorMessage}`);
}
const eventDetail = await eventDetailResponse.json();

Response Template

json
{
  "id": "event-record-id",
  "eventId": "123456",
  "eventGroup": "Distribution",
  "eventType": "CashDividend",
  "eventTypeDescription": "Cash Dividend",
  "subEventType": "CDeemedDividend",
  "subEventTypeDescription": "305C - Deemed Dividend",
  "status": "ConditionallyApproved",
  "category": "MandatoryCashDistribution",
  "isSupported": false,
  "dtcMandatory": "Mandatory",
  "security": { "id": "security-id", "cusip": "46625H202", "name": "Example Security", "issuerDescription": "Example Issuer", "assetClass": "Equity", "assetType": "Common Stock", "ticker": "EX" },
  "coreDates": { "exDate": "2026-06-24T00:00:00Z", "recordDate": "2026-06-24T00:00:00Z", "declaredPayableDate": "2026-06-24T00:00:00Z", "allocationDateTime": null }
}

TypeScript Interface

typescript
interface CorporateActionEventResponse {
  id: string;
  security: { id: string; cusip: string; name: string; issuerDescription: string; assetClass: string; assetType: string; ticker: string };
  eventId: string;
  eventGroup: string;
  eventType: string;
  eventTypeDescription: string;
  subEventType: string;
  subEventTypeDescription: string;
  status: string;
  category: string;
  isSupported: boolean;
  dtcMandatory: string;
  reconversionDate: string | null;
  coreDates: Record<string, string | null>;
}

Single Endpoint Detail

The event detail response includes security information, event classification, status, category, DTC mandatory classification, support indicator, reconversion date, and coreDates. No separate entitlements endpoint is needed for the workflow described in the source material.

Error Handling

Handle 401 as an expired credential, 403 as lockout or missing detail permission, 404 as an invalid or deleted event, 400 as an invalid event ID format, and 500 with retry. The response body carries ErrorCode and ErrorMessage, which should be surfaced rather than discarded.

Common Error Types

HTTPConditionExpected integration behavior
400Invalid event identifier formatCorrect the request. Do not retry as-is.
401JWT access credential missing, expired, or invalidRequest a new JWT access credential, then retry once.
403Service account lacks the required permission, or the account is lockedSurface access denied. Do not retry.
404Invalid or deleted eventSurface event not found. Do not retry.
500, 503Service failureRetry with exponential backoff, maximum three attempts.

Retry Guidance

Read-only GET; safe to retry on 5xx or network timeout. Use exponential backoff with a maximum of three retries.

Permissions & Scopes

Auth PatternService Account Credentials grant
Credential DeliveryAuthorization: Bearer {access_token}
Reference

Corporate Action Enumerations

These enumerations are shared across the Corporate Actions endpoints. Each value is defined once here; the endpoint tables above link into this reference. Values are case-sensitive and must be sent exactly as shown.

Event Type Enumeration

High-level corporate action classification. Used as the type field inside each eventTypes[] filter item, and returned as type on event responses. Descriptions are sourced from the SR2026 Corporate Action Announcements Data Dictionary.

Show all 53 event types
ValueEvent NameDescription
AutomaticDividendReinvestmentAutomatic Dividend ReinvestmentA mandatory event for which the dividend payment is paid only in additional shares of the same security. This event type will predominantly be used for US securities and differs from the Dividend Reinvestment option (a voluntary portion of the event that applies to non-US securities). "DRIP" also appears as an option under relevant events (e.g., Cash Dividend).
CapitalGainsDistributionCapital Gains DistributionA distribution of cash that the issuer has determined will be declared as income financed from capital gains and not ordinary income.
CashDividendCash DividendA distribution of cash to shareholders, paid by the issuer, usually based upon current earnings and/or accumulated profits as declared by the board of directors. There are separate events for Dividends with Options and Stock Dividends.
CDEarlyRedemptionCD Early RedemptionA feature of a security that allows an issuer to make a payment to the security holder. This event will be used for securities subject to redemptions other than those categorized as full and partial calls (e.g., early CD redemptions). Deferred until Phase 4 implementation.
ChangeChangeAn event where the issuer is announcing a change in company or security details.
ConsentConsentSolicitation to security holders for their agreement (consent) to proposed changes in the terms of the security, usually without a formal general meeting. A fee may be paid to the security holder.
ConversionConversionConversion of securities (generally convertible bonds or preferred shares) into another form of securities (usually common shares) at a pre-stated price or rate.
DefaultDefaultA notice of failure by the issuer to honour commitments made within the terms of the issued security. It usually relates to making timely payments of interest and principal as they come due. A payment may be made in lieu of reinstituting the original payments.
DistributionDistributionA distribution by the issuer that is not classified as another specific event.
DividendWithOptionDividend with OptionA distribution of a dividend to shareholders with the choice of payment method. The shareholder has the option to choose the form of payment (e.g., securities, cash, or both). There are separate events for Cash Dividends, Stock Dividends, and Dividends with Options.
DutchAuctionDutch AuctionIdentifies a tender event in which the corporation offers to purchase up to a certain amount of securities within a price range. Holders must submit a specific price within that range that they would be willing to accept. The actual tender price is not determined until the end of the offer.
ExchangeOfferExchange OfferAn offer to surrender securities in exchange for other securities or a combination of securities and cash. The exchange may also include a consent solicitation.
FinalPaydownFinal PaydownThe final distribution of principal due on a security, typically CMOs.
FullCallFull CallThe security is redeemed for cash in its entirety on a date that is prior to the maturity date, and for which the holders receive the principal amount of the security.
FullPrerefundingFull PrerefundingThe exercise of a privilege by the issuer to repay, in full, any debt security prior to maturity when the issuer deposits assets in trust. This irrevocably restricts their use to satisfaction of the debt.
GeneralInformationGeneral InformationGeneral information provided by the issuer that should not result in material changes to the security.
InterestInterestThe payment of an obligation that the issuer agrees to make to holders of an interest-bearing security. Usually, the payment is made in cash and on a scheduled basis.
LiquidationLiquidationA company reports its intentions to dismantle its business, paying off debts in order of priority and distributing the remaining assets in cash and/or securities to the owners of the securities. The payment of proceeds may require the presentation of securities.
MandatoryExchangeMandatory ExchangeA corporate action requiring the surrender of certificates to be exchanged for a new security or cash.
MandatoryPutMandatory PutThe mandatory exchange of all outstanding bonds (with a putable feature) for cash or a new security, where the event security is remarketed. The issuer may offer holders the right to retain their securities instead of exchanging them.
MaturityMaturityThe final repayment, usually in cash, by an issuer for the entire issue, or remaining outstanding securities of a specific security on a specified date.
MeetingMeetingA meeting of a company's share or bond holders to address resolutions put forth by the issuer.
MergerMergerThe exchange of one company's security for another company's security, cash, or a combination of cash and securities.
NameChangeName ChangeThe issuer changes its name or the name of its security/securities. This may involve surrendering physical securities. A new security identifier may be assigned to the new name, especially if new securities are issued.
OddLotOfferOdd Lot OfferIdentifies a tender offer event made by the corporation or its agent to purchase shares from odd-lot shareholders. An odd-lot shareholder typically refers to a holder of less than 100 shares of stock.
PartialCallPartial CallSecurities are redeemed by the issuer for cash, in part, before their scheduled maturity date. The outstanding amount of securities will be proportionally reduced based on a specific percentage of holding. A lottery may be run where pooled securities are held.
PartialDefeasancePartial DefeasanceIssuer sets aside cash in escrow to pay off a portion of the issue before the maturity date. New securities are issued for the portion defeased.
PartialMandatoryPutPartial Mandatory PutThe mandatory exchange of a portion of bonds where the exchanged securities are usually remarketed. The issuer may offer holders the right to retain instead of exchanging their securities.
PartialPrerefundingPartial PrerefundingSimilar to a Full Prerefunding, a partial prerefunding is the exercise of a privilege by the issuer to repay, in part, any debt security prior to maturity when the issuer deposits assets in trust. This irrevocably restricts their use to satisfaction of the debt. New securities are issued for the portion prerefunded.
PayInKindPay in KindIncome on interest-bearing securities where the payment is made in additional securities rather than cash.
PlanOfReorganizationPlan of ReorganizationReorganisation plan devised by the company or trustees that is usually associated with a bankruptcy filing. Identifies an event where a vote/consent is sought for the plan of reorganisation.
PrincipalPrincipalA cash payment that represents a reduction of the principal in the security.
PutPutA feature of a bond that entitles the holder to elect to surrender the bond for cash during a predetermined time period, with a predetermined payable date.
RedemptionOfRightsRedemption of RightsAn event where the issuer pays proceeds to shareholders prior to acquiring or merging with an existing company.
RedemptionOfWarrantsRedemption of WarrantsAn event where the issuer pays proceeds to holders at or after the expiration date of the warrant rather than expire the warrant for no cash (worthless).
ReorganizationReorganizationA reorganization event announced by the issuer that cannot be classified as another event.
ReturnOfCapitalReturn of CapitalA distribution of cash resulting from the sale of a capital asset or securities, or any other transaction unrelated to retained earnings. Security holders may have to adjust the "cost basis" of their holding to account for the payment.
ReverseStockSplitReverse Stock SplitThe exchange of a company's security for the same company's new security at a preset rate. This corporate action reduces the number of shares outstanding.
RightsDistributionRights DistributionSecurities distributed to common stock holders of a company that grant the option to purchase new or additional securities of the same company during a predetermined time period at a predetermined price. A Rights Distribution is accompanied by a corresponding Rights Subscription, which provides the details related to exercising the rights. In some cases, DTC will allocate rights that are not issued by the company to process a subscription offer.
RightsSubscriptionRights SubscriptionA privilege granted to holders of rights to purchase new or additional securities. Rights are often tradable in a secondary market.
SaleOfRightsSale Of RightsA feature of a security that allows an issuer to make a payment to the security holder. This event will be used for securities subject to redemptions other than full and partial calls (e.g., early CD redemptions).
SecuritySeparationSecurity SeparationNo corresponding entry in the SR2026 data dictionary; description not published.
SpecialDividendSpecial DividendA cash payment to shareholders that represents an extra or non-regular payment. There are separate events for Cash Dividends, Dividends with Options, and Stock Dividends.
SpinOffSpin-OffA distribution of subsidiary securities to the shareholders of the parent company without a surrender of securities or payment. A spin-off represents a form of divestiture resulting in an independent company.
StockDividendStock DividendA dividend paid to shareholders in the form of shares of stock in either the issuing company or in another company. There are separate events for Cash Dividends, Dividends with Options, and Special Dividends.
StockSplitStock SplitThe increase in a company's number of outstanding shares of stock without any change in the shareholder's equity or the aggregate market value at the time of the split. The share price is normally reduced. Forward split events are included here.
TaxEventTax EventTax Event announcements are information only announcements regarding taxable events that may give rise to information and/or withholding obligations which occur even in the absence of an actual distribution of dividend and interest payments ("Tax Events").
TaxRefundTax RefundAn event that enables DTC to make a withholding tax refund, usually on non-U.S. dividends.
TenderOfferTender OfferAn offer made to security holders, normally by a third party, requesting them to sell (tender) their securities for a specified price (usually at a premium over prevailing market prices). Generally, the objective of a tender offer is to take control of the target company.
TerminationTerminationA security, usually a form of a derivative (e.g., ADR or UIT), for which the agent or issuer has decided to terminate the derivative based on a change to the underlying security(ies) or a change in strategy.
WarrantsExerciseWarrants ExerciseA feature of a security that permits the holder to exercise an option to exchange the security into another form (usually, warrants into shares). The exercise will commonly require a payment based upon a pre-determined value and time.
WorthlessWorthlessDTCC advising its participants that their positions in that security will be taken down. The announcement is created when DTC receives a formal letter advising that securities held are worthless.
BankruptcyBankruptcyBankruptcy (Vote) is a legal process for relieving debt that the borrower cannot repay. It's a measure of last resort that typically requires liquidating assets or entering a repayment plan. (Added 7/15/2026.)

Sub-Event Type Enumeration

Finer classification nested beneath an event type. Valid type / subType pairings are enumerated by GET /v2/corporate-actions/event-types; do not assume every subtype is valid for every type. Descriptions are sourced from the SR2026 Corporate Action Announcements Data Dictionary; some codes apply across multiple event types and are described generically.

Show all 52 sub-event types
ValueSub-Event NameDescription
None(Non-specific)Non-specific event with no sub-event classification.
DRIPDTCOnlyDRIP (DTC only)Identifies an event where the Issue is eligible for a Dividend Reinvestment program.
OptOutDTCOnlyOpt Out (DTC only)Identifies an event (e.g., Cash Dividend) where DTC offers a DRIP option as a default option (holder must opt out of the DRIP Option).
DomicileDomicileIdentifies an event where the Issuer has changed the domicile of the Corporation / a change in the place of incorporation of the legal entity of the issuing company.
DomicileNewCUSIPDomicile New CUSIPA domicile change accompanied by the assignment of a new CUSIP.
DomicilePresentationRequiredDomicile Presentation RequiredA domicile change for which presentation of securities is required.
DomicileNewCUSIPPresentationRequiredDomicile New CUSIP Presentation RequiredA domicile change with a new CUSIP for which presentation of securities is required.
WithPayoutWith PayoutIdentifies an event where a fee is paid to the registered holder. DTC will not be processing as information only event.
WithoutPayoutWithout PayoutIdentifies an event where no fee is paid. DTC will not be processing as information only event.
FinalPaymentFinal PaymentIdentifies an event that include notification of a final payment in lieu of the original commitment.
InterimPaymentInterim PaymentIdentifies an event that include notification of an interim payment in lieu of the original commitment.
TaxCreditTax CreditTax credit notification for informational purpose only. A tax credit will be generated in addition to a redemption and interest allocations. This tax credit can be a part of the debt instrument or can be stripped and traded separately. Commonly known in U.S. as Build America Bonds.
ConsentConsentIdentifies an event that includes a consent fee.
A144144aIdentifies an event where the security is a 144a private placement security.
CashAndSecuritiesCash and SecuritiesIdentifies an event with a combination of Cash and Securities as payout.
RegSReg SIdentifies an event where the security is a Regulation S type.
UnwindUnwindIdentifies an event where "unwinding" of the basket of securities occurs. Example: in order to participate in the tender offer of one of the underlying securities, holder must unwind the basket. DTC creates the event for the holder to respond - "unwind". Tender Offer itself would be a separate event. OR notification that UIT can be "unwinded" in IVORs (separate instruction system) with expiration dates supplied.
ConversionOngoingIdentifies an event with an expiration date stipulated in the security, or a security with an open-ended expiration date up to/near the maturity date for holders to convert the security. This expiration is usually a date far into the future.
ImportantNoticeImportant NoticeIdentifies an information only event of DTC Money Market Instrument (MMI) Important Notice announcements. Announcements are based on changes to the MMI security that are entered by the agent. Specific to MMI Important notices only.
DayExemptionQualifiedNoticeDay Exemption Qualified NoticeIdentifies a qualified notice issued by a publicly traded partnership stating applicability of the 10 percent exception under IRS regulation 1.1446(f)-4(b)(3).
BasedOnRecordDateHoldingsBased on Record Date HoldingsIdentifies an event processed as dividend event.
PresentationRequiredPresentation RequiredIdentifies an event processed as Reorg event and may include options.
RetainRetainIdentifies an event that include an option to retain the event securities rather than exchange them.
SecuritiesSecuritiesIdentifies an event where the payment will be made in the form of securities.
AnnualAnnualIdentifies an annual meeting event.
ExtraordinaryExtraordinaryIdentifies an extraordinary meeting event.
GeneralGeneral MeetingIdentifies a meeting event called by the company on behalf of security holders at which the company can present corporate resolutions that may require a vote by the holders.
SpecialSpecialIdentifies a special meeting event.
CashCashIdentifies an event with a payout of cash only.
CUSIPChangePresentationRequiredCUSIP Change Presentation RequiredIdentifies a CUSIP change for which presentation of securities is required.
NewCUSIPNew CUSIPIdentifies an event accompanied by the assignment of a new CUSIP.
VoteVoteIdentifies an event where a vote is sought.
MortgageBackedMortgage-BackedIndicates an event where the Issue has an early redemption feature that allows the holder to elect to sell bonds back to the issuer on a monthly basis, according to specified conditions.
SurvivorOptionsSurvivor OptionsIndicates an event where the Issue has an early redemption feature. This feature allows the holder to elect to sell bonds back to the issuer on a predetermined basis (excluding monthly) according to specific priorities.
SPACSPACIdentifies a Special Purpose Acquisition Company to raise money through an initial public offering (IPO) to acquire or merge with an existing company.
SaleOfAssetsSale of AssetsIdentifies an event where the distribution is from the proceeds of the sale of assets.
PhysicalRightsNotIssuedPhysical Rights not IssuedIdentifies an event where the company is not issuing a security with the right to subscribe for additional shares. In these instances, a User CUSIP is created by DTC (as opposed to a company-issued CUSIP) in order to identify these issues.
ADRADRIdentifies when the event security is an ADR, or a sale of rights where domicile restrictions require the ADR agent to sell rather than issue rights.
PoisonPillPoison PillIdentifies sale of rights event where issuers redeem poison pill rights.
CDeemedDividend305C - Deemed DividendDeemed distribution under Section 305(c) of the Internal Revenue Code.
DividendEquivalentPayment871MDividend Equivalent Payment under Section 871(m) of the Internal Revenue Code.
ExcessOfCumulativeNetIncomeECNIIdentifies when a publicly traded partnership identifies the amount realised on such portion of the distribution as an amount in excess of cumulative net income under IRS regulation 1.1446(f)-4(c)(2)(iii).
SClassifications1042RCLA (1042S Classifications)Identifies distributions that have multiple components for tax withholding and 1042-S reporting purposes.
BidTenderSealedTenderBid Tender/Sealed TenderIdentifies a tender offer event in which the holder can choose the price at which they are willing to tender their securities. This price may or may not be accepted by the offeror.
CashInLieuCash in LieuIdentifies DTC specific sub-event where holders can elect to "sell" whole shares to satisfy fractional entitlements (usually as a result of a merger) at the beneficial owner level.
ConvertAndTenderConvert and TenderIdentifies a tender offer event in which the holder must convert securities in order to take part in the event.
MiniTenderMini TenderIdentifies a tender offer event presented by a third party to shareholders of the target company, in which the conditions of the offer (e.g., quantity sought) are less than the requirements established by market regulators. As such, regulatory approval is not required.
OfferToPurchaseOffer to PurchaseIdentifies a tender offer event made by another company or the issuing company (buy back) to purchase a portion or all of the outstanding shares.
SelfTenderSelf TenderIdentifies a tender offer event made by the issuing company (buy back) to purchase a portion or all of the outstanding shares.
GDRGDRIdentifies when the event security is a GDR.
MeetingTypeMeeting TypeIdentifies the type classification for a meeting event.

Event Status Enumeration

ValueMeaning
ApprovedEvent is approved and final.
ConditionallyApprovedApproved subject to conditions.
IncompleteEvent data is not yet complete.
CancelledEvent was cancelled.
DeletedEvent was deleted.

DTC Mandatory

ValueMeaning
MandatoryParticipation is automatic; no election required.
MandatoryWithOptionsMandatory, but participants may choose from options.
VoluntaryParticipation requires explicit election by the holder.

Event Category

Value
InterestOnTreasury
MaturityOnTreasury
MandatoryCashDistribution
MandatorySecurityDistribution
MandatoryWithChoiceDistribution
MandatoryReorganization
VoluntaryReorganization
Meetings

Event Fields (orderBy)

Value
Id
EventId
EventType
Status
SecurityName
SecurityCusip
PositionCaptureDate
DeclaredPayableDate
EarliestDTCAnticipatedPaymentDate
EarliestDTCInstructionExpirationDate
UpdatedAt
DigitalAllocationDate

Sort Order

Value
Ascending
Descending

Core Dates by Event Category

CategoryRelevant Core Dates
InterestOnTreasurydeclaredPayableDate, allocationDateTime
MaturityOnTreasurydeclaredPayableDate, allocationDateTime
MandatoryCashDistributionexDate, recordDate, dtcPositionCaptureDate or captureDate, declaredPayableDate, anticipateDate, allocationDateTime
MandatorySecurityDistributionexDate, recordDate, positionCaptureDate, allocationDateTime
MandatoryWithChoiceDistributionexDate, recordDate, positionCaptureDate, instructionExpiration, allocationDateTime
MandatoryReorganizationeffectiveDateCompany, positionCaptureDate, allocationDateTime, reconversionDate
VoluntaryReorganizationdtcInstructionExpirationDateTime, positionCaptureDate, allocationDateTime
MeetingsmeetingDate

DTC Mandatory Classification

ValueMeaning
MandatoryParticipation is automatic; no election required.
MandatoryWithOptionMandatory but participants may choose from options.
VoluntaryParticipation requires explicit election by the holder.
Retry and dependencies: The event list is a read-only POST /v2/corporate-actions query, while the event type, securities, and event-detail calls are read-only GET requests. All are side-effect free and can be retried on network or service failures. The DTCC APIs provides event listing, taxonomy, securities reference data, and event details.
Certification

Corporate Actions Workflow Certification Test

CERT
Corporate Actions Workflow Certification Test
Certification · v1 · Load Events → Load Types + Securities → Inspect → Apply Context
›

This certification verifies both API connectivity and the customer's ability to correctly interpret corporate action event data.

Certification Workflow

Authenticate, load events, load event types and securities in parallel, inspect the event, then apply context.

Authenticate

Obtain a JWT access credential using SA-CorporateActionsBot.

Load Events

POST /v2/corporate-actions

Load Types + Securities

event-types plus securities in parallel.

Inspect Event

GET /v2/corporate-actions/{id}

Apply Context

Status, category, DTC classification, and core dates.

Single endpoint detail: All event detail information is retrieved from GET /v2/corporate-actions/{id}. No additional entitlement endpoint is required.
AuthenticationParallel LoadingEvent FiltersEvent Detail

Key Business Rules

RuleRequirement
Parallel LoadingRetrieve events, event types, and securities concurrently.
Supported StatusesApproved, ConditionallyApproved, Incomplete, Cancelled, Deleted.
Detail RetrievalAll detail information is retrieved from GET /v2/corporate-actions/{id}.
Context InterpretationCustomers must correctly apply status, category, DTC mandatory classification, support indicator, and core dates.

Prerequisites

Tenant ID, service account, service account password, base URL, a known corporate action event, and securities access. Required endpoints: /connect/token, POST /v2/corporate-actions, /v2/corporate-actions/event-types, /v1/conversion/securities, /v2/corporate-actions/{id}.

Test Data

typescript
const tenantId = "<tenant-id>";
const baseUrl = "<base-url>";
const username = "SA-CorporateActionsBot";
const password = process.env.SERVICE_ACCOUNT_PASSWORD!;

Shared Helper Functions

typescript
async function loadCorporateActionsData(accessToken: string) {
  const [eventsResponse, eventTypesResponse, securitiesResponse] = await Promise.all([
    fetch(`${baseUrl}/v2/corporate-actions`, {
      method: "POST",
      headers: { Authorization: `Bearer ${accessToken}`, "Content-Type": "application/json" },
      body: JSON.stringify({ offset: 0, count: 25 })
    }),
    fetch(`${baseUrl}/v2/corporate-actions/event-types`, { headers: { Authorization: `Bearer ${accessToken}` } }),
    fetch(`${baseUrl}/v1/conversion/securities`, { headers: { Authorization: `Bearer ${accessToken}` } })
  ]);
  return {
    events: await eventsResponse.json(),
    eventTypes: await eventTypesResponse.json(),
    securities: await securitiesResponse.json()
  };
}

async function getEventDetail(accessToken: string, eventId: string) {
  const response = await fetch(`${baseUrl}/v2/corporate-actions/${eventId}`, {
    headers: { Authorization: `Bearer ${accessToken}` }
  });
  if (!response.ok) {
    const error = await response.json();
    throw new Error(`Event detail failed: ${error.ErrorCode} - ${error.ErrorMessage}`);
  }
  return response.json();
}

POST
Step 1 — Authentication
${baseUrl}/connect/token
›

Goal

This step validates that the integration can obtain a JWT access credential from the Identity Server using service account credentials. The JWT access credential proves the caller's identity and must be supplied as a bearer credential on every subsequent API call in this workflow.

Expected Result

HTTP 200; JWT access credential returned; credential accepted by downstream APIs.

Common Error Types

HTTPConditionExpected integration behavior
400Invalid credentialsSurface authentication rejected. Do not retry with the same credentials.
500, 503Identity Server failureRetry with exponential backoff, maximum three attempts.

POST
Step 2 — Load Corporate Action Events
${baseUrl}/v2/corporate-actions
›

Goal

Verify the integration can retrieve a paginated corporate action event inventory with statuses and event identifiers populated.

Procedure

typescript
const data = await loadCorporateActionsData(accessToken);

Validation

Events returned; pagination supported; statuses populated; event identifiers returned.

Expected Result

HTTP 200; corporate action inventory loaded successfully.

Common Error Types

HTTPConditionExpected integration behavior
400Invalid filter parametersCorrect the request. Do not retry as-is.
401Expired or invalid JWT access credentialRe-authenticate, then retry once.
403Missing permissionSurface access denied. Do not retry.
500, 503Service failureRetry with exponential backoff, maximum three attempts.

GET
Step 3 — Load Event Type Taxonomy
${baseUrl}/v2/corporate-actions/event-types
›

Goal

Verify the integration can retrieve the event type and sub-event type taxonomy used for hierarchical event filtering.

Validation

Event types returned; sub-event types returned; hierarchy available.

Expected Result

HTTP 200; event taxonomy successfully loaded.

Common Error Types

HTTPConditionExpected integration behavior
401Expired or invalid JWT access credentialRe-authenticate, then retry once.
500, 503Event-type service unavailableFilter data unavailable; display a meaningful error and keep the workflow stable.

GET
Step 4 — Load Securities Filter Data
${baseUrl}/v1/conversion/securities
›

Goal

Verify the integration can retrieve securities reference data, including CUSIPs and support flags, for filtering corporate action events.

Validation

Security identifiers returned; CUSIPs returned; support flags returned.

Expected Result

HTTP 200; security filtering possible.

Common Error Types

HTTPConditionExpected integration behavior
401Expired or invalid JWT access credentialRe-authenticate, then retry once.
500, 503Securities service unavailableSecurity filter unavailable; display a meaningful error and keep the workflow stable.

GET
Step 5 — Event Filtering
filter by status, type, sub-type, security, and search text
›

Goal

Verify the integration can narrow the event inventory to a relevant subset using status, event type, sub-event type, security, and search text.

Procedure

typescript
const approvedEvents = events.filter(
  event => event.status === "Approved"
);

Validation

Successful filtering by status, event type, sub-event type, security, and search text.

Expected Result

Relevant events identified.

Common Error Types

HTTPConditionExpected integration behavior
400Invalid filter parametersValidation error. Correct the filter values before retrying.

GET
Step 6 — Retrieve Event Detail
${baseUrl}/v2/corporate-actions/{id}
›

Goal

Verify the integration can retrieve full event detail from the single detail endpoint, including security, category, status, classification, and core dates.

Procedure

typescript
const detail = await getEventDetail(accessToken, eventId);

Validation

Security returned; category returned; status returned; DTC classification returned; core dates returned.

Expected Result

HTTP 200; event detail successfully retrieved.

Common Error Types

HTTPConditionExpected integration behavior
400Invalid event identifier formatCorrect the request. Do not retry as-is.
404Invalid event ID; event not foundSurface event not found. Do not retry.
500, 503Event detail service failureInvoke retry logic with exponential backoff and handle the failure gracefully.

GET
Step 7 — Apply Event Context
interpret category, status, support flag, and DTC classification
›

Goal

Verify the integration derives correct business context from the returned category, status, support indicator, and DTC classification.

Procedure

typescript
if (detail.dtcMandatory === "Voluntary") {
  console.log("Election Required");
}

Validation

Interpret category, status, support flag, and DTC classification.

Expected Result

Business context successfully derived.

Common Error Types

This step performs no API calls. If a required context field is absent from the event detail response, treat the step as failed rather than applying a default classification.


GET
Step 8 — Category-Specific Date Interpretation
identify relevant dates by category
›

Goal

Verify the integration identifies the correct set of lifecycle dates for each corporate action category it processes.

Required Dates by Category

CategoryRequired Dates
InterestOnTreasurydeclaredPayableDate, allocationDateTime
MaturityOnTreasurydeclaredPayableDate, allocationDateTime
MandatoryCashDistributionexDate, recordDate, captureDate, declaredPayableDate, anticipateDate, allocationDateTime
MeetingsmeetingDate

Validation

Correctly identify the relevant dates for at least one event available in each category.

Expected Result

The correct set of lifecycle dates is identified for each category present in the test dataset.

Common Error Types

This step performs no API calls. If a required date is null for a category that mandates it, surface the gap rather than substituting a placeholder date.


GET
Step 9 — DTC Classification Interpretation
classify events by returned values
›

Goal

Verify the integration correctly classifies each event as Mandatory, MandatoryWithOption, or Voluntary and acts on whether an election is required.

Classification Values

ValueMeaning
MandatoryParticipation automatic.
MandatoryWithOptionOptions available to holder.
VoluntaryElection required.

Validation

The customer correctly classifies events using the returned values.

Expected Result

Each event is classified as Mandatory, MandatoryWithOption, or Voluntary, and election requirements are applied accordingly.

Common Error Types

This step performs no API calls. An unrecognized dtcMandatory value must be surfaced as an unhandled classification rather than defaulted to Mandatory.


E2E
Step 10 — End-to-End Workflow Execution
executeWorkflow()
›

Goal

Execute the complete corporate actions workflow in a single run to confirm every stage succeeds in sequence.

Procedure

typescript
async function executeWorkflow() {
  const token = await authenticate();
  const { events, eventTypes, securities } = await loadCorporateActionsData(token);
  const selectedEvent = events[0];
  const detail = await getEventDetail(token, selectedEvent.id);
  return { events, eventTypes, securities, detail };
}

Expected Result

log
Authentication    PASS
Load Events       PASS
Load Event Types  PASS
Load Securities   PASS
Filter Events     PASS
Retrieve Detail   PASS
Apply Context     PASS
Workflow Complete PASS

Each constituent call returns its expected success code.

Negative Test Cases

IDScenarioHTTPExpected result
NT-1Invalid Credentials400Authentication rejected.
NT-2Expired Credential401Re-authentication required.
NT-3Invalid Event ID404Event not found.
NT-4Missing Permission403Access denied.
NT-5Invalid Filter Parameters400Validation error.
NT-6Event-Type Service Unavailable500, 503Filter data unavailable; meaningful error displayed; workflow remains stable.
NT-7Securities Service Unavailable500, 503Security filter unavailable; meaningful error displayed; workflow remains stable.
NT-8Event Detail Service Failure500, 503Retry logic invoked; graceful failure handling.

Production Certification Criteria

The customer must demonstrate authentication, event retrieval, event-type retrieval, securities retrieval, event filtering, event-detail retrieval, context interpretation, category-date interpretation, DTC classification interpretation, negative-test handling, and end-to-end workflow execution.

Release History
Site Changelog

This tab records every change applied to this reference guide. Each version card carries the date the change was applied, and lists the changes grouped by the tab or section of the site affected.

RELEASE
Version 1.95
September 30, 2026
›

Authentication and Authorization

  • Standardized every documented workflow on the Service Account Credentials grant and removed all references to the OAuth 2.0 Client Credentials grant from the live guide. All token requests now use grant_type=urn:dtcc:params:oauth:grant-type:service-account-credentials, type=conveyance, entity context, and acr_values=tenant:{tenantId}.
  • Removed the Authentication panel exception callout that described Conversion Order endpoints using the Client Credentials grant, and simplified the Required Token Inputs note for username / password to state that service-account credentials are always used.
  • Added a Sample Token Request code example to the Authentication panel (opened from the Authentication hero button), showing a runnable authenticate() call against /connect/token using the Service Account Credentials grant, consistent with the certification helpers.

Account Management

  • Converted the Get Account Balances endpoint Permissions & Scopes from the OAuth 2.0 Client Credentials grant to the Service Account Credentials grant.
  • Reworked the Account Management Certification Test so all five steps use a single service-account credential: updated the workflow intro and the balances branch note, removed the clientId / clientSecret / scope test data, rewrote Step 5 to reuse the Step 1 token via getBalances(accessToken, accountId), reworded the Step 5 error envelopes and negative tests (NT-1, NT-6, NT-7) away from client-credential terminology, and changed the production criteria from "invalid scope" to "insufficient permission".

Conversion Orders

  • Converted the Conversion Orders authentication pattern callout from the OAuth 2.0 Client Credentials grant to the Service Account Credentials grant.
  • Reworked the Conversion Order Certification Tests to authenticate with the service-account grant: updated the certification intro, the Step 1 workflow-diagram label, and the flow-key chip; replaced the clientId / clientSecret / CONVERSION_SCOPE test data with tenantId / username / password; rewrote the authenticate() helper to use the service-account grant; and reworded Step 1, Step 2, Step 5, and negative test NT-1 away from client-credential terminology.
  • Added the status input query filter to the List Registered Securities and Filter Data card. Documented it in the Request Parameters table as an optional single-value filter accepting one FinancialSecurityStatus value (Onboarding, Active, Pause, Failed), and added a matching Input (query) row to the GET /v1/conversion/securities Enumerations table.
  • Aligned the Conversion Order Certification Tests authenticate() helper with the Account and Wallet certification helpers so it returns data.access_token directly rather than the full token object, and simplified the Step 1 call site to const accessToken = await authenticate();.

Document

  • Published as version 4.18. Prior changelog entries that reference the OAuth 2.0 Client Credentials grant are retained as historical record.
RELEASE
Version 1.94a
September 29, 2026
›

Corporate Actions

  • Consolidated the corporate action enumerations into a single Corporate Action Enumerations reference block at the end of the section. The event-list, event-types, and event-detail Enumerations tables no longer repeat the full value lists; each row now links to the shared reference.
  • Presented EventTypeEnumeration and SubEventTypeEnumeration as value / description tables, collapsed behind a show-all disclosure. Numeric codes are not published in the reference because the OpenAPI enums are declared as plain string enums; the authoritative code mapping is whatever GET /v2/corporate-actions/event-types returns at runtime.
  • Defined the smaller shared enumerations (EventStatusEnumeration, DtcMandatory, EventCategory, EventFields, SortOrder) once in the same reference and linked to them from the endpoint tables.
  • Added a note that valid type / subType pairings are enumerated by GET /v2/corporate-actions/event-types.
RELEASE
Version 1.94
September 29, 2026
›

Corporate Actions

  • Migrated the corporate action events list from the deprecated GET /v1/corporate-actions to POST /v2/corporate-actions. The filter and pagination fields are now supplied in a JSON request body (EventFilterRequest) rather than query-string parameters.
  • Aligned the Request Parameters with the V2 EventFilterRequest schema: offset and count are required; ids filters by internal (GUID) event identifiers and eventIds by external DTC event identifiers; eventTypes is an array of EventTypeFilterItem objects (each with a type and optional subType); added securityIds and securityCusips; retained status, searchFor, orderBy, and sortOrder as body fields.
  • Updated the List Corporate Action Events and Reference Data card: changed the method badge to POST, updated the path header, added an endpoint-migration callout, moved all filter fields to the request body, relabeled the Enumerations table to POST /v2/corporate-actions with Input (body) directions (including the EventFields values for orderBy and the nested eventTypes[].type / eventTypes[].subType filter), and rewrote the sample request to issue a POST with a JSON body.
  • Corrected the response template and TypeScript interface to the V2 CorporateActionEventResponse schema, using type, typeDescription, subType, subTypeDescription, the DTC date fields, dtcProcessingIndicator, and the SecurityListResponse security shape.
  • Updated the Corporate Actions workflow summary, the "Retry and dependencies" callout, and the per-card retry guidance to reflect that the events list is now a read-only POST query while the event-types and securities calls remain GET requests.
  • Updated the Corporate Actions Workflow Certification Test: the workflow diagram, prerequisites, shared loadCorporateActionsData helper, and Step 2 now call POST /v2/corporate-actions with a JSON body.

Overview

  • Updated the Primary API Journeys table Corporate Actions row to reference /v2/corporate-actions in place of /v1/corporate-actions.

Reference

  • Updated the API Families modal Corporate Action APIs box and the Endpoint Catalog to list POST /v2/corporate-actions in place of the deprecated GET /v1/corporate-actions.
  • Updated the Pagination Model Endpoint Support table to show POST /v2/corporate-actions, noting that Offset and Count are sent in the request body rather than the query string.
RELEASE
Version 1.93
September 29, 2026
›

Conversion Orders

  • Documented batch behavior for the idempotencyKeys array on POST /v1/conversion/async-operations/query. Clarified that the server processes all keys supplied in a single query, and established a best practice of submitting no more than 100 keys per request to avoid the performance impact of very large arrays.
  • Added a Batch Query Behavior section covering unmatched keys (no error is returned and only matched records appear in the response), pagination of results via Count and Offset, and the recommended batch size.
RELEASE
Version 1.92
September 29, 2026
›

Conversion Orders

  • Documented the fromTransactionId and toTransactionId fields on the Submit and Track Conversion Orders card. Added a Transaction Identifiers section defining each field as the on-chain ledger transaction hash for the source (debit) and destination (credit) legs, noting they are null while an order is Processing and populated once the order reaches Completed.
  • Recorded that these identifiers appear only on the order detail endpoint GET /v1/conversion/orders/{orderId} and not on the orders list endpoint.
  • Explained the direction dependency, that only the digital-wallet leg maps to a blockchain transaction while the DTC Classic leg does not, and the relationship to external custody or validator providers such as Fireblocks, which report the same underlying on-chain hash.
  • Updated the order detail response template to show a Completed order with populated fromTransactionId and toTransactionId hashes.
RELEASE
Version 1.91
September 29, 2026
›

Account Management

  • Replaced the plain-text Activity Types list on the Get Account Activities endpoint with a Value and Description table defining each activity type, and stated that the definitions apply to both the activityType input filter and the output values.
  • Added an activityType row (ActivityType enumeration) to the Get Account Activities Enumerations table, covering Payment, PaymentReceived, Fee, Mint, Burn, Pause, Unpause, Freeze, Unfreeze, Revoked, Clawedback, and Clawback.

Conversion Orders

  • Moved the ConversionOperationsEngine__WalletNotFound error code from the HTTP 404 table to the HTTP 400 table in the Error Code Reference.
RELEASE
Version 1.9
September 28, 2026
›

Overview

  • Removed the /v1/tracking/networks endpoint from the Primary API Journeys table for the Wallet Management and Conversion Orders rows.

Wallet Management

  • Removed the /v1/tracking/networks ledger-networks endpoint. Renamed the combined "Load Ledger and Account Reference Data" endpoint to "Load Account Reference Data", now covering only /v1/conversion/clients, and updated the workflow summary and certification test (flow, prerequisites, helper functions, steps, and end-to-end execution) to load account reference data only.

Conversion Orders

  • Removed /v1/tracking/networks from the List Registered Securities and Filter Data endpoint, its workflow summary, enumerations, sample request, and certification filter-data helper. The network query filter on the securities list is retained.

Reference

  • Removed /v1/tracking/networks from the API Families modal and the Endpoint Catalog.
RELEASE
Version 1.8
September 28, 2026
›

Conversion Orders

  • Expanded the Common Error Types section on the Submit and Track Conversion Orders endpoint. Split the combined 500/503 row into separate 500 and 503 rows and added cross-references from the 400, 404, 409, and 500 rows to the new detail tables.
  • Added an Error Code Reference subsection listing the machine-readable errorCode values, causes, and corrections for HTTP 400, 404, 409, and 500.
RELEASE
Version 1.7
September 25, 2026
›

Conversion Orders

  • Added a Status and Restrictions Are Separate Signals section to the List Registered Securities and Filter Data card, explaining that all eligible securities carry an Active status but may still have a chill or lock in effect, that a chill or lock is a transfer restriction applied to the entire security, and how to read the restrictions object to detect it.
  • Documented the three restriction types, dOChill, globalLock, and complianceLock, each reported with an enabled flag and an updatedAt timestamp, and noted that the enabled flag should always be tested rather than checking whether a field exists.
  • Added the restrictions block to the securities response template and the SecurityRestrictions and RestrictionState types to the TypeScript interface.
  • Extended the eligibility rules on the Load Active Securities and Registered Wallets card to state that an Active status is necessary but not sufficient, and that an Active security must be confirmed unrestricted before it is treated as usable.
RELEASE
Version 1.6
September 22, 2026
›

Account Management

  • Replaced the string UUID type with string on the account hierarchy summary and account activities parameter tables.

Conversion Orders

  • Replaced the string UUID type with string on the Submit and Track Conversion Orders parameter table.

Corporate Actions

  • Added an introductory paragraph noting that the corporate action notification API endpoints leverage DTCC's ISO CANO messages, with a link to DTCC's ISO 20022 Messaging Specifications.

Onboarding

  • Removed the workflow summary description sentence and the Entity Creation, Account Provisioning, Service Accounts, and Production Activation labels from the workflow summary.
RELEASE
Version 1.5
September 17, 2026
›

Wallet Management

  • Corrected the ledgers endpoint path from /v1/networks/ledgers to /v1/tracking/networks to match the API specification.
  • Updated the response template and TypeScript interface to the flat network model with name, displayName, networkStatus, nodeFormats, and listenerEnabled, and fixed the sample request filter accordingly.
  • Renamed the response enumeration field from status to networkStatus and removed the nodeStatus / NetworkNodeStatus row, which the specification does not define.

Pagination Model

  • Expanded the Endpoint Support table to list every endpoint in the endpoint catalog, added a Method column, and recorded pagination support for each based on the API specifications.
RELEASE
Version 1.4
September 16, 2026
›

Conversion Orders

  • Replaced the certification section with twelve steps drawn from the Conversion Order Lifecycle Workflow Certification Test v2, covering authentication, reference data retrieval, security validation, wallet validation, order submission, idempotency, async operation tracking, async-to-order correlation, final order retrieval, lifecycle validation, audit validation, and end-to-end execution. Renamed the card to Conversion Order Certification Tests.
  • Excluded Test 11 Maker-Checker Validation, and removed maker and checker references from the order detail validation model, the end-to-end checklist, and the workflow diagram so nothing points at an excluded test.
  • Removed Declined from the lifecycle states, leaving Processing, Completed, and Failed.
  • Switched the authentication pattern to the OAuth 2.0 Client Credentials grant and recorded the departure from the Service Account Credentials grant used by the other API families.
  • Added queryOperation and getOrder helper functions, which the source document referenced without defining, and changed the correlation step to query by idempotency key rather than by an operation identifier the workflow never produces.
  • Kept the four-call filter loader as loadFilterData and extended Step 2 to call it, so the issue type, issue sub-type, and ledger endpoints remain within the certification.
  • Replaced the negative test cases with eight scenarios, assigning HTTP codes only where the guide already documents them and leaving the async processing failure without one because a Failed async status is not an HTTP condition.
  • Renamed the pagination parameters to Offset and Count on the orders list, the securities list, the wallets list, and the async operation query.

Account Management

  • Renamed the wallet type field to type on the account balances card.
  • Left limit and offset unchanged on the account hierarchy summary and account activities cards.

Wallet Management

  • Renamed the wallet fields to type and state, matching the API integration guide, and removed the note that recorded the earlier naming discrepancy.
  • Renamed the pagination parameters to Offset and Count.

Corporate Actions

  • Left offset and count unchanged.

All Endpoint Tabs

  • Added a case-sensitivity callout to all ten Enumerations sections stating that enumeration values must be provided exactly as defined.
  • Removed Deleting from the ProcessingStates values in all five places it appeared, covering both wallet and security rows so the enumeration keeps a single definition.
  • Renamed the idempotency header to X-Idempotency-Key throughout.
  • Replaced the remaining COE_SCOPE environment variable reference with API_SCOPE.

Authentication and Authorization

  • Added an exception recording that Conversion Order endpoints use the OAuth 2.0 Client Credentials grant rather than the Service Account Credentials grant described in the panel.

Pagination Model

  • Added a Pagination Model hero button and modal panel documenting offset-based pagination, the Offset and Count query parameters, the X-Paging response headers, endpoint support, and iteration guidance.
  • Recorded that the async operation query accepts Offset and Count in the request body rather than the query string, an exception to the model's general rule.
RELEASE
Version 1.3
September 15, 2026
›

Conversion Orders

  • Documented the asynchronous submission contract. POST /v1/conversion/orders returns 202 Accepted with no response body, so the order identifier is resolved by polling the async operation with the idempotency key retained at submission.
  • Added three endpoints: GET /v1/conversion/orders, POST /v1/conversion/async-operations/query, and GET /v1/conversion/orders/{orderId}.
  • Renamed the Submit Conversion Order card to Submit and Track Conversion Orders, and gave each of its four endpoints its own labeled Request Parameters table and Enumerations table.
  • Removed the response enumerations from the submission endpoint, which described fields a 202 response does not return. Relocated asyncOperationStatus, objectKind, and operationName to the async operation query, and orderBy to the orders list.
  • Added the OrderOrigin enumeration with values Participant, Admin, and ForcedReconversion.
  • Extended wallet eligibility to require conversionEligible true in addition to an Idle processing state, applied across the eligibility rules, the workflow summary, the key business rules, and the production certification criteria.
  • Expanded the workflow summary from six steps to eight, adding the async operation poll and the order detail retrieval.
  • Documented querying the orders list before submission to detect whether a prior submission with the same intent already exists.
  • Reduced the certification test to Step 1 Eligibility Validation and Step 2 Lifecycle Validation, renumbered from the former Steps 4 and 6. Step 2 was rewritten for the asynchronous contract, resolving resourceId before retrieving the order. Remaining certification steps are being regenerated.

Account Management

  • Added Failed to the FinancialSecurityStatus values published on the account balances card.

Wallet Management

  • Added FailedCompliance and Failed to the ProcessingStates values.
  • Recorded that the COE integration guide publishes the wallet type and processing state fields as type and state, while the guide follows the enumeration reference document naming.

Corporate Actions

  • Carried the FinancialSecurityStatus and ProcessingStates value additions into the securities reference enumerations on the events card.

Overview

  • Extended the Conversion Orders journey row with the async operation query and order detail endpoints.

API Families

  • Added the async operation query and order detail endpoints to the Conversion Orders APIs box.

Workflow Patterns

  • Added the async operation poll and order detail retrieval steps to the Conversion Orders pattern.

Endpoint Catalog

  • Added rows for the three new conversion endpoints and noted that submission returns 202 Accepted with no response body.
RELEASE
Version 1.2
September 9, 2026
›

Account Management

  • Rebuilt the Enumerations tables on the account hierarchy summary, account activities, and account balances cards to the four-column shape used in the enumeration reference document, with Direction as the leading column and a method and path label above each table.

Wallet Management

  • Rebuilt the registered wallets Enumerations table to the four-column shape with Direction leading.
  • Split the ledger and account reference data Enumerations table into separate labeled tables for /v1/tracking/networks and /v1/conversion/clients.

Conversion Orders

  • Split the registered securities and filter data Enumerations table into four labeled tables, one per endpoint.
  • Split the active securities and registered wallets Enumerations table into two labeled tables, one per endpoint.
  • Rebuilt the Submit Conversion Order Enumerations table to the four-column shape with Direction leading.

Corporate Actions

  • Split the events and reference data Enumerations table into three labeled tables, one per endpoint.
  • Rebuilt the event detail Enumerations table to the four-column shape with Direction leading.
RELEASE
Version 1.1
September 9, 2026
›

Conversion Orders

  • Removed the PendingApproval status from the conversion order lifecycle. Orders are processed straight through from Processing to Completed, with Failed retained as the terminal failure state.
  • Removed Declined from the OrderStatus enumeration along with the approval decision it recorded.
  • Removed maker-checker approval references from the category lead, the workflow summary, the order submission rule, and the Conversion Orders certification test.
  • Added a pre-submission recommendation to the Submit Conversion Order card advising retrieval and verification of the wallet and securities before an order is submitted.
  • Expanded the category lead to describe conversions between electronic book entry and digital tokenized forms, and to state that the process is identical in both directions with only the source and destination assignments differing.
  • Added Enumerations tables to the registered securities and filter data card, the active securities and registered wallets card, and the Submit Conversion Order card.

Account Management

  • Expanded the category lead to describe how accounts organize wallets, and to document the Internal and Clients accounts configured by default.
  • Added Enumerations tables to the account hierarchy summary card, the account activities card, and the account balances card.

Wallet Management

  • Added Enumerations tables to the registered wallets card and the ledger and account reference data card.

Corporate Actions

  • Added Enumerations tables to the events and reference data card and the event detail card, covering the full event type and sub-event type taxonomies, event status, DTC mandatory classification, event category, and position processing status values.

Overview

  • Replaced the maker-checker lifecycle reference in the Conversion Orders domain card with order lifecycle tracking.

API Families

  • Split the first four conversion endpoints out of the Conversion Orders APIs box into a dedicated Eligible Securities APIs box.

Workflow Patterns

  • Replaced the Maker-checker lifecycle step in the Conversion Orders workflow pattern with Track lifecycle.

Changelog

  • Added this tab to record changes applied to the guide.