curl --request POST \
--url https://api.lightspark.com/grid/2025-10-13/auth/credentials/{id}/verify \
--header 'Authorization: Basic <encoded-value>' \
--header 'Content-Type: application/json' \
--data '
{
"type": "EMAIL_OTP",
"otp": "123456",
"clientPublicKey": "04f45f2a22c908b9ce09a7150e514afd24627c401c38a4afc164e1ea783adaaa31d4245acfb88c2ebd42b47628d63ecabf345484f0a9f665b63c54c897d5578be2"
}
'{
"id": "Session:019542f5-b3e7-1d02-0000-000000000003",
"accountId": "InternalAccount:019542f5-b3e7-1d02-0000-000000000002",
"type": "OAUTH",
"nickname": "example@lightspark.com",
"createdAt": "2026-04-08T15:30:01Z",
"updatedAt": "2026-04-08T15:35:00Z",
"expiresAt": "2026-04-09T15:30:01Z",
"encryptedSessionSigningKey": "w99a5xV6A75TfoAUkZn869fVyDYvgVsKrawMALZXmrauZd8hEv66EkPU1Z42CUaHESQjcA5bqd8dynTGBMLWB9ewtXWPEVbZvocB4Tw2K1vQVp7uwjf"
}Complete the verification step for a previously created authentication credential and issue a session signing key.
For EMAIL_OTP credentials, supply the one-time password that was emailed to the user along with a client-generated public key. For OAUTH credentials, supply a fresh OIDC token (iat must be less than 60 seconds before the request) along with the client-generated public key; this is also the reauthentication path after a prior session expired. For PASSKEY credentials, the client completes a WebAuthn assertion (navigator.credentials.get()) against the Grid-issued challenge returned from either POST /auth/credentials (first authentication) or POST /auth/credentials/{id}/challenge (reauthentication), and submits the resulting assertion along with the client-generated public key. The requestId that accompanied the challenge must be echoed in the Request-Id header so Grid can correlate the assertion with the pending challenge; Grid verifies the WebAuthn signature against the stored credential before issuing the session.
On success, the response contains an encryptedSessionSigningKey that is encrypted to the supplied clientPublicKey, along with an expiresAt timestamp marking when the session expires. The clientPublicKey is ephemeral and one-time-use per verification request.
curl --request POST \
--url https://api.lightspark.com/grid/2025-10-13/auth/credentials/{id}/verify \
--header 'Authorization: Basic <encoded-value>' \
--header 'Content-Type: application/json' \
--data '
{
"type": "EMAIL_OTP",
"otp": "123456",
"clientPublicKey": "04f45f2a22c908b9ce09a7150e514afd24627c401c38a4afc164e1ea783adaaa31d4245acfb88c2ebd42b47628d63ecabf345484f0a9f665b63c54c897d5578be2"
}
'{
"id": "Session:019542f5-b3e7-1d02-0000-000000000003",
"accountId": "InternalAccount:019542f5-b3e7-1d02-0000-000000000002",
"type": "OAUTH",
"nickname": "example@lightspark.com",
"createdAt": "2026-04-08T15:30:01Z",
"updatedAt": "2026-04-08T15:35:00Z",
"expiresAt": "2026-04-09T15:30:01Z",
"encryptedSessionSigningKey": "w99a5xV6A75TfoAUkZn869fVyDYvgVsKrawMALZXmrauZd8hEv66EkPU1Z42CUaHESQjcA5bqd8dynTGBMLWB9ewtXWPEVbZvocB4Tw2K1vQVp7uwjf"
}API token authentication using format <api token id>:<api client secret>
The requestId returned alongside the Grid-issued challenge from POST /auth/credentials or POST /auth/credentials/{id}/challenge, echoed back here so Grid can correlate the assertion with the pending challenge. Required when type is PASSKEY; ignored for EMAIL_OTP and OAUTH.
The id of the authentication credential to verify (the id field of the AuthMethod returned from POST /auth/credentials).
Discriminator value identifying this as an email OTP verification.
EMAIL_OTP The one-time password received by the user via email.
"123456"
Client-generated P-256 public key, hex-encoded in uncompressed SEC1 format (0x04 prefix followed by the 32-byte X and 32-byte Y coordinates; 130 hex characters total). The matching private key must remain on the client. Grid encrypts the session signing key returned in the response to this public key. The key is ephemeral and one-time-use per verification request.
"04f45f2a22c908b9ce09a7150e514afd24627c401c38a4afc164e1ea783adaaa31d4245acfb88c2ebd42b47628d63ecabf345484f0a9f665b63c54c897d5578be2"
Authentication credential verified and session issued
An authentication session on an Embedded Wallet internal account. Returned from GET /auth/sessions (list) and POST /auth/credentials/{id}/verify (on credential verification). Only the verify response includes encryptedSessionSigningKey — it is delivered exactly once at the moment the session is issued and is never returned by the list endpoint.
System-generated unique identifier for the session. Pass this value to DELETE /auth/sessions/{id} to revoke the session before expiresAt. Overrides the id inherited from AuthMethod so this response identifies the session rather than the authenticating credential.
"Session:019542f5-b3e7-1d02-0000-000000000003"
Identifier of the internal account that this credential authenticates.
"InternalAccount:019542f5-b3e7-1d02-0000-000000000002"
The type of authentication credential.
OAUTH: OpenID Connect (OIDC) token issued by an identity provider such as Google or Apple.EMAIL_OTP: A one-time password delivered to the user's email address.PASSKEY: A WebAuthn passkey bound to the user's device.OAUTH, EMAIL_OTP, PASSKEY Human-readable identifier for this credential. For EMAIL_OTP credentials this is the email address; for OAUTH credentials it is typically the email claim from the OIDC token; for PASSKEY credentials it is the nickname provided at registration time.
"example@lightspark.com"
Creation timestamp.
"2026-04-08T15:30:01Z"
Last update timestamp.
"2026-04-08T15:35:00Z"
Timestamp after which the session is no longer valid and the encryptedSessionSigningKey must not be used to sign further requests.
"2026-04-09T15:30:01Z"
HPKE-encrypted session signing key, sealed to the clientPublicKey supplied on the verify request. Encoded as a base58check string: the decoded payload is a 33-byte compressed P-256 encapsulated public key followed by AES-256-GCM ciphertext. The client decrypts this key with its private key and uses it to sign subsequent Embedded Wallet requests until expiresAt.
Only returned from POST /auth/credentials/{id}/verify (where the session is first issued). Omitted from responses that simply surface existing sessions (e.g. GET /auth/sessions) — Grid does not retain the plaintext key after the client has decrypted it.
"w99a5xV6A75TfoAUkZn869fVyDYvgVsKrawMALZXmrauZd8hEv66EkPU1Z42CUaHESQjcA5bqd8dynTGBMLWB9ewtXWPEVbZvocB4Tw2K1vQVp7uwjf"
Was this page helpful?