Skip to content

add a swift external account type#473

Merged
shreyav merged 1 commit into
mainfrom
05-18-add_a_swift_external_account_type
May 18, 2026
Merged

add a swift external account type#473
shreyav merged 1 commit into
mainfrom
05-18-add_a_swift_external_account_type

Conversation

@shreyav
Copy link
Copy Markdown
Contributor

@shreyav shreyav commented May 18, 2026

No description provided.

@vercel
Copy link
Copy Markdown

vercel Bot commented May 18, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
grid-flow-builder Ready Ready Preview, Comment May 18, 2026 8:33pm

Request Review

Copy link
Copy Markdown
Contributor Author

shreyav commented May 18, 2026

This stack of pull requests is managed by Graphite. Learn more about stacking.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 18, 2026

✱ Stainless preview builds for grid

This PR will update the grid SDKs with the following commit messages.

cli

chore(internal): regenerate SDK with no functional changes

csharp

feat: add a swift external account type

go

feat(api): add SwiftAccount type to external accounts

kotlin

feat: add a swift external account type

openapi

feat(api): add SWIFT account support to external accounts

php

feat(api): add Swift external account type to agents/customers/platform

python

feat(api): add Swift account support to agents/customers/platform external accounts

ruby

feat: add a swift external account type

typescript

feat(api): add SWIFT account type to external accounts
⚠️ grid-openapi studio · code

Your SDK build had at least one warning diagnostic.
generate ✅

⚠️ grid-ruby studio · code

Your SDK build had a failure in the lint CI job, which is a regression from the base state.
generate ⚠️build ✅lint ❗test ✅

⚠️ grid-go studio · code

Your SDK build had a failure in the lint CI job, which is a regression from the base state.
generate ❗build ✅lint ❗test ❗

go get github.com/stainless-sdks/grid-go@afd45990ac11c0a7b2a74de0c16b463883a265a3
⚠️ grid-kotlin studio · code

Your SDK build had a failure in the test CI job, which is a regression from the base state.
generate ✅build ✅lint ✅test ❗

⚠️ grid-python studio · code

Your SDK build had at least one warning diagnostic.
generate ✅build ✅lint ✅test ✅

pip install https://pkg.stainless.com/s/grid-python/72de174bd8012b3fa38c767f3ea0518856d41539/grid-0.0.1-py3-none-any.whl
⚠️ grid-csharp studio · code

Your SDK build had a failure in the build CI job, which is a regression from the base state.
generate ❗build ❗lint ❗test ❗

⚠️ grid-typescript studio · code

Your SDK build had a failure in the build CI job, which is a regression from the base state.
generate ✅build ❗lint ❗test ❗

⚠️ grid-php studio · code

Your SDK build had at least one "error" diagnostic.
generate ❗lint ✅test ✅

⚠️ grid-cli studio · code

Your SDK build had a failure in the test CI job, which is a regression from the base state.
generate ⚠️build ⏭️lint ⏭️test ❗


This comment is auto-generated by GitHub Actions and is automatically kept up to date as you push.
If you push custom code to the preview branch, re-run this workflow to update the comment.
Last updated: 2026-05-18 21:15:31 UTC

@shreyav shreyav force-pushed the 05-18-add_a_swift_external_account_type branch from 2c9b7bb to 8b11c8e Compare May 18, 2026 20:32
@shreyav shreyav marked this pull request as ready for review May 18, 2026 20:34
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 18, 2026

Greptile Summary

This PR introduces a new SWIFT_ACCOUNT external account type, adding schemas for the account info, create info, beneficiary (individual and business), and wiring the new type into the oneOf union and discriminator mappings. It also reorders the existing enum and oneOf lists alphabetically as housekeeping.

  • New schemas added: SwiftAccountInfoBase, SwiftAccountInfo (read-side, includes paymentRails), SwiftBeneficiary, SwiftExternalAccountCreateInfo, and SwiftExternalAccountInfo — the create/read split and beneficiary discriminator follow the established pattern for other account types.
  • Schema gap in SwiftAccountInfoBase: Neither accountNumber nor iban is in the required array, yet the field descriptions say one must be present depending on the corridor. A request can pass schema validation with neither field set.
  • Minor doc inaccuracy: Brazil (BR) is listed as an IBAN-only corridor in both field descriptions, but Brazil is not part of the IBAN registry.

Confidence Score: 3/5

The new SWIFT account type is mostly well-structured, but the base schema allows a create request to pass validation with no bank account identifier at all — accountNumber and iban are both optional despite the docs saying one is mandatory.

The SwiftAccountInfoBase schema leaves accountNumber and iban both optional, meaning clients can submit a create request that passes OpenAPI validation but carries no usable bank routing information. This would only surface as a runtime failure, not a schema error, making it easy to miss in client-side validation or SDK generation.

openapi/components/schemas/common/SwiftAccountInfoBase.yaml needs the account identifier constraint tightened before the new account type goes live.

Important Files Changed

Filename Overview
openapi/components/schemas/common/SwiftAccountInfoBase.yaml Core SWIFT account schema — neither accountNumber nor iban is required, so schema validation allows creating an account with no bank identifier; also contains an incorrect corridor example (BR is not an IBAN country).
openapi/components/schemas/common/SwiftBeneficiary.yaml Individual beneficiary schema for SWIFT — requires beneficiaryType and fullName; address is optional (unlike AedBeneficiary which requires it), which appears intentional for SWIFT corridors.
openapi/components/schemas/external_accounts/SwiftExternalAccountCreateInfo.yaml Create-side SWIFT account schema — composes BaseExternalAccountInfo + SwiftAccountInfoBase, adds required beneficiary with discriminated oneOf (INDIVIDUAL/BUSINESS). Structure follows existing patterns.
openapi/components/schemas/external_accounts/SwiftExternalAccountInfo.yaml Read-side SWIFT account schema — uses SwiftAccountInfo (which includes paymentRails) instead of SwiftAccountInfoBase. Correctly mirrors the create schema pattern used across other account types.
openapi/components/schemas/external_accounts/ExternalAccountType.yaml Enum reordered alphabetically with SWIFT_ACCOUNT added and wallet types grouped at the end. Clean housekeeping change.
openapi/components/schemas/external_accounts/ExternalAccountCreateInfoOneOf.yaml SwiftExternalAccountCreateInfo added to oneOf list and discriminator mapping; list reordered alphabetically. SWIFT_ACCOUNT discriminator mapping is correct.
openapi/components/schemas/external_accounts/ExternalAccountInfoOneOf.yaml SwiftExternalAccountInfo added to oneOf list and discriminator mapping; list reordered alphabetically. Pre-existing LIGHTNING / LIGHTNING_ACCOUNT dual mapping retained unchanged.

Class Diagram

%%{init: {'theme': 'neutral'}}%%
classDiagram
    class SwiftExternalAccountCreateInfo {
        +title: SWIFT Account
    }
    class SwiftExternalAccountInfo {
        +title: SWIFT Account
    }
    class BaseExternalAccountInfo {
        +accountType: ExternalAccountType
    }
    class SwiftAccountInfoBase {
        +accountType: SWIFT_ACCOUNT (required)
        +swiftCode: string (required)
        +bankName: string (required)
        +country: string (required)
        +accountNumber: string (optional)
        +iban: string (optional)
    }
    class SwiftAccountInfo {
        +paymentRails: SWIFT[] (required)
    }
    class SwiftBeneficiary {
        +beneficiaryType: INDIVIDUAL (required)
        +fullName: string (required)
        +address: Address (optional)
    }
    class BusinessBeneficiary {
        +beneficiaryType: BUSINESS (required)
        +legalName: string (required)
        +address: Address (optional)
    }

    SwiftExternalAccountCreateInfo --|> BaseExternalAccountInfo : allOf
    SwiftExternalAccountCreateInfo --|> SwiftAccountInfoBase : allOf
    SwiftExternalAccountCreateInfo --> SwiftBeneficiary : beneficiary oneOf
    SwiftExternalAccountCreateInfo --> BusinessBeneficiary : beneficiary oneOf

    SwiftExternalAccountInfo --|> BaseExternalAccountInfo : allOf
    SwiftExternalAccountInfo --|> SwiftAccountInfo : allOf
    SwiftExternalAccountInfo --> SwiftBeneficiary : beneficiary oneOf
    SwiftExternalAccountInfo --> BusinessBeneficiary : beneficiary oneOf

    SwiftAccountInfo --|> SwiftAccountInfoBase : allOf
Loading

Fix All in Claude Code

Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
openapi/components/schemas/common/SwiftAccountInfoBase.yaml:32-48
**No enforcement that at least one of `accountNumber` or `iban` is provided**

Both `accountNumber` and `iban` are absent from the `required` list, yet the descriptions state that one is mandatory depending on the corridor. A client can submit a valid (schema-passing) create request with neither field, which would only fail at runtime. A JSON Schema `oneOf` / `if-then-else` or a simple `anyOf` with two options (one requiring `accountNumber`, one requiring `iban`) is the standard way to enforce "exactly one of" at the spec layer, matching the pattern used by corridor-specific schemas like `AedAccountInfoBase.yaml` where the relevant identifier is listed directly in `required`.

### Issue 2 of 2
openapi/components/schemas/common/SwiftAccountInfoBase.yaml:32-44
Brazil (BR) does not use IBAN — it is not part of the IBAN registry. Listing it alongside GB as an "IBAN-only corridor" will mislead integrators trying to set up BRL SWIFT transfers. A well-known IBAN-mandatory country pair for SWIFT is `DE` / `GB`.

```suggestion
  accountNumber:
    type: string
    description: >-
      The bank account number. Required for most corridors.
      Use iban instead for IBAN-only corridors (e.g. DE, GB).
    example: '1234567890'
    minLength: 1
    maxLength: 34
  iban:
    type: string
    description: >-
      The IBAN of the bank account. Required for IBAN-only corridors (e.g. DE, GB).
      Use accountNumber for all other corridors.
```

Reviews (1): Last reviewed commit: "add a swift external account type" | Re-trigger Greptile

Comment on lines +32 to +48
accountNumber:
type: string
description: >-
The bank account number. Required for most corridors.
Use iban instead for IBAN-only corridors (e.g. BR, GB).
example: '1234567890'
minLength: 1
maxLength: 34
iban:
type: string
description: >-
The IBAN of the bank account. Required for IBAN-only corridors (e.g. BR, GB).
Use accountNumber for all other corridors.
example: GB29NWBK60161331926819
minLength: 15
maxLength: 34
pattern: ^[A-Z]{2}[0-9]{2}[A-Za-z0-9]{11,30}$
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 No enforcement that at least one of accountNumber or iban is provided

Both accountNumber and iban are absent from the required list, yet the descriptions state that one is mandatory depending on the corridor. A client can submit a valid (schema-passing) create request with neither field, which would only fail at runtime. A JSON Schema oneOf / if-then-else or a simple anyOf with two options (one requiring accountNumber, one requiring iban) is the standard way to enforce "exactly one of" at the spec layer, matching the pattern used by corridor-specific schemas like AedAccountInfoBase.yaml where the relevant identifier is listed directly in required.

Prompt To Fix With AI
This is a comment left during a code review.
Path: openapi/components/schemas/common/SwiftAccountInfoBase.yaml
Line: 32-48

Comment:
**No enforcement that at least one of `accountNumber` or `iban` is provided**

Both `accountNumber` and `iban` are absent from the `required` list, yet the descriptions state that one is mandatory depending on the corridor. A client can submit a valid (schema-passing) create request with neither field, which would only fail at runtime. A JSON Schema `oneOf` / `if-then-else` or a simple `anyOf` with two options (one requiring `accountNumber`, one requiring `iban`) is the standard way to enforce "exactly one of" at the spec layer, matching the pattern used by corridor-specific schemas like `AedAccountInfoBase.yaml` where the relevant identifier is listed directly in `required`.

How can I resolve this? If you propose a fix, please make it concise.

Fix in Claude Code

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we dont want another level of nesting / one of here

Comment on lines +32 to +44
accountNumber:
type: string
description: >-
The bank account number. Required for most corridors.
Use iban instead for IBAN-only corridors (e.g. BR, GB).
example: '1234567890'
minLength: 1
maxLength: 34
iban:
type: string
description: >-
The IBAN of the bank account. Required for IBAN-only corridors (e.g. BR, GB).
Use accountNumber for all other corridors.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Brazil (BR) does not use IBAN — it is not part of the IBAN registry. Listing it alongside GB as an "IBAN-only corridor" will mislead integrators trying to set up BRL SWIFT transfers. A well-known IBAN-mandatory country pair for SWIFT is DE / GB.

Suggested change
accountNumber:
type: string
description: >-
The bank account number. Required for most corridors.
Use iban instead for IBAN-only corridors (e.g. BR, GB).
example: '1234567890'
minLength: 1
maxLength: 34
iban:
type: string
description: >-
The IBAN of the bank account. Required for IBAN-only corridors (e.g. BR, GB).
Use accountNumber for all other corridors.
accountNumber:
type: string
description: >-
The bank account number. Required for most corridors.
Use iban instead for IBAN-only corridors (e.g. DE, GB).
example: '1234567890'
minLength: 1
maxLength: 34
iban:
type: string
description: >-
The IBAN of the bank account. Required for IBAN-only corridors (e.g. DE, GB).
Use accountNumber for all other corridors.
Prompt To Fix With AI
This is a comment left during a code review.
Path: openapi/components/schemas/common/SwiftAccountInfoBase.yaml
Line: 32-44

Comment:
Brazil (BR) does not use IBAN — it is not part of the IBAN registry. Listing it alongside GB as an "IBAN-only corridor" will mislead integrators trying to set up BRL SWIFT transfers. A well-known IBAN-mandatory country pair for SWIFT is `DE` / `GB`.

```suggestion
  accountNumber:
    type: string
    description: >-
      The bank account number. Required for most corridors.
      Use iban instead for IBAN-only corridors (e.g. DE, GB).
    example: '1234567890'
    minLength: 1
    maxLength: 34
  iban:
    type: string
    description: >-
      The IBAN of the bank account. Required for IBAN-only corridors (e.g. DE, GB).
      Use accountNumber for all other corridors.
```

How can I resolve this? If you propose a fix, please make it concise.

Fix in Claude Code

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the IBAN (International Bank Account Number) is used in Brazil.
It is officially regulated by the Banco Central do Brasil (Central Bank of Brazil) and is exclusively required when sending or receiving international wire transfers

type: string
description: The country of residence of the beneficiary
address:
$ref: ./Address.yaml
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Re: line +31]

is this different from a regular Individual beneficiary?

See this comment inline on Graphite.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no but I was following the existing pattern of having a dedicated individual bene schema per account type

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh yeah it was so we could separate out required fields based on country

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@claude add a note to openapi/readme.md to note for external accounts, we created individual beneficiares as not each country has the same fields / required information

@shreyav shreyav merged commit 3598073 into main May 18, 2026
9 checks passed
@shreyav shreyav deleted the 05-18-add_a_swift_external_account_type branch May 18, 2026 21:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants