diff --git a/docs/preview/index.mdx b/docs/preview/index.mdx index d4ad779321..fd7f61978f 100644 --- a/docs/preview/index.mdx +++ b/docs/preview/index.mdx @@ -14,7 +14,7 @@ These features are in active development and will be available soon. Some may be | Feature | Description | ETA | |---------|-------------|-----| -| - | - | - | +| [Account onboarding enhancements](/preview/new-onboarding) | Redesigned onboarding mutations and queries with cleaner naming, typed responses, and improved data collection for compliance. | Q1, 2026 | @@ -26,6 +26,6 @@ These features are in beta and available for testing. We use feedback to refine | Feature | Description | ETA | |---------|-------------|-----| -| [Card insurance](card-insurance) | Comprehensive insurance coverage for Swan-issued cards including theft, fraud, and travel protection | In private beta | +| [Card insurance](/preview/card-insurance) | Comprehensive insurance coverage for Swan-issued cards including theft, fraud, and travel protection. | In private beta | \ No newline at end of file diff --git a/docs/preview/new-onboarding/company.mdx b/docs/preview/new-onboarding/company.mdx new file mode 100644 index 0000000000..868914caed --- /dev/null +++ b/docs/preview/new-onboarding/company.mdx @@ -0,0 +1,132 @@ +--- +title: Company onboarding fields +--- + +# Company onboarding fields + +Field reference for company account holder onboarding. + +:::warning Work in progress +Field requirements and validations are being finalized. This section will be updated before release. +::: + +## Account + +| API v1 | API v2 | +|---|---| +| `accountCountry` | `accountInfo.country` | +| `accountName` | `accountInfo.name` | +| - | `accountInfo.intendedUsages` (new) | + +## Account administrator + +| API v1 | API v2 | +|---|---| +| `legalRepresentativePersonalAddress.addressLine1` | `accountAdmin.address.addressLine1` | +| `legalRepresentativePersonalAddress.addressLine2` | `accountAdmin.address.addressLine2` | +| `legalRepresentativePersonalAddress.city` | `accountAdmin.address.city` | +| `legalRepresentativePersonalAddress.country` | `accountAdmin.address.country` | +| `legalRepresentativePersonalAddress.postalCode` | `accountAdmin.address.postalCode` | +| `legalRepresentativePersonalAddress.state` | `accountAdmin.address.state` | +| - | `accountAdmin.birthInfo.birthDate` (new) | +| - | `accountAdmin.birthInfo.city` (new) | +| - | `accountAdmin.birthInfo.country` (new) | +| - | `accountAdmin.birthInfo.postalCode` (new) | +| `email` | `accountAdmin.email` | +| - | `accountAdmin.firstName` | +| - | `accountAdmin.lastName` (new) | +| - | `accountAdmin.nationality` (new) | +| `language` | `accountAdmin.preferredLanguage` | +| - | `accountAdmin.taxIdentificationNumber` (new) | +| `typeOfRepresentation` | `accountAdmin.typeOfRepresentation` | +| - | `accountAdmin.unitedStatesTaxInfo.isUnitedStatesPerson` (new) | +| - | `accountAdmin.unitedStatesTaxInfo.unitedStatesTaxIdentificationNumber` (new) | +| - | `accountAdmin.userDeviceInfo.geoloc.lat` (new) | +| - | `accountAdmin.userDeviceInfo.geoloc.lng` (new) | +| - | `accountAdmin.userDeviceInfo.ip` (new) | +| - | `accountAdmin.userDeviceInfo.userAgent` (new) | + +## Company + +| API v1 | API v2 | +|---|---| +| `residencyAddress.addressLine1` | `company.address.addressLine1` | +| `residencyAddress.addressLine2` | `company.address.addressLine2` | +| `residencyAddress.city` | `company.address.city` | +| `residencyAddress.country` | `company.address.country` | +| `residencyAddress.postalCode` | `company.address.postalCode` | +| `residencyAddress.state` | `company.address.state` | +| `acquisitionChannel` | `company.acquisitionChannel` | +| `businessActivityDescription` | `company.businessActivityDescription` | +| - | `company.businessActivityCode` (new) | +| `companyType` | `company.companyType` | +| - | `company.forecastYearlyIncome` (new) | +| - | `company.headcount` (new) | +| - | `company.legalFormCode` (new) | +| `monthlyPaymentVolume` | `company.monthlyPaymentVolume` | +| `name` | `company.name` | +| - | `company.registrationDate` (new) | +| `registrationNumber` | `company.registrationNumber` | +| - | `company.regulatoryClassification` (new) | +| - | `company.signupDate` (new) | +| `taxIdentificationNumber` | `company.taxIdentificationNumber` | +| `tradeName` | `company.tradeName` | +| `vatNumber` | `company.vatNumber` | +| - | `company.websites` (new) | + +### Legal representative information + +| API v1 | API v2 | +|---|---| +| `representatives[i].residencyAddress.addressLine1` | `company.representatives[i].address.addressLine1` | +| `representatives[i].residencyAddress.addressLine2` | `company.representatives[i].address.addressLine2` | +| `representatives[i].residencyAddress.city` | `company.representatives[i].address.city` | +| `representatives[i].residencyAddress.country` | `company.representatives[i].address.country` | +| `representatives[i].residencyAddress.postalCode` | `company.representatives[i].address.postalCode` | +| `representatives[i].residencyAddress.state` | `company.representatives[i].address.state` | +| `representatives[i].birthDate` | `company.representatives[i].birthInfo.birthDate` | +| `representatives[i].birthCity` | `company.representatives[i].birthInfo.city` | +| `representatives[i].birthCountryCode` | `company.representatives[i].birthInfo.country` | +| `representatives[i].birthCityPostalCode` | `company.representatives[i].birthInfo.postalCode` | +| `representatives[i].entityName` | `company.representatives[i].entityName` | +| `representatives[i].firstName` | `company.representatives[i].firstName` | +| `representatives[i].lastName` | `company.representatives[i].lastName` | +| `representatives[i].legalForm` | `company.representatives[i].legalForm` | +| `representatives[i].nationality` | `company.representatives[i].nationality` | +| `representatives[i].preferredFirstName` | `company.representatives[i].preferredFirstName` | +| `representatives[i].registrationNumber` | `company.representatives[i].registrationNumber` | +| `representatives[i].roles` | `company.representatives[i].roles` | +| `representatives[i].gender` | `company.representatives[i].sex` | +| `representatives[i].type` | `company.representatives[i].type` | +| - | `company.representatives[i].email` (new) | + +### Ultimate Beneficial Owners + +| API v1 | API v2 | +|---|---| +| `individualUltimateBeneficialOwners[i].residencyAddress.addressLine1` | `company.ultimateBeneficialOwners[i].address.addressLine1` | +| `individualUltimateBeneficialOwners[i].residencyAddress.addressLine2` | `company.ultimateBeneficialOwners[i].address.addressLine2` | +| `individualUltimateBeneficialOwners[i].residencyAddress.city` | `company.ultimateBeneficialOwners[i].address.city` | +| `individualUltimateBeneficialOwners[i].residencyAddress.country` | `company.ultimateBeneficialOwners[i].address.country` | +| `individualUltimateBeneficialOwners[i].residencyAddress.postalCode` | `company.ultimateBeneficialOwners[i].address.postalCode` | +| `individualUltimateBeneficialOwners[i].residencyAddress.state` | `company.ultimateBeneficialOwners[i].address.state` | +| `individualUltimateBeneficialOwners[i].birthDate` | `company.ultimateBeneficialOwners[i].birthInfo.birthDate` | +| `individualUltimateBeneficialOwners[i].birthCity` | `company.ultimateBeneficialOwners[i].birthInfo.city` | +| `individualUltimateBeneficialOwners[i].birthCountryCode` | `company.ultimateBeneficialOwners[i].birthInfo.country` | +| `individualUltimateBeneficialOwners[i].birthCityPostalCode` | `company.ultimateBeneficialOwners[i].birthInfo.postalCode` | +| - | `company.ultimateBeneficialOwners[i].controlTypes` (new) | +| `individualUltimateBeneficialOwners[i].firstName` | `company.ultimateBeneficialOwners[i].firstName` | +| `individualUltimateBeneficialOwners[i].identityDocumentDetails.expiryDate` | `company.ultimateBeneficialOwners[i].identityDocumentDetails.expiryDate` | +| `individualUltimateBeneficialOwners[i].identityDocumentDetails.issueDate` | `company.ultimateBeneficialOwners[i].identityDocumentDetails.issueDate` | +| `individualUltimateBeneficialOwners[i].identityDocumentDetails.issuingAuthority` | `company.ultimateBeneficialOwners[i].identityDocumentDetails.issuingAuthority` | +| `individualUltimateBeneficialOwners[i].identityDocumentDetails.number` | `company.ultimateBeneficialOwners[i].identityDocumentDetails.number` | +| `individualUltimateBeneficialOwners[i].identityDocumentDetails.type` | `company.ultimateBeneficialOwners[i].identityDocumentDetails.type` | +| `individualUltimateBeneficialOwners[i].lastName` | `company.ultimateBeneficialOwners[i].lastName` | +| `individualUltimateBeneficialOwners[i].direct` | `company.ultimateBeneficialOwners[i].ownership.direct` | +| `individualUltimateBeneficialOwners[i].indirect` | `company.ultimateBeneficialOwners[i].ownership.indirect` | +| `individualUltimateBeneficialOwners[i].totalCapitalPercentage` | `company.ultimateBeneficialOwners[i].ownership.percentage` | +| - | `company.ultimateBeneficialOwners[i].qualificationType` (new) | +| `individualUltimateBeneficialOwners[i].gender` | `company.ultimateBeneficialOwners[i].sex` | +| `individualUltimateBeneficialOwners[i].taxIdentificationNumber` | `company.ultimateBeneficialOwners[i].taxIdentificationNumber` | +| - | `company.ultimateBeneficialOwners[i].unitedStatesTaxInfo.isUnitedStatesPerson` (new) | +| - | `company.ultimateBeneficialOwners[i].unitedStatesTaxInfo.unitedStatesTaxIdentificationNumber` (new) | \ No newline at end of file diff --git a/docs/preview/new-onboarding/index.mdx b/docs/preview/new-onboarding/index.mdx new file mode 100644 index 0000000000..c1df9b1890 --- /dev/null +++ b/docs/preview/new-onboarding/index.mdx @@ -0,0 +1,230 @@ +--- +title: Account onboarding enhancements +--- + +# Account onboarding enhancements + +Redesigned onboarding mutations and queries with cleaner naming, typed responses, and improved data collection for enhanced risk assessment and regulatory compliance. + +:::info Target availability +This API is in active development and will be available by the end of Q1 2026. +::: + +## Overview + +We are introducing a redesigned onboarding API that replaces the existing mutations and queries. The new API provides improved developer experience through consistent naming conventions, structured input types, and typed responses. + +### What's changing + +| Aspect | Current API | New API | +|---|---|---| +| **Naming** | Mixed patterns (`onboardIndividualAccountHolder`, `unauthenticatedOnboardPublic...`). | Consistent pattern (`createIndividualAccountHolderOnboarding`, `createPublicIndividualAccountHolderOnboarding`). | +| **Input structure** | Flat input with all fields at root level. | Nested structure with `accountInfo`, `accountAdmin`, and `company` objects. | +| **Data requirements** | Limited data collection. | New fields to strengthen risk assessment and compliance. | +| **Response types** | Generic `Onboarding` type for all responses. | Typed `IndividualAccountHolderOnboarding` and `CompanyAccountHolderOnboarding`. | +| **Registry data** | Automatically populates empty onboarding fields. | Dedicated query; no auto-population. | + +### Authentication patterns + +The new API uses a consistent pattern across all endpoints. + +| Endpoint type | Token required | Use case | +|---|---|---| +| `Public` mutations and queries | None | Public onboarding links. | +| Standard mutations and queries | Project access token | Backend integrations, partner-initiated onboarding. | +| `finalize` mutation | User access token | Completing onboarding after user identification. | + +## Individual onboarding + +### Create an individual onboarding + +Call the `createIndividualAccountHolderOnboarding` mutation with a project access token. + +| New mutation | Replaces | +|---|---| +| `createIndividualAccountHolderOnboarding` | `onboardIndividualAccountHolder` | +| `createPublicIndividualAccountHolderOnboarding` | `unauthenticatedOnboardPublicIndividualAccountHolder` | + +The input uses a nested structure with two required objects: + +- `accountInfo`: Account-level details (`country`, `name`, `intendedUsages` (new)). +- `accountAdmin`: Individual's personal information (`email`, `employmentStatus`, `monthlyIncome`, `address`, `sourcesOfFunds` (new), etc.). + +```graphql +input CreateIndividualAccountHolderOnboardingInput { + accountInfo: IndividualAccountHolderOnboardingAccountInput! + accountAdmin: IndividualAccountHolderOnboardingAccountAdminInput! + oAuthRedirectParameters: OAuthRedirectParametersInput +} +``` + +### Update an individual onboarding + +Call the `updateIndividualAccountHolderOnboarding` mutation with a project access token. + +| New mutation | Replaces | +|---|---| +| `updateIndividualAccountHolderOnboarding` | `updateIndividualOnboarding` | +| `updatePublicIndividualAccountHolderOnboarding` | `unauthenticatedUpdateIndividualOnboarding` | + +## Company onboarding + +### Create a company onboarding + +Call the `createCompanyAccountHolderOnboarding` mutation with a project access token. + +| New mutation | Replaces | +|---|---| +| `createCompanyAccountHolderOnboarding` | `onboardCompanyAccountHolder` | +| `createPublicCompanyAccountHolderOnboarding` | `unauthenticatedOnboardPublicCompanyAccountHolder` | + +The input uses a nested structure with three required objects: + +- `accountInfo`: Account-level details (`country`, `name`, `intendedUsages` (new)). +- `accountAdmin`: Legal representative's personal information (`email`, `firstName`, `lastName`, `typeOfRepresentation`, etc.). +- `company`: Company details (`registrationNumber`, `name`, `legalForm`, `ultimateBeneficialOwners`, `representatives`, etc.). + +```graphql +input CreateCompanyAccountHolderOnboardingInput { + accountInfo: CompanyAccountHolderOnboardingAccountInput! + accountAdmin: CompanyAccountHolderOnboardingAccountAdminInput! + oAuthRedirectParameters: OAuthRedirectParametersInput + company: CompanyInfoInput! +} +``` + +### Update a company onboarding + +Call the `updateCompanyAccountHolderOnboarding` mutation with a project access token. + +| New mutation | Replaces | +|---|---| +| `updateCompanyAccountHolderOnboarding` | `updateCompanyOnboarding` | +| `updatePublicCompanyAccountHolderOnboarding` | `unauthenticatedUpdateCompanyOnboarding` | + +## Finalize onboarding + +The `finalizeAccountHolderOnboarding` mutation replaces `finalizeOnboarding`. It requires a **user access token** and returns an `AccountHolderOnboarding` union type. + +| New mutation | Replaces | +|---|---| +| `finalizeAccountHolderOnboarding` | `finalizeOnboarding` | + +## Queries + +### Retrieve onboarding information + +| New query | Authentication | Replaces | +|---|---|---| +| `publicAccountHolderOnboarding` | None | `onboardingInfo` | +| `accountHolderOnboarding` | Project access token | `onboarding` | +| `accountHolderOnboardings` | Project access token | `onboardings` | + +Single-onboarding queries return a payload union that includes the `AccountHolderOnboarding` on success. The `accountHolderOnboardings` query returns an `AccountHolderOnboardingConnection` for [paginated results](/developers/using-api/pagination). + +### Company registry data + +A new dedicated query retrieves company information from official registries, enabling pre-fill capabilities for smoother onboarding. Currently available for companies registered in **France (`FRA`) only**. This replaces the previous behavior where empty onboarding fields were automatically populated with registry data. + +| New query | Authentication | +|---|---| +| `companyInfoRegistryData` | Project access token | + +The query requires a `registrationNumber` and `residencyAddressCountry`. + +:::caution Behavior change +The new API **does not** automatically populate onboarding fields with registry data. You must explicitly query the registry, then use that data when creating or updating the onboarding. +::: + +#### Query + +```graphql +query GetCompanyRegistryData { + companyInfoRegistryData( + input: { + registrationNumber: "123456789" + residencyAddressCountry: FRA + } + ) { + ... on CompanyInfoRegistryDataSuccessPayload { + companyInfo { + name + legalForm + registrationDate + address { + addressLine1 + city + postalCode + country + } + ultimateBeneficialOwners { + firstName + lastName + } + representatives { + ... on OnboardingIndividualRepresentative { + firstName + lastName + roles + } + } + } + } + ... on CompanyRegistryNotFoundRejection { + message + registrationNumber + country + } + } +} +``` + +## Field reference + +:::warning Work in progress +Field requirements and validations are being finalized. This section will be updated before release. +::: + +The following pages provide complete field mappings from the deprecated API to the new API: + +- [Individual onboarding fields](./individual) +- [Company onboarding fields](./company) + +Field requirements vary by country. French company onboardings support pre-fill via the `companyInfoRegistryData` query for company, representative, and UBO fields. + +## Response types + +### IndividualAccountHolderOnboarding + +```graphql +type IndividualAccountHolderOnboarding implements AccountHolderOnboardingBase { + id: ID! + statusInfo: OnboardingStatusInfo! + supportingDocumentCollection: SupportingDocumentCollection + createdAt: DateTime! + updatedAt: DateTime! + accountInfo: IndividualAccountHolderOnboardingAccount + accountAdmin: IndividualAccountHolderOnboardingAccountAdmin +} +``` + +### CompanyAccountHolderOnboarding + +```graphql +type CompanyAccountHolderOnboarding implements AccountHolderOnboardingBase { + id: ID! + statusInfo: OnboardingStatusInfo! + supportingDocumentCollection: SupportingDocumentCollection + createdAt: DateTime! + updatedAt: DateTime! + accountInfo: CompanyAccountHolderOnboardingAccount + accountAdmin: CompanyAccountHolderOnboardingAccountAdmin + company: CompanyInfo +} +``` + +### AccountHolderOnboarding union + +```graphql +union AccountHolderOnboarding = IndividualAccountHolderOnboarding | CompanyAccountHolderOnboarding +``` \ No newline at end of file diff --git a/docs/preview/new-onboarding/individual.mdx b/docs/preview/new-onboarding/individual.mdx new file mode 100644 index 0000000000..26aa4a9d62 --- /dev/null +++ b/docs/preview/new-onboarding/individual.mdx @@ -0,0 +1,51 @@ +--- +title: Individual onboarding fields +--- + +# Individual onboarding fields + +Field reference for individual account holder onboarding. + +:::warning Work in progress +Field requirements and validations are being finalized. This section will be updated before release. +::: + +## Account + +| API v1 | API v2 | +|---|---| +| `accountCountry` | `accountInfo.country` | +| `accountName` | `accountInfo.name` | +| - | `accountInfo.intendedUsages` (new) | + +## Account administrator + +| API v1 | API v2 | +|---|---| +| - | `accountAdmin.acquisitionChannel` (new) | +| `residencyAddress.addressLine1` | `accountAdmin.address.addressLine1` | +| `residencyAddress.addressLine2` | `accountAdmin.address.addressLine2` | +| `residencyAddress.city` | `accountAdmin.address.city` | +| `residencyAddress.country` | `accountAdmin.address.country` | +| `residencyAddress.postalCode` | `accountAdmin.address.postalCode` | +| `residencyAddress.state` | `accountAdmin.address.state` | +| - | `accountAdmin.birthInfo.birthDate` (new) | +| - | `accountAdmin.birthInfo.city` (new) | +| - | `accountAdmin.birthInfo.country` (new) | +| - | `accountAdmin.birthInfo.postalCode` (new) | +| `email` | `accountAdmin.email` | +| `employmentStatus` | `accountAdmin.employmentStatus` | +| - | `accountAdmin.firstName` (new) | +| - | `accountAdmin.lastName` (new) | +| `monthlyIncome` | `accountAdmin.monthlyIncome` | +| - | `accountAdmin.nationality` (new) | +| `language` | `accountAdmin.preferredLanguage` | +| - | `accountAdmin.signupDate` (new) | +| - | `accountAdmin.sourcesOfFunds` (new) | +| `taxIdentificationNumber` | `accountAdmin.taxIdentificationNumber` | +| - | `accountAdmin.unitedStatesTaxInfo.isUnitedStatesPerson` (new) | +| - | `accountAdmin.unitedStatesTaxInfo.unitedStatesTaxIdentificationNumber` (new) | +| - | `accountAdmin.userDeviceInfo.geoloc.lat` (new) | +| - | `accountAdmin.userDeviceInfo.geoloc.lng` (new) | +| - | `accountAdmin.userDeviceInfo.ip` (new) | +| - | `accountAdmin.userDeviceInfo.userAgent` (new) | \ No newline at end of file diff --git a/sidebars.js b/sidebars.js index b1a4e10cfe..f16f085d16 100644 --- a/sidebars.js +++ b/sidebars.js @@ -772,7 +772,7 @@ module.exports = { label: 'Upcoming features', className: 'sidebar-preview-notice', }, - /*{ + { type: "category", label: "Preview", collapsible: false, @@ -780,17 +780,16 @@ module.exports = { items: [ { type: "category", - label: "Belgian IBANS", - link: { type: "doc", id: "preview/belgian-ibans/belgian-ibans" }, + label: "Account onboarding enhancements", + link: { type: "doc", id: "preview/new-onboarding/index" }, collapsed: true, items: [ - "preview/belgian-ibans/partnership_document-center_company-registration_belgium", + "preview/new-onboarding/individual", + "preview/new-onboarding/company", ], }, - // Add more preview features here ], - },*/ - // Add more categories here + }, { type: "category", label: "Beta", @@ -806,7 +805,6 @@ module.exports = { "preview/card-insurance/guide-insurance-integration", ], }, - // Add more beta features here ], }, ],