Skip to content

[grid-api] async-ops: GET /operations + wallet_operation webhooks (DRAFT — do not merge until async feature deploys)#559

Draft
carsonp6 wants to merge 1 commit into
mainfrom
grid-api-async-ops-public-surface
Draft

[grid-api] async-ops: GET /operations + wallet_operation webhooks (DRAFT — do not merge until async feature deploys)#559
carsonp6 wants to merge 1 commit into
mainfrom
grid-api-async-ops-public-surface

Conversation

@carsonp6

@carsonp6 carsonp6 commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

What

Publish the canonical async-operations public surface in the Grid API spec + docs: the GET /operations/{operationId} endpoint (with Operation / OperationResult / OperationError schemas), and the WALLET_OPERATION.COMPLETED / WALLET_OPERATION.FAILED webhooks (with WalletOperationWebhook* schemas + WebhookType enum values), plus the async-operations.mdx Mintlify guide and the webhooks snippet.

Why

This is the partner-facing contract for the Turnkey request-driven async migration. When a state-changing or data-returning Turnkey op goes async it returns 202 {operationId: "Operation:<uuid>"}; partners then poll GET /operations/{operationId} and/or receive a WALLET_OPERATION.* webhook on terminal state. The endpoint is the only way to retrieve a data-returning result (wallet.export's HPKE bundle) — it is re-fetched on demand and never stored by Grid, never delivered in the webhook. This spec is what gates flipping GRID_TURNKEY_ASYNC_EXPORT ON. See 50-async-ops-api-design.md §1/§2.

This is the external lightsparkdev/grid-api source-of-truth counterpart to the monorepo's vendored regen (sparkcore PR #28463); the two stay in lockstep.

Notable points

  • status is PROCESSING/COMPLETED/FAILED (uppercase) on the GET; webhook data.status is lowercase completed/failed — the docs call out branching on webhook type, not data.status.
  • Webhook type casing is WALLET_OPERATION.* (UPPERCASE OBJECT.EVENT), matching the established WebhookType convention; reconciled atomically with the emitter in sparkcore PR #28460. Safe pre-GA since no partner has consumed the event yet.
  • OperationResult is tagged by type so result shapes can grow per operation type without a breaking change; state-changing ops return result: null.

Status

DRAFT — part of the Turnkey login-family migration / async-ops program; do not merge yet. Hold until the async feature actually deploys (the underlying knobs are still OFF), so the published docs don't promise an endpoint partners can't yet use.


Part of the Turnkey login-family migration program. See 00-program-plan.md in the sparkcore login-migration docs.

Mirror the async-ops public API surface from webdev sparkcore PR #28463
(which edited webdev's vendored grid-api/openapi.yaml) into the canonical
grid-api spec + docs.

Spec (openapi/ source, rebundled into openapi.yaml + mintlify/openapi.yaml):
- GET /operations/{operationId} polling endpoint (getOperationById), tagged
  under a new "Operations" tag
- Operation / OperationResult / OperationError schemas
- wallet-operation webhook (WALLET_OPERATION.COMPLETED / .FAILED) +
  WalletOperationWebhook / WalletOperationWebhookData schemas
- WALLET_OPERATION.COMPLETED / .FAILED added to the WebhookType enum

Adapted to the canonical spec's OpenAPI 3.1.0 dialect: nullable fields use
type-array / anyOf-with-`null` instead of the 3.0 `nullable: true` used in
webdev's vendored copy.

Docs:
- New api-reference/async-operations.mdx prose page (polling endpoint +
  wallet_operation webhooks), wired into docs.json nav
- WALLET_OPERATION.* row added to the shared webhooks retry-policy table

redocly + spectral (--fail-severity=error) both pass.

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

vercel Bot commented Jun 9, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
grid-flow-builder Ignored Ignored Jun 9, 2026 5:27pm

Request Review

@github-actions github-actions Bot added the breaking-change Introduces a breaking change to the OpenAPI spec label Jun 9, 2026
@github-actions

github-actions Bot commented Jun 9, 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

feat(api): add WalletOperationWebhookEvent webhook type

go

feat(api): add wallet operation webhook event type

kotlin

feat(api): add walletOperation event to webhook types

openapi

feat(api): add operations resource, wallet-operation webhook, operation types

php

feat(api): add wallet operation webhook event

python

feat(api): add WalletOperationWebhookEvent type

ruby

feat(api): add wallet operation webhook event

typescript

feat(api): add WalletOperationWebhookEvent to webhooks

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

grid-kotlin studio · code · diff

Your SDK build had at least one new note diagnostic, which is a regression from the base state.
generate ✅build ✅lint ✅test ✅ (prev: test ❗)

New diagnostics (1 note)
💡 Endpoint/NotConfigured: Skipped endpoint because it's not in your Stainless config: `get /operations/{operationId}`
grid-python studio · code · diff

Your SDK build had at least one "note" diagnostic, which is a regression from the base state.
generate ✅build ✅lint ❗test ❗

pip install https://pkg.stainless.com/s/grid-python/3f880416b5af805eeb562d36d1aadf706c018da1/grid-0.0.1-py3-none-any.whl
New diagnostics (1 note)
💡 Endpoint/NotConfigured: Skipped endpoint because it's not in your Stainless config: `get /operations/{operationId}`
grid-cli studio · code · diff

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

New diagnostics (1 note)
💡 Endpoint/NotConfigured: Skipped endpoint because it's not in your Stainless config: `get /operations/{operationId}`
grid-typescript studio · code · diff

Your SDK build had at least one "note" diagnostic, which is a regression from the base state.
generate ✅build ✅lint ✅test ✅

npm install https://pkg.stainless.com/s/grid-typescript/914375eb109b147e5ec6f7f819971e8d57e4c687/dist.tar.gz
New diagnostics (1 note)
💡 Endpoint/NotConfigured: Skipped endpoint because it's not in your Stainless config: `get /operations/{operationId}`
grid-ruby studio · code · diff

Your SDK build had at least one "note" diagnostic, which is a regression from the base state.
generate ✅build ✅lint ✅test ✅

New diagnostics (1 note)
💡 Endpoint/NotConfigured: Skipped endpoint because it's not in your Stainless config: `get /operations/{operationId}`
grid-go studio · code · diff

Your SDK build had at least one "note" diagnostic, which is a regression from the base state.
generate ✅build ✅lint ❗test ❗

go get github.com/stainless-sdks/grid-go@7a1b27129464ec67c40c0f57d054c97f2e6681b8
New diagnostics (1 note)
💡 Endpoint/NotConfigured: Skipped endpoint because it's not in your Stainless config: `get /operations/{operationId}`
grid-csharp studio · code · diff

Your SDK build had at least one new note diagnostic, which is a regression from the base state.
generate ⚠️build ❗lint ✅test ❗

New diagnostics (2 note)
💡 Endpoint/NotConfigured: Skipped endpoint because it's not in your Stainless config: `get /operations/{operationId}`
💡 Name/Renamed: 248 names were renamed due to language constraints, so fallback names will be used instead.
grid-php studio · code · diff

Your SDK build had at least one "note" diagnostic, which is a regression from the base state.
generate ✅lint ✅test ✅

New diagnostics (1 note)
💡 Endpoint/NotConfigured: Skipped endpoint because it's not in your Stainless config: `get /operations/{operationId}`
grid-openapi studio · code · diff

Your SDK build had at least one new note diagnostic, which is a regression from the base state.
generate ✅

New diagnostics (1 note)
💡 Endpoint/NotConfigured: Skipped endpoint because it's not in your Stainless config: `get /operations/{operationId}`

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-09 17:35:31 UTC

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking-change Introduces a breaking change to the OpenAPI spec

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant