From e433f00defdd3fb0e50e589ce2bae1e9151ed502 Mon Sep 17 00:00:00 2001 From: shreyav Date: Thu, 13 Aug 2026 21:14:44 +0000 Subject: [PATCH 1/2] feat: add custody type and VASP link to external accounts --- .stainless/stainless.yml | 1 + mintlify/openapi.yaml | 21 +++++++++++++++++++ openapi.yaml | 21 +++++++++++++++++++ .../components/schemas/errors/Error400.yaml | 2 ++ .../external_accounts/CustodyType.yaml | 12 +++++++++++ .../external_accounts/ExternalAccount.yaml | 8 +++++++ .../ExternalAccountCreateRequest.yaml | 9 ++++++++ 7 files changed, 74 insertions(+) create mode 100644 openapi/components/schemas/external_accounts/CustodyType.yaml diff --git a/.stainless/stainless.yml b/.stainless/stainless.yml index 49100e04..d5e8591e 100644 --- a/.stainless/stainless.yml +++ b/.stainless/stainless.yml @@ -209,6 +209,7 @@ resources: external_account: '#/components/schemas/ExternalAccount' external_account_create: '#/components/schemas/ExternalAccountCreateRequest' external_account_info_one_of: "#/components/schemas/ExternalAccountInfoOneOf" + custody_type: "#/components/schemas/CustodyType" business_beneficiary: "#/components/schemas/BusinessBeneficiary" address: "#/components/schemas/Address" beneficiary_verified_data: "#/components/schemas/BeneficiaryVerifiedData" diff --git a/mintlify/openapi.yaml b/mintlify/openapi.yaml index 6e4523f1..80a9de2c 100644 --- a/mintlify/openapi.yaml +++ b/mintlify/openapi.yaml @@ -11835,6 +11835,7 @@ components: | STABLECOIN_PROVIDER_ACCOUNT_SELECTION_REQUIRED | Multiple active provider account links exist; pass `stablecoinProviderAccountId` to select one | | CARDHOLDER_KYC_NOT_APPROVED | The cardholder's KYC status is not `APPROVED`, so a card cannot be issued | | TRANSACTION_SIZE_LIMIT_EXCEEDED | The requested amount exceeds the configured maximum single-transaction amount for this trade corridor or withdrawal currency | + | COUNTERPARTY_USER_INFO_REQUIRED | The destination account needs beneficiary information before this transfer can proceed; update the external account with a `beneficiary` and retry | enum: - INVALID_INPUT - END_USER_TERMS_VERSION_NOT_FOUND @@ -11878,6 +11879,7 @@ components: - STABLECOIN_PROVIDER_ACCOUNT_SELECTION_REQUIRED - CARDHOLDER_KYC_NOT_APPROVED - TRANSACTION_SIZE_LIMIT_EXCEEDED + - COUNTERPARTY_USER_INFO_REQUIRED message: type: string description: Error message @@ -16858,6 +16860,13 @@ components: - THIRD_PARTY description: Whether the external account belongs to the customer themselves (first party) or to someone else (third party) example: FIRST_PARTY + CustodyType: + type: string + enum: + - SELF_CUSTODY + - VASP_HOSTED + description: 'How a crypto wallet external account is custodied: `SELF_CUSTODY` for a wallet whose keys the owner controls directly, or `VASP_HOSTED` for an account held at a Virtual Asset Service Provider (an exchange or other custodial platform). Only relevant for crypto wallet accounts; defaults to `SELF_CUSTODY`. Ownership verification applies only to `SELF_CUSTODY` wallets — `VASP_HOSTED` accounts never require it.' + example: SELF_CUSTODY BeneficiaryVerificationStatus: type: string enum: @@ -19230,6 +19239,12 @@ components: example: acc_123456789 ownershipType: $ref: '#/components/schemas/OwnershipType' + custodyType: + $ref: '#/components/schemas/CustodyType' + vaspId: + type: string + description: The VASP that custodies this account, from the VASP directory (`GET /vasps`). Only present when `custodyType` is `VASP_HOSTED`. + example: Vasp:019542f5-b3e7-1d02-0000-000000000001 currency: type: string description: The ISO 4217 currency code @@ -20144,6 +20159,12 @@ components: example: ext_acc_123456 ownershipType: $ref: '#/components/schemas/OwnershipType' + custodyType: + $ref: '#/components/schemas/CustodyType' + vaspId: + type: string + description: The VASP that custodies this account, from the VASP directory (`GET /vasps`). Required when `custodyType` is `VASP_HOSTED`; must be omitted otherwise. + example: Vasp:019542f5-b3e7-1d02-0000-000000000001 defaultUmaDepositAccount: type: boolean description: Whether to set the external account as the default UMA deposit account. When set to true, incoming payments to this customer's UMA address will be automatically deposited into this external account. False if not provided. Note that only one external account can be set as the default UMA deposit account for a customer, so if there is already a default UMA deposit account, this will override the existing default UMA deposit account. If there is no default UMA deposit account, incoming UMA payments will be deposited into the primary internal account for the customer. diff --git a/openapi.yaml b/openapi.yaml index 6e4523f1..80a9de2c 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -11835,6 +11835,7 @@ components: | STABLECOIN_PROVIDER_ACCOUNT_SELECTION_REQUIRED | Multiple active provider account links exist; pass `stablecoinProviderAccountId` to select one | | CARDHOLDER_KYC_NOT_APPROVED | The cardholder's KYC status is not `APPROVED`, so a card cannot be issued | | TRANSACTION_SIZE_LIMIT_EXCEEDED | The requested amount exceeds the configured maximum single-transaction amount for this trade corridor or withdrawal currency | + | COUNTERPARTY_USER_INFO_REQUIRED | The destination account needs beneficiary information before this transfer can proceed; update the external account with a `beneficiary` and retry | enum: - INVALID_INPUT - END_USER_TERMS_VERSION_NOT_FOUND @@ -11878,6 +11879,7 @@ components: - STABLECOIN_PROVIDER_ACCOUNT_SELECTION_REQUIRED - CARDHOLDER_KYC_NOT_APPROVED - TRANSACTION_SIZE_LIMIT_EXCEEDED + - COUNTERPARTY_USER_INFO_REQUIRED message: type: string description: Error message @@ -16858,6 +16860,13 @@ components: - THIRD_PARTY description: Whether the external account belongs to the customer themselves (first party) or to someone else (third party) example: FIRST_PARTY + CustodyType: + type: string + enum: + - SELF_CUSTODY + - VASP_HOSTED + description: 'How a crypto wallet external account is custodied: `SELF_CUSTODY` for a wallet whose keys the owner controls directly, or `VASP_HOSTED` for an account held at a Virtual Asset Service Provider (an exchange or other custodial platform). Only relevant for crypto wallet accounts; defaults to `SELF_CUSTODY`. Ownership verification applies only to `SELF_CUSTODY` wallets — `VASP_HOSTED` accounts never require it.' + example: SELF_CUSTODY BeneficiaryVerificationStatus: type: string enum: @@ -19230,6 +19239,12 @@ components: example: acc_123456789 ownershipType: $ref: '#/components/schemas/OwnershipType' + custodyType: + $ref: '#/components/schemas/CustodyType' + vaspId: + type: string + description: The VASP that custodies this account, from the VASP directory (`GET /vasps`). Only present when `custodyType` is `VASP_HOSTED`. + example: Vasp:019542f5-b3e7-1d02-0000-000000000001 currency: type: string description: The ISO 4217 currency code @@ -20144,6 +20159,12 @@ components: example: ext_acc_123456 ownershipType: $ref: '#/components/schemas/OwnershipType' + custodyType: + $ref: '#/components/schemas/CustodyType' + vaspId: + type: string + description: The VASP that custodies this account, from the VASP directory (`GET /vasps`). Required when `custodyType` is `VASP_HOSTED`; must be omitted otherwise. + example: Vasp:019542f5-b3e7-1d02-0000-000000000001 defaultUmaDepositAccount: type: boolean description: Whether to set the external account as the default UMA deposit account. When set to true, incoming payments to this customer's UMA address will be automatically deposited into this external account. False if not provided. Note that only one external account can be set as the default UMA deposit account for a customer, so if there is already a default UMA deposit account, this will override the existing default UMA deposit account. If there is no default UMA deposit account, incoming UMA payments will be deposited into the primary internal account for the customer. diff --git a/openapi/components/schemas/errors/Error400.yaml b/openapi/components/schemas/errors/Error400.yaml index bbb12f63..28edc6ec 100644 --- a/openapi/components/schemas/errors/Error400.yaml +++ b/openapi/components/schemas/errors/Error400.yaml @@ -56,6 +56,7 @@ properties: | STABLECOIN_PROVIDER_ACCOUNT_SELECTION_REQUIRED | Multiple active provider account links exist; pass `stablecoinProviderAccountId` to select one | | CARDHOLDER_KYC_NOT_APPROVED | The cardholder's KYC status is not `APPROVED`, so a card cannot be issued | | TRANSACTION_SIZE_LIMIT_EXCEEDED | The requested amount exceeds the configured maximum single-transaction amount for this trade corridor or withdrawal currency | + | COUNTERPARTY_USER_INFO_REQUIRED | The destination account needs beneficiary information before this transfer can proceed; update the external account with a `beneficiary` and retry | enum: - INVALID_INPUT - END_USER_TERMS_VERSION_NOT_FOUND @@ -99,6 +100,7 @@ properties: - STABLECOIN_PROVIDER_ACCOUNT_SELECTION_REQUIRED - CARDHOLDER_KYC_NOT_APPROVED - TRANSACTION_SIZE_LIMIT_EXCEEDED + - COUNTERPARTY_USER_INFO_REQUIRED message: type: string description: Error message diff --git a/openapi/components/schemas/external_accounts/CustodyType.yaml b/openapi/components/schemas/external_accounts/CustodyType.yaml new file mode 100644 index 00000000..8197cd50 --- /dev/null +++ b/openapi/components/schemas/external_accounts/CustodyType.yaml @@ -0,0 +1,12 @@ +type: string +enum: + - SELF_CUSTODY + - VASP_HOSTED +description: >- + How a crypto wallet external account is custodied: `SELF_CUSTODY` for a + wallet whose keys the owner controls directly, or `VASP_HOSTED` for an + account held at a Virtual Asset Service Provider (an exchange or other + custodial platform). Only relevant for crypto wallet accounts; defaults to + `SELF_CUSTODY`. Ownership verification applies only to `SELF_CUSTODY` + wallets — `VASP_HOSTED` accounts never require it. +example: SELF_CUSTODY diff --git a/openapi/components/schemas/external_accounts/ExternalAccount.yaml b/openapi/components/schemas/external_accounts/ExternalAccount.yaml index 08449b83..e9568235 100644 --- a/openapi/components/schemas/external_accounts/ExternalAccount.yaml +++ b/openapi/components/schemas/external_accounts/ExternalAccount.yaml @@ -24,6 +24,14 @@ allOf: example: acc_123456789 ownershipType: $ref: ./OwnershipType.yaml + custodyType: + $ref: ./CustodyType.yaml + vaspId: + type: string + description: >- + The VASP that custodies this account, from the VASP directory + (`GET /vasps`). Only present when `custodyType` is `VASP_HOSTED`. + example: Vasp:019542f5-b3e7-1d02-0000-000000000001 currency: type: string description: The ISO 4217 currency code diff --git a/openapi/components/schemas/external_accounts/ExternalAccountCreateRequest.yaml b/openapi/components/schemas/external_accounts/ExternalAccountCreateRequest.yaml index b97ace94..e1354085 100644 --- a/openapi/components/schemas/external_accounts/ExternalAccountCreateRequest.yaml +++ b/openapi/components/schemas/external_accounts/ExternalAccountCreateRequest.yaml @@ -20,6 +20,15 @@ allOf: example: ext_acc_123456 ownershipType: $ref: ./OwnershipType.yaml + custodyType: + $ref: ./CustodyType.yaml + vaspId: + type: string + description: >- + The VASP that custodies this account, from the VASP directory + (`GET /vasps`). Required when `custodyType` is `VASP_HOSTED`; + must be omitted otherwise. + example: Vasp:019542f5-b3e7-1d02-0000-000000000001 defaultUmaDepositAccount: type: boolean description: >- From ccff0defc054948d5b5137c9b574e3300a9cead9 Mon Sep 17 00:00:00 2001 From: shreyav Date: Thu, 13 Aug 2026 21:37:27 +0000 Subject: [PATCH 2/2] Identify custodying VASP by canonical name, matching the discovery pattern --- mintlify/openapi.yaml | 12 ++++++------ openapi.yaml | 12 ++++++------ .../schemas/external_accounts/ExternalAccount.yaml | 9 +++++---- .../ExternalAccountCreateRequest.yaml | 10 +++++----- 4 files changed, 22 insertions(+), 21 deletions(-) diff --git a/mintlify/openapi.yaml b/mintlify/openapi.yaml index 80a9de2c..e0daf069 100644 --- a/mintlify/openapi.yaml +++ b/mintlify/openapi.yaml @@ -19241,10 +19241,10 @@ components: $ref: '#/components/schemas/OwnershipType' custodyType: $ref: '#/components/schemas/CustodyType' - vaspId: + vaspName: type: string - description: The VASP that custodies this account, from the VASP directory (`GET /vasps`). Only present when `custodyType` is `VASP_HOSTED`. - example: Vasp:019542f5-b3e7-1d02-0000-000000000001 + description: Canonical name of the VASP that custodies this account, from the VASP directory (`GET /vasps`). Only present when `custodyType` is `VASP_HOSTED`. + example: Kraken currency: type: string description: The ISO 4217 currency code @@ -20161,10 +20161,10 @@ components: $ref: '#/components/schemas/OwnershipType' custodyType: $ref: '#/components/schemas/CustodyType' - vaspId: + vaspName: type: string - description: The VASP that custodies this account, from the VASP directory (`GET /vasps`). Required when `custodyType` is `VASP_HOSTED`; must be omitted otherwise. - example: Vasp:019542f5-b3e7-1d02-0000-000000000001 + description: Canonical name of the VASP that custodies this account, from the VASP directory (`GET /vasps`). Required when `custodyType` is `VASP_HOSTED`; must be omitted otherwise. + example: Kraken defaultUmaDepositAccount: type: boolean description: Whether to set the external account as the default UMA deposit account. When set to true, incoming payments to this customer's UMA address will be automatically deposited into this external account. False if not provided. Note that only one external account can be set as the default UMA deposit account for a customer, so if there is already a default UMA deposit account, this will override the existing default UMA deposit account. If there is no default UMA deposit account, incoming UMA payments will be deposited into the primary internal account for the customer. diff --git a/openapi.yaml b/openapi.yaml index 80a9de2c..e0daf069 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -19241,10 +19241,10 @@ components: $ref: '#/components/schemas/OwnershipType' custodyType: $ref: '#/components/schemas/CustodyType' - vaspId: + vaspName: type: string - description: The VASP that custodies this account, from the VASP directory (`GET /vasps`). Only present when `custodyType` is `VASP_HOSTED`. - example: Vasp:019542f5-b3e7-1d02-0000-000000000001 + description: Canonical name of the VASP that custodies this account, from the VASP directory (`GET /vasps`). Only present when `custodyType` is `VASP_HOSTED`. + example: Kraken currency: type: string description: The ISO 4217 currency code @@ -20161,10 +20161,10 @@ components: $ref: '#/components/schemas/OwnershipType' custodyType: $ref: '#/components/schemas/CustodyType' - vaspId: + vaspName: type: string - description: The VASP that custodies this account, from the VASP directory (`GET /vasps`). Required when `custodyType` is `VASP_HOSTED`; must be omitted otherwise. - example: Vasp:019542f5-b3e7-1d02-0000-000000000001 + description: Canonical name of the VASP that custodies this account, from the VASP directory (`GET /vasps`). Required when `custodyType` is `VASP_HOSTED`; must be omitted otherwise. + example: Kraken defaultUmaDepositAccount: type: boolean description: Whether to set the external account as the default UMA deposit account. When set to true, incoming payments to this customer's UMA address will be automatically deposited into this external account. False if not provided. Note that only one external account can be set as the default UMA deposit account for a customer, so if there is already a default UMA deposit account, this will override the existing default UMA deposit account. If there is no default UMA deposit account, incoming UMA payments will be deposited into the primary internal account for the customer. diff --git a/openapi/components/schemas/external_accounts/ExternalAccount.yaml b/openapi/components/schemas/external_accounts/ExternalAccount.yaml index e9568235..1410d929 100644 --- a/openapi/components/schemas/external_accounts/ExternalAccount.yaml +++ b/openapi/components/schemas/external_accounts/ExternalAccount.yaml @@ -26,12 +26,13 @@ allOf: $ref: ./OwnershipType.yaml custodyType: $ref: ./CustodyType.yaml - vaspId: + vaspName: type: string description: >- - The VASP that custodies this account, from the VASP directory - (`GET /vasps`). Only present when `custodyType` is `VASP_HOSTED`. - example: Vasp:019542f5-b3e7-1d02-0000-000000000001 + Canonical name of the VASP that custodies this account, from the + VASP directory (`GET /vasps`). Only present when `custodyType` is + `VASP_HOSTED`. + example: Kraken currency: type: string description: The ISO 4217 currency code diff --git a/openapi/components/schemas/external_accounts/ExternalAccountCreateRequest.yaml b/openapi/components/schemas/external_accounts/ExternalAccountCreateRequest.yaml index e1354085..40792175 100644 --- a/openapi/components/schemas/external_accounts/ExternalAccountCreateRequest.yaml +++ b/openapi/components/schemas/external_accounts/ExternalAccountCreateRequest.yaml @@ -22,13 +22,13 @@ allOf: $ref: ./OwnershipType.yaml custodyType: $ref: ./CustodyType.yaml - vaspId: + vaspName: type: string description: >- - The VASP that custodies this account, from the VASP directory - (`GET /vasps`). Required when `custodyType` is `VASP_HOSTED`; - must be omitted otherwise. - example: Vasp:019542f5-b3e7-1d02-0000-000000000001 + Canonical name of the VASP that custodies this account, from the + VASP directory (`GET /vasps`). Required when `custodyType` is + `VASP_HOSTED`; must be omitted otherwise. + example: Kraken defaultUmaDepositAccount: type: boolean description: >-