Skip to main content
POST
/
auth
/
credentials
cURL
curl --request POST \
  --url https://api.lightspark.com/grid/2025-10-13/auth/credentials \
  --header 'Authorization: Basic <encoded-value>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "type": "EMAIL_OTP",
  "accountId": "InternalAccount:019542f5-b3e7-1d02-0000-000000000002"
}
'
{
  "id": "AuthMethod:019542f5-b3e7-1d02-0000-000000000001",
  "accountId": "InternalAccount:019542f5-b3e7-1d02-0000-000000000002",
  "type": "EMAIL_OTP",
  "nickname": "example@lightspark.com",
  "otpEncryptionTargetBundle": "'{version:v1.0.0,data:7b227461726765745075626c6963...,dataSignature:30450221...,enclaveQuorumPublic:04a1b2c3...}'",
  "createdAt": "2026-04-08T15:30:01Z",
  "updatedAt": "2026-04-08T15:30:01Z"
}

Authorizations

Authorization
string
header
required

API token authentication using format <api token id>:<api client secret>

Headers

Grid-Wallet-Signature
string

Full API-key stamp built over the prior payloadToSign with the session API keypair of an existing verified authentication credential on the target internal account. Required on the signed retry.

Request-Id
string

The requestId returned in a prior 202 response, echoed back exactly on the signed retry so the server can correlate it with the issued challenge. Required on the signed retry when registering a credential; must be paired with Grid-Wallet-Signature.

Body

application/json
type
enum<string>
required

Discriminator value identifying this as an email OTP credential.

Available options:
EMAIL_OTP
accountId
string
required

Identifier of the internal account that this credential will authenticate.

Example:

"InternalAccount:019542f5-b3e7-1d02-0000-000000000002"

Response

Authentication credential created successfully. The body is the created AuthMethod for all three credential types. For EMAIL_OTP, the email is the customer email tied to the internal account, and the response also carries otpEncryptionTargetBundle — the HPKE target bundle the client uses to encrypt the OTP attempt on the subsequent POST /auth/credentials/{id}/verify. For PASSKEY, the credential must be authenticated for the first time via POST /auth/credentials/{id}/challenge followed by POST /auth/credentials/{id}/verify to produce a session — there is no inline authentication challenge on the registration response.

Strict wrapper around AuthMethod. Used directly as the registration response on POST /auth/credentials (all three credential types) and inside AuthCredentialResponseOneOf for the EMAIL_OTP branch of POST /auth/credentials/{id}/challenge. The only difference from AuthMethod is unevaluatedProperties: false, which disambiguates the oneOf against PasskeyAuthChallenge — without the strictness, an AuthMethod with extra fields would ambiguously match both branches.

For EMAIL_OTP credentials, the response also carries otpEncryptionTargetBundle so the client can HPKE-encrypt the OTP code in the subsequent POST /auth/credentials/{id}/verify call without the plaintext code ever transiting the server.

id
string
required

System-generated unique identifier for the authentication credential.

Example:

"AuthMethod:019542f5-b3e7-1d02-0000-000000000001"

accountId
string
required

Identifier of the internal account that this credential authenticates.

Example:

"InternalAccount:019542f5-b3e7-1d02-0000-000000000002"

type
enum<string>
required

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.
Available options:
OAUTH,
EMAIL_OTP,
PASSKEY
nickname
string
required

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 validated nickname provided at registration time.

Example:

"example@lightspark.com"

createdAt
string<date-time>
required

Creation timestamp.

Example:

"2026-04-08T15:30:01Z"

updatedAt
string<date-time>
required

Last update timestamp.

Example:

"2026-04-08T15:35:00Z"

credentialId
string

Base64url-encoded WebAuthn credential identifier for this passkey. Present only for PASSKEY authentication credentials. Corresponds to PublicKeyCredential.rawId; pass this value as allowCredentials[].id when requesting a passkey assertion for this auth method.

Example:

"KEbWNCc7NgaYnUyrNeFGX9_3Y-8oJ3KwzjnaiD1d1LVTxR7v3CaKfCz2Vy_g_MHSh7yJ8yL0Pxg6jo_o0hYiew"

otpEncryptionTargetBundle
string

HPKE encryption target bundle for the freshly initiated OTP challenge. Returned only for EMAIL_OTP credentials. The client generates an ephemeral P-256 keypair (the Target Encryption Key, or TEK) and uses this bundle as the recipient when HPKE-encrypting {otp_code, public_key}; the encrypted payload is submitted as encryptedOtpBundle on POST /auth/credentials/{id}/verify. The bundle is one-time-use per OTP issuance — re-issue via POST /auth/credentials/{id}/challenge to obtain a fresh bundle. The matching TEK private key must remain on the client and is used to sign the verificationToken returned on the subsequent signed-retry. Treat the bundle as opaque and pass it to your HPKE library; the Global Accounts client-keys guide shows how.

Example:

"{\"version\":\"v1.0.0\",\"data\":\"7b227461726765745075626c6963...\",\"dataSignature\":\"30450221...\",\"enclaveQuorumPublic\":\"04a1b2c3...\"}"