---
title: "Create a delegated signing key"
method: POST
path: "/auth/delegated-keys"
tags: ["Embedded Wallet Auth"]
---

# Create a delegated signing key

`POST /auth/delegated-keys`

## Request

- Base URL: `https://api.lightspark.com/grid/2025-10-13`
- URL: `https://api.lightspark.com/grid/2025-10-13/auth/delegated-keys`
- Auth: HTTP basic

Delegate Spark token-transaction signing authority for a card funding source or agent backed by an Embedded Wallet internal account to a Grid-custodied P-256 API key. Grid uses the requested owner and internal account to identify the wallet, generates the keypair server-side, creates an isolated signer identity holding the public key, then policies granting that identity signing and self-revocation authority. The private key is custodied by Grid and never returned. Both activities must be authorized by the wallet owner, so creation is a three-leg signed-retry flow:

1. Call `POST /auth/delegated-keys` with no signature headers. Grid generates the delegated keypair and the response is `202` with a `payloadToSign`, `requestId`, and `expiresAt`.

2. Use the session API keypair of a verified credential on the requested Embedded Wallet internal account to build an API-key stamp over `payloadToSign`, then retry the same request with that full stamp as the `Grid-Wallet-Signature` header and the `requestId` echoed back as the `Request-Id` header. The response is a second `202` with a new `payloadToSign`, `requestId`, and `expiresAt`.

3. Stamp the new `payloadToSign` with the same session keypair and retry once more with the new `Request-Id`. The signed retry returns `201` with the created `DelegatedKey` in `ACTIVE` status. For card keys, a provisioned `PENDING_AUTH` card using this funding source becomes `ACTIVE` automatically. Cards still provisioning remain `PROCESSING`; frozen and closed cards retain their status.

The same request body must be sent on all three legs. A flow abandoned after the second leg leaves the key in `PENDING` status: the signer identity exists but holds no policies, so it cannot sign or revoke itself. Abandoned `PENDING` card keys do not block creating another delegated key. For an agent, a `PENDING` key blocks a new one until it is revoked with `DELETE /auth/delegated-keys/{id}`; revoking a `PENDING` key only discards Grid's key material. After activation, Grid uses the custodied key to authorize signing for the card's Embedded Wallet funding account or for policy-approved agent actions in place of a session keypair; the platform never handles the key material.

Each card funding source may have at most one `ACTIVE` delegated key, and each agent and Embedded Wallet pair at most one unrevoked (`PENDING` or `ACTIVE`) delegated key; revoke the existing key before creating a new one. A delegated key authorizes raw-payload signing for the wallet and cannot be scoped to amounts or recipients by the public API. Revoke it with `DELETE /auth/delegated-keys/{id}` when no longer needed.

## Headers

- `Grid-Wallet-Signature` string
- `Request-Id` string

## Request body

- DelegatedKeyCreateRequest: Creates a delegated signing key for a card funding source or an agent. Exactly one of `cardId` or `agentId` is required. Requests that provide both fields or neither field return a 400 response.
  - `cardId` string: The id of the card whose Embedded Wallet funding account will use this delegated signing key. Omit when creating a key for an agent.
  - `agentId` string: The id of the agent that will use this delegated signing key. The agent must belong to the customer that owns the Embedded Wallet internal account. Omit when creating a key for a card.
  - `internalAccountId` string, required: The id of the Embedded Wallet internal account this key may sign for. For a card key, Grid uses the `(cardId, internalAccountId)` pair to find the active card funding-source binding. For an agent key, the account must belong to the agent's customer.
  - `nickname` string, required: Human-readable label for the delegated key.

## Response `201`

Delegated key created and policy granted. The key is `ACTIVE` and Grid may use it to stamp card-payment quote executions or policy-approved actions for the selected agent.

- DelegatedKey: A delegated signing key for either a card funding source or an agent, backed by an Embedded Wallet internal account. Card keys include `cardId` and `fundingSourceId`; agent keys include `agentId`. Returned from `POST /auth/delegated-keys` (on activation), `GET /auth/delegated-keys` (list), and `GET /auth/delegated-keys/{id}`. The keypair is generated and custodied by Grid; the private key is never returned. While `ACTIVE`, Grid may use the key to authorize Spark token-transaction signing for the selected card funding source or agent in place of a session keypair. `publicKey` is informational metadata identifying the credential.
  - `id` string, required: Grid-issued `DelegatedKey:<uuid>` identifier.
  - `cardId` string: The card this key is delegated for. Present only for card keys.
  - `fundingSourceId` string: The card funding source this key is delegated for. Present only for card keys.
  - `agentId` string: The agent this key is delegated for. Present only for agent keys.
  - `accountId` string, required: The Embedded Wallet internal account this key is delegated for, derived from the card funding source or the agent's customer.
  - `publicKey` string, required: Compressed P-256 public key (hex) of the delegated API keypair.
  - `nickname` string, required: Human-readable label for the delegated key.
  - `status` 'PENDING' | 'ACTIVE' | 'REVOKED', required: Status of a delegated signing key. - `PENDING`: The delegated user exists but the policy-creation leg never completed. The key cannot sign. - `ACTIVE`: The policy is granted and the key may stamp quote executions. - `REVOKED`: The delegated user has been deleted and the key can no longer sign.
  - `createdAt` string, date-time, required: When the delegated key was created.
  - `updatedAt` string, date-time, required: When the delegated key was last updated.

## Other responses

- `202`: Challenge issued for the next leg. Stamp `payloadToSign` and retry the same request with `Grid-Wallet-Signature` and `Request-Id`.
- `400`: Bad request. Returned when both `cardId` and `agentId` are provided, or when neither owner id is provided.
- `401`: Unauthorized. Returned when the provided `Grid-Wallet-Signature` is missing on a retry, malformed, or does not match the pending challenge, or when the `Request-Id` does not match an unexpired pending challenge.
- `404`: Card, agent, card funding source, or Embedded Wallet account not found
- `409`: An `ACTIVE` delegated key already exists for this card funding source, or an `ACTIVE` or `PENDING` key already exists for this agent and Embedded Wallet pair. Revoke it with `DELETE /auth/delegated-keys/{id}` before creating a new one.
- `500`: Internal service error

## Changes

> 115 revisions in range; 2 not diffed.

- **2026-10-28** `d996ddfb9d2b`: 2 info
  - added the optional property `details/missingFields` to the response with the `400` status
  - added the optional property `details/refusalReason` to the response with the `400` status
- **2026-10-26** `f11f1e76bdd7`: 1 warning
  - added the new `PURCHASE_CARD_LIMIT_REACHED` enum value to the `code` response property for the response status `409`
- **2026-10-26** `0a6dad5815c7`: 1 warning
  - added the new `INVOICE_ALREADY_USED` enum value to the `code` response property for the response status `409`
- **2026-10-24** `715332dcb111`: 1 warning
  - added the new `EXACT_AMOUNT_UNAVAILABLE` enum value to the `code` response property for the response status `400`
- **2026-10-20** `761d1d030cb5`: 2 warning
  - added the new `AGENT_CARD_EXISTS` enum value to the `code` response property for the response status `409`
  - added the new `CARDHOLDER_AGREEMENT_NOT_ACCEPTED` enum value to the `code` response property for the response status `400`

[Operation history](https://skmtc.dev/lightsparkdev/apis/grid-api/changes/auth/delegated-keys/post.md)

---

[API](https://skmtc.dev/lightsparkdev/apis/grid-api.md) - [All operations](https://skmtc.dev/lightsparkdev/apis/grid-api/llms.txt) - [OpenAPI document](https://skmtc.dev/lightsparkdev/apis/grid-api/revisions/7a1db46ec552?raw)
