Create an authentication credential
Register an authentication credential for an Embedded Wallet customer.
First credential on an internal account
If the target internal account does not yet have any authentication credential registered, call this endpoint with the credential details. The response is 201 with the created AuthMethod. For EMAIL_OTP credentials, this call also triggers a one-time password email to the address on the customer record tied to the internal account; the credential must be activated via POST /auth/credentials/{id}/verify before it can sign requests. For OAUTH credentials, the supplied oidcToken is validated inline against the issuer's .well-known OpenID configuration (the token's iat must be less than 60 seconds before the request); activation still happens via POST /auth/credentials/{id}/verify. For PASSKEY credentials, the client completes a WebAuthn registration (navigator.credentials.create()) using a challenge issued by the platform backend and submits the resulting attestation here; the credential must still be activated via POST /auth/credentials/{id}/verify by completing a WebAuthn assertion. Unlike the registration challenge (platform-issued), the challenge for the first authentication is issued by Grid and returned inline on the 201 response alongside the AuthMethod fields, plus a requestId and challenge expiresAt (see PasskeyAuthChallenge). The client uses that Grid-issued challenge to produce the assertion and submits it with Request-Id: <requestId> to POST /auth/credentials/{id}/verify. On every subsequent reauthentication the challenge is re-issued via POST /auth/credentials/{id}/challenge. Only one PASSKEY credential is supported per internal account in v1.
Adding an additional credential
Registering an additional credential against an internal account that already has one requires a signature from an existing verified credential. Call this endpoint with the new credential's details; if an existing credential is already registered on the internal account the response is 202 with a payloadToSign and a requestId. Sign the payload with the session private key of an existing verified credential on the same internal account (decrypted client-side from its encryptedSessionSigningKey) and retry the same request with the signature supplied as the Grid-Wallet-Signature header and the requestId echoed back as the Request-Id header. The signed retry returns 201 with the created AuthMethod. For EMAIL_OTP, the OTP email is triggered on the signed retry, and the credential must then be activated via POST /auth/credentials/{id}/verify.
Headers
Signature over the payloadToSign returned in a prior 202 response, produced with the session private key of an existing verified authentication credential on the target internal account and base64-encoded. Required when registering an additional credential on an internal account that already has one; ignored when the internal account has no existing credentials.
The requestId returned in a prior 202 response, echoed back on the signed retry so the server can correlate it with the issued challenge. Required on the signed retry when registering an additional credential; must be paired with Grid-Wallet-Signature.
Request body
Example request
{
"accountId": "InternalAccount:019542f5-b3e7-1d02-0000-000000000002"
}Response
Authentication credential created successfully. For EMAIL_OTP and OAUTH, the body is a plain AuthMethod. For PASSKEY, the body is a PasskeyAuthChallenge — an AuthMethod with the Grid-issued challenge, requestId, and expiresAt that drive the first authentication assertion.
Example response
{
"id": "AuthMethod:019542f5-b3e7-1d02-0000-000000000001",
"accountId": "InternalAccount:019542f5-b3e7-1d02-0000-000000000002",
"nickname": "example@lightspark.com",
"createdAt": "2026-04-08T15:30:01Z",
"updatedAt": "2026-04-08T15:35:00Z"
}