Skip to content

feat(statements): balance changes and statement delivery confirmation - #1079

Open
benwgold wants to merge 4 commits into
mainfrom
09-25-periodic-statements-spec
Open

benwgold wants to merge 4 commits into
mainfrom
09-25-periodic-statements-spec

Conversation

@benwgold

@benwgold benwgold commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds the two operations a platform needs to build a Regulation E periodic statement for an internal account and record that it was delivered. Both sit under a new Periodic Statements tag.

  • GET /internal-accounts/{id}/balance-changes returns one row per change to the account's balance in a half-open window [from, to), ordered by when the money moved. The window's openingBalance and closingBalance come in the same response. The balances describe the window rather than the page, so openingBalance + Σ(data[].amount) == closingBalance holds summed across all pages. Paginated with limit / cursor.
  • POST /internal-accounts/{id}/statement-confirmations records that a period's statement was delivered to the customer. It is idempotent, and the stored time is the first delivery.

Contract details documented in the spec:

  • A statement period is a calendar month in US Central time (America/Chicago). The examples use Central offsets, and only a window of exactly one such month counts as a statement fetch.
  • A statement is issued for each customer's own USD internal account and covers their whole balance. Money received through a rule-based account appears on its owner's statement. Rule-based, bulk settlement and platform-owned accounts get 400.
  • deliveredAt, or the request time it defaults to, must not be in the future and must be at or after the end of the period.
  • transactionId on a balance change groups the lines of one movement. The spec says it is not a Transaction id.

New error code: 409 NOT_YET_AVAILABLE. The request is valid, but its result could still change, so it isn't served yet; retry later. The name is generic so other endpoints can reuse it. For balance changes it means card settlement for a window boundary has not closed.

Changes

  • openapi/paths/internal_accounts/internal_accounts_{id}_balance-changes.yaml, …_statement-confirmations.yaml: new operations
  • openapi/components/schemas/internal_accounts/: BalanceChange, BalanceChangeListResponse, ConfirmStatementDeliveryRequest, StatementDelivery
  • openapi/components/schemas/errors/Error409.yaml: NOT_YET_AVAILABLE in both the description table and the enum
  • openapi/openapi.yaml: tag and path refs
  • .stainless/stainless.yml: customers.list_balance_changes, customers.confirm_statement_delivery, and the four models
  • openapi.yaml, mintlify/openapi.yaml: regenerated

Test plan

  • make build bundles cleanly, and openapi.yaml and mintlify/openapi.yaml are identical
  • make lint passes: Redocly valid, Spectral 0 errors, and no new warnings or infos on any added path or schema
  • Nullable timestamps use anyOf with type: 'null', following the repo's OpenAPI 3.1 convention

🤖 Generated with Claude Code

Adds the two operations a platform needs to build and evidence a periodic
statement for an internal account: GET /internal-accounts/{id}/balance-changes
returns one row per change to the balance with the window's opening and closing
balances in the same response, and POST
/internal-accounts/{id}/statement-confirmations records that a statement was
delivered. Adds 409 BALANCE_NOT_YET_FINAL and 422 PERIOD_NOT_REPORTABLE.

Co-Authored-By: benwgold <benwgold@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Sep 26, 2026

Copy link
Copy Markdown
Contributor

This PR does not match any of the 3 configured review trigger rules.

@vercel

vercel Bot commented Sep 26, 2026 •

Copy link
Copy Markdown

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

3 Skipped Deployments
Project Deployment Actions Updated
grid-cards-demo Ignored Ignored Preview Sep 26, 2026 1:50am UTC
grid-flow-builder Ignored Ignored Preview Sep 26, 2026 1:50am UTC
grid-wallet-demo Ignored Ignored Preview Sep 26, 2026 1:50am UTC

Request Review

@benwgold
benwgold marked this pull request as ready for review September 26, 2026 00:11

Copy link
Copy Markdown

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

The code tells a caller to come back later, which is not specific to balances.
A generic name lets any endpoint whose answer is not ready yet reuse it, and
the reason text still says what is outstanding.

Co-Authored-By: benwgold <benwgold@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@mintlify

mintlify Bot commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated
Grid 🟢 Ready View Preview Sep 26, 2026, 1:50 AM

benwgold and others added 2 commits September 26, 2026 01:05
Every settled window can now be served, so balance changes no longer answers
422 PERIOD_NOT_REPORTABLE.

Co-Authored-By: benwgold <benwgold@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…delivery can be confirmed

A statement covers a customer's whole balance and is issued for their own USD
account; rule-based, bulk settlement and platform-owned accounts are refused.
A period is a calendar month in US Central time, and only a window that is
exactly one such month counts as a statement fetch, so the examples now carry
the Central offset. deliveredAt, and the request time it defaults to, must
fall after the period ends. The balance-changes 400 also names an unrecognized
cursor.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

This branch was successfully deployed

1 active deployment
staging - mintlify — 76bd117c Deployed Sep 26, 2026 by mintlify[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants