Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 89 additions & 12 deletions mintlify/openapi.yaml

Large diffs are not rendered by default.

19 changes: 19 additions & 0 deletions mintlify/snippets/global-accounts/authentication.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,25 @@ Key rules:
- The retry must reach Grid before `expiresAt` (typically 5 minutes from issue).
- The `requestId` is returned as `Request:<uuid>` and is single-use; reusing one yields `401`.

### Still-processing responses (202 PENDING)

Global Account operations that touch the wallet — sign-in (`POST /auth/credentials/{id}/verify`), the OTP or passkey challenge (`POST /auth/credentials/{id}/challenge`), adding or revoking a credential, refreshing a session, exporting a wallet, updating a wallet-tied customer email or phone, and creating or revoking a delegated key — run optimistically in line and usually finish within the request. When one can't finish synchronously it falls back to asynchronous processing, and Grid returns **HTTP `202` with `{ "status": "PENDING" }`** instead of the terminal response. This is not an error, and it is not the signed-retry challenge above — it means the request has been accepted and is still in flight.

When you receive a `202 PENDING`, **re-send the identical request** — same method, path, body, and headers — on a short interval until it returns a terminal `200`/`201`/`204` (or a `4xx`/`5xx` error):

```json
{
"status": "PENDING"
}
```

Key rules:

- Repeat the request **exactly as you last sent it**. On the initial leg that is the unsigned request; on a signed retry that is the same request *with* its `Grid-Wallet-Signature` and `Request-Id`. A `202 PENDING` never asks you to sign anything new — there is no `payloadToSign` to stamp.
- Re-sending an in-flight signed request is the expected idempotent resubmit — it continues the same operation and is **not** the reused-`requestId` case that returns `401` (that applies only once the request has reached a terminal response).
- Tell the two `202` bodies apart by their fields: a `payloadToSign` means "sign and retry"; a `status` of `PENDING` means "re-send unchanged and keep polling".
- Poll on a short, bounded interval (for example, every 1–2 seconds with a sensible cap) rather than in a tight loop.

### Add an additional credential

Requires an active session on an *existing* credential on the same account. The first call uses the normal credential-create body; Grid detects the pre-existing credential and responds `202` instead of `201`. `OAUTH` and `PASSKEY` are the typical additional credential types. `EMAIL_OTP` can be added back only after the existing email OTP credential has been removed, because each account supports one.
Expand Down
101 changes: 89 additions & 12 deletions openapi.yaml

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
title: Authentication Signed Request Challenge Or Processing Pending
description: >-
The two possible `202` bodies on Embedded Wallet Auth endpoints that use the
signed-retry flow. Either an `AuthSignedRequestChallenge` — carrying
`payloadToSign` plus the credential `type`, which the client stamps and
re-sends with `Grid-Wallet-Signature` and `Request-Id` — or a
`ProcessingPendingResponse` (`status: PENDING`), meaning the operation is
still processing and the identical request should be re-sent unchanged until
it returns a terminal response. Distinguish the two by their fields: a
`payloadToSign` means sign and retry; a `status` of `PENDING` means re-send
unchanged and keep polling.
anyOf:
- $ref: ./AuthSignedRequestChallenge.yaml
- $ref: ../common/ProcessingPendingResponse.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
title: Delegated Key Signed Request Challenge Or Processing Pending
description: >-
The two possible `202` bodies on the delegated-key create flow. Either a
`DelegatedKeySignedRequestChallenge` — carrying `payloadToSign` for the next
leg, which the client stamps and re-sends with `Grid-Wallet-Signature` and
`Request-Id` — or a `ProcessingPendingResponse` (`status: PENDING`), meaning
the operation is still processing and the identical request should be re-sent
unchanged until it returns the next challenge or a terminal response.
Distinguish the two by their fields: a `payloadToSign` means sign and retry; a
`status` of `PENDING` means re-send unchanged and keep polling.
anyOf:
- $ref: ./DelegatedKeySignedRequestChallenge.yaml
- $ref: ../common/ProcessingPendingResponse.yaml
27 changes: 27 additions & 0 deletions openapi/components/schemas/common/ProcessingPendingResponse.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
title: Processing Pending
type: object
required:
- status
description: >-
Non-terminal response body returned with HTTP `202` when an Embedded Wallet
operation is still processing. These operations run optimistically in line and
usually complete within the request, but can fall back to asynchronous
processing; when that happens Grid returns this body with `202`. The request
has been accepted and is progressing — re-send the identical request (same
method, path, body, and headers) to check on and complete it. Keep re-sending
on a short interval until the operation resolves to its terminal success
response (`200`/`201`/`204`, depending on the endpoint) or to a `4xx`/`5xx`
error. Each re-send is idempotent and continues the same in-flight operation
rather than starting a new one, so this body carries no `payloadToSign` and no
request identifier — there is nothing to sign and nothing new to correlate,
the request is simply repeated unchanged.
properties:
status:
type: string
enum:
- PENDING
description: >-
Always `PENDING`. Signals that the operation has not reached a terminal
state yet and that the identical request should be re-sent, unchanged, to
check for completion.
example: PENDING
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
title: Signed Request Challenge Or Processing Pending
description: >-
The two possible `202` bodies on Embedded Wallet endpoints that use the
signed-retry flow. Either a `SignedRequestChallenge` — carrying
`payloadToSign`, which the client stamps and re-sends with
`Grid-Wallet-Signature` and `Request-Id` — or a `ProcessingPendingResponse`
(`status: PENDING`), meaning the operation is still processing and the
identical request should be re-sent unchanged until it returns a terminal
response. Distinguish the two by their fields: a `payloadToSign` means sign
and retry; a `status` of `PENDING` means re-send unchanged and keep polling.
anyOf:
- $ref: ./SignedRequestChallenge.yaml
- $ref: ./ProcessingPendingResponse.yaml
26 changes: 20 additions & 6 deletions openapi/paths/auth/auth_credentials.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -152,15 +152,25 @@ post:
updatedAt: '2026-04-08T15:30:01Z'
'202':
description: >-
Challenge issued. Build an API-key stamp over `payloadToSign` with
the session API keypair of an existing verified credential on the
same internal account, then send that full stamp as
`Grid-Wallet-Signature` and echo `requestId` as `Request-Id` on
the retry.
Non-terminal response carrying one of two bodies, distinguished by
their fields. A signed-retry challenge (`payloadToSign` plus
`requestId`) is returned on the initial call: build an API-key stamp
over `payloadToSign` with the session API keypair of an existing
verified credential on the same internal account, then send that full
stamp as `Grid-Wallet-Signature` and echo `requestId` as `Request-Id`
on the retry.


A still-processing body (`status: PENDING`) is returned when the
operation ran optimistically in line but has fallen back to
asynchronous processing — this can occur on the signed retry. Re-send
the identical request, unchanged, on a short interval until it returns
the terminal `201`. Do not add or alter a signature; the request is
simply repeated as-is.
content:
application/json:
schema:
$ref: ../../components/schemas/auth/AuthSignedRequestChallenge.yaml
$ref: ../../components/schemas/auth/AuthSignedRequestChallengeOrProcessingPending.yaml
examples:
emailOtp:
summary: Additional email OTP credential challenge
Expand Down Expand Up @@ -190,6 +200,10 @@ post:
payloadToSign: '{"organizationId":"org_2m9F...","parameters":{"authenticators":[{"attestation":{"attestationObject":"o2NmbXRk...","clientDataJson":"eyJjaGFsbGVuZ2UiOiJBcktRa...","credentialId":"AdKXJEch1aV5Wo7bj7qLHskVY4OoNaj9qu8TPdJ7kSAgUeRxWNngXlcNIGt4gexZGKVGcqZpqqWordXb_he1izY"},"authenticatorName":"iPhone Face-ID","challenge":"ArkQi2yAYHPlgnJNFBlneIwchQdWXBOTrdB-AmMUB21Lx","transports":["internal","hybrid"]}],"userId":"user_2m9F..."},"timestampMs":"1775681700000","type":"ACTIVITY_TYPE_CREATE_AUTHENTICATORS_V2"}'
requestId: Request:7c4a8d09-ca37-4e3e-9e0d-8c2b3e9a1f21
expiresAt: '2026-04-08T15:35:00Z'
processingPending:
summary: Operation still processing (re-send the identical request)
value:
status: PENDING
'400':
description: >-
Bad request. Returned with `EMAIL_OTP_CREDENTIAL_ALREADY_EXISTS`
Expand Down
13 changes: 13 additions & 0 deletions openapi/paths/auth/auth_credentials_{id}_challenge.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,19 @@ post:
challenge: 6b35a4c41d9aa7a2a0e742f9f9e7a1c2d65a2db33a3fb748f6d4f1ce78d9a729
requestId: Request:7c4a8d09-ca37-4e3e-9e0d-8c2b3e9a1f21
expiresAt: '2026-04-08T15:35:00Z'
'202':
description: >-
The operation is still processing. Grid ran it optimistically in line
but it has fallen back to asynchronous processing (for example, while a
new OTP is being issued or a passkey reauthentication challenge is being
prepared). No action beyond retrying is required: re-send the identical
request — same method, path, body, and headers — on a short interval
until it returns the terminal `200`. The response body carries
`status: PENDING` and nothing else to act on.
content:
application/json:
schema:
$ref: ../../components/schemas/common/ProcessingPendingResponse.yaml
'400':
description: Bad request
content:
Expand Down
30 changes: 21 additions & 9 deletions openapi/paths/auth/auth_credentials_{id}_verify.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -144,18 +144,26 @@ post:
$ref: ../../components/schemas/auth/AuthSession.yaml
'202':
description: >-
Verification challenge issued. Returned only for OTP credentials,
on the first leg of the secure OTP login flow.
Build an API-key stamp over `payloadToSign` (the
`verificationToken`) with the TEK keypair the client generated
for this login, then resubmit the same request with that full
stamp as `Grid-Wallet-Signature` and `requestId` echoed as
`Request-Id` to receive the issued session on the signed
retry.
Non-terminal response carrying one of two bodies, distinguished by
their fields. A signed-retry challenge (`payloadToSign` plus
`requestId`) is returned for OTP credentials on the first leg of the
secure OTP login flow: build an API-key stamp over `payloadToSign` (the
`verificationToken`) with the TEK keypair the client generated for this
login, then resubmit the same request with that full stamp as
`Grid-Wallet-Signature` and `requestId` echoed as `Request-Id` to
receive the issued session on the signed retry.


A still-processing body (`status: PENDING`) is returned when the
operation ran optimistically in line but has fallen back to
asynchronous processing — this can occur on the OTP signed retry or on
`OAUTH`/`PASSKEY` verification. Re-send the identical request,
unchanged, on a short interval until it returns the terminal `200`. Do
not add or alter a signature; the request is simply repeated as-is.
content:
application/json:
schema:
$ref: ../../components/schemas/auth/AuthSignedRequestChallenge.yaml
$ref: ../../components/schemas/auth/AuthSignedRequestChallengeOrProcessingPending.yaml
examples:
emailOtp:
summary: Email OTP verification challenge (sign and retry)
Expand All @@ -164,6 +172,10 @@ post:
payloadToSign: eyJhbGciOiJFUzI1NiIsImtpZCI6InR1cm5rZXkifQ.eyJzdWIiOiJUWnk2NkVPa1RGYTd2NkpXZ0VxaVgyZGFXOENXc2pMQzVDVU9aRUlGY3hzIiwiaWF0IjoxNzc5NDA3MjIxLCJleHAiOjE3Nzk0MTA4MjF9.gKX9MWYGkw8Y55bgzsgrRftvUHFruIe8yu0w9Kpjp5qnrZnXcTV71WVoltGPsr015IY_oRTOkIFLHmiGNG9zBw
requestId: Request:7c4a8d09-ca37-4e3e-9e0d-8c2b3e9a1f21
expiresAt: '2026-04-08T15:35:00Z'
processingPending:
summary: Operation still processing (re-send the identical request)
value:
status: PENDING
'400':
description: Bad request
content:
Expand Down
17 changes: 14 additions & 3 deletions openapi/paths/auth/auth_delegated-keys.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,23 @@ post:
updatedAt: '2026-04-08T15:30:42Z'
'202':
description: >-
Challenge issued for the next leg. Stamp `payloadToSign` and retry
the same request with `Grid-Wallet-Signature` and `Request-Id`.
Non-terminal response carrying one of two bodies, distinguished by
their fields. A signed-retry challenge (`payloadToSign` plus
`requestId`) is returned for the next leg of the flow: stamp
`payloadToSign` and retry the same request with `Grid-Wallet-Signature`
and `Request-Id`.


A still-processing body (`status: PENDING`) is returned when the
operation ran optimistically in line but has fallen back to
asynchronous processing — this can occur on either signed leg. Re-send
the identical request, unchanged, on a short interval until it returns
either the next signed-retry challenge or the terminal `201`. Do not
add or alter a signature; the request is simply repeated as-is.
content:
application/json:
schema:
$ref: ../../components/schemas/auth/DelegatedKeySignedRequestChallenge.yaml
$ref: ../../components/schemas/auth/DelegatedKeySignedRequestChallengeOrProcessingPending.yaml
'400':
description: Bad request
content:
Expand Down
11 changes: 11 additions & 0 deletions openapi/paths/auth/auth_delegated-keys_{id}.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,17 @@ delete:
type: string
example: DelegatedKey:019542f5-b3e7-1d02-0000-000000000021
responses:
'202':
description: >-
The revocation is still processing. Grid ran it optimistically in line
but it has fallen back to asynchronous processing. Re-send the identical
`DELETE` request — same method, path, and headers — on a short interval
until it returns the terminal `204`. The response body carries
`status: PENDING` and nothing else to act on.
content:
application/json:
schema:
$ref: ../../components/schemas/common/ProcessingPendingResponse.yaml
'204':
description: >-
Delegated key revoked. The key can no longer authorize signing.
Expand Down
22 changes: 18 additions & 4 deletions openapi/paths/auth/auth_sessions_{id}_refresh.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -88,20 +88,34 @@ post:
expiresAt: '2026-04-08T15:50:00Z'
'202':
description: >-
Challenge issued. The response contains `payloadToSign` plus a
`requestId`. Build an API-key stamp over `payloadToSign` with the
current session API keypair, then echo `requestId` on the signed retry.
Non-terminal response carrying one of two bodies, distinguished by
their fields. A signed-retry challenge (`payloadToSign` plus
`requestId`) is returned on the initial call: build an API-key stamp
over `payloadToSign` with the current session API keypair, then echo
`requestId` on the signed retry.


A still-processing body (`status: PENDING`) is returned when the
operation ran optimistically in line but has fallen back to
asynchronous processing — this can occur on the signed retry. Re-send
the identical request, unchanged, on a short interval until it returns
the terminal `201`. Do not add or alter a signature; the request is
simply repeated as-is.
content:
application/json:
schema:
$ref: ../../components/schemas/common/SignedRequestChallenge.yaml
$ref: ../../components/schemas/common/SignedRequestChallengeOrProcessingPending.yaml
examples:
challenge:
summary: Session refresh challenge
value:
payloadToSign: '{"organizationId":"org_abc123","parameters":{"targetPublicKey":"04f45f2a22c908b9ce09a7150e514afd24627c401c38a4afc164e1ea783adaaa31d4245acfb88c2ebd42b47628d63ecabf345484f0a9f665b63c54c897d5578be2"},"timestampMs":"1746736509954","type":"ACTIVITY_TYPE_CREATE_READ_WRITE_SESSION_V2"}'
requestId: Request:019542f5-b3e7-1d02-0000-000000000010
expiresAt: '2026-04-08T15:35:00Z'
processingPending:
summary: Operation still processing (re-send the identical request)
value:
status: PENDING
'400':
description: Bad request
content:
Expand Down
27 changes: 20 additions & 7 deletions openapi/paths/customers/customers_{customerId}.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -175,16 +175,25 @@ patch:
$ref: ../../components/schemas/customers/CustomerOneOf.yaml
'202':
description: >-
Challenge issued for an Embedded Wallet email or SMS auth phone update.
The response contains `payloadToSign` plus a `requestId`. Build an
API-key stamp over `payloadToSign` with the session API keypair from a
verified authentication credential on one of the customer's tied
Embedded Wallets, then retry the same request with
`Grid-Wallet-Signature` and `Request-Id`.
Non-terminal response for an Embedded Wallet email or SMS auth phone
update, carrying one of two bodies distinguished by their fields. A
signed-retry challenge (`payloadToSign` plus `requestId`) is returned
on the initial call: build an API-key stamp over `payloadToSign` with
the session API keypair from a verified authentication credential on one
of the customer's tied Embedded Wallets, then retry the same request
with `Grid-Wallet-Signature` and `Request-Id`.


A still-processing body (`status: PENDING`) is returned when the
operation ran optimistically in line but has fallen back to
asynchronous processing — this can occur on the signed retry. Re-send
the identical request, unchanged, on a short interval until it returns
the terminal `200`. Do not add or alter a signature; the request is
simply repeated as-is.
content:
application/json:
schema:
$ref: ../../components/schemas/common/SignedRequestChallenge.yaml
$ref: ../../components/schemas/common/SignedRequestChallengeOrProcessingPending.yaml
examples:
embeddedWalletEmailUpdate:
summary: Embedded Wallet customer email update challenge
Expand All @@ -198,6 +207,10 @@ patch:
payloadToSign: '{"organizationId":"org_2m9F...","parameters":{"userId":"user_2m9F...","userPhoneNumber":"+14155559876"},"timestampMs":"1775681700000","type":"ACTIVITY_TYPE_UPDATE_USER_PHONE_NUMBER"}'
requestId: Request:019542f5-b3e7-1d02-0000-000000000011
expiresAt: '2026-04-08T15:35:00Z'
processingPending:
summary: Operation still processing (re-send the identical request)
value:
status: PENDING
'400':
description: Bad request
content:
Expand Down
Loading
Loading