---
title: "Submit a FROST signer for on-chain registration"
method: POST
path: "/v1/agent-wallets/register-signer"
tags: ["Agent Wallet Signers"]
---

# Submit a FROST signer for on-chain registration

`POST /v1/agent-wallets/register-signer`

## Request

- Base URL: `https://api.prod.keyban.io`
- URL: `https://api.prod.keyban.io/v1/agent-wallets/register-signer`
- Auth: one of:
  - API key in header `X-Api-Key`
  - `bearer` (a scheme the document does not define)

Called by the agent (via MCP) after FROST DKG. Enqueues a job that broadcasts SchnorrAccount.registerSigner(frostBytes, signature) to consume the on-chain commitment and add the agent as a signer. The signature must be made by the corresponding KEYBAN_INVITE_KEY over keccak256(abi.encode(chainId, walletAddress, frostBytes)). Returns immediately with a jobId — poll GET /agent-wallets/register-signer/:jobId for status. A registration is attempted up to 3 times (2 retries, exponential backoff from 2 s); one the contract rejects for good (malformed signature or signer already registered) fails without retry.

## Request body

- RegisterRequestDto
  - `frostBytes` string, required: ERC-7913 signer bytes for the FROST signer (84 bytes): frostVerifier || abi.encode(pkX, pkY)
  - `signature` string, required: ECDSA signature (65 bytes, r || s || v) over keccak256(abi.encode(chainId, walletAddress, frostBytes)), signed with KEYBAN_INVITE_KEY

## Response `202`

Job enqueued. Poll GET /agent-wallets/register-signer/:jobId for completion.

- object
  - `jobId` string

---

[API](https://skmtc.dev/keyban/apis/keyban-rest-apis.md) · [All operations](https://skmtc.dev/keyban/apis/keyban-rest-apis/llms.txt) · [OpenAPI document](https://skmtc.dev/keyban/apis/keyban-rest-apis/revisions/0bb79a1da961?raw)
