curl --request POST \
--url https://api.lightspark.com/grid/2025-10-13/internal-accounts/{id}/export \
--header 'Authorization: Basic <encoded-value>' \
--header 'Content-Type: application/json' \
--data '
{
"clientPublicKey": "04f45f2a22c908b9ce09a7150e514afd24627c401c38a4afc164e1ea783adaaa31d4245acfb88c2ebd42b47628d63ecabf345484f0a9f665b63c54c897d5578be2"
}
'{
"id": "InternalAccount:019542f5-b3e7-1d02-0000-000000000002",
"encryptedWalletCredentials": "{\"version\":\"v1.0.0\",\"data\":\"7b22656e6361707065645075626c6963223a22303433...\",\"dataSignature\":\"3045022100c9...\",\"enclaveQuorumPublic\":\"04a1b2c3...\"}"
}Export the wallet credentials of an Embedded Wallet internal account. The returned wallet credentials are HPKE-encrypted to the clientPublicKey supplied in the request body.
Export is a two-step signed-retry flow (same pattern as add-additional credential, revoke credential, and revoke session):
Call POST /internal-accounts/{id}/export with the request body { "clientPublicKey": "..." } and no signature headers. Grid binds the clientPublicKey into the payloadToSign it returns, so the subsequent stamp in Grid-Wallet-Signature commits to the target encryption key. The response is 202 with payloadToSign, requestId, and expiresAt.
Use the session API keypair of a verified authentication credential on the same internal account to build an API-key stamp over payloadToSign, then retry with that full stamp as the Grid-Wallet-Signature header and the requestId echoed back as the Request-Id header. The retry body must carry the same clientPublicKey submitted in step 1 — Grid rejects the retry with 401 if it disagrees with what was bound into payloadToSign. The signed retry returns 200 with encryptedWalletCredentials, which the client decrypts with the matching private key.
The clientPublicKey is ephemeral: generate a fresh P-256 keypair for this export and discard the private key after decrypting. Do not reuse the keypair from any prior verify call — that private key was already discarded after decrypting the session signing key it was issued against.
curl --request POST \
--url https://api.lightspark.com/grid/2025-10-13/internal-accounts/{id}/export \
--header 'Authorization: Basic <encoded-value>' \
--header 'Content-Type: application/json' \
--data '
{
"clientPublicKey": "04f45f2a22c908b9ce09a7150e514afd24627c401c38a4afc164e1ea783adaaa31d4245acfb88c2ebd42b47628d63ecabf345484f0a9f665b63c54c897d5578be2"
}
'{
"id": "InternalAccount:019542f5-b3e7-1d02-0000-000000000002",
"encryptedWalletCredentials": "{\"version\":\"v1.0.0\",\"data\":\"7b22656e6361707065645075626c6963223a22303433...\",\"dataSignature\":\"3045022100c9...\",\"enclaveQuorumPublic\":\"04a1b2c3...\"}"
}API token authentication using format <api token id>:<api client secret>
Full API-key stamp built over the prior payloadToSign with the session API keypair of a verified authentication credential on the target internal account. Required on the signed retry; ignored on the initial call.
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; must be paired with Grid-Wallet-Signature.
The id of the internal account to export.
Request body for POST /internal-accounts/{id}/export. The clientPublicKey is required on both steps of the signed-retry flow. On step 1 Grid binds it into payloadToSign so the subsequent stamp in Grid-Wallet-Signature commits to the target pubkey; on step 2 the client echoes the same clientPublicKey back and Grid uses it to encrypt the wallet credentials returned in the 200 response.
Fresh P-256 public key, uncompressed SEC1 hex — 130 hex chars where the first two are 04 (the uncompressed-point indicator). Generate a new keypair for each export and discard the private key after decrypting the response.
"04f45f2a22c908b9ce09a7150e514afd24627c401c38a4afc164e1ea783adaaa31d4245acfb88c2ebd42b47628d63ecabf345484f0a9f665b63c54c897d5578be2"
Signed retry accepted. Returns the encrypted wallet credentials.
The id of the internal account that was exported.
"InternalAccount:019542f5-b3e7-1d02-0000-000000000002"
Encrypted wallet mnemonic, sealed to the clientPublicKey from the request body using HPKE: DHKEM(P-256, HKDF-SHA256) + HKDF-SHA256 + AES-256-GCM. Decrypt with the matching private key, then manage the mnemonic securely because it is the master key of the self-custodial Embedded Wallet.
The value is a JSON string of the form {"version": "v1.0.0", "data": "<hex>", "dataSignature": "<hex>", "enclaveQuorumPublic": "<hex>"}. data hex-decodes to JSON {"encappedPublic": "<hex>", "ciphertext": "<hex>", "organizationId": "<id>"}, where encappedPublic is the uncompressed SEC1 ephemeral public key. dataSignature is an ECDSA-P256-SHA256 signature over the data bytes produced by the issuer key in enclaveQuorumPublic; verify before decrypting.
In sandbox, dataSignature and enclaveQuorumPublic are empty strings. Clients should bypass attestation verification when calling against sandbox.
"{\"version\":\"v1.0.0\",\"data\":\"7b22656e6361707065645075626c6963223a22303433...\",\"dataSignature\":\"3045022100c9...\",\"enclaveQuorumPublic\":\"04a1b2c3...\"}"
Was this page helpful?