Skip to content

docs: add sandbox email OTP inbox endpoint#489

Open
DhruvPareek wants to merge 1 commit into
dp/docs-realistic-oidc-sandboxfrom
dp/docs-sandbox-email-otp
Open

docs: add sandbox email OTP inbox endpoint#489
DhruvPareek wants to merge 1 commit into
dp/docs-realistic-oidc-sandboxfrom
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.
  • Add the new endpoint to .stainless/stainless.yml and make the Stainless workflow use the repo config instead of stale hosted/generated config.
  • Regenerate the bundled openapi.yaml and Mintlify OpenAPI copy.

Stack

Test Plan

  • ruby -e 'require "yaml"; YAML.load_file(".github/workflows/stainless-action.yml"); YAML.load_file(".stainless/stainless.yml"); puts "yaml ok"'
  • npm run build:openapi
  • npm run lint:openapi
  • npm run lint

@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 26, 2026 9:07pm

Request Review

Copy link
Copy Markdown
Contributor Author

DhruvPareek commented May 22, 2026

@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, but this did not represent a regression.
generate ❗

🚧 grid-ruby studio

Your SDK build had a "fatal" conclusion, and no code was generated, but this did not represent a regression.

New diagnostics (1 fatal)
FormatterCommandError: Formatter command failed after code generation: `/home/tempuser-66esvu/run/codegen-output/lightspark/grid-ruby/scripts/fast-format`
grid-go studio · code · diff

Your SDK build had at least one "error" diagnostic, but this did not represent a regression.
generate ❗build ✅lint ❗test ❗

go get github.com/stainless-sdks/grid-go@fb5273804326c53c35de72241742563acf0408f2
grid-typescript studio · code · diff

Your SDK build had at least one "error" diagnostic, but this did not represent a regression.
generate ❗build ❗lint ❗test ❗

grid-kotlin studio · code · diff

Your SDK build had at least one "error" diagnostic, but this did not represent a regression.
generate ❗build ✅lint ✅test ❗

grid-python studio · code · diff

Your SDK build had at least one "error" diagnostic, but this did not represent a regression.
generate ❗build ✅lint ✅test ✅

pip install https://pkg.stainless.com/s/grid-python/2df2f00fd82cd5f3933e369eb390fe3b3ef78c3b/grid-0.0.1-py3-none-any.whl
grid-csharp studio · code · diff

Your SDK build had at least one "error" diagnostic, but this did not represent a regression.
generate ❗build ❗lint ✅test ❗

grid-php studio · code · diff

Your SDK build had at least one "error" diagnostic, but this did not represent a regression.
generate ❗lint ✅test ✅

grid-cli studio · code · diff

Your SDK build had at least one "error" diagnostic, but this did not represent a regression.
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-05-26 21:14:43 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