Skip to content

[brale-link] Add stablecoin provider account API surface#594

Merged
kphurley7 merged 1 commit into
mainfrom
kph/brale-link-provider-api
Jun 17, 2026
Merged

[brale-link] Add stablecoin provider account API surface#594
kphurley7 merged 1 commit into
mainfrom
kph/brale-link-provider-api

Conversation

@kphurley7

@kphurley7 kphurley7 commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Adds the Grid API surface required by the first Brale-link webdev PR: stablecoin provider account link/list/get endpoints, provider account models, and provider-account error codes. Validation: - make build - make lint

@vercel

vercel Bot commented Jun 17, 2026

Copy link
Copy Markdown

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

2 Skipped Deployments
Project Deployment Actions Updated (UTC)
grid-flow-builder Ignored Ignored Preview Jun 17, 2026 1:57pm
grid-wallet-demo Ignored Ignored Preview Jun 17, 2026 1:57pm

Request Review

@github-actions

github-actions Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

✱ 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

chore(internal): regenerate SDK with no functional changes

go

chore(internal): regenerate SDK with no functional changes

kotlin

chore(internal): regenerate SDK with no functional changes

openapi

feat(api): add stablecoin provider accounts endpoints and types

php

chore(internal): regenerate SDK with no functional changes

python

chore(internal): regenerate SDK with no functional changes

ruby

chore(internal): regenerate SDK with no functional changes

typescript

chore(internal): regenerate SDK with no functional changes
grid-openapi studio · code

Your SDK build had at least one "note" diagnostic.
generate ✅

grid-ruby studio · code

Your SDK build had at least one "note" diagnostic.
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@a83a4ec009ea9ebc2ac0be5d37130e2aa30b0bdb
grid-kotlin studio · code

Your SDK build had at least one "note" diagnostic.
generate ✅build ⏭️lint ⏭️test ✅

⚠️ grid-python 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-csharp 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-php studio · code

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

grid-typescript studio · code

Your SDK build had at least one "note" diagnostic.
generate ✅build ⏭️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-06-17 21:44:10 UTC

@kphurley7 kphurley7 marked this pull request as ready for review June 17, 2026 14:41
@kphurley7 kphurley7 requested a review from shreyav June 17, 2026 14:41
@greptile-apps

greptile-apps Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds the Grid API surface for Brale-link stablecoin provider accounts: three new endpoints (link, list, get), five new schema files, and new 400/404 error codes. The bundled openapi.yaml and mintlify/openapi.yaml are correctly regenerated via make build.

  • New endpointsPOST /stablecoin-provider-accounts (link credentials, idempotency-keyed), GET /stablecoin-provider-accounts (paginated list with provider/status filters), and GET /stablecoin-provider-accounts/{id} (fetch by ID), all scoped to the authenticated platform via BasicAuth.
  • New schemasStablecoinProvider (enum, BRALE only), StablecoinProviderEnvironment (SANDBOX/PRODUCTION), StablecoinProviderAccountStatus (ACTIVE/INVALID/REVOKED), StablecoinProviderAccount (response object), StablecoinProviderAccountLinkRequest (writeOnly secret), and StablecoinProviderAccountListResponse (cursor-paginated).
  • New error codes — Three 400 codes for post-link state errors and one 404 code for missing links; the apiClientSecret is correctly marked writeOnly: true so it never appears in responses.

Confidence Score: 4/5

Safe to merge; all three new endpoints follow established patterns, credentials are write-only, and the bundled files are up to date.

The spec is internally consistent and the generated bundles match the source. Two minor documentation gaps and the absence of a dedicated error code to distinguish a bad apiClientSecret from a malformed request are the only items worth addressing before the next public-facing release.

openapi/paths/stablecoins/stablecoin-provider-accounts.yaml and openapi/components/schemas/stablecoins/StablecoinProviderAccountListResponse.yaml have the small gaps noted in the review comments.

Important Files Changed

Filename Overview
openapi/components/schemas/stablecoins/StablecoinProviderAccount.yaml New schema for the provider account link resource; required fields and types look correct, lastVerifiedAt is correctly optional.
openapi/components/schemas/stablecoins/StablecoinProviderAccountListResponse.yaml Pagination response schema; nextCursor description is missing the "(only present if hasMore is true)" note found in every other list response schema in the repo.
openapi/paths/stablecoins/stablecoin-provider-accounts.yaml Defines POST (link) and GET (list) for provider accounts; provider/status query params lack descriptions; no dedicated error code for provider credential verification failure at link time.
openapi/paths/stablecoins/stablecoin-provider-accounts_{stablecoinProviderAccountId}.yaml Defines GET by ID for provider account links; correct 404 / 401 / 500 responses, no issues found.
openapi/components/schemas/errors/Error400.yaml Adds three new 400 error codes for stablecoin provider account state errors; enum and description table entries are in sync.
openapi/components/schemas/errors/Error404.yaml Adds STABLECOIN_PROVIDER_ACCOUNT_NOT_FOUND to the 404 enum; table and enum are consistent.
openapi/components/schemas/stablecoins/StablecoinProviderAccountLinkRequest.yaml Link request schema; apiClientSecret is correctly marked writeOnly: true; optional providerAccountId is well-described.
openapi/openapi.yaml Registers the two new stablecoin provider account path files and adds the Stablecoins tag; references look correct.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant Client
    participant GridAPI
    participant BraleProvider

    Client->>GridAPI: POST /stablecoin-provider-accounts
    GridAPI->>BraleProvider: Verify credentials
    BraleProvider-->>GridAPI: Account verified (providerAccountId)
    GridAPI-->>Client: 201 StablecoinProviderAccount (ACTIVE)

    Client->>GridAPI: GET /stablecoin-provider-accounts
    GridAPI-->>Client: 200 StablecoinProviderAccountListResponse

    Client->>GridAPI: "GET /stablecoin-provider-accounts/{id}"
    GridAPI-->>Client: 200 StablecoinProviderAccount
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant Client
    participant GridAPI
    participant BraleProvider

    Client->>GridAPI: POST /stablecoin-provider-accounts
    GridAPI->>BraleProvider: Verify credentials
    BraleProvider-->>GridAPI: Account verified (providerAccountId)
    GridAPI-->>Client: 201 StablecoinProviderAccount (ACTIVE)

    Client->>GridAPI: GET /stablecoin-provider-accounts
    GridAPI-->>Client: 200 StablecoinProviderAccountListResponse

    Client->>GridAPI: "GET /stablecoin-provider-accounts/{id}"
    GridAPI-->>Client: 200 StablecoinProviderAccount
Loading
Prompt To Fix All With AI
Fix the following 3 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 3
openapi/components/schemas/stablecoins/StablecoinProviderAccountListResponse.yaml:13-15
**`nextCursor` description omits when-present condition**

Every other list response in the codebase (`CustomerListResponse`, `TransactionListResponse`, etc.) documents `nextCursor` as "Cursor to retrieve the next page of results (only present if `hasMore` is true)". Without that note, clients have no contract guarantee about when the field is populated and may attempt to paginate even when `hasMore` is `false`.

```suggestion
  nextCursor:
    type: string
    description: Cursor to retrieve the next page of results (only present if hasMore is true).
```

### Issue 2 of 3
openapi/paths/stablecoins/stablecoin-provider-accounts.yaml:60-68
**`provider` and `status` query params lack `description` fields**

The `limit` and `cursor` parameters on this same endpoint each carry a `description`, but `provider` and `status` do not. All query parameters on other list endpoints include descriptions (e.g., `GET /customers`). Without them, generated docs and SDK clients surface these params with no context about their purpose or effect on the result set.

### Issue 3 of 3
openapi/paths/stablecoins/stablecoin-provider-accounts.yaml:34-52
**No error code for failed provider credential verification**

The three new 400 codes (`STABLECOIN_PROVIDER_ACCOUNT_INVALID`, `STABLECOIN_PROVIDER_ACCOUNT_REVOKED`, `STABLECOIN_PROVIDER_ACCOUNT_SELECTION_REQUIRED`) address post-link state errors, but there is no code to signal that the submitted `apiClientSecret` itself failed provider-side verification during the link call. A caller whose credentials are outright rejected would receive a generic `INVALID_INPUT` 400, making it impossible to distinguish a bad secret from a bad payload. A dedicated code (e.g., `STABLECOIN_PROVIDER_CREDENTIALS_INVALID`) would close this gap.

Reviews (1): Last reviewed commit: "Add stablecoin provider account API surf..." | Re-trigger Greptile

Comment on lines +13 to +15
nextCursor:
type: string
description: Cursor to retrieve the next page of results.

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 nextCursor description omits when-present condition

Every other list response in the codebase (CustomerListResponse, TransactionListResponse, etc.) documents nextCursor as "Cursor to retrieve the next page of results (only present if hasMore is true)". Without that note, clients have no contract guarantee about when the field is populated and may attempt to paginate even when hasMore is false.

Suggested change
nextCursor:
type: string
description: Cursor to retrieve the next page of results.
nextCursor:
type: string
description: Cursor to retrieve the next page of results (only present if hasMore is true).
Prompt To Fix With AI
This is a comment left during a code review.
Path: openapi/components/schemas/stablecoins/StablecoinProviderAccountListResponse.yaml
Line: 13-15

Comment:
**`nextCursor` description omits when-present condition**

Every other list response in the codebase (`CustomerListResponse`, `TransactionListResponse`, etc.) documents `nextCursor` as "Cursor to retrieve the next page of results (only present if `hasMore` is true)". Without that note, clients have no contract guarantee about when the field is populated and may attempt to paginate even when `hasMore` is `false`.

```suggestion
  nextCursor:
    type: string
    description: Cursor to retrieve the next page of results (only present if hasMore is true).
```

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

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment on lines +60 to +68
tags:
- Stablecoins
security:
- BasicAuth: []
parameters:
- name: provider
in: query
required: false
schema:

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 provider and status query params lack description fields

The limit and cursor parameters on this same endpoint each carry a description, but provider and status do not. All query parameters on other list endpoints include descriptions (e.g., GET /customers). Without them, generated docs and SDK clients surface these params with no context about their purpose or effect on the result set.

Prompt To Fix With AI
This is a comment left during a code review.
Path: openapi/paths/stablecoins/stablecoin-provider-accounts.yaml
Line: 60-68

Comment:
**`provider` and `status` query params lack `description` fields**

The `limit` and `cursor` parameters on this same endpoint each carry a `description`, but `provider` and `status` do not. All query parameters on other list endpoints include descriptions (e.g., `GET /customers`). Without them, generated docs and SDK clients surface these params with no context about their purpose or effect on the result set.

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

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment on lines +34 to +52
content:
application/json:
schema:
$ref: ../../components/schemas/errors/Error400.yaml
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: ../../components/schemas/errors/Error401.yaml
'409':
description: Conflict
content:
application/json:
schema:
$ref: ../../components/schemas/errors/Error409.yaml
'500':
description: Internal service error
content:

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 No error code for failed provider credential verification

The three new 400 codes (STABLECOIN_PROVIDER_ACCOUNT_INVALID, STABLECOIN_PROVIDER_ACCOUNT_REVOKED, STABLECOIN_PROVIDER_ACCOUNT_SELECTION_REQUIRED) address post-link state errors, but there is no code to signal that the submitted apiClientSecret itself failed provider-side verification during the link call. A caller whose credentials are outright rejected would receive a generic INVALID_INPUT 400, making it impossible to distinguish a bad secret from a bad payload. A dedicated code (e.g., STABLECOIN_PROVIDER_CREDENTIALS_INVALID) would close this gap.

Prompt To Fix With AI
This is a comment left during a code review.
Path: openapi/paths/stablecoins/stablecoin-provider-accounts.yaml
Line: 34-52

Comment:
**No error code for failed provider credential verification**

The three new 400 codes (`STABLECOIN_PROVIDER_ACCOUNT_INVALID`, `STABLECOIN_PROVIDER_ACCOUNT_REVOKED`, `STABLECOIN_PROVIDER_ACCOUNT_SELECTION_REQUIRED`) address post-link state errors, but there is no code to signal that the submitted `apiClientSecret` itself failed provider-side verification during the link call. A caller whose credentials are outright rejected would receive a generic `INVALID_INPUT` 400, making it impossible to distinguish a bad secret from a bad payload. A dedicated code (e.g., `STABLECOIN_PROVIDER_CREDENTIALS_INVALID`) would close this gap.

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

@kphurley7 kphurley7 merged commit dd07184 into main Jun 17, 2026
10 checks passed
@kphurley7 kphurley7 deleted the kph/brale-link-provider-api branch June 17, 2026 21:35
pengying pushed a commit that referenced this pull request Jun 18, 2026
## Summary
- Added `FAMILY_SUPPORT` and `SALARY_PAYMENT` to the documented purpose of payment codes in the cross-currency transfers guide

These values were added to the OpenAPI schema in PR #592 (commit 460f14d) but the Mintlify documentation wasn't updated.

## Changes
**Documentation (mintlify/):**
- `mintlify/snippets/sending/cross-currency.mdx` - Added missing purpose of payment codes to match the schema

## Not updated (no changes needed)
- **Contact verification endpoints** (PR #557): Already documented in `mintlify/snippets/kyc/kyc-unregulated.mdx`
- **Stablecoin provider accounts** (PR #594): New API surface - not referenced in existing guides
- **Kotlin sample app**: Uses SDK factory method for PurposeOfPayment which auto-supports new values
- **Grid Visualizer**: Uses `'GIFT'` as example value which remains valid

🤖 Generated with [Claude Code](https://claude.com/claude-code)
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.

2 participants