Skip to content

Add discoveries api endpoint. This GET endpoint returns payment railes available by currency and country#298

Open
matthappens wants to merge 1 commit intomainfrom
03-26-add_discoveries_api_endpoint._this_get_endpoint_returns_payment_railes_available_by_currency_and_country
Open

Add discoveries api endpoint. This GET endpoint returns payment railes available by currency and country#298
matthappens wants to merge 1 commit intomainfrom
03-26-add_discoveries_api_endpoint._this_get_endpoint_returns_payment_railes_available_by_currency_and_country

Conversation

@matthappens
Copy link
Copy Markdown
Contributor

@matthappens matthappens commented Mar 26, 2026

TL;DR

Added a new /discoveries endpoint to retrieve available payment rails for specific country and currency combinations.

What changed?

  • Added a new "Discoveries" tag and endpoint group for payment rail discovery functionality
  • Implemented GET /discoveries endpoint that accepts country (ISO 3166-1 alpha-2) and currency (ISO 4217) query parameters
  • The endpoint returns a list of payment rails with stable identifiers, names, display names, country, and currency information
  • Each payment rail's id field serves as the stable identifier to use when creating external accounts
  • Included comprehensive error handling for 400, 401, and 500 status codes
  • Added example response showing Philippine banks (BDO Unibank and Bank of the Philippine Islands)

How to test?

  1. Make a GET request to /discoveries?country=PH&currency=PHP with proper authentication
  2. Verify the response contains a payment_rails array with bank information
  3. Test error cases by omitting required parameters or using invalid country/currency codes
  4. Confirm the returned id values can be used as bankName when creating external accounts via POST /customers/{id}/external-accounts

Why make this change?

This endpoint enables developers to programmatically discover which payment rails, banks, and providers are available for specific country-currency corridors supported by Grid's partners, eliminating the need to hardcode bank names and providing a dynamic way to populate payment options in applications.

@vercel
Copy link
Copy Markdown

vercel bot commented Mar 26, 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 Mar 27, 2026 0:54am

Request Review

Copy link
Copy Markdown
Contributor Author

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 26, 2026

✱ Stainless preview builds

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

kotlin

feat(api): add discoveries resource

openapi

feat(api): add discoveries list endpoint for payment rails

python

feat(api): add discoveries resource with list method

typescript

feat(api): add discoveries resource and list method

Edit this comment to update them. They will appear in their respective SDK's changelogs.

⚠️ grid-openapi studio · code · diff

Your SDK build had at least one "warning" diagnostic, which is a regression from the base state.
generate ⚠️ (prev: generate ✅)

New diagnostics (1 warning)
⚠️ Method/PaginatedWithoutMatchingScheme: Skipped pagination for method `get /discoveries` (no matching pagination scheme).
⚠️ grid-python studio · code · diff

Your SDK build had at least one "warning" diagnostic, which is a regression from the base state.
generate ⚠️ (prev: generate ✅) → build ✅lint ❗test ✅

pip install https://pkg.stainless.com/s/grid-python/bbc1009b6773057cb74edea0c6cfa52ba70858e9/grid-0.0.1-py3-none-any.whl
New diagnostics (1 warning)
⚠️ Method/PaginatedWithoutMatchingScheme: Skipped pagination for method `get /discoveries` (no matching pagination scheme).
⚠️ grid-kotlin studio · code · diff

Your SDK build had at least one "warning" diagnostic, which is a regression from the base state.
generate ⚠️ (prev: generate ✅) → build ✅lint ✅test ✅

New diagnostics (1 warning)
⚠️ Method/PaginatedWithoutMatchingScheme: Skipped pagination for method `get /discoveries` (no matching pagination scheme).
⚠️ grid-typescript studio · code · diff

Your SDK build had at least one "warning" diagnostic, which is a regression from the base state.
generate ⚠️ (prev: generate ✅) → build ✅lint ❗test ✅

npm install https://pkg.stainless.com/s/grid-typescript/eb479070c0f849b3ef9c2e5b2f878c66d3427d75/dist.tar.gz
New diagnostics (1 warning)
⚠️ Method/PaginatedWithoutMatchingScheme: Skipped pagination for method `get /discoveries` (no matching pagination scheme).

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-03-27 00:59:30 UTC

@matthappens matthappens force-pushed the 03-26-add_discoveries_api_endpoint._this_get_endpoint_returns_payment_railes_available_by_currency_and_country branch from 01c98e8 to 76b15e1 Compare March 26, 2026 18:55
- Discoveries
security:
- BasicAuth: []
parameters:
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.

should this be a searchable list? Eg instead of a drop down of however many banks, it's a searchable list and we return options starting with the search param they pass in.

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.

I'm open to this list - would you structure that as /discoveries providing a string parameter to narrow down the results?

schema:
type: object
properties:
payment_rails:
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.

This should follow our standard pagination scheme I think? https://github.com/lightsparkdev/grid-api/tree/main/openapi#pagination

- country
- currency
properties:
id:
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.

what's teh difference between id, name and display name? Should it only be id / display_name?

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.

short answer, yes should be id and display_name. long answer, the name field is a kludge because the external account integration api requires a name rather than an id for bankName / provider etc. I think the right thing to do would be to change the external account to require an id instead, then have discoveries return {id, display_name}

description: >
Human-friendly display name. Falls back to name if the provider
has not set a distinct display name.
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.

i forget the use case for including these. Is it if a country supports multiple currencies? or if a currency is across multiple countries?

Should the country / currency url params both be required instead?

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.

Just trying to think about how SoFi and others would build the flow. I think the user would have already selected the country + currency

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.

the immediate use case for us is currencies used in multiple countries, like XOF. we don't support this yet, but conceivably we could have multiple currencies per country, like EUR & DKK for denmark

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.

if country and currency are required on the request, and we limit to those, is there any benefit to returning them for every entry on the response?

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.

I don't think there is. But I was ok leaving them since I'm not sure exactly how integrators will use it.

Does it make sense to make country required?

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.

it seems kind of weird to me.. id rather leave it out and add if we see a need later

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.

i don't feel too strongly either way

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 don't need to require it. I think the present list of bank names is small enough we could send it back in one block. I assume this api will most often be called with a country_code parameter

@matthappens matthappens force-pushed the 03-26-add_discoveries_api_endpoint._this_get_endpoint_returns_payment_railes_available_by_currency_and_country branch from 76b15e1 to 7ddcc07 Compare March 26, 2026 20:34
@matthappens matthappens force-pushed the 03-26-add_discoveries_api_endpoint._this_get_endpoint_returns_payment_railes_available_by_currency_and_country branch from 7ddcc07 to f9196d4 Compare March 27, 2026 00:13
@matthappens matthappens force-pushed the 03-26-add_discoveries_api_endpoint._this_get_endpoint_returns_payment_railes_available_by_currency_and_country branch from f9196d4 to b7b43e5 Compare March 27, 2026 00:23
Copy link
Copy Markdown
Contributor Author

@pengying trying to remember, we were 'no' on pagination for now?

@matthappens matthappens marked this pull request as ready for review March 27, 2026 00:29
Copy link
Copy Markdown
Contributor

Yeah - if they're going to implement filtering on the client, I think pagination would slow down the UI. And 100 * ~100-150 bytes is not terrible.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 27, 2026

Greptile Summary

This PR adds a new GET /discoveries endpoint that lets developers programmatically query which payment rails (banks, providers) are available for a given country/currency corridor, removing the need to hardcode bank names. The implementation is clean, follows existing spec conventions, and the generated bundles (openapi.yaml, mintlify/openapi.yaml) are consistent with the source changes in openapi/.\n\nKey changes:\n- New openapi/paths/discoveries/discoveries.yaml defining GET /discoveries with required country and currency query parameters\n- Discoveries tag added to all three spec files\n- $ref wired into the root openapi/openapi.yaml\n- Two minor findings: (1) the 200 response schema is missing required: [data], which is inconsistent with all other list endpoints and could trip up generated clients; (2) there is no pagination mechanism — worth at least documenting the intent before this endpoint sees broad adoption.

Confidence Score: 4/5

Safe to merge after the small required: [data] schema fix; pagination is a follow-up concern that can be addressed separately.

The core implementation is correct and follows existing patterns. One concrete schema inconsistency (data not in required) should be fixed for generated-client correctness, but it won't break the API at runtime. Pagination omission is a design note rather than a blocker for the initial release.

openapi/paths/discoveries/discoveries.yaml — missing required: [data] on the 200 response object.

Important Files Changed

Filename Overview
openapi/paths/discoveries/discoveries.yaml New endpoint definition for GET /discoveries; missing required: [data] on the 200 response schema and no pagination support on the list response.
openapi/openapi.yaml Root spec updated to add the Discoveries tag and $ref the new path; looks correct.
openapi.yaml Generated bundle (via make build) — changes mirror the source spec, no issues.
mintlify/openapi.yaml Generated Mintlify bundle — changes are consistent with the source edits in openapi/, no issues.

Sequence Diagram

sequenceDiagram
    participant Dev as Developer
    participant Grid as Grid API
    participant EA as External Accounts

    Dev->>Grid: GET /discoveries?country=PH&currency=PHP
    Grid-->>Dev: 200 { data: [{ bankName, displayName, country, currency }] }

    Note over Dev: Pick bankName from list

    Dev->>EA: POST /customers/external-accounts<br/>{ accountInfo: { bankName: "Bank of the Philippine Islands", ... } }
    EA-->>Dev: 201 External Account created
Loading
Prompt To Fix All With AI
This is a comment left during a code review.
Path: openapi/paths/discoveries/discoveries.yaml
Line: 33-40

Comment:
**`data` not marked as required in the 200 response schema**

Unlike every other list endpoint in this spec (e.g. `customers_external_accounts.yaml` marks `required: [data, hasMore]`), the 200 response here omits a `required` block. This means OpenAPI validators and generated client code will treat `data` as optional even on a successful response, which is inconsistent and could cause null-pointer issues in generated SDKs.

```suggestion
            type: object
            required:
              - data
            properties:
              data:
                type: array
                description: List of payment rails matching the filter criteria
```

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

---

This is a comment left during a code review.
Path: openapi/paths/discoveries/discoveries.yaml
Line: 1-30

Comment:
**No pagination support on a potentially unbounded list**

All other collection endpoints (`/customers/external-accounts`, `/transactions`, etc.) support `limit`/`cursor` pagination and return `hasMore` + `nextCursor`. The `GET /discoveries` endpoint returns a plain array with no pagination controls.

For most corridors today, payment-rail lists are likely short, so this may be fine for the initial release. However, if the list grows (e.g., the Philippines alone has 40+ InstaPay-enabled banks), clients will have no way to paginate without a breaking API change. Consider at least stubbing out the optional `limit` and `cursor` parameters now, or documenting that this list is intentionally non-paginated and expected to stay small.

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

Reviews (2): Last reviewed commit: "remove pagination" | Re-trigger Greptile

@matthappens matthappens force-pushed the 03-26-add_discoveries_api_endpoint._this_get_endpoint_returns_payment_railes_available_by_currency_and_country branch from b7b43e5 to 236f653 Compare March 27, 2026 00:54
Copy link
Copy Markdown
Contributor Author

Yeah - if they're going to implement filtering on the client, I think pagination would slow down the UI. And 100 * ~100-150 bytes is not terrible.

​done, pagination removed

displayName: BDO Unibank
country: PH
currency: PHP
- bankName: Bank of the Philippine Islands
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.

is the bankName / displayName for thie example reversed?

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! will fix

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