Skip to content

docs: add sandbox email OTP inbox endpoint#489

Open
DhruvPareek wants to merge 1 commit into
graphite-base/489from
dp/docs-sandbox-email-otp
Open

docs: add sandbox email OTP inbox endpoint#489
DhruvPareek wants to merge 1 commit into
graphite-base/489from
dp/docs-sandbox-email-otp

Conversation

@DhruvPareek
Copy link
Copy Markdown
Contributor

@DhruvPareek DhruvPareek commented May 22, 2026

Reason

The backend sandbox OTP PR adds a sandbox-only test inbox endpoint for dynamic email OTP codes. The OpenAPI and Mintlify docs need the same API surface so sandbox clients can implement the production-like OTP flow without relying on the old hardcoded 000000 code.

Overview

  • Add GET /sandbox/email-otps/latest.
  • Document the required authMethodId query parameter.
  • Add SandboxEmailOtpResponse with authMethodId, accountId, email, otpId, otpCode, expiresAt, and attemptsRemaining.
  • Update the Global Accounts sandbox guide to fetch otpCode from the sandbox inbox before calling POST /auth/credentials/{id}/verify.
  • Keep OAuth docs on supported-provider OIDC tokens / JWT-shaped sandbox test tokens; the dedicated sandbox OIDC token endpoint PR was removed.
  • Regenerate the bundled openapi.yaml and Mintlify OpenAPI copy.

Stack

Test Plan

  • npm run build:openapi
  • npm run lint:openapi

@vercel
Copy link
Copy Markdown

vercel Bot commented May 22, 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 22, 2026 6:56pm

Request Review

Copy link
Copy Markdown
Contributor Author

DhruvPareek commented May 22, 2026

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

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 22, 2026

✱ Stainless preview builds for grid

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

cli

feat(api): add retrieve-latest method to sandbox email OTPs

csharp

feat(api): add retrieve latest email OTP endpoint to sandbox

go

feat(api): add GetLatest method to sandbox email otps

kotlin

feat(api): add retrieveLatest method to sandbox emailOtps resource

openapi

feat(api): add get latest email OTP method to sandbox resource

php

feat(api): add email_otps resource to sandbox

python

feat(api): add retrieve_latest method to sandbox email_otps

ruby

feat(api): add retrieve_latest method to sandbox email_otps

typescript

feat(api): add retrieveLatest method to sandbox emailOtps

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 "error" diagnostic, which is a regression from the base state.
generate ❗ (prev: generate ✅)

New diagnostics (1 error)
Endpoint/NotFound: Skipped endpoint because it's not in your OpenAPI spec: `post /sandbox/oidc/token`
⚠️ grid-ruby studio · code · diff

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

New diagnostics (1 error)
Endpoint/NotFound: Skipped endpoint because it's not in your OpenAPI spec: `post /sandbox/oidc/token`
⚠️ grid-python studio · code · diff

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

pip install https://pkg.stainless.com/s/grid-python/000a5ca3973328be46e93dd598635211f91727f1/grid-0.0.1-py3-none-any.whl
New diagnostics (1 error)
Endpoint/NotFound: Skipped endpoint because it's not in your OpenAPI spec: `post /sandbox/oidc/token`
⚠️ grid-go studio · code · diff

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

go get github.com/stainless-sdks/grid-go@62b942f1ed714f77de9daf720c3d4786177d7671
New diagnostics (1 error)
Endpoint/NotFound: Skipped endpoint because it's not in your OpenAPI spec: `post /sandbox/oidc/token`
⚠️ grid-kotlin studio · code · diff

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

New diagnostics (1 error)
Endpoint/NotFound: Skipped endpoint because it's not in your OpenAPI spec: `post /sandbox/oidc/token`
⚠️ grid-csharp studio · code · diff

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

New diagnostics (1 error)
Endpoint/NotFound: Skipped endpoint because it's not in your OpenAPI spec: `post /sandbox/oidc/token`
⚠️ grid-php studio · code · diff

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

New diagnostics (1 error)
Endpoint/NotFound: Skipped endpoint because it's not in your OpenAPI spec: `post /sandbox/oidc/token`
⚠️ grid-cli studio · code · diff

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

New diagnostics (1 error)
Endpoint/NotFound: Skipped endpoint because it's not in your OpenAPI spec: `post /sandbox/oidc/token`
⚠️ grid-typescript studio · code · diff

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

New diagnostics (1 error)
Endpoint/NotFound: Skipped endpoint because it's not in your OpenAPI spec: `post /sandbox/oidc/token`

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-22 19:02:33 UTC

@DhruvPareek DhruvPareek changed the base branch from dp/docs-sandbox-oidc-token to graphite-base/489 May 22, 2026 18:55
@DhruvPareek DhruvPareek force-pushed the dp/docs-sandbox-email-otp branch from 1971b3b to 6b3905e Compare May 22, 2026 18:55
@DhruvPareek DhruvPareek marked this pull request as ready for review May 22, 2026 20:33
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 22, 2026

Greptile Summary

This PR documents the new GET /sandbox/email-otps/latest endpoint, replacing the old hardcoded 000000 magic OTP with a dynamic sandbox inbox that returns the live OTP code for a given authMethodId. The SandboxEmailOtpResponse schema, updated code examples, and prose changes across the Mintlify sandbox guide are all included, along with a regenerated bundle.

  • New endpoint & schema: GET /sandbox/email-otps/latest is added to both the source OpenAPI spec and the generated bundles; SandboxEmailOtpResponse exposes otpCode, expiresAt, attemptsRemaining, and related fields.
  • Docs updated: The sandbox-testing guide, index card, and the shared sandbox-global-account-magic snippet are updated to replace the 000000 magic value with the inbox-fetch → verify flow.
  • Error403 relocated: The schema definition was moved earlier in the components list (no content change); the diff is purely positional.

Confidence Score: 4/5

Safe to merge; changes are documentation and spec-only with no application logic.

The endpoint definition, schema, and prose are well-structured. Two minor documentation inconsistencies were found: the email field description mentions 'display name' while declaring format: email, and the new code example uses an undefined $GRID_BASE_URL variable while every adjacent example in the same snippet uses a full hardcoded URL.

openapi/components/schemas/sandbox/SandboxEmailOtpResponse.yaml and mintlify/snippets/sandbox-global-account-magic.mdx are worth a quick look before merging.

Important Files Changed

Filename Overview
openapi/paths/sandbox/sandbox_email-otps_latest.yaml New GET endpoint definition for sandbox OTP inbox; error responses and required parameter are correctly specified.
openapi/components/schemas/sandbox/SandboxEmailOtpResponse.yaml New schema for sandbox OTP response; the email field's description ('Email address or display name') conflicts with its format: email constraint.
mintlify/snippets/sandbox-global-account-magic.mdx Email OTP section rewritten to use sandbox inbox; new bash example uses $GRID_BASE_URL variable while all other examples in the same file use hardcoded URLs.
mintlify/global-accounts/platform-tools/sandbox-testing.mdx Description and 'Moving to production' step updated to reflect sandbox inbox instead of magic OTP value; changes are accurate and consistent.
openapi/openapi.yaml Root spec correctly wires up the new path reference alongside the existing sandbox webhook path.
openapi.yaml Generated bundle updated with new endpoint and schema; Error403 definition relocated (no content change).
mintlify/openapi.yaml Mintlify copy of generated bundle updated in sync with root openapi.yaml; changes mirror the source spec.
mintlify/global-accounts/index.mdx Card description for the sandbox-testing page updated to reflect inbox-based OTP; no issues.

Sequence Diagram

sequenceDiagram
    participant Client
    participant GridSandbox as Grid Sandbox API

    Note over Client,GridSandbox: 1. Register EMAIL_OTP credential
    Client->>GridSandbox: POST /auth/credentials (type: EMAIL_OTP)
    GridSandbox-->>Client: 201 Created - authMethodId returned

    Note over Client,GridSandbox: 2. Retrieve OTP from sandbox inbox (new endpoint)
    Client->>GridSandbox: GET /sandbox/email-otps/latest with authMethodId query param
    GridSandbox-->>Client: 200 SandboxEmailOtpResponse with otpCode

    Note over Client,GridSandbox: 3. Verify with live OTP code
    Client->>GridSandbox: "POST /auth/credentials/{id}/verify with otpCode"
    GridSandbox-->>Client: 200 Session and encrypted session signing key
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/sandbox/SandboxEmailOtpResponse.yaml:19-23
The `email` field description says "Email address or display name" but the field declares `format: email`, which expects a plain RFC 5321 address. A display name like `Alice Smith <alice@example.com>` would fail `format: email` validation in strict validators. Either drop "or display name" from the description (if the field is always a bare email address) or remove `format: email` (if the field can hold display-name notation).

```suggestion
  email:
    type: string
    format: email
    description: Email address associated with the auth method.
    example: alice@example.com
```

### Issue 2 of 2
mintlify/snippets/sandbox-global-account-magic.mdx:12-15
The Email OTP example references `$GRID_BASE_URL`, but every other example in this snippet — passkey, wallet signature, OAuth — uses the fully-qualified hardcoded URL (`https://api.lightspark.com/grid/2025-10-13/...`). `$GRID_BASE_URL` is never defined on the page, so a reader who copies only this block will get a broken curl command. For consistency with the rest of the snippet, use the same hardcoded base URL.

```suggestion
OTP_CODE=$(curl -sS "https://api.lightspark.com/grid/2025-10-13/sandbox/email-otps/latest?authMethodId=AuthMethod:abc123" \
  -u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET" | jq -r '.otpCode')

curl -X POST "https://api.lightspark.com/grid/2025-10-13/auth/credentials/AuthMethod:abc123/verify" \
```

Reviews (1): Last reviewed commit: "docs: add sandbox email OTP inbox endpoi..." | Re-trigger Greptile

Comment on lines +19 to +23
email:
type: string
format: email
description: Email address or display name associated with the auth method.
example: alice@example.com
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 The email field description says "Email address or display name" but the field declares format: email, which expects a plain RFC 5321 address. A display name like Alice Smith <alice@example.com> would fail format: email validation in strict validators. Either drop "or display name" from the description (if the field is always a bare email address) or remove format: email (if the field can hold display-name notation).

Suggested change
email:
type: string
format: email
description: Email address or display name associated with the auth method.
example: alice@example.com
email:
type: string
format: email
description: Email address associated with the auth method.
example: alice@example.com
Prompt To Fix With AI
This is a comment left during a code review.
Path: openapi/components/schemas/sandbox/SandboxEmailOtpResponse.yaml
Line: 19-23

Comment:
The `email` field description says "Email address or display name" but the field declares `format: email`, which expects a plain RFC 5321 address. A display name like `Alice Smith <alice@example.com>` would fail `format: email` validation in strict validators. Either drop "or display name" from the description (if the field is always a bare email address) or remove `format: email` (if the field can hold display-name notation).

```suggestion
  email:
    type: string
    format: email
    description: Email address associated with the auth method.
    example: alice@example.com
```

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

Fix in Claude Code

Comment on lines +12 to +15
OTP_CODE=$(curl -sS "$GRID_BASE_URL/sandbox/email-otps/latest?authMethodId=AuthMethod:abc123" \
-u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET" | jq -r '.otpCode')

curl -X POST "$GRID_BASE_URL/auth/credentials/AuthMethod:abc123/verify" \
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 The Email OTP example references $GRID_BASE_URL, but every other example in this snippet — passkey, wallet signature, OAuth — uses the fully-qualified hardcoded URL (https://api.lightspark.com/grid/2025-10-13/...). $GRID_BASE_URL is never defined on the page, so a reader who copies only this block will get a broken curl command. For consistency with the rest of the snippet, use the same hardcoded base URL.

Suggested change
OTP_CODE=$(curl -sS "$GRID_BASE_URL/sandbox/email-otps/latest?authMethodId=AuthMethod:abc123" \
-u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET" | jq -r '.otpCode')
curl -X POST "$GRID_BASE_URL/auth/credentials/AuthMethod:abc123/verify" \
OTP_CODE=$(curl -sS "https://api.lightspark.com/grid/2025-10-13/sandbox/email-otps/latest?authMethodId=AuthMethod:abc123" \
-u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET" | jq -r '.otpCode')
curl -X POST "https://api.lightspark.com/grid/2025-10-13/auth/credentials/AuthMethod:abc123/verify" \
Prompt To Fix With AI
This is a comment left during a code review.
Path: mintlify/snippets/sandbox-global-account-magic.mdx
Line: 12-15

Comment:
The Email OTP example references `$GRID_BASE_URL`, but every other example in this snippet — passkey, wallet signature, OAuth — uses the fully-qualified hardcoded URL (`https://api.lightspark.com/grid/2025-10-13/...`). `$GRID_BASE_URL` is never defined on the page, so a reader who copies only this block will get a broken curl command. For consistency with the rest of the snippet, use the same hardcoded base URL.

```suggestion
OTP_CODE=$(curl -sS "https://api.lightspark.com/grid/2025-10-13/sandbox/email-otps/latest?authMethodId=AuthMethod:abc123" \
  -u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET" | jq -r '.otpCode')

curl -X POST "https://api.lightspark.com/grid/2025-10-13/auth/credentials/AuthMethod:abc123/verify" \
```

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

Fix in 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.

1 participant